Autor
|
Tema: [?] Duda PE Crypter (Leído 4,605 veces)
|
MeCraniDOS
Desconectado
Mensajes: 337
Sr. Glass
|
Hello!
Estoy intentando entender la estructura PE para poder entender como se hacen los crypters y esas cosas, y me he quedado estancado en una parte, llevo dos dias buscando para no preguntar porque quizás es algo obvio...
Si yo quiero añadir una sección a un ejecutable, tengo que incrementar el NumberOfSections y el SizeOfImage, y luego añadir los datos de la nueva sección, lo estaba programando y tengo de momento esto// .... IMAGE_DOS_HEADER DOS_Header; IMAGE_NT_HEADERS NT_Header; IMAGE_SECTION_HEADER *SECTION_Header; FILE *Archivo = fopen("Test.exe", "rb"); if(Archivo) { CopyFile("Test.exe", "Backup.exe", TRUE); printf("Basic File Information\n\n"); printf("File Name: Test.exe\n"); /* Obtenemos el tamaño del fichero */ fseek(Archivo ,0, SEEK_END ); unsigned long Tamanyo = ftell(Archivo ); fseek(Archivo ,0, SEEK_SET ); printf("File Size: %lu (%lx)", Tamanyo , Tamanyo ); /* Obtenemos la estructura DOS_HEADER */ fread(&DOS_Header , sizeof(IMAGE_DOS_HEADER ), 1, Archivo ); /* Saltamos hasta la posicion donde empieza NT_HEADER, esa posicion se almacena en e_lfanew */ fseek(Archivo , DOS_Header. e_lfanew, SEEK_SET ); fread(&NT_Header , sizeof(IMAGE_NT_HEADERS ), 1, Archivo ); NT_Header.FileHeader.NumberOfSections += 1; //NT_Header.OptionalHeader.SizeOfImage +=; /* Reservamos memoria para las secciones */ SECTION_Header = (IMAGE_SECTION_HEADER *)malloc(NT_Header. FileHeader. NumberOfSections*sizeof(IMAGE_SECTION_HEADER )); /* Guardamos las secciones */ for(unsigned int i=0;i<NT_Header.FileHeader.NumberOfSections-1;i++) { fread(&SECTION_Header [i ], sizeof(IMAGE_SECTION_HEADER ), 1, Archivo ); } // .... // ....
Entonces lo que había pensado era hacer esto:// .... IMAGE_DOS_HEADER DOS_Header; IMAGE_NT_HEADERS NT_Header; IMAGE_SECTION_HEADER *SECTION_Header; FILE *Archivo = fopen("Test.exe", "rb+"); if(Archivo) { CopyFile("Test.exe", "Backup.exe", TRUE); /* Obtenemos el tamaño del fichero */ fseek(Archivo ,0, SEEK_END ); unsigned long Tamanyo = ftell(Archivo ); fseek(Archivo ,0, SEEK_SET ); /* Obtenemos la estructura DOS_HEADER */ fread(&DOS_Header , sizeof(IMAGE_DOS_HEADER ), 1, Archivo ); /* Saltamos hasta la posicion donde empieza NT_HEADER, esa posicion se almacena en e_lfanew */ fseek(Archivo , DOS_Header. e_lfanew, SEEK_SET ); fread(&NT_Header , sizeof(IMAGE_NT_HEADERS ), 1, Archivo ); NT_Header.FileHeader.NumberOfSections += 1; /* Reservamos memoria para las secciones (+1 para la nueva sección)*/ SECTION_Header = (IMAGE_SECTION_HEADER *)malloc((NT_Header. FileHeader. NumberOfSections)*sizeof(IMAGE_SECTION_HEADER )); /* Guardamos las secciones */ for(int i=0;i<NT_Header.FileHeader.NumberOfSections-1;i++) { fread(&SECTION_Header [i ], sizeof(IMAGE_SECTION_HEADER ), 1, Archivo ); } DWORD Tamanyo_RawData = 0x10; DWORD VirtualAddressEnd = SECTION_Header[NT_Header.FileHeader.NumberOfSections-2].VirtualAddress; /* Escribimos los datos de la nueva sección */ BYTE NombreSeccion[8] = ".mecra"; memcpy(SECTION_Header [NT_Header. FileHeader. NumberOfSections-1]. Name, NombreSeccion , 8); SECTION_Header[NT_Header.FileHeader.NumberOfSections-1].SizeOfRawData = Tamanyo_RawData; SECTION_Header[NT_Header.FileHeader.NumberOfSections-1].PointerToRawData = Tamanyo; SECTION_Header[NT_Header.FileHeader.NumberOfSections-1].Characteristics = 0xE0000020; SECTION_Header[NT_Header.FileHeader.NumberOfSections-1].VirtualAddress = VirtualAddressEnd+NT_Header.OptionalHeader.SectionAlignment; SECTION_Header[NT_Header.FileHeader.NumberOfSections-1].Misc.VirtualSize = Tamanyo_RawData; /* Incrementamos el SizeOfImage */ NT_Header.OptionalHeader.SizeOfImage += Tamanyo_RawData; /* Escribimos los datos en el archivo */ //Nos situamos al inicio de la NT Header fseek(Archivo , DOS_Header. e_lfanew, SEEK_SET ); //Escribimos la cabecera fwrite(&NT_Header , sizeof(IMAGE_NT_HEADERS ), 1, Archivo ); //Saltamos al Section Header fseek(Archivo , DOS_Header. e_lfanew + sizeof(IMAGE_NT_HEADERS ), SEEK_SET ); //Escribimos los datos y la cagamos porque nos cargamos lo que sigue al insertar la sección asi ^^ for(int i=0;i<NT_Header.FileHeader.NumberOfSections;i++) { fwrite(&SECTION_Header [i ], sizeof(IMAGE_SECTION_HEADER ), 1, Archivo ); } // .... // ....
Los que sepan del tema ya sabrán donde estoy fallando, y yo me hago una ligera idea
Según he estado leyendo, tiene que haber espacio para poder insertar la sección, cosa que no compruebo, pero donde está el contenido de cada sección? Justo despues de IMAGE_SECTION_HEADER?
Lo que habia pensado era guardar el contenido que hay justo después de la última sección, insertar la mia, insertar el contenido que he guardado, y modificar de cada sección el PointerToRawData sumando el tamaño de la cabecera de la nueva sección, para apuntar de nuevo donde empieza la sección
Si no se hace así, a ver si alguien me puede dar una idea de como se hace.. Tengo los conceptos un poco liados Dos cositas mas
He estado leyendo el código de [Zero] de como añadir una sección..
http://foro.elhacker.net/analisis_y_diseno_de_malware/srcc_anadir_una_seccion-t261801.0.html
Y veo que utiliza PIMAGE_DOS_HEADER; PIMAGE_NT_HEADERS; PIMAGE_SECTION_HEADER; En vez de utilizar estoIMAGE_DOS_HEADER; IMAGE_NT_HEADERS; IMAGE_SECTION_HEADER; Hay alguna diferencia? (Ventajas)
PIMAGE_DOS_HEADER sería un puntero a IMAGE_DOS_HEADER?
Y ya por último...
He visto en un crypter que he encontrado por internet esta rutina para descifrar una sección//Rutina encargada de descifrar la sección cifrada char uncryptroutine[] = //21 bytes "\xB8\x00\x10\x40\x00" //B8 00104000 MOV EAX, 401000 Section Start ||Este valor será modificado "\x80\x30\xBB" //8030 BB XOR BYTE[EAX], BB Key "\x40" //40 INC EAX "\x3D\x00\x45\x40\x00" //3D 00454000 CMP EAX, 404500 Section End ||Este valor será modificado "\x75\xF5" //75 F5 JNZ SHORT -11 (Complemento a dos de 11 = F5) "\xB8\x00\x20\x40\x00" //B8 00204000 MOV EAX, 402000 Pone en EAX el OEP || Este valor será modificado "\xFF\xE0"; //FFE0 JMP EAX Salta al OEP
Se supone que eso son instrucciones en ASM?
Saludos
|
|
|
En línea
|
"La física es el sistema operativo del Universo" -- Steven R Garman
|
|
|
|
x64core
Desconectado
Mensajes: 1.908
|
Según he estado leyendo, tiene que haber espacio para poder insertar la sección, cosa que no compruebo, pero donde está el contenido de cada sección? Justo despues de IMAGE_SECTION_HEADER?
Se puede añadir una sección sin problemas pero requiere más trabajo, se debe incrementar el tamaño de las cabeceras y realinear todas las secciones y posiblemente actualizar RVAs a cualquier posible sección realineada esto es imposible si el ejecutable no tiene tabla de relocalización, bueno es 80% imposible todo depende del tipo de ejecutable. Lo que habia pensado era guardar el contenido que hay justo después de la última sección, insertar la mia, insertar el contenido que he guardado, y modificar de cada sección el PointerToRawData sumando el tamaño de la cabecera de la nueva sección, para apuntar de nuevo donde empieza la sección Si no se hace así, a ver si alguien me puede dar una idea de como se hace.. Tengo los conceptos un poco liados [/size] Eso y muchas cosas más http://foro.elhacker.net/analisis_y_diseno_de_malware/taller_en_construccionsecciones_en_archivos_pe-t362515.0.html;msg1912797#msg1912797definiciones de tipo para punteros a las estructuras. Se supone que eso son instrucciones en ASM?
Saludos Sí
|
|
|
En línea
|
|
|
|
MeCraniDOS
Desconectado
Mensajes: 337
Sr. Glass
|
no se mucho del formato pe , pero te recomiendo que no uses fopen sino la api de windows createfile y readfile y writefile Y eso? Se supone que eso son instrucciones en ASM? Saludos Sí Que bien, que yo sepa el ASM no es así (visualmente), pero ya me ha contestado daryo
Cuando he dicho lo de la sección, era que mas o menos se lo que tengo que hacer, pero la lío tal y como lo hago, ya me habia leido el Taller en construcción que has pasado, y estaba intentando automatizar la Practica 1, agregar una sección, pero no se por donde seguir con el código porque siempre se rompe el ejecutable
|
|
|
En línea
|
"La física es el sistema operativo del Universo" -- Steven R Garman
|
|
|
x64core
Desconectado
Mensajes: 1.908
|
ah te referis a los bytes de las instrucciones. mejor lee el entero archivo de una vez y luego vas analizando las cabeceras del ejecutable y demás cosas.
|
|
|
En línea
|
|
|
|
MeCraniDOS
Desconectado
Mensajes: 337
Sr. Glass
|
Era eso a lo que me refería, gracias
Otra pregunta, Karcrack me ha recomendado que monte el fichero en memoria y haga las modificaciones en memoria
He estado investigando sobre el tema, y me he hecho este mini código, pero no se si es del todo correcto... PIMAGE_DOS_HEADER DOS_Header; char Fichero[] = "Test.exe"; HANDLE hFile = CreateFile((LPCTSTR)Fichero,GENERIC_READ | GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); if(hFile == INVALID_HANDLE_VALUE) { printf("No se puede abrir el fichero: %s Error: %lu\n", Fichero , GetLastError ()); return EXIT_FAILURE; } HANDLE FMapped = CreateFileMapping(hFile, 0, PAGE_READONLY, 0, 0, 0); if(FMapped == INVALID_HANDLE_VALUE) { printf("No se puede mapear el fichero en memoria. Error: %lu\n" , GetLastError ()); CloseHandle(hFile); return EXIT_FAILURE; } BYTE *FileMapped = (BYTE*)MapViewOfFile(FMapped, FILE_MAP_READ, 0, 0, 0); if(FileMapped == NULL) { printf("No se puede mapear el fichero en memoria. Error: %lu\n" , GetLastError ()); CloseHandle(FMapped); CloseHandle(hFile); return EXIT_FAILURE; } DOS_Header = (PIMAGE_DOS_HEADER)&FileMapped[0]; // ....
Alguien me puede decir si es la manera correcta de cargar el ejecutable en memoria? (Mapear el archivo en memoria) O si hay alguna manera mas fácil..
Buenas noches!
|
|
« Última modificación: 2 Julio 2014, 01:05 am por MeCraniDOS »
|
En línea
|
"La física es el sistema operativo del Universo" -- Steven R Garman
|
|
|
x64core
Desconectado
Mensajes: 1.908
|
Era eso a lo que me refería, gracias
Otra pregunta, Karcrack me ha recomendado que monte el fichero en memoria y haga las modificaciones en memoria
He estado investigando sobre el tema, y me he hecho este mini código, pero no se si es del todo correcto... PIMAGE_DOS_HEADER DOS_Header; char Fichero[] = "Test.exe"; HANDLE hFile = CreateFile((LPCTSTR)Fichero,GENERIC_READ | GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); if(hFile == INVALID_HANDLE_VALUE) { printf("No se puede abrir el fichero: %s Error: %lu\n", Fichero , GetLastError ()); return EXIT_FAILURE; } HANDLE FMapped = CreateFileMapping(hFile, 0, PAGE_READONLY, 0, 0, 0); if(FMapped == INVALID_HANDLE_VALUE) { printf("No se puede mapear el fichero en memoria. Error: %lu\n" , GetLastError ()); CloseHandle(hFile); return EXIT_FAILURE; } BYTE *FileMapped = (BYTE*)MapViewOfFile(FMapped, FILE_MAP_READ, 0, 0, 0); if(FileMapped == NULL) { printf("No se puede mapear el fichero en memoria. Error: %lu\n" , GetLastError ()); CloseHandle(FMapped); CloseHandle(hFile); return EXIT_FAILURE; } DOS_Header = (PIMAGE_DOS_HEADER)&FileMapped[0]; // ....
Alguien me puede decir si es la manera correcta de cargar el ejecutable en memoria? (Mapear el archivo en memoria) O si hay alguna manera mas fácil..
Buenas noches! ¿Porqué mapear el archivo? Suponiendo que se quiere agregar la sección al ejecutable y luego guardar la nueva imagen en disco simplemente leer la imagen CreateFile+ReadFile
|
|
|
En línea
|
|
|
|
|
x64core
Desconectado
Mensajes: 1.908
|
Para mi el mapear el archivo es innecesario sino que alguien diga porque es necesario mapearlo.
|
|
|
En línea
|
|
|
|
Karcrack
Desconectado
Mensajes: 2.416
Se siente observado ¬¬'
|
Para mi el mapear el archivo es innecesario sino que alguien diga porque es necesario mapearlo.
No es necesario mapearlo. En mi opinión es más sencillo trabajar cuando te olvidas de buffers. No tienes que usar una cosa para leer y otra para escribir, sencillamente trabajas con punteros y luego lo reflejas en disco...
|
|
|
En línea
|
|
|
|
|
Mensajes similares |
|
Asunto |
Iniciado por |
Respuestas |
Vistas |
Último mensaje |
|
|
Crypter
Programación Visual Basic
|
CamaleonB
|
8
|
5,474
|
15 Enero 2008, 17:50 pm
por ~~
|
|
|
Duda haciendo un crypter
Programación Visual Basic
|
aaronduran2
|
7
|
3,260
|
27 Septiembre 2008, 13:25 pm
por aaronduran2
|
|
|
Duda para modificar un crypter
Análisis y Diseño de Malware
|
caramel0rar0
|
4
|
4,476
|
5 Enero 2012, 14:16 pm
por caramel0rar0
|
|
|
[Duda] ¿Cómo crear un crypter?
« 1 2 »
Análisis y Diseño de Malware
|
Yoker66666
|
13
|
13,081
|
23 Julio 2012, 18:30 pm
por m0rf
|
|
|
Crypter Duda
Análisis y Diseño de Malware
|
Jeezy
|
1
|
2,557
|
21 Abril 2018, 04:12 am
por xv0
|
|