Problema al modificar sección .text

Iniciado por Vaagish, 7 Octubre 2014, 19:39 PM

0 Miembros y 4 Visitantes están viendo este tema.

Vaagish

Hola!

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

Código (cpp) [Seleccionar]
PIMAGE_DOS_HEADER
PIMAGE_NT_HEADERS
PIMAGE_OPTIONAL_HEADER
PIMAGE_SECTION_HEADER


Por lo que entiendo si hago esto:

Código (cpp) [Seleccionar]
// Ajusto el punto de inicio a lo que necesito...

//IOH->AddressOfEntryPoint += 16;
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!

Eternal Idol

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?
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

Vaagish

Hi! Gracias por responder EI!

CitarAddressOfEntryPoint
    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!

Eternal Idol

No se muy bien que estas tratando de hacer, te recomiendo usar el WinDbg (!dh direccion te ayudara) para ir depurando tu codigo.
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

Vaagish

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

CitarNo 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!

Vaagish

Bueno.. no di con la solucion.. algo me esta faltando,, pongo el code a ver si alguien ve algo malo..

Código (cpp) [Seleccionar]
if(strcmp((char *)ISH->Name, ".text") == 0)
{

//  Se agranda la sección para ocupar hasta un bloque de 16 justo
while(ISH->Misc.VirtualSize%16 != 0) ISH->Misc.VirtualSize++;

//  Funcion "Cifradora", se cifra la sección .text
Cifra((DWORD)(lpFileMap + ISH->PointerToRawData), ISH->Misc.VirtualSize);

// Una copia de la sección .text cifrada (+ align 16)
char *lptextsect = new char[ISH->Misc.VirtualSize];
memset(lptextsect, 0, ISH->Misc.VirtualSize);
memcpy(lptextsect, (void *)(DWORD)(lpFileMap + ISH->PointerToRawData), ISH->Misc.VirtualSize);

// Se guarda el punto de inicio  ** push Entrypoint **
ASize = IOH->ImageBase + IOH->AddressOfEntryPoint;

__asm { mov eax, ASize }
__asm { mov dword ptr[opcodes + 11h], eax }

// VirtualSize a EAX y se ajustan los jmps, calls y cmp
// ****************************************************
ASize = ISH->Misc.VirtualSize;
__asm { mov eax, ASize }

__asm { mov dword ptr[opcodes + 44h], eax } // -> call endopcodes
__asm { mov dword ptr[endopcodes + 5], eax } // -> RETADDR, ???? (Size To Decrypt)

__asm { neg eax }
__asm { mov dword ptr[opcodes + 38h], eax } // -> cmp ebx, -????

ASize = sizeof(opcodes)-8;
__asm { sub eax, ASize }
__asm { mov dword ptr[endopcodes + 0Ch], eax } // -> jmp -????

// ****************************************************


// Se Copia todo al PE!
DWORD StartOffset = (DWORD)lpFileMap + ISH->PointerToRawData;
memcpy((void *)(StartOffset), (void *)opcodes, sizeof(opcodes));
memcpy((void *)(StartOffset + sizeof(opcodes)-1), (void *)(lptextsect), ISH->Misc.VirtualSize);
memcpy((void *)(StartOffset + ISH->Misc.VirtualSize + sizeof(opcodes)-1), (void *)endopcodes, sizeof(endopcodes));
// ***************************************************************

// Se ajusta la sección
ISH->Characteristics = 0xE0000020; // Lectura, Ejecucion y escritura!
IOH->AddressOfEntryPoint = (DWORD)IOH->BaseOfCode + 16; // Empezar despues de la clave de 16 digitos
}


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!

Eternal Idol

¿Que se supone que haces con esto al final? ¿Escribir un nuevo ejecutable cifrado en disco?
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

Vaagish

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!

Eternal Idol

#8
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?
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

Vaagish

#9
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):

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

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

CitarName: .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!