Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: Vaagish en 7 Octubre 2014, 19:39 pm



Título: Problema al modificar sección .text
Publicado por: Vaagish en 7 Octubre 2014, 19:39 pm
Hola!

Estoy armando un programa que modifica la sección .text de un ejecutable..
Uso las estructuras:

Código
  1. PIMAGE_DOS_HEADER
  2. PIMAGE_NT_HEADERS
  3. PIMAGE_OPTIONAL_HEADER
  4. PIMAGE_SECTION_HEADER

Por lo que entiendo si hago esto:

Código
  1. // Ajusto el punto de inicio a lo que necesito...
  2.  
  3. //IOH->AddressOfEntryPoint += 16;
  4. IOH->AddressOfEntryPoint = IOH->BaseOfCode + 16;

Cualquiera de esas dos variantes deberían hacer lo mismo, verdad? Bueno, el problema es que en mi programa de pruebas funciona bien, pero en otros no funciona,, el entrypoint no cambia, y si cambia, lo hace mal..

La pregunta: ¿Puede verse afectado esto por algo asi como un relloc, o hay algo que no tengo en cuanta?

Gracias! Saludos!


Título: Re: Problema al modificar sección .text
Publicado por: Eternal Idol en 7 Octubre 2014, 20:19 pm
Si la primera instruccion de codigo en la sección no es el entry point no es lo mismo, es decir siempre que AddressOfEntryPoint sea diferente de BaseOfCode.

DUMPBIN /headers calc.exe

...
OPTIONAL HEADER VALUES
             10B magic # (PE32)
            9.00 linker version
           52E00 size of code
           6A600 size of initialized data
               0 size of uninitialized data
           12D6C entry point (01012D6C)
            1000 base of code

           52000 base of data
         1000000 image base (01000000 to 010BFFFF)
...

     
AddressOfEntryPoint
    A pointer to the entry point function, relative to the image base address. For executable files, this is the starting address.

BaseOfCode
    A pointer to the beginning of the code section, relative to the image base.

¿Estas escribiendo en disco o en memoria?


Título: Re: Problema al modificar sección .text
Publicado por: Vaagish en 7 Octubre 2014, 21:06 pm
Hi! Gracias por responder EI!

Citar
AddressOfEntryPoint
    A pointer to the entry point function, relative to the image base address. For executable files, this is the starting address.

BaseOfCode
    A pointer to the beginning of the code section, relative to the image base.

Con que ahí esta el asunto.. pero cambie el que cambie, no queda en la dirección que quiero..

Citar
¿Estas escribiendo en disco o en memoria?

En memoria.. tengo una imagen sacada con CreateFileMapping y MapViewOfFile..

Puntualmente entonces lo que necesitaría es que el entrypoint sea siempre desde baseofcode + 16, siendo (generalmente) 0040100.. pero baseofcode puede cambiar, no puedo poner eso como una constante  :silbar:
Y no me funciono..

Gracias! Saludos!


Título: Re: Problema al modificar sección .text
Publicado por: Eternal Idol en 7 Octubre 2014, 21:36 pm
No se muy bien que estas tratando de hacer, te recomiendo usar el WinDbg (!dh direccion te ayudara) para ir depurando tu codigo.


Título: Re: Problema al modificar sección .text
Publicado por: Vaagish en 7 Octubre 2014, 23:31 pm
Bueno, después de darle vueltas al asunto me parece que lo mejor va a ser modificar "la lógica" del mismo...

El problema radica en que yo al principio de la sección .text pongo X código, al final pongo otro Z código.. mi intención era ejecutar código X y Z primero, para luego saltar al código del ejecutable..

Bueno, si EntryPoint de ejecutable es 0040100 me "pisa" el código X, y si EntryPoint es distinto pasa otra cosa...

Voy a hacer unas pruebas, si todo sale bien pongo el resultado, sino pregunto  :xD

Citar
No se muy bien que estas tratando de hacer, te recomiendo usar el WinDbg (!dh direccion te ayudara) para ir depurando tu codigo.

Gracias EI, me sirvió para razonar otras posibles situaciones..

Saludos!


Título: Re: Problema al modificar sección .text
Publicado por: Vaagish en 9 Octubre 2014, 22:14 pm
Bueno.. no di con la solucion.. algo me esta faltando,, pongo el code a ver si alguien ve algo malo..

