Salut à tous ! Ça faisait longtemps que je n'avais pas posté quelque chose d'interessant et j'ai envie de contribuer un peu plus à ce forum. J'ai vu pas mal de gens ici, et sur d'autres forums, qui prétendaient connaitre le format PE alors qu'ils ne savaient que le corrompre. Ils produisent pas mal de code, inutiles, buggés ou qui rendent tout simplement le PE infecté instable, le faisant parfois crasher. Cet article a pour but d'être une introduction à la corruption de PE, pour ceux que cela interesse évidemment ! Le programme qui suit fonctionne simplement: il lit un fichier, test si c'est un PE valide, et si c'est le cas il inserre une nouvelle section à l'intérieur. Avec le principe d'infection en tête, je vais seulement inserrer des chaines de caractères dans la section nouvellement créée, juste pour en faire un exemple. Et voici sans plus tarder le code, améliorez le comme vous le voulez et faites ce que vous voulez avec ! ENJOY!!! #include #include DWORD align(DWORD size, DWORD align, DWORD addr){ if (!(size % align)) return addr + size; return addr + (size / align + 1) * align; } bool AddSection(char *filepath, char *sectionName, DWORD sizeOfSection){ HANDLE file = CreateFile(filepath, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (file == INVALID_HANDLE_VALUE) return false; DWORD fileSize = GetFileSize(file, NULL); //Pour connaître la taille du buffer à allouer BYTE *pByte = new BYTE[fileSize]; DWORD dw; //On récupère l'entiereté du fichier pour pouvoir utiliser les informations que nous fournit le format PE ReadFile(file, pByte, fileSize, &dw, NULL); PIMAGE_DOS_HEADER dos = (PIMAGE_DOS_HEADER)pByte; if (dos->e_magic != IMAGE_DOS_SIGNATURE) return false; //invalid PE PIMAGE_FILE_HEADER FH = (PIMAGE_FILE_HEADER)(pByte + dos->e_lfanew + sizeof(DWORD)); PIMAGE_OPTIONAL_HEADER OH = (PIMAGE_OPTIONAL_HEADER)(pByte + dos->e_lfanew + sizeof(DWORD)+sizeof(IMAGE_FILE_HEADER)); PIMAGE_SECTION_HEADER SH = (PIMAGE_SECTION_HEADER)(pByte + dos->e_lfanew + sizeof(IMAGE_NT_HEADERS)); ZeroMemory(&SH[FH->NumberOfSections], sizeof(IMAGE_SECTION_HEADER)); CopyMemory(&SH[FH->NumberOfSections].Name, sectionName, 8); //On utilise 8 octets pour le nom de la section parce que c'est la ta taille maximale que nous pouvons allouer à d'un nom de section //Inserrons maintenant toutes les infos requises à propos de notre nouvelle section SH[FH->NumberOfSections].Misc.VirtualSize = align(sizeOfSection, OH->SectionAlignment, 0); SH[FH->NumberOfSections].VirtualAddress = align(SH[FH->NumberOfSections - 1].Misc.VirtualSize, OH->SectionAlignment, SH[FH->NumberOfSections - 1].VirtualAddress); SH[FH->NumberOfSections].SizeOfRawData = align(sizeOfSection, OH->FileAlignment, 0); SH[FH->NumberOfSections].PointerToRawData = align(SH[FH->NumberOfSections - 1].SizeOfRawData, OH->FileAlignment, SH[FH->NumberOfSections - 1].PointerToRawData); SH[FH->NumberOfSections].Characteristics = 0xE00000E0; /* 0xE00000E0 = IMAGE_SCN_MEM_WRITE | IMAGE_SCN_CNT_CODE | IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ */ SetFilePointer(file, SH[FH->NumberOfSections].PointerToRawData + SH[FH->NumberOfSections].SizeOfRawData, NULL, FILE_BEGIN); //On atteint la fin du fichier ici: la dernière section + sa taille SetEndOfFile(file); //Maintenant, on change la taille de l'image pour qu'elle corresponde à nos modifications //En ajoutant une nouvelle section, la taille de l'image augmente OH->SizeOfImage = SH[FH->NumberOfSections].VirtualAddress + SH[FH->NumberOfSections].Misc.VirtualSize; //Nous avons ajouté la section, on change également le NOS FH->NumberOfSections += 1; SetFilePointer(file, 0, NULL, FILE_BEGIN); //Et finalement on applique les modifications au fichier WriteFile(file, pByte, fileSize, &dw, NULL); CloseHandle(file); return true; } bool AddCode(char *filepath){ HANDLE file = CreateFile(filepath, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (file == INVALID_HANDLE_VALUE) return false; DWORD filesize = GetFileSize(file, NULL); BYTE *pByte = new BYTE[filesize]; DWORD dw; ReadFile(file, pByte, filesize, &dw, NULL); PIMAGE_DOS_HEADER dos = (PIMAGE_DOS_HEADER)pByte; PIMAGE_NT_HEADERS nt = (PIMAGE_NT_HEADERS)(pByte + dos->e_lfanew); //Puisque nous avons ajouté une nouvelle section, elle doit être la dernière section ajoutée à cause du code à l'interieur //AddSection function, ainsi nous devrions pouvoir inserrer notre code dans la dernière section ;) PIMAGE_SECTION_HEADER first = IMAGE_FIRST_SECTION(nt); PIMAGE_SECTION_HEADER last = first + (nt->FileHeader.NumberOfSections - 1); SetFilePointer(file, last->PointerToRawData, NULL, FILE_BEGIN); char *str = "ATHENIAN WAS HERE"; WriteFile(file, str, strlen(str), &dw, 0); CloseHandle(file); return TRUE; } void main() { if (AddSection("C:\\Users\\M\\Desktop\\Athena.exe", ".ATH", 400)){ printf("Section added!\n"); //Inserrons nos données dans la dernière section if (AddCode("C:\\Users\\M\\Desktop\\Athena.exe")){ printf("Code written!\n"); } else printf("Error writting code!\n"); } else printf("Error adding section!\n"); } Traduit de l'anglais par S01den ;)