Análisis packer 01 - Parte VIII
Errores típicos de ejecución
En la Parte VII de este tutorial vimos cómo resolver un problema curioso sobre código que se ejecutaba antes del OEP. Después de todo lo anterior podríamos pensar en un dumpeado correcto que he llamado dumpe_08.exe, sin embargo, (esto ya lo esperaba) lo ejecuto en OllyDBG y tras pulsar F9 obtengo el siguiente error que voy a de nominar error típico de ejecución (y vamos a ver cómo resolverlo de forma general): "Don't know how to continue because memory at address 01FF0000 is not readable":
A partir de aquí son todo errores de este tipo. No puede leer la dirección XXXXXXXX. Esto se produce porque estas direcciones como 01F0000 han sido emuladas, encriptadas por el packer usando en algunos casos la máquina virtual y en el dumpeado no existen, hay que hacer el proceso que ya he explicado. Voy a analizar 01F0000 y nos servirá como ejemplo genérico para las siguientes.
Analizando la dirección 01FF0000 en el dumpeado
Acepto el mensaje de error, pongo OllyDBG en pause y me dirijo a la pila. Allí veo el último retorno:
0012FBBC 004A9440 RETURN to dumpe_08.004A9440 from dumpe_08.0040BCF0
Me dirijo al código desensamblado del cual procede:
004A943B . E8 B028F6FF call 0040BCF0
004A9440 . 85C0 test eax,eax
Y me dirijo a la call 0040BCF0 a ver qué ocurre:
0040BCF0 /$ 68 0000FF01 push 1FF0000
0040BCF5 \. C3 retn
Como puedes observar, no tiene ningún misterio. El código se redirige a 01FF0000 y es una dirección que no existe en el dumpeado. Por este motivo vamos a analizar la dirección 01FF0000 en el protegido.
Analizando la dirección 01FF0000 en el protegido
Cargo en OllyDBG el archivo original y pongo un Hardware Breakpoint en 01FF0000. Cuando para examino el código:
01FF0000 56 push esi
01FF0001 57 push edi
01FF0002 53 push ebx
01FF0003 83EE F5 sub esi,-0B
01FF0006 C1DE 31 rcr esi,31
01FF0009 64:EB 02 jmp short 01FF000E
...
Es un código ofuscado pero sencillo. En otros caso hace uso de la máquina virtual, que ya he explicado cómo analizarla. Uso el plugin Code-Doctor, lo analizo pasando también con F7, examino códigos similares de un Delphi 7 cualquiera y al final la subrutina 01FF0000 me queda así:
00BDA000 56 push esi
00BDA001 57 push edi
00BDA002 53 push ebx
00BDA003 89C6 mov esi,eax
00BDA005 89D7 mov edi,edx
00BDA007 09C0 or eax,eax
00BDA009 74 03 je short 00BDA00E
00BDA00B 8B40 FC mov eax,dword ptr ds:[eax-4]
00BDA00E 09D2 or edx,edx
00BDA010 74 03 je short 00BDA015
00BDA012 8B52 FC mov edx,dword ptr ds:[edx-4]
00BDA015 89C1 mov ecx,eax
00BDA017 39D1 cmp ecx,edx
00BDA019 76 02 jbe short 00BDA01D
00BDA01B 89D1 mov ecx,edx
00BDA01D 39C9 cmp ecx,ecx
00BDA01F F3:A6 repe cmps byte ptr es:[edi],byte ptr ds:[esi]
00BDA021 74 2A je short 00BDA04D
00BDA023 8A5E FF mov bl,byte ptr ds:[esi-1]
00BDA026 80FB 61 cmp bl,61
00BDA029 72 08 jb short 00BDA033
00BDA02B 80FB 7A cmp bl,7A
00BDA02E 77 03 ja short 00BDA033
00BDA030 80EB 20 sub bl,20
00BDA033 8A7F FF mov bh,byte ptr ds:[edi-1]
00BDA036 80FF 61 cmp bh,61
00BDA039 72 08 jb short 00BDA043
00BDA03B 80FF 7A cmp bh,7A
00BDA03E 77 03 ja short 00BDA043
00BDA040 80EF 20 sub bh,20
00BDA043 38FB cmp bl,bh
00BDA045 ^ 74 D8 je short 00BDA01F
00BDA047 0FB6C3 movzx eax,bl
00BDA04A 0FB6D7 movzx edx,bh
00BDA04D 29D0 sub eax,edx
00BDA04F 5B pop ebx
00BDA050 5F pop edi
00BDA051 5E pop esi
00BDA052 C3 retn
Añadir nueva sección de 1000h bytes
Para que quepan todos los códigos, voy a crear una sección con un tamaño de 1000h bytes. Para esto pongo dumpe_08.exe en el programa Add PE bytes. Pulso el botón derecho y añado una nueva sección:
Se habrá creado una sección llamada "karmany". La seleccionamos y ya nos dirá el número máximo de bytes que podemos añadir. La configuración es la siguiente:
- Opciones: añadir bytes -> sección elegida
- Usuarios avanzados: déjalo por defecto, el programa deja la mejor opción.
- Nº bytes: 1000. El programa trabaja con números hexadecimales.
- Patrón: 77. Yo pongo 77 para reconocer el código rápidamente. Tú puedes poner lo que quieras.
Imagen de cómo queda:
Pulso el botón Aplicar y Add PE bytes hace su trabajo y nos crea 1000 bytes en la sección .karmany. Renombro el nuevo archivo como: dumpe_09.exe
Enlazar con la nueva sección
Abrimos dumpe_09.exe con OllyDBG. Voy a las secciones y examino dónde se ha creado la nueva sección. Como el patrón es 77 rápidamente veo dónde está:
00BDA000 77 77 77 77 77 77 77 77 wwwwwwww
00BDA008 77 77 77 77 77 77 77 77 wwwwwwww
00BDA010 77 77 77 77 77 77 77 77 wwwwwwww
00BDA018 77 77 77 77 77 77 77 77 wwwwwwww
00BDA020 77 77 77 77 77 77 77 77 wwwwwwww
00BDA028 77 77 77 77 77 77 77 77 wwwwwwww
00BDA030 77 77 77 77 77 77 77 77 wwwwwwww
...
Mi nueva sección está en 00BDA000. Por este motivo, redirijo el código de 01FF0000 hacia aquí, es decir, donde estaba esto:
0040BCF0 /$ 68 0000FF01 push 1FF0000
0040BCF5 \. C3 retn
Pongo esto:
0040BCF0 /$ 68 00A0BD00 push 0BDA000
0040BCF5 \. C3 retn
Y ahora simplemente en 0BDA000 pego el código anterior que desofusqué, ayudándome del plugin MultiAssembler. De este modo se solucionan casi todos los errores. Aún así después de haber reparado practicamente todos, me encuentro con alguna sorpresa curiosa como la que vamos a ver en el siguiente y casi seguramente último artículo sobre este packer 01.