Código
  1. if(strcmp((char *)ISH->Name, ".text") == 0)
  2. {
  3.  
  4. //  Se agranda la sección para ocupar hasta un bloque de 16 justo
  5. while(ISH->Misc.VirtualSize%16 != 0) ISH->Misc.VirtualSize++;
  6.  
  7. //  Funcion "Cifradora", se cifra la sección .text
  8. Cifra((DWORD)(lpFileMap + ISH->PointerToRawData), ISH->Misc.VirtualSize);
  9.  
  10. // Una copia de la sección .text cifrada (+ align 16)
  11. char *lptextsect = new char[ISH->Misc.VirtualSize];
  12. memset(lptextsect, 0, ISH->Misc.VirtualSize);
  13. memcpy(lptextsect, (void *)(DWORD)(lpFileMap + ISH->PointerToRawData), ISH->Misc.VirtualSize);
  14.  
  15. // Se guarda el punto de inicio  ** push Entrypoint **
  16. ASize = IOH->ImageBase + IOH->AddressOfEntryPoint;
  17.  
  18. __asm { mov eax, ASize }
  19. __asm { mov dword ptr[opcodes + 11h], eax }
  20.  
  21. // VirtualSize a EAX y se ajustan los jmps, calls y cmp
  22. // ****************************************************
  23. ASize = ISH->Misc.VirtualSize;
  24. __asm { mov eax, ASize }
  25.  
  26. __asm { mov dword ptr[opcodes + 44h], eax } // -> call endopcodes
  27. __asm { mov dword ptr[endopcodes + 5], eax } // -> RETADDR, ???? (Size To Decrypt)
  28.  
  29. __asm { neg eax }
  30. __asm { mov dword ptr[opcodes + 38h], eax } // -> cmp ebx, -????
  31.  
  32. ASize = sizeof(opcodes)-8;
  33. __asm { sub eax, ASize }
  34. __asm { mov dword ptr[endopcodes + 0Ch], eax } // -> jmp -????
  35.  
  36. // ****************************************************
  37.  
  38.  
  39. // Se Copia todo al PE!
  40. DWORD StartOffset = (DWORD)lpFileMap + ISH->PointerToRawData;
  41. memcpy((void *)(StartOffset), (void *)opcodes, sizeof(opcodes));
  42. memcpy((void *)(StartOffset + sizeof(opcodes)-1), (void *)(lptextsect), ISH->Misc.VirtualSize);
  43. memcpy((void *)(StartOffset + ISH->Misc.VirtualSize + sizeof(opcodes)-1), (void *)endopcodes, sizeof(endopcodes));
  44. // ***************************************************************
  45.  
  46. // Se ajusta la sección
  47. ISH->Characteristics = 0xE0000020; // Lectura, Ejecucion y escritura!
  48. IOH->AddressOfEntryPoint = (DWORD)IOH->BaseOfCode + 16; // Empezar despues de la clave de 16 digitos
  49. }

Bueno, la idea es ir recorriendo las secciones (Funciona), e ir buscando la sección ".text", una vez encontrada, cifrarla y ponerle su respectiva función descifradora (opcodes y endopcodes)

Desde la linea 15 a la 35 lo que hago es ajustar esos "opcodes", (que funciona tambien)..

El Problema: Si el EntryPoint es 00401000 lo cambio por 00401010 y todo bien! Si el EntryPoint es otro cualquiera, no lo puedo modificar a 00401010! Queda el que tenia antes, y lo raro, el olly me indica con rojo la direccion 00401010 pero igual inicia en donde era el EntryPoint..

Gracias por su tiempo! Saludos!


Título: Re: Problema al modificar sección .text
Publicado por: Eternal Idol en 10 Octubre 2014, 00:02 am
¿Que se supone que haces con esto al final? ¿Escribir un nuevo ejecutable cifrado en disco?


Título: Re: Problema al modificar sección .text
Publicado por: Vaagish en 10 Octubre 2014, 00:25 am
Citar
¿Que se supone que haces con esto al final? ¿Escribir un nuevo ejecutable cifrado en disco?

Upss.. perdón,, pensé que había dicho al principio.. Es un crypter, no creo un nuevo archivo no  :silbar:

Trabajo sobre la imagen del mismo PE, la abro con CreateFile,, uso CreateFileMapping y cierro la imagen... Capaz que la *** ahí?!   :rolleyes:

