¡Hola a todos! Ha pasado tiempo desde la última vez que posteé algo interesante, y siento que tengo que contribuir más a este foro. He visto gente por ahí, y en otros foros, que pretende entender el formato de ficheros PE, y que saben cómo corromper uno. Mucho código de por ahí es inútil, está buggeado o produce un PE inestable, ¡o directamente crashea! Esto pretende ser una introducción a la corrupción de PE, para aquellos que estén interesados. El programa que voy a mostraros lee un fichero, comprueba si es un PE válido y entonces inserta una nueva sección en el PE. Con la intención de infectar el PE, introduzco una cadena de texto en la nueva sección, a modo de ejemplo. Aquí está, ¡mejóralo o haz lo que quieras con él! 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); //para saber cuanto buffer asignar BYTE *pByte = new BYTE[fileSize]; DWORD dw; //vamos a leer el archivo completo, para poder usar la informacion del PE ReadFile(file, pByte, fileSize, &dw, NULL); PIMAGE_DOS_HEADER dos = (PIMAGE_DOS_HEADER)pByte; if (dos->e_magic != IMAGE_DOS_SIGNATURE) return false; //PE invalido 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); //Usaremos 8 bytes para el nombre de la seccion, porque es el tamano maximo permitido //vamos a insertar toda la informacion requerida sobre nuestra nueva seccion 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); //aqui termina el fichero, en la ultima seccion + el tamano de la propia seccion. SetEndOfFile(file); //ahora cambiaremos el tamano de la imagen, para corresponderse con nuestras modificaciones. //Anadiendo una nueva seccion, el tamano de la imagen ahora es mayor. OH->SizeOfImage = SH[FH->NumberOfSections].VirtualAddress + SH[FH->NumberOfSections].Misc.VirtualSize; //y como hemos anadido una nueva seccion, modificamos el NOS tambien. FH->NumberOfSections += 1; SetFilePointer(file, 0, NULL, FILE_BEGIN); //Y finalmente, anadimos todas las modificaciones al fichero. 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); //como hemos anadido una nueva seccion, debe ser la ultima seccion anadida por el //codigo de la funcion AddSection, asi que nos movemos a la ultima seccion para //introducir nuestra informacion secreta :) 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 ESTUVO AQUI"; WriteFile(file, str, strlen(str), &dw, 0); CloseHandle(file); return TRUE; } void main() { if (AddSection("C:\\Users\\M\\Desktop\\Athena.exe", ".ATH", 400)){ printf("Seccion anadida!\n"); //Vamos a anadir informacion en la ultima seccion if (AddCode("C:\\Users\\M\\Desktop\\Athena.exe")){ printf("Codigo escrito!\n"); } else printf("Error escribiendo codigo!\n"); } else printf("Error anadiendo una seccion!\n"); }