Análisis Packer 01 - Parte V

Tamaño de letra:

Recordando datos

Voy a recordar todos los datos que tenemos:

  • OEP (antes de emular los stolen bytes y en el packer): 1B903DE
  • -------------------------------------------------------------------------------
  • INICIO IAT: 0076D258
  • FIN IAT:0076DDE0
  • TAMAÑO IAT: B88 bytes
  • DIRECCIÓN VIRTUAL RELATIVA (RVA) del inicio de la IAT: 0036D258
  • --------------------------------------------------------------------------------------------------
  • INICIO INIT TABLE: 0074BB20
  • FIN INIT TABLE: 0074C764
  • OEP ORIGINAL: 0074C768
  • ---------------------------------------
  • Tenemos una tabla con todas las calls intermodular.

 

Preparando el el dumpeado

Iniciamos todo. Usando el script de la parte II para reparar la IAT, vamos a ejecutarla para reparar la IAT y le vamos a decir que nos pare en el OEP en  1B903DE. Ejecuto el script y se detiene en el OEP:

OEP con stolen bytes

Compruebo la IAT:

0076D250 00000000
0076D254 00000000
0076D258 7C92135A  ntdll.RtlDeleteCriticalSection
0076D25C 7C9110E0  ntdll.RtlLeaveCriticalSection
0076D260 7C911000  ntdll.RtlEnterCriticalSection
0076D264 7C809F81  kernel32.InitializeCriticalSection
0076D268 7C809B74  kernel32.VirtualFree
0076D26C 7C809AE1  kernel32.VirtualAlloc
0076D270 7C8099BF  kernel32.LocalFree
0076D274 7C809A1D  kernel32.LocalAlloc
0076D278 7C81126A  kernel32.GetVersion
0076D27C 7C8097B8  kernel32.GetCurrentThreadId
0076D280 7C80980A  kernel32.InterlockedDecrement
0076D284 7C8097F6  kernel32.InterlockedIncrement
0076D288 7C80BA61  kernel32.VirtualQuery
0076D28C 7C80A164  kernel32.WideCharToMultiByte
0076D290 7C8360F5  kernel32.SetCurrentDirectoryA
0076D294 7C809C88  kernel32.MultiByteToWideChar
0076D298 7C80BE46  kernel32.lstrlenA
0076D29C 7C8101A1  kernel32.lstrcpynA
0076D2A0 7C801D53  kernel32.LoadLibraryExA
0076D2A4 7C80A4A5  kernel32.GetThreadLocale
0076D2A8 7C801EF2  kernel32.GetStartupInfoA
0076D2AC 00BA9B04  protegid.00BA9B04            <= Sin reparar. Recuerda que habrá 3 sin resolver
0076D2B0 7C80B731  kernel32.GetModuleHandleA
...
0076DDBC 00000000
0076DDC0 00C8BB90  sicmplr.Compiler_DataLink3000
0076DDC4 00C8BBF4  sicmplr.CompileRC
0076DDC8 00000000
0076DDCC 7E3A99CB  user32.NotifyWinEvent
0076DDD0 00000000
0076DDD4 77EFD7AE  GDI32.GetRandomRgn
0076DDD8 00000000
0076DDDC 7C812B6E  kernel32.GetVersionExA
0076DDE0 00000000

Debemos reparar las 3 entradas que quedan sin resolver, recuerda la parte sobre la IAT, así:

0076D2A8 7C801EF2  kernel32.GetStartupInfoA
0076D2AC 7C80AE30  kernel32.GetProcAddress
0076D2B0 7C80B731  kernel32.GetModuleHandleA
...
0076D2F8 7C801812  kernel32.ReadFile
0076D2FC 7C812A99  kernel32.RaiseException
0076D300 7C812FC9  kernel32.GetStdHandle
...
0076D4AC 7C82147D  kernel32.GetProfileStringA
0076D4B0 7C80AE30  kernel32.GetProcAddress
0076D4B4 7C832B6E  kernel32.GetPrivateProfileStringA

 

Anexando la INIT TABLE

Vamos a reparar la INIT TABLE que lo haremos de forma rápida y sencilla. Yo la guardé si recuerdas en un archivo de texto, así que lo abro, lo copio todo, y me voy en la ventana de dump de OllyDBG al inicio de la INIT TABLE0074BB20, la selecciono entera y botón derecho ratón -> binary -> binary paste. Ya se ha pegado correctamente entera:

0074BB20 00000188
0074BB24 0074BB28 protegid.0074BB28
0074BB28 0040800C protegid.0040800C
0074BB2C 00407FDC protegid.00407FDC
0074BB30 00407E00 protegid.00407E00
...
0074C750 0070A704 protegid.0070A704
0074C754 0070A6D4 protegid.0070A6D4
0074C758 00729F20 protegid.00729F20
0074C75C 00729D58 protegid.00729D58
0074C760 00000000
0074C764 0074BAA4 protegid.0074BAA4

 

Reparando las calls intermodulars

Como recordarás, todas las calls intermodulars malas se encuentran en una tabla que hicimos. Ahora sencillamente puedes crear un injerto o puedes crear un script para poder repararlas. Yo me decido por un injerto ya que el script tiene muchas limitaciones a la hora de crear algo en ensamblador. Lo primero que haré es pegar la tabla en la dirección 680000 (por ningún motivo especial) y después de repararla la dejaré como estaba (undo selection). El código irá un poco más abajo, en 680500.

¿Qué tiene que hacer el script?

Pues es muy sencillo. Voy a tomar la primera dirección de la tabla de calls malas:

00680000 00401314  protegid.00401314
00680004 7C810EE1  kernel32.GetFileType

La dirección donde está la call mala es: 00401314 así que voy ahí:

0040130A   .  8BC0            mov eax,eax
0040130C   $- FF25 0CD37600   jmp near dword ptr ds:[76D30C]               ; kernel32.CreateFileA
00401312      8BC0            mov eax,eax
00401314 $  E8 E7EC7A01     call 01BB0000
00401319      8B              db 8B
0040131A      8BC0            mov eax,eax

He dejado la API de arriba que esa ya está bien. Como puedes observar lo que tiene que hacer el script es transformar la call 01BB0000 en su correspondiente dirección basándose en la IAT. Me voy a la IAT a buscar dónde está GetFileType:

0076D308  7C810EE1  kernel32.GetFileType

Por lo tanto, ya tenemos todos los datos y podemos transformarlo así:

0040130A   .  8BC0            mov eax,eax
0040130C   $- FF25 0CD37600   jmp near dword ptr ds:[76D30C]               ; kernel32.CreateFileA
00401312      8BC0            mov eax,eax
00401314 - FF25 08D37600   jmp near dword ptr ds:[76D308]               ; kernel32.GetFileType
0040131A      8BC0            mov eax,eax

Sencillo ¿no?. Voy a crear el injerto reparador. Lo voy a poner debajo de esta tabla en 680500 por ejemplo. Para guardar datos uso la pila para no modificar nada en memoria y que luego no se pueda revertir. Para hacer el injerto en OllyDBG yo uso el plugin Multimate Assembler, realmente muy muy muy útil y que te ahorra muchísimo trabajo. El injerto es el siguiente:

<00680500>
pushad
push 680000               ; Direccion inicio Tabla de calls

@bucle:
mov ecx, 0B88             ; Size IAT
mov edi, 0076D258         ; Direccion inicio IAT
mov ebx, dword [esp]
mov ebx, dword [ebx]      ; Direccion call
add dword [esp], 4
mov eax, dword [esp]
mov eax, dword [eax]      ; Direccion API

repne scas dword [edi]
jnz short @no_encontrado

@encontrado:
sub edi, 4
mov word [ebx], 025FF
mov dword [ebx+2], edi
add dword [esp], 4
cmp dword [esp], 680450
jnz @bucle
nop ; Breakpoint FINAL
@no_encontrado:
nop ; Breakpoint API no encontrada
pop eax
popad

Pongo el eip al comienzo del injerto, pongo los dos breakpoints que indico y ejecuto el script. No da tiempo ni de pulsar el ratón que ya ha terminado. Observa que bien ha quedado:

00680000 00401314  jmp to kernel32.GetFileType
00680004 7C810EE1  kernel32.GetFileType
00680008 0040131C  jmp to kernel32.GetFileSize
0068000C 7C810B07  kernel32.GetFileSize
00680010 00401324  jmp to kernel32.GetStdHandle
...
00680440 00442F88  jmp to comdlg32.ChooseFontA
00680444 7637C1C1  comdlg32.ChooseFontA
00680448 00442F90  jmp to comdlg32.PrintDlgA
0068044C 763846FD  comdlg32.PrintDlgA

Antes de seguir te recuerdo que tenemos que dejar todo intacto, por lo tanto, todo lo que hemos usado en la dirección 680000 hay que restaurarlo: undo selection. Importante.

 

Dumpeando

¡Por fin! después de tanto trabajo ya puedo decir que ya podemos dumpear con OllyDBG:

Dumpeado

Quitamos Rebuild Import porque lo vamos a hacer con Import REconstructor y si te fijas he cambiado el Entry Point... Tienes que poner el valor RVA, no la Virtual Address, ¿por qué he cambiado el Entry Point?. Porque es el OEP original y porque voy a restaurar los stolen bytes. Lo guardo como "dumpe.exe".

 

Reparando la Tabla de Importaciones

Voy a crear una nueva IID, para ello aún con OllyDBG parado en el OEP, ejecuto Import REconstructor y selecciono el proceso: "protegido.exe". Y pongo los datos correctamente que en el tutorial sobre la IAT ya expliqué y están en el inicio de este artículo. Los pongo porque Import REconstructor no atina. Cambio el OEP a 0034C768 y pulso en Get Imports:

Import REconstructor

Como ya resolvimos las 3 entradas malas pues está toda la IAT perfecta. Pulso en Fix Dump y selecciono "dumpe.exe", se crea "dumpe_.exe". Qué gran trabajo hace Import REconstructor... ¡el tiempo que perderíamos haciéndolo a mano...! Si quiero, para saber dónde ha creado la IID miro el log de Import RE:

*** New section added successfully. RVA:007C5000 SIZE:00004000
Image Import Descriptor size: 244; Total length: 345E
C:\karmanyWeb\Estudio Packer 01\dumpe_.exe saved successfully.

El programa lo dejo parado en el OEP porque en el próximo tutorial veremos cómo descubrir los stolen bytes, partiremos desde el OEP.

Ahora ya tenemos un dumpeado con el OEP original (aunque destrozado), con la INIT TABLE reparada, con la IAT reparada con una nueva sección donde está la IID que nos ha creado Import RE y con las calls intermodulars reparadas. Con todo eso reparado, ya podemos abrir "dumpe.exe" en OllyDBG, examinar todo lo que hemos reparado por si hay algún fallo, y observar que el OEP está destrozado porque faltan los stolen bytes.

Última actualización: Domingo, 10 Julio 2011

No tiene privilegios para responder a los comentarios.


 
Visitas: 8562252