Saludos!


Título: Re: Problema al modificar sección .text
Publicado por: Eternal Idol en 10 Octubre 2014, 00:34 am
No pero entonces mira el resultado con DUMPBIN (/headers). Otra cargalo en WinDbg - File>>Open Executable/ Ctrl + E) y antes de nada hace !dh modulo. ¿Es correcto el entry point o no segun esas herramientas?


Título: Re: Problema al modificar sección .text
Publicado por: Vaagish en 10 Octubre 2014, 01:38 am
Huu.. si.. cualquiera.. Con Olly que es la única herramienta que tengo ahora a mano me dice esto como EntryPoint

ASCII = rC
HEX = 09 72 43

Ahora si que me descoloco, pero es una buena pista.. en casa lo tendré que ver con DUMPBIN y WinDbg

Que raro.. en un ejecutable simple, con 3 secciones funciona.. Bue, reviso y posteo..

Gracias Genio!


Actualizo:

Bueno.. creo haber encontrado algo.. pero por que lo hace??

Netcat antes de cifrar (dumpbin /HEADERS):

Citar
Name: .text
VirtualSize: 5234
VirtualAddress: 1000
SizeOfRawData: 5400
FilePointerToRawData: 400
SizeOfCode: 5400
RVA EntryPoint: 1160
Summary: 6000

Netcat después de cifrar (dumpbin /HEADERS):

Citar
Name: .text
VirtualSize: 5240 (Aumento para alinear el code)
VirtualAddress: 1000
SizeOfRawData: 5400
FilePointerToRawData: 400
SizeOfCode: 5400
RVA EntryPoint: 1010 (Empiezo donde necesito empezar, pero no funca)

Netcat antes de cifrar (WinDbg !dh):

Citar
.text
AddressOfEntryPoint: 1160
BaseOfCode: 1000
Align 16

Netcat después de cifrar (WinDbg !dh):

Citar
.text
AddressOfEntryPoint: 1160
BaseOfCode: 1000
Align (no align specified)   -->  :o

Bueno.. ahí esta.. Ese align debe estar *!&*"·$ el formato.. Perché ?

Gracias!! Saludos!


Título: Re: Problema al modificar sección .text
Publicado por: Vaagish en 16 Octubre 2014, 23:48 pm
Bueno.. como no funciona y ya no entiendo que pasa, hice un codigo ejemplo..

Alguien se anima a probar este codigo?

Código
  1. int Crypt(char *filename, char *section)
  2. {
  3. LPBYTE Start;
  4.  
  5. HANDLE hFile = CreateFile(filename, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
  6. if (hFile == INVALID_HANDLE_VALUE)
  7. return -1;
  8. HANDLE hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 0, NULL);
  9. if (hFileMapping == 0){
  10. CloseHandle(hFile);
  11. return -1;
  12. }
  13. LPBYTE lpFileMap = (LPBYTE)MapViewOfFile(hFileMapping, FILE_MAP_ALL_ACCESS, 0, 0, 0);
  14. if (lpFileMap == 0){
  15. CloseHandle(hFileMapping);
  16. CloseHandle(hFile);
  17. return -1;
  18. }
  19.  
  20. PIMAGE_DOS_HEADER IDH = (PIMAGE_DOS_HEADER) lpFileMap;
  21. PIMAGE_NT_HEADERS INH = (PIMAGE_NT_HEADERS)((BYTE *)IDH + IDH->e_lfanew);
  22. PIMAGE_OPTIONAL_HEADER IOH = (PIMAGE_OPTIONAL_HEADER)&INH->OptionalHeader;
  23. PIMAGE_SECTION_HEADER ISH;
  24.  
  25. for (byte i = 0; i < INH->FileHeader.NumberOfSections; i++)
  26. {
  27.  
  28. ISH = (PIMAGE_SECTION_HEADER)(lpFileMap + IDH->e_lfanew + sizeof(IMAGE_NT_HEADERS)+ sizeof(IMAGE_SECTION_HEADER)*i);
  29.  
  30. Start = lpFileMap + ISH->PointerToRawData;
  31. if (strcmp((char *)ISH->Name, section) == 0)
  32. {
  33. for(DWORD i=0; i<ISH->Misc.VirtualSize; i++)
  34. Start[i] ^= 'a';
  35. }
  36. }
  37.  
  38. UnmapViewOfFile((LPCVOID)lpFileMap);
  39. CloseHandle(hFileMapping);
  40. CloseHandle(hFile);
  41.  
  42. return 0;
  43. }

El problema que tengo yo con esto es que al cifrar el programa Netcat, le cambia el EntryPoint a 4057F2 cuando debería ser otro..

Esta claro, pero por las dudas...
Código
  1. Crypt("nc.exe", ".text");

Gracias! Saludos!


Título: Re: Problema al modificar sección .text
Publicado por: Eternal Idol en 17 Octubre 2014, 00:04 am
Mmm al parecer te estas pasando de rango ... ¿Donde se supone que estas cambiando el entry point en ese codigo exactamente? ¿O es un efecto no deseado?

Tendrias que usar SizeOfRawData.


Título: Re: Problema al modificar sección .text
Publicado por: Vaagish en 17 Octubre 2014, 00:26 am
Citar
¿Donde se supone que estas cambiando el entry point en ese codigo exactamente? ¿O es un efecto no deseado?

Es un defecto no deseado  :xD
Así como esta no le cambio el EP, se cambia solo..  :rolleyes:

Citar
¿No sera que Start deberia usar VirtualAddress en realidad?:
Start = lpFileMap + ISH->PointerToRawData;

Ya probé hasta con la dirección psíquica!

Citar
Mmm al parecer te estas pasando de rango

Ya no tengo ni idea que puede ser.. hace rato que estoy con esto, y me estoy por decantar a que es "problema" del netcat..   :¬¬

Saludos! Gracias!


Título: Re: Problema al modificar sección .text
Publicado por: Eternal Idol en 17 Octubre 2014, 00:29 am
No, Start estaba bien (no lo estas mappeando con SEC_IMAGE), pero entonces deberias usar SizeOfRawData. No tengo ese ejecutable a mano, pero con unos simples printfs podrias ver a que equivale lpFileMap, Start e IOH que es lo que estas tocando sin querer.


Título: Re: Problema al modificar sección .text
Publicado por: Vaagish en 17 Octubre 2014, 00:43 am
Citar
entonces deberias usar SizeOfRawData

Oky, cambiado..

Citar
No tengo ese ejecutable a mano, pero con unos simples printfs podrias ver a que equivale lpFileMap, Start e IOH que es lo que estas tocando sin querer.

Ya imprimí, use dumpbin, windgb, olly, la mar en coche, etc, etc  :xD

Ya creo que es con nc, voy a probar con otros ejecutables grandes.. a ver que pasa..

Salu2!


Título: Re: Problema al modificar sección .text
Publicado por: Eternal Idol en 17 Octubre 2014, 00:47 am
Ya imprimí, use dumpbin, windgb, olly, la mar en coche, etc, etc  :xD

¿Y que te dio? Start deberia ser muy cercano a IOH para que se produzca el problema ... o es otra parte del programa de la cual no tenemos el codigo. ¿Probaste a aislar esto solo y ya genera el problema?


Título: Re: Problema al modificar sección .text
Publicado por: Vaagish en 17 Octubre 2014, 00:59 am
Mira:

Valores de Start

Citar
900098 -> IOH

900400 -> .text
905800 -> .data
905A00 -> .rdata
900000 -> .bss
906C00 -> .idata
907800 -> .CRT
907A00 -> .tls

Si comento esto:
Código
  1. for(DWORD i=0; i<ISH->SizeOfRawData; i++)
  2. Start[i] ^= 'a';

El EP no cambia,, pero claro.. tampoco se cifra   :silbar:

Ahora que veo bien... porque va a estar IOH en ese lugar ???? No esta mal eso?

Salu2


Título: Re: Problema al modificar sección .text
Publicado por: Eternal Idol en 17 Octubre 2014, 01:09 am
Si tu Start arranca en 0x900400 no veo como puede escribir en 0x9000A8 ... ¿El nc.exe es el mismo que esta aca? http://eternallybored.org/misc/netcat/ Con ese no me pasa lo que decis ... ¿Tu programa es de 32 o 64 bits? ¿Estas viendo el EP con DUMPBIN, no?


Título: Re: Problema al modificar sección .text
Publicado por: Vaagish en 17 Octubre 2014, 03:37 am
Yo tampoco.. voy a bajar ese nc a ver si es por eso.. tengo una version de nc con su codigo, pero jamas pense que fuera eso.. va.. ya dudaba de todo en realidad..

Es de 32 bits (nc y crypter)

Mañana actualizo..

Saludos!


Título: Re: Problema al modificar sección .text
Publicado por: MCKSys Argentina en 17 Octubre 2014, 06:57 am
Bueno, no programo en C++ (sólo lo sé leer) pero si sé algo sobre este tema.

Agrandar una sección (y más aún, la sección de código) es un dolor de cabeza bastante grande. Quizás, si el código del cripter es pequeño, podrías encontrar algún code-cave en la sección e insertarlo ahí. Pero esto no siempre es posible.

Lo que normalmente se hace es agregar una nueva sección ejecutable al EXE y desde ahi puedes reconstruir el ejecutable tal cual estaba.

Si quieres un ejemplo, puedes revisar lo que hace el packer UPX (http://upx.sourceforge.net/).

De ahí seguro sacarás ideas interesantes...

Saludos!


Título: Re: Problema al modificar sección .text
Publicado por: Vaagish en 17 Octubre 2014, 19:25 pm
Citar
¿El nc.exe es el mismo que esta aca? http://eternallybored.org/misc/netcat/ Con ese no me pasa lo que decis

Ya lo baje, esa version 1.12 pesa un poco mas, (yo tenia la 1.11) A vos no te pasa EI pusiste ahi.. el mio sigue igual..

Debe ser un problema de tamaño y sino dejo la computación y me dedico a la mecánica  :xD

Vos tenes 64bits.. yo 32.. es la única diferencia que noto..

@MCKSys: En ese code no se cambia el tamaño, pero en el otro crypter si, voy a revisar el UPX a ver que trae.. a lo mejor sea agregar una sección mas la solución.. como decís..

Saludos! Gracias!!


Título: Re: Problema al modificar sección .text
Publicado por: Eternal Idol en 17 Octubre 2014, 19:31 pm
Ya lo baje, esa version 1.12 pesa un poco mas, (yo tenia la 1.11) A vos no te pasa EI pusiste ahi.. el mio sigue igual..

1290 entry point (00401290)

¿Te sigue pasando con esa version? Vos tomas el ejecutable original, lo pasas por la funcion Crypt y despues el DUMPBIN te dice que cambio el EP. ¿Correcto? No puede ser  ;D Tu codigo no puede ser el mismo, debes estar haciendo algo mas. Lo unico que yo hice fue sumar un miserable main:
Código
  1. void main(int argc, char **argv)
  2. {
  3.   Crypt(argv[1], argv[2]);
  4. }

Debe ser un problema de tamaño y sino dejo la computación y me dedico a la mecánica  :xD

No, de alguna manera estas escribiendo donde no debes, no hay otra forma para que cambie el EP, es un campo en una estructura que no cambia de lugar ... a menos que la estes haciendo apuntar a otro lado  ;D

Vos tenes 64bits.. yo 32.. es la única diferencia que noto..

El S.O. es 64 si pero originalmente compile el programa en 32 bits, solo lo compile en 64 para ver si asi explotaba, cosa que no hizo.


Título: Re: Problema al modificar sección .text
Publicado por: Vaagish en 17 Octubre 2014, 20:37 pm
Citar
1290 entry point (00401290)

¿Te sigue pasando con esa version? Vos tomas el ejecutable original, lo pasas por la funcion Crypt y despues el DUMPBIN te dice que cambio el EP. ¿Correcto?

Mmm.. Si / No.. Resultados de dumpbin:

Antes de cifrar: 1290 EntryPoint
Después de cifrar: 1290 EntryPoint

Según dumpbin queda igual.. pero en ollydbg empieza en 00405822, ademas, si inserto la rutina descifradora, windows dice que "dejo de funcionar" (suponiendo que todo esta bien,,, menos ese maldito EP!)

Yo llamo así a la función (pero uso CommandLineToArgvW):
Código
  1. Crypt(filenin, ".text");

Igual con una simple pausa puedo ver que los parámetros de Crypt están bien...

EDITO: Tengo otros PE's que NO pasa lo mismo..  :rolleyes:


Título: Re: Problema al modificar sección .text
Publicado por: Eternal Idol en 17 Octubre 2014, 21:13 pm
Mmm.. Si / No.. Resultados de dumpbin:

Entonces no tenes ese problema que decis realmente; tendras otro, te recomiendo usar el WinDbg.