Documente online.
Zona de administrare documente. Fisierele tale
Am uitat parola x Creaza cont nou
 HomeExploreaza
upload
Upload




Armadillo 4.x parte2 version2

Spaniola


Armadillo 4.x parte2 version2

por Tk0017



Información General

Programa

Collectorz.com Movie Collector 4.4 build 3

Protección

Armadillo 4.x [CopyMemII + Nanomites]

Herramientas

LordPE Deluxe, ImpRec 1.6, OllyDbg 1.10, ArmTools 0.1, N-Rec 1.7, HexWorkshop 4.23, UltraEdit 10.10 Notepad y Calculadora

Dificultad

Mínima

Este Armadillo es de la nueva generación en la que se añaden dos trucos anti-Olly, el primero es una llamada a la API OutputDebugStringA con el parámetro “%s%s%s%s%s%s%s%s%s%s....." esto crea un desbordamiento de la pila que provoca que el Olly se cuelgue, el segundo es simplemente una extensión de IsDebuggerPresent, lo nuevo es que no da el mensaje de error sino que ahora cuelga el Olly, estas 2 nuevas estrategias son risibles, supongo el ArmaTeam tiene una filosofía muy Daria

Um... I believe you should try everything once no matter how unmistakably stupid it is.

Como sea, vamos a expiar nuestra torturadas almas destrozando este software Shareware

Carguemos nuestra app [MovieCollector.exe] en el Olly, escondemos el dbg, damos F9 y

Sorpresa, sorpresa!! Parece que el ArmaTeam ha hecho su tarea o al menos se ha pirateado ideas de los foros y los tutes sobre su producto, como ya mencione esta es una llamada a OutputDebugStringA, así que aceptamos los errores y el Olly simplemente se cierra

¿Nos han vencido? Claro que no, a diferencia de los programadores comerciales nosotros somos seres de lento aprendizaje y cuando algo no nos sale bien lo intentamos hasta que reviente =)

Bien, carguemos nuestra app en el Olly, escondemos el dbg, ponemos un bp OutputDebugStringA, damos F9 y para en

77E749B7 > 68 2C020000 PUSH 22C

77E749BC 68 8853E777 PUSH kernel32.77E75388

77E749C1 E8 1259FEFF CALL kernel32.77E5A2D8

77E749C6 8365 FC 00 AND DWORD PTR SS:[EBP-4],0

77E749CA 8B4D 08 MOV ECX,DWORD PTR SS:[EBP+8]

77E749CD 8BC1 MOV EAX,ECX

77E749CF 8D70 01 LEA ESI,DWORD PTR DS:[EAX+1]

77E749D2 8A10 MOV DL,BYTE PTR DS:[EAX]

77E749D4 40 INC EAX

77E749D5 84D2 TEST DL,DL

77E749D7 ^75 F9 JNZ SHORT kernel32.77E749D2

77E749D9 2BC6 SUB EAX,ESI

77E749DB 40 INC EAX

77E749DC 8945 E0 MOV DWORD PTR SS:[EBP-20],EAX

77E749DF 894D E4 MOV DWORD PTR SS:[EBP-1C],ECX

77E749E2 8D45 E0 LEA EAX,DWORD PTR SS:[EBP-20]

77E749E5 50 PUSH EAX

77E749E6 6A 02 PUSH 2

77E749E8 6A 00 PUSH 0

77E749EA 68 06000140 PUSH 40010006

77E749EF E8 43EEFDFF CALL kernel32.RaiseException

77E749F4 834D FC FF OR DWORD PTR SS:[EBP-4],FFFFFFFF

77E749F8 E8 A259FEFF CALL kernel32.77E5A39F

77E749FD C2 0400 RETN 4

Esta es la API OutputDebugStringA [la dirección de memoria cambia en cada maquina], veamos que nos dice la pila [stack]

0012BCBC 006E41A7 /CALL to OutputDebugStringA from MovieCol.006E41A4

0012BCC0 003AF800 \String = "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s… "

La parte resaltada es lo interesante, vayamos a esa dirección de memoria en el Dump

003AF800 25 73 25 73 25 73 25 73 %s%s%s%s

003AF808 25 73 25 73 25 73 25 73 %s%s%s%s

003AF810 25 73 25 73 25 73 25 73 %s%s%s%s

003AF818 25 73 25 73 25 73 25 73 %s%s%s%s

003AF820 25 73 25 73 25 73 25 73 %s%s%s%s

003AF828 25 73 25 73 25 73 25 73 %s%s%s%s

003AF830 25 73 25 73 25 73 25 73 %s%s%s%s

003AF838 25 73 25 73 25 73 25 73 %s%s%s%s

003AF840 25 73 25 73 25 73 25 73 %s%s%s%s

003AF848 25 73 25 73 25 73 25 73 %s%s%s%s

003AF850 25 73 25 73 25 73 25 73 %s%s%s%s

003AF858 00 A8 BF BA 0D F0 AD BA .¨¿º.ð­º

El formato y el tamaño de la cadena es lo que provoca el desbordamiento de la pila y consecuentemente el cuelgue del Olly, me pregunto que pasaría si ponemos un byte 00 al inicio de la cadena para que quede así

0012BCBC 006E41A7 /CALL to OutputDebugStringA from MovieCol.006E41A4

0012BCC0 003AF800 \String = ""

003AF800 73 25 73 25 73 25 73 .s%s%s%s

003AF808 25 73 25 73 25 73 25 73 %s%s%s%s

003AF810 25 73 25 73 25 73 25 73 %s%s%s%s

003AF818 25 73 25 73 25 73 25 73 %s%s%s%s

003AF820 25 73 25 73 25 73 25 73 %s%s%s%s

003AF828 25 73 25 73 25 73 25 73 %s%s%s%s

003AF830 25 73 25 73 25 73 25 73 %s%s%s%s

003AF838 25 73 25 73 25 73 25 73 %s%s%s%s

003AF840 25 73 25 73 25 73 25 73 %s%s%s%s

003AF848 25 73 25 73 25 73 25 73 %s%s%s%s

003AF850 25 73 25 73 25 73 25 73 %s%s%s%s

003AF858 00 A8 BF BA 0D F0 AD BA .¨¿º.ð­º

Como se puede observar el parámetro de la función es ahora una cadena nula, presionemos F9 y vuelve a parar en la API OutputDebugStringA, vemos la pila y

0012BCBC 006E41A7 /CALL to OutputDebugStringA from MovieCol.006E41A4

0012BCC0 003AF800 \String = "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s… "

Otra llamada desde la misma dirección y con el mismo parámetro, así pues, como en la llamada anterior, vayamos a la dirección 003AF800, pongamos un byte 00, demos un F9 y arranca perfectamente

Me di cuenta de que es mas cómodo poner un Hardware Breakpoint on execution en el inicio de la API OutputDebugStringA en lugar de un bp normal, ya que vamos a cargar varias veces la app en el Olly, cada vez tendremos que evitar el desbordamiento, por lo que cada vez tendríamos que poner el bp, es mas fácil solo cerrar el Olly y al volver a abrirlo el Hardware Breakpoint aun estará ahí, aunque este no es el primer paso que realizo comúnmente, lo puse al principio por que es lo nuevo del Armadillo y a partir de aquí ya todo es mas estándar

Ejecutemos nuestra app, cuando ya este cargada abramos el LordPE y veremos que hay 2 procesos MovieCollector.exe, esto nos indica que el programa tiene CopyMemII o Nanomites, en algunos casos, como lo es este, contienen ambas protecciones. Bien, el primer paso es obtener nuestro Dump con todas las zonas desencriptadas, yo prefiero usar las herramientas que ya se han hecho para estos menesteres, en este caso usaremos

Presionamos Load, indicamos la ruta hacia MovieCollector.exe y el Armadillo goblin se congela sin realizar su tarea =(

Exactamente para esto es para lo que uso las herramientas ya programadas, es muy simple; una vez que ya has destripado el CopyMemII es lo mismo en otros programas, así que para que gastar tiempo/esfuerzo en hacer lo mismo para cada ejecutable si podemos hacerlo con un par de clics de ratón o mejor aun, como lo es en este caso, al usar herramientas que funcionan basadas en un esquema de protección ya conocido y fallar nos indica que el esquema ha cambiado, yo no se en que, ya que la manera de desencriptar todos las zonas del código es la misma que siempre ha sido, como sea, al menos nos han obligado a hacerlo a mano

Primero, lo primero, daré una explicación simple del funcionamiento del CopyMemII

X       Ejecutamos el primer proceso MovieCollector.exe [padre]

X       El primer proceso [padre] crea un segundo proceso [hijo] copiándose a si mismo en memoria

X       El proceso padre funge como debugger para con el hijo

X       El padre modifica el EP [no el OEP] del hijo para crear un bucle infinito

X       El padre hace comprobaciones y otras basuras para preparar la ejecución del hijo

X       El padre modifica el EP del hijo para quitar el bucle infinito

X       El hijo ejecuta el mismo código del armadillo que el padre pero ahora como hijo

X       El hijo llega al OEP y causa un error al estar encriptado/ausente

X       El padre capta el error con la API WaitForDebugEvent

X       El padre ve el registro EIP, comprueba el error y se prepara para desencriptar de la zona del OEP

X       El padre desencripta la zona necesaria con la API WriteProcessMemory [1000h bytes]

X       Si el padre ve que hay una zona que no este en uso la encripta/destruye

X       El padre le regresa el control al hijo en el OEP ya desencriptado y se pone en modo de espera

X       El hijo se sigue ejecutando hasta llegar al próximo error y vuelve a comenzar el bucle

Los dos pasos que marque son las zonas calientes de este esquema, así que vamos a por el

Carguemos nuestra app en el Olly, escondemos el dbg, el Hardware Breakpoint ya debe estar en el inicio de la API OutputDebugStringA y cada vez que pare ponemos un byte 00 en el inicio de la cadena, ponemos un bp WaitForDebugEvent, al parar vemos la pila y

0012BCB8 006E264F /CALL to WaitForDebugEvent from MovieCol.006E2649

0012BCBC 0012CD90 |pDebugEvent = 0012CD90

0012BCC0 000003E8 \Timeout = 1000. ms

La marca nos indica que en la dirección de memoria 0012CD90 es donde se escribirá el reporte de que es lo que pasa con el proceso hijo, así que vayamos a esa zona de memoria en el Dump, quitemos el bp y pongamos un bp WriteProcessMemory, demos F9, para 2 veces en la API OutputDebugStringA, hacemos las modificaciones, las pasamos, y luego para en el bp que acabamos de poner, vallamos a la pila y

0012BB58 006E65E7 /CALL to WriteProcessMemory from MovieCol.006E65E1

0012BB5C 00000050 |hProcess = 00000050 (window)

0012BB60 00689000 |Address = 689000

0012BB64 003ADD50 |Buffer = 003ADD50

0012BB68 00001000 |BytesToWrite = 1000 (4096.)

0012BB6C 0012BC74 \pBytesWritten = 0012BC74

Las marcas nos dan la información que por el momento necesitamos, la primera nos dice en que dirección de memoria del hijo se escribirán los 1000h bytes que se encuentren en la zona de memoria del padre que indique la segunda marca, en otras palabras

Se escribirán 1000h bytes del padre [003ADD50] al hijo [0689000]

Ahora veamos el reporte de la API WaitForDebugEvent, vallamos a la dirección 0012CD90 en el Dump y

0012CD90 01 00 00 00 E0 04 00 00 ...à ..

0012CD98 EC 04 00 00 01 00 00 80 ì ....€

0012CDA0 00 00 00 00 00 00 00 00 ........

0012CDA8 EC 90 68 00 02 00 00 00 ì h.[1]...

0012CDB0 00 00 00 00 EC 90 68 00 ....ì h.

0012CDB8 EC 90 68 00 00 00 00 00 ì h.....

0012CDC0 01 83 51 E1 00 00 00 00 ƒQá....

0012CDC8 18 AD 81 F5 00 00 00 00 ­

Las marcas nos indican donde se escribe el valor del EIP [del hijo] que crea el error, este valor es 006890EC este es nuestro OEP, anotémoslo para futuros usos, si recuerdan la zona que va a escribirse es 00689000, así pues de esto se concluye que como el OEP esta en 006890EC se tiene que desencriptar la zona del código que va desde 00689000 hasta 0068A000 [1000h bytes] para que el OEP pueda ejecutarse, esto nos da la leve sospecha de que si modificamos las direcciones de memoria que guardan el EIP del hijo entonces podemos ordenarle al Armadillo que desencripte todas las zonas del código que nosotros queramos, esto es cierto, pero… ¿y la función que vuelve a encriptar las zonas desencriptadas que ya no están en uso?

Esa función es una call, en otros tutoriales ya se ha hablado de esta call y de hecho esta call apunta a la misma zona de código que la call que desencripta el programa ¿…?, sí, es la misma call solo que al pasarle un parámetro diferente se puede modificar su comportamiento de encriptar a desencriptar y viceversa, este parámetro antes era un push 1 o un push 0, mas sin embargo en esta nueva versión del Armadillo intentan disfrazar un poco las cosas y ya no ponen el push x tan crudo como en otras versiones, aun así es fácil encontrar nuestro call encriptador

Regresemos al Olly, seguimos parados en el inicio de la API WriteProcessMemory, demos un Ctrl+F9, un F8 y saldremos aquí

006E65E7 . 85C0 TEST EAX,EAX

006E65E9 . 75 4B JNZ SHORT MovieCol.006E6636

006E65EB . 50 PUSH EAX

006E65EC . F7D0 NOT EAX

006E65EE . 0FC8 BSWAP EAX

006E65F0 . 58 POP EAX

006E65F1 . 73 00 JNB SHORT MovieCol.006E65F3

006E65F3 > 9C PUSHFD

006E65F4 . 60 PUSHAD

006E65F5 . EB 2B JMP SHORT MovieCol.006E6622

Presionemos Alt+K para ver la ventana de Call stack y no nos dará nada de información, así que demos otro Ctrl+F9 y para aquí

006E66E3 . C3 RETN

006E66E4 $ 55 PUSH EBP

006E66E5 . 8BEC MOV EBP,ESP

006E66E7 . 51 PUSH ECX

006E66E8 . 6A 00 PUSH 0 ; /Arg2 = 00000000

006E66EA . 8B45 08 MOV EAX,DWORD PTR SS:[EBP+8] ; |

006E66ED . 50 PUSH EAX ; |Arg1

006E66EE . E8 24000000 CALL MovieCol.006E6717 ; \MovieCol.006E6717

Presionemos Alt+K y veremos

Call stack of main thread

Address Stack Procedure/arguments Called from Frame

0012BC80 006E5255 MovieCol.006E559D MovieCol.006E5250 0012BCB0

La línea marcada nos dice de donde fue hecha la llamada al código que se esta ejecutando y le regresara el control, amenos que sufran de lagunas mentales recordaran que el código que se esta ejecutando es el que desencripto la zona del OEP del código del hijo, así pues vayamos a la dirección 006E5250 en el desensamblado y veremos esto

006E524B . 51 PUSH ECX

006E524C . 8B55 08 MOV EDX,DWORD PTR SS:[EBP+8]

006E524F . 52 PUSH EDX

006E5250 . E8 48030000 CALL MovieCol.006E559D

006E5255 > 83C4 0C ADD ESP,0C

006E5258 . 25 FF000000 AND EAX,0FF

006E525D . 85C0 TEST EAX,EAX

006E525F . 75 07 JNZ SHORT MovieCol.006E5268

006E5261 . 32C0 XOR AL,AL

006E5263 . E9 2E030000 JMP MovieCol.006E5596

Esta es nuestra llamada desencriptadora, así que la otra llamada [solo deben ser 2] a esta misma zona del código [006E559D] deberá ser nuestra llamada encriptadora, así que vayamos a la dirección 006E559D y veremos

006E559D $ 55 PUSH EBP

006E559E . 8BEC MOV EBP,ESP

006E55A0 . 81EC 00010000 SUB ESP,100

006E55A6 . 53 PUSH EBX

006E55A7 . 56 PUSH ESI

006E55A8 . 57 PUSH EDI

006E55A9 . 8B45 08 MOV EAX,DWORD PTR SS:[EBP+8]

006E55AC . C1E0 0C SHL EAX,0C

006E55AF . 8B0D 34DF7100 MOV ECX,DWORD PTR DS:[71DF34] ; MovieCol.00401000

Si vemos la pequeña ventana debajo del desensamblado nos dará buenas noticias

Local calls from 006E5250, 006E5525

La llamada de 006E5250 es la call desencriptadora, por ende la llamada marcada [006E5525] es la llamada encriptadora, así que vayamos a esa zona y veremos

006E551B . 8B15 50DF7100 MOV EDX,DWORD PTR DS:[71DF50]

006E5521 . 8B048A MOV EAX,DWORD PTR DS:[EDX+ECX*4]

006E5524 . 50 PUSH EAX

006E5525 . E8 73000000 CALL MovieCol.006E559D

006E552A . 83C4 0C ADD ESP,0C

006E552D . 50 PUSH EAX

006E552E . F7D0 NOT EAX

Así que NOPeemos esta instrucción para que quede así

006E551B . 8B15 50DF7100 MOV EDX,DWORD PTR DS:[71DF50]

006E5521 . 8B048A MOV EAX,DWORD PTR DS:[EDX+ECX*4]

006E5524 . 50 PUSH EAX

006E5525 90 NOP

006E5526 90 NOP

006E5527 90 NOP

006E5528 90 NOP

006E5529 90 NOP

006E552A . 83C4 0C ADD ESP,0C

006E552D . 50 PUSH EAX

006E552E . F7D0 NOT EAX

Como pueden ver ya no se usa el push 0 o el push 1

Con esto haremos que cuando el Armadillo desencripte una zona del código del hijo e intente encriptar la zona anterior, que ya no esta en uso, simplemente no haga nada, el Armadillo la dejara correcta y lista para nuestras maquiavélicas intenciones de dumpeo

Hagamos una pequeña prueba para ver si nuestros cambios dan el resultado esperado, así que quitemos el bp que aun tenemos en la API WriteProcessMemory, demos un F9 y

El programa se ejecuta normalmente o al menos eso parece, abramos el LordPE y demos un dump full… al proceso hijo [no explicare como diferenciarlos ya que es muy simple] y nos dará el error

Cambiemos el ‘active dump engine’ a IntelliDump, demos un dump full… y nos dará el informe

Aceptamos y guardamos el archivo como Prueba.exe, cerramos el LordPE, cerramos el Olly y ahora cargamos en el Olly el ejecutable que acabamos de dumpear [Prueba.exe] y apareceremos en

006F24D3 >/$ 55 PUSH EBP

006F24D4 |. 8BEC MOV EBP,ESP

006F24D6 |. 6A FF PUSH -1

006F24D8 |. 68 20CB7100 PUSH Prueba.0071CB20

006F24DD |. 68 10226F00 PUSH Prueba.006F2210 ; SE handler installation

006F24E2 |. 64:A1 00000000 MOV EAX,DWORD PTR FS:[0]

006F24E8 |. 50 PUSH EAX

006F24E9 |. 64:8925 000000>MOV DWORD PTR FS:[0],ESP

006F24F0 |. 83EC 58 SUB ESP,58

006F24F3 |. 53 PUSH EBX

006F24F4 |. 56 PUSH ESI

006F24F5 |. 57 PUSH EDI

006F24F6 |. 8965 E8 MOV DWORD PTR SS:[EBP-18],ESP

006F24F9 |. FF15 88717100 CALL DWORD PTR DS:[<&KERNEL32.GetVersion>

Este es el mismo EP que el de nuestra app original, lo que nos interesa es ver si el OEP aun esta desencriptado, así que vallamos al OEP que es 006890EC y veremos en el desensamblado

006890EC 55 PUSH EBP

006890ED 8BEC MOV EBP,ESP

006890EF 83C4 DC ADD ESP,-24

006890F2 33C0 XOR EAX,EAX

006890F4 8945 EC MOV DWORD PTR SS:[EBP-14],EAX

006890F7 B8 04896800 MOV EAX,Prueba.00688904

006890FC E8 D7E9D7FF CALL Prueba.00407AD8

00689101 33C0 XOR EAX,EAX

00689103 55 PUSH EBP

00689104 68 60926800 PUSH Prueba.00689260

00689109 64:FF30 PUSH DWORD PTR FS:[EAX]

0068910C 64:8920 MOV DWORD PTR FS:[EAX],ESP

0068910F E8 1C36DDFF CALL Prueba.0045C730

00689114 3D 47000400 CMP EAX,40047

00689119 7D 78 JGE SHORT Prueba.00689193

0068911B 6A 04 PUSH 4

0068911D 68 6C926800 PUSH Prueba.0068926C ; ASCII "Collectorz.c..."

00689122 8D45 EC LEA EAX,DWORD PTR SS:[EBP-14]

00689125 50 PUSH EAX

00689126 B8 94926800 MOV EAX,Prueba.00689294 ; ASCII "Movie Collector"

0068912B 8945 DC MOV DWORD PTR SS:[EBP-24],EAX

0068912E C645 E0 0B MOV BYTE PTR SS:[EBP-20],0B

00689132 B8 94926800 MOV EAX,Prueba.00689294 ; ASCII "Movie Collector"

00689137 8945 E4 MOV DWORD PTR SS:[EBP-1C],EAX

0068913A C645 E8 0B MOV BYTE PTR SS:[EBP-18],0B

0068913E 8D55 DC LEA EDX,DWORD PTR SS:[EBP-24]

00689141 B9 01000000 MOV ECX,1

00689146 B8 AC926800 MOV EAX,Prueba.006892AC ; ASCII "%s needs ve... "

0068914B E8 C028D8FF CALL Prueba.0040BA10

00689150 8B45 EC MOV EAX,DWORD PTR SS:[EBP-14]

00689153 E8 9CC5D7FF CALL Prueba.004056F4

00689158 50 PUSH EAX

00689159 E8 36F5D7FF CALL Prueba.00408694 ; JMP to USER32.GetDesktopWindow

Se nota que el OEP esta en buenas condiciones, se ven referencias a cadenas de texto legibles e incluso se ve una llamada a la API GetDesktopWindow, de esto concluimos que la call que NOPeamos efectivamente era la call que encriptaba las zonas del código que ya no estaban en uso, una vez comprobado esto, vamos a escribir un pequeño código para que el Armadillo haga nuestro trabajo sucio, le ordenaremos al padre que desencripte todas las zonas del código del hijo, NOPearemos la call encriptadora y dumpearemos al hijo en perfectas condiciones, ¿fácil, no?, pues de hecho es mas fácil de lo que suena en primera instancia, cerremos el Olly y borremos Prueba.exe

Abramos el Olly, carguemos nuestra app, escondamos el dbg, evitemos el desbordamiento de OutputDebugStringA cada vez que se ofrezca, pongamos un bp WriteProcessMemory, demos un F9 y parara 2 veces en las que solo se escribirán 2 bytes, así que demos F9 hasta llegar a la llamada que desencripta la zona del código del OEP

0012BB58 006E65E7 /CALL to WriteProcessMemory from MovieCol.006E65E1

0012BB5C 00000050 |hProcess = 00000050 (window)

0012BB60 00689000 |Address = 689000

0012BB64 003ADD50 |Buffer = 003ADD50

0012BB68 00001000 |BytesToWrite = 1000 (4096.)

0012BB6C 0012BC74 \pBytesWritten = 0012BC74

Esta es la primera llamada a WriteProcessMemory que escribe 1000h bytes y es causada por la primera llamada al call desencriptador, antes de cualquier cosa NOPeemos el call encriptador en la dirección de memoria 006E5525 para que quede así

006E551B . 8B15 50DF7100 MOV EDX,DWORD PTR DS:[71DF50]

006E5521 . 8B048A MOV EAX,DWORD PTR DS:[EDX+ECX*4]

006E5524 . 50 PUSH EAX

006E5525 90 NOP

006E5526 90 NOP

006E5527 90 NOP

006E5528 90 NOP

006E5529 90 NOP

006E552A . 83C4 0C ADD ESP,0C

006E552D . 50 PUSH EAX

006E552E . F7D0 NOT EAX

Ahora necesitamos hacer que el hijo se ejecute en un bucle infinito para que no moleste mientras trabajamos con el padre, esto lo haremos modificando el OEP del hijo, aun estamos en el inicio de la API WriteProcessMemory, la zona de memoria en el padre donde se tomaran los bytes a escribir en el hijo es 003ADD50, la zona de memoria en el hijo donde se escribirán los bytes del padre es 00689000, el OEP es 006890EC, de esto concluimos que

OEP - Zona Base = Desplazamiento

006890EC – 00689000 = EC

Zona Base + Desplazamiento = Zona de los bytes del OEP

003ADD50 + EC = 003ADE3C

así que vallamos a la zona de memoria 003ADE3C y veremos

003ADE3C 55 8B EC 83 C4 DC 33 C0 U‹ìƒÄÜ3À

003ADE44 89 45 EC B8 04 89 68 00 ‰Eì¸ ‰h.

003ADE4C E8 D7 E9 D7 FF 33 C0 55 è×é×ÿ3ÀU

003ADE54 68 60 92 68 00 64 FF 30 h`’h.dÿ0

003ADE5C 64 89 20 E8 1C 36 DD FF d‰ è6Ýÿ

003ADE64 3D 47 00 04 00 7D 78 6A =G. .}xj

003ADE6C 04 68 6C 92 68 00 8D 45 hl’h. E

003ADE74 EC 50 B8 94 92 68 00 89 ìP¸”’h.‰

Como se puede observar estos bytes corresponden al OEP desencriptado que será escrito en el hijo, así que si cambiamos los bytes 558B a EBFE crearemos un bucle infinito en el hijo que nos dejara trabajar en el padre, esto quedara así

003ADE3C EB FE EC 83 C4 DC 33 C0 ëþìƒÄÜ3À

003ADE44 89 45 EC B8 04 89 68 00 ‰Eì¸ ‰h.

003ADE4C E8 D7 E9 D7 FF 33 C0 55 è×é×ÿ3ÀU

003ADE54 68 60 92 68 00 64 FF 30 h`’h.dÿ0

003ADE5C 64 89 20 E8 1C 36 DD FF d‰ è6Ýÿ

003ADE64 3D 47 00 04 00 7D 78 6A =G. .}xj

003ADE6C 04 68 6C 92 68 00 8D 45 hl’h. E

003ADE74 EC 50 B8 94 92 68 00 89 ìP¸”’h.‰

Una ves hecho esto, quitemos el bp que esta en el inicio de WriteProcessMemory, pongamos un bp WaitForDebugEvent, demos F9 y veamos la pila

0012BCB8 006E264F /CALL to WaitForDebugEvent from MovieCol.006E2649

0012BCBC 0012CD90 |pDebugEvent = 0012CD90

0012BCC0 000003E8 \Timeout = 1000. ms

La línea marcada nos indica la dirección de memoria donde se guardara el reporte del estado del hijo, como aun no se ha ejecutado la API el reporte que esta en 0012CD90 es el del error anterior, esto nos será de gran ayuda ya que el Armadillo capta el error que fue causado y con respecto a esa información realiza diferentes funciones, la función que nosotros buscamos es la de desencriptar las zonas del código que le indiquemos, así que el error siempre tendrá que ser el mismo

Vallamos a la dirección de memoria 0012CD90 en el Dump y veremos

0012CD90 01 00 00 00 AC 04 00 00 ...¬ ..

0012CD98 P....€

0012CDA0 ........

0012CDA8 EC 90 68 00 02 00 00 00 ìh. ...

0012CDB0 00 00 00 00 EC 90 68 00 ....ìh.

0012CDB8 EC 90 68 00 00 00 00 00 ìh.....

0012CDC0 01 49 52 E1 00 00 00 00 IRá....

0012CDC8 18 3D C6 F3 00 00 00 00 =Æó....

En amarillo vemos las zonas de memoria donde se escribe el EIP que causo el error, en verde vemos las zonas de memoria donde se escribe el tipo de error que fue producido por el hijo, así pues las zonas verdes son las que tendremos que restaurar a estos mismos valores cada vez que sea llamada la API WaitForDebugEvent, marquemos la zona de memoria que va desde 0012CD90 hasta 0012CDA8 y démosle un binary copy

Bien, aun estamos en el principio de WaitForDebugEvent quitemos el bp que esta ahí, demos un Ctrl+F9, un F8 y saldremos aquí

006E263B 3361 XOR ESP,DWORD PTR DS:[ECX+68] ; |

006E263E E8 0300008B CALL 8B6E2646

006E2643 95 XCHG EAX,EBP

006E2644 DCF5 FDIVR ST(5),ST

006E2646 FFFF ??? ; Unknown command

006E2648 52 PUSH EDX ; |pDebugEvent

006E2649 FF15 E0707100 CALL DWORD PTR DS:[<&KERNEL32. WaitForDebugEvent>

006E264F 85C0 TEST EAX,EAX

006E2651 0F84 2B270000 JE MovieCol.006E4D82

Veamos el reporte en el Dump

0012CD90 02 00 00 00 AC 04 00 00 ...¬ ..

0012CD98 T..h...

0012CDA0 00 D0 FD 7F 42 D3 E5 77 .ÐýBÓåw

0012CDA8 EC 90 68 00 02 00 00 00 ì h.[1]...

0012CDB0 00 00 00 00 EC 90 68 00 ....ì h.

0012CDB8 EC 90 68 00 00 00 00 00 ì h.....

0012CDC0 01 49 52 E1 00 00 00 00 IRá....

0012CDC8 18 3D C6 F3 00 00 00 00 =Æó....

Si pueden ver 5 de las primeras 6 dword han cambiado [estos valores pueden cambiar en cada ejecución aun en la misma maquina] por que el hijo ahora se esta ejecutando en un bucle infinito por lo cual no creara ningún error, en el desensamblado también pueden notar que el código esta ofuscado, mas no lo suficiente ya que se pueden ver fácilmente los bytes 68E8030000 [verde], que equivale a la instrucción

push 000003E8 [1000 decimal]

Si recordamos los parámetros que se le dan a WaitForDebugEvent, son

0012BCB8 006E264F /CALL to WaitForDebugEvent from MovieCol.006E2649

0012BCBC 0012CD90 |pDebugEvent = 0012CD90

0012BCC0 000003E8 \Timeout = 1000. ms

Por lo que la API esperara 1 segundo [1000 ms] antes de captar el error [si lo hay] en el hijo, para agilizar las cosas cambiemos ese parámetro de 000003E8 a 00000001, para que solo tarde 1 milisegundo en buscar el error, así que vayamos a la dirección donde esta el 68E8030000 y modifiquémoslo para que quede así

006E263B 3361 68 XOR ESP,DWORD PTR DS:[ECX+68] ; |

006E263E ADD DWORD PTR DS:[EAX],EAX

006E2640 0000 ADD BYTE PTR DS:[EAX],AL

006E2642 8B95 DCF5FFFF MOV EDX,DWORD PTR SS:[EBP-A24] ; |

006E2648 52 PUSH EDX ; |pDebugEvent

006E2649 FF15 E0707100 CALL DWORD PTR DS:[<&KERNEL32.WaitForDebugEvent>

006E264F 85C0 TEST EAX,EAX

006E2651 0F84 2B270000 JE MovieCol.006E4D82

Solo se cambiaron los bytes E803 a 0100 [amarillo], ahora vamos a escribir el código que restaurara las 6 dword del reporte e incrementara en 1000h bytes las direcciones del EIP que causa el error, aun estamos en la línea verde, ahí ensamblemos un salto para desviar el control a nuestro código

006E263B 3361 68 XOR ESP,DWORD PTR DS:[ECX+68] ; |

006E263E 0100 ADD DWORD PTR DS:[EAX],EAX

006E2640 0000 ADD BYTE PTR DS:[EAX],AL

006E2642 8B95 DCF5FFFF MOV EDX,DWORD PTR SS:[EBP-A24] ; |

006E2648 52 PUSH EDX ; |pDebugEvent

006E2649 FF15 E0707100 CALL DWORD PTR DS:[<&KERNEL32.WaitForDebugEvent>

006E264F -E9 ACE9D1FF JMP MovieCol.00401000

006E2654 90 NOP

006E2655 90 NOP

006E2656 90 NOP

Elegí la dirección 00401000 por que es donde comienza el código del ejecutable original, más, como estamos en el padre, esta zona no será usada, así que vallamos a esa zona y ensamblemos esto

00401000 90 NOP

C705 90CD1200 >MOV DWORD PTR DS:[12CD90],1

0040100B C705 94CD1200 >MOV DWORD PTR DS:[12CD94],4AC

C705 98CD1200 >MOV DWORD PTR DS:[12CD98],650

0040101F C705 9CCD1200 >MOV DWORD PTR DS:[12CD9C],80000001

C705 A0CD1200 >MOV DWORD PTR DS:[12CDA0],0

C705 A4CD1200 >MOV DWORD PTR DS:[12CDA4],0

0040103D 8105 A8CD1200 >ADD DWORD PTR DS:[12CDA8],1000

8105 B4CD1200 >ADD DWORD PTR DS:[12CDB4],1000

8105 B8CD1200 >ADD DWORD PTR DS:[12CDB8],1000

0040105B 813D B8CD1200 >CMP DWORD PTR DS:[12CDB8],MovieCol.00689000

00401065 ^74 D6 JE SHORT MovieCol.0040103D

813D B8CD1200 >CMP DWORD PTR DS:[12CDB8],MovieCol.0068A000

00401071 -0F8C DD152E00 JL MovieCol.006E2654

00401077 90 NOP

Las líneas en verde son las que restauran el reporte a como estaba cuando se produjo el error que causo la desencripción de la zona del EIP del hijo, si tienen problemas para obtener estos valores recuerden que los tenemos en el portapapeles por el binary copy, las líneas en amarillo son las que aumentan en 1000h bytes las zonas de memoria donde se guarda la dirección de memoria del hijo a ser desencriptada, las dos línea que están en turquesa son una comprobación para que cuando se llegue a la zona 00689000 le añada otros 1000h bytes ya que como esa zona ya fue desencriptada si se intenta desencriptar creara un error, las dos líneas en fucsia son la comprobación que reiniciara el bucle justo después del salto que pusimos a esta zona, le regresara el control al código del Armadillo solo si la dirección a desencriptar del hijo es menor a 0068A000 ya que ese es el final de la sección de código del hijo, esto lo podemos ver en el Memory Map

Memory map

Address Size Owner Section Contains Type Access Initial Mapped as

00401000 00289000 MovieCol CODE Imag R RWE

Así pues, si comienza en 00401000 y tiene un tamaño de 00289000 su valor máximo será

00401000 + 00289000 = 0068A000

Pongamos un Hardware Breakpoint on execution en 00401077 que es el final del bucle que desencriptara el código, vallamos al reporte en el Dump y modifiquemos las líneas que guardan el EIP del hijo que causo el error para que quede así

0012CD90 01 00 00 00 AC 04 00 00 ...¬ ..

0012CD98 50 06 00 00 01 00 00 80 P....€

0012CDA0 00 00 00 00 00 00 00 00 ........

0012CDA8 02 00 00 00 ..@. ...

0012CDB0 00 00 00 00 ......@.

0012CDB8 00 00 00 00 ..@.....

0012CDC0 01 49 52 E1 00 00 00 00 IRá....

0012CDC8 18 3D C6 F3 00 00 00 00 =Æó....

Les damos el valor 00400000 por que al pasar por primera vez en nuestro código se le añadirán 1000h bytes y así apuntaran al inicio de la sección del código original a ser desencriptado, demos un F9, tardara unos 20 o 30 segundos e incluso parecerá que se ha congelado el Olly, pero déjenlo trabajar y parara en

00401065 ^74 D6 JE SHORT MovieCol.0040103D

00401067 813D B8CD1200 >CMP DWORD PTR DS:[12CDB8],MovieCol.0068A000

00401071 -0F8C DD152E00 JL MovieCol.006E2654

00401077 90 NOP

00401078 0000 ADD BYTE PTR DS:[EAX],AL

0040107A 0000 ADD BYTE PTR DS:[EAX],AL

Quitemos el Breakpoint de ahí, abramos el LordPE, demos un dump full… [no necesitaran cambiar a IntelliDump, o al menos yo no lo necesite] al proceso hijo y guardemos el archivo como MovieCollector_dmp.exe, cerremos el LordPE y el Olly

Ahora editemos nuestro dump [MovieCollector_dmp.exe] en el LordPE y cambiemos el EntryPoint así

Presionemos Save, OK, carguemos este archivo en el Olly y veremos

006890EC >-EB FE JMP SHORT MovieCol.<ModuleEntryPoint>

006890EE EC IN AL,DX ; I/O command

006890EF 83C4 DC ADD ESP,-24

006890F2 33C0 XOR EAX,EAX

006890F4 8945 EC MOV DWORD PTR SS:[EBP-14],EAX

006890F7 B8 04896800 MOV EAX,MovieCol.00688904

006890FC E8 D7E9D7FF CALL MovieCol.00407AD8

00689101 33C0 XOR EAX,EAX

00689103 55 PUSH EBP

00689104 68 60926800 PUSH MovieCol.00689260

00689109 64:FF30 PUSH DWORD PTR FS:[EAX]

0068910C 64:8920 MOV DWORD PTR FS:[EAX],ESP

0068910F E8 1C36DDFF CALL MovieCol.0045C730

00689114 3D 47000400 CMP EAX,40047

00689119 7D 78 JGE SHORT MovieCol.00689193

Si mas no recuerdan creamos un bucle infinito en el hijo para que nos dejara trabajar, ahora hay que restaurar los bytes originales y quedara así

006890EC > 55 PUSH EBP

006890ED 8BEC MOV EBP,ESP

006890EF 83C4 DC ADD ESP,-24

006890F2 33C0 XOR EAX,EAX

006890F4 8945 EC MOV DWORD PTR SS:[EBP-14],EAX

006890F7 B8 04896800 MOV EAX,MovieCol.00688904

006890FC E8 D7E9D7FF CALL MovieCol.00407AD8

00689101 33C0 XOR EAX,EAX

00689103 55 PUSH EBP

00689104 68 60926800 PUSH MovieCol.00689260

00689109 64:FF30 PUSH DWORD PTR FS:[EAX]

0068910C 64:8920 MOV DWORD PTR FS:[EAX],ESP

0068910F E8 1C36DDFF CALL MovieCol.0045C730

00689114 3D 47000400 CMP EAX,40047

00689119 7D 78 JGE SHORT MovieCol.00689193

Así pues seleccionamos las instrucciones modificadas, damos un Copy to executable, Selection y lo guardamos como MovieCollector_dmp.exe y nos advertirá

Presionamos Sí y cerramos el Olly

Se habrá creado el archivo MovieCollector_dmp.bak, abramos el Olly y carguemos el archivo MovieCollector_dmp.exe y veremos

006890EC > 55 PUSH EBP

006890ED 8BEC MOV EBP,ESP

006890EF 83C4 DC ADD ESP,-24

006890F2 33C0 XOR EAX,EAX

006890F4 8945 EC MOV DWORD PTR SS:[EBP-14],EAX

006890F7 B8 04896800 MOV EAX,MovieCol.00688904

006890FC E8 D7E9D7FF CALL MovieCol.00407AD8

00689101 33C0 XOR EAX,EAX

00689103 55 PUSH EBP

00689104 68 60926800 PUSH MovieCol.00689260

00689109 64:FF30 PUSH DWORD PTR FS:[EAX]

0068910C 64:8920 MOV DWORD PTR FS:[EAX],ESP

0068910F E8 1C36DDFF CALL MovieCol.0045C730

00689114 3D 47000400 CMP EAX,40047

00689119 7D 78 JGE SHORT MovieCol.00689193

Y ya tenemos nuestro archivo dump totalmente desencriptado, con el OEP OK, ahora vamos sobre la IAT, avanzare rápido sobre este respecto ya que se ha explicado tanto ese tema que ya es algo aburrido, analicemos la información que nos da el Olly sobre la IAT, con el ratón bajemos hasta llegar a

00689150 8B45 EC MOV EAX,DWORD PTR SS:[EBP-14]

00689153 E8 9CC5D7FF CALL MovieCol.004056F4

00689158 50 PUSH EAX

00689159 E8 36F5D7FF CALL MovieCol.00408694 ; JMP to USER32.GetDesktopWindow

0068915E 50 PUSH EAX

0068915F E8 50F7D7FF CALL MovieCol.004088B4

00689164 83F8 06 CMP EAX,6

Sigamos la call que esta marcada y veremos

00408694 -FF25 A4686900 JMP DWORD PTR DS:[6968A4] ; USER32.GetDesktopWindow

0040869A 8BC0 MOV EAX,EAX

0040869C -FF25 A0686900 JMP DWORD PTR DS:[6968A0] ; USER32.GetDlgItem

Así que la IAT esta en la zona de memoria 006968A4, esa zona esta dentro de la sección

Memory map

Address Size Owner Section Contains Type Access Initial Mapped as

00696000 00004000 MovieCol .idata Imag R RWE

Así que vallamos a la dirección de memoria 006968A4 en el Dump y veremos

006968A4 D7 A0 D1 77 FD 85 D1 77 × Ñwý…Ñw

006968AC 32 53 D1 77 C0 41 D1 77 2SÑwÀAÑw

006968B4 66 80 D2 77 69 80 D3 77 f€Òwi€Ów

006968BC E6 7F D3 77 BF 45 D1 77 æÓw¿EÑw

006968C4 CB 82 D2 77 66 94 D1 77 Ë‚Òwf”Ñw

006968CC A7 3E D6 77 56 46 D1 77 §>ÖwVFÑw

006968D4 AF 79 D1 77 C1 83 D2 77 ¯yÑwÁƒÒw

Movámonos hacia arriba buscando el inicio de la IAT, que esta en

006961D0 00 00 00 00 00 00 00 00 ........

006961D8 00 00 00 00 00 00 00 00 ........

006961E0 CA 25 F4 77 90 56 F6 77 Ê%ôw Vöw

006961E8 DE 55 F6 77 45 A7 E5 77 ÞUöwE§åw

006961F0 CB 15 E6 77 72 AC E5 77 Ëæwr¬åw

006961F8 A0 60 E5 77 82 A6 E5 77  `åw‚¦åw

00696200 9B A2 E5 77 7F 61 E5 77 ›¢åwaåw

00696208 1D 98 F9 00 DF A7 E5 77 ˜ù.ߧåw

00696210 71 A6 E5 77 60 A6 E5 77 q¦åw`¦åw

El inicio de la IAT es 006961E0, recordemos esta dirección de memoria ya que nos servirá para encontrar nuestro salto mágico, cerremos el Olly

Abramos el Olly, carguemos nuestra app [MovieCollector.exe], escondamos el dbg, evitemos el desbordamiento de OutputDebugStringA cada vez que se ofrezca, pongamos un bp WriteProcessMemory, demos un F9 y parara la primera vez en la que solo se escribirán 2 bytes, así que demos otro F9 para llegar a la llamada que vuelve a escribir solo 2 bytes, vemos la pila y

0012B9B8 006E6B3D /CALL to WriteProcessMemory from MovieCol.006E6B37

0012B9BC 00000050 |hProcess = 00000050 (window)

0012B9C0 006F24D3 |Address = 6F24D3

0012B9C4 0071DE34 |Buffer = MovieCol.0071DE34

0012B9C8 00000002 |BytesToWrite = 2

0012B9CC 0012BCAC \pBytesWritten = 0012BCAC

La línea marcada indica la dirección de memoria de donde se tomaran los bytes a escribir en el hijo, vallamos a esa dirección en el Dump

0071DE34 55 8B 00 00 00 00 00 00 U‹......

0071DE3C 00 00 00 00 00 00 00 00 ........

0071DE44 00 00 00 00 00 00 00 00 ........

0071DE4C 00 00 00 00 00 00 00 00 ........

Como recordaran la primera llamada crea un bucle infinito en el hijo, esta segunda llamada quita ese bucle restaurando los bytes originales, pero como nosotros queremos trabajar con el padre sin que moleste el hijo, cambiemos esos bytes a EBFE para mantener el bucle infinito y quedara así

0071DE34 EB FE 00 00 00 00 00 00 ëþ......

0071DE3C 00 00 00 00 00 00 00 00 ........

0071DE44 00 00 00 00 00 00 00 00 ........

0071DE4C 00 00 00 00 00 00 00 00 ........

Damos F9, vamos al Memory Map y le damos un F2 a la sección de código del Armadillo

Memory map

Address Size Owner Section Contains Type Access Initial Mapped as

006C7000 00040000 MovieCol .text code Imag R RWE

Y puede parar en 2 lugares, el primero y el mas común es

006E0285 . 3D 02010000 CMP EAX,102

006E028A . 75 02 JNZ SHORT MovieCol.006E028E

006E028C .^EB D3 JMP SHORT MovieCol.006E0261

006E028E > 68 FA000000 PUSH 0FA ; /Timeout = 250. ms

006E0293 . FF15 A0717100 CALL DWORD PTR DS:[<&KERNEL32.Sleep>]

006E0299 > 8B45 DC MOV EAX,DWORD PTR SS:[EBP-24]

Este no sirve, así que demos un F9, después un F2 en la sección .text hasta llegar a

006E264F 85C0 TEST EAX,EAX

006E2651 0F84 2B270000 JE MovieCol.006E4D82

006E2657 . 8B85 FCFDFFFF MOV EAX,DWORD PTR SS:[EBP-204]

006E265D . 25 FF000000 AND EAX,0FF

006E2662 . 85C0 TEST EAX,EAX

006E2664 . 74 13 JE SHORT MovieCol.006E2679

006E2666 . 8B0D 44DF7100 MOV ECX,DWORD PTR DS:[71DF44]

006E266C . 8379 20 00 CMP DWORD PTR DS:[ECX+20],0

006E2670 . 74 07 JE SHORT MovieCol.006E2679

006E2672 . C685 FCFDFFFF >MOV BYTE PTR SS:[EBP-204],0

006E2679 > 68 38DE7100 PUSH MovieCol.0071DE38 ; /pCriticalSection = 0071DE38

006E267E . FF15 A4717100 CALL DWORD PTR DS:[<&KERNEL32.EnterCriticalSection>

Aquí ensamblamos unas líneas de código para separar al padre del hijo

006E264F 90 NOP

006E2650 68 74020000 PUSH 274

006E2655 E8 D9CB7A77 CALL kernel32.DebugActiveProcessStop

006E265A 90 NOP

006E265B 90 NOP

006E265C 90 NOP

La línea marcada es cuando se empuja a la pila el PID del proceso hijo [no diré como hallarlo y que es muy fácil], presionemos F8 hasta llegara la línea 006E265A, una vez ahí ya se abra separado el padre del hijo y ahora podremos analizarlo con el Olly

Sin cerrar el Olly que tiene al padre, abramos otra instancia del Olly y attacheemos el proceso 274, escondamos el dbg, evitemos el desbordamiento de OutputDebugStringA cada vez que se ofrezca, vallamos al Memory Map, pongamos un F2 en la sección .text, demos F9 y parara en

006F24D3 >-EB FE JMP SHORT MovieCol.<ModuleEntryPoint>

006F24D5 EC IN AL,DX ; I/O command

006F24D6 6A FF PUSH -1

006F24D8 68 20CB7100 PUSH MovieCol.0071CB20

006F24DD 68 10226F00 PUSH MovieCol.006F2210

Como recordaran este es el bucle infinito que evitamos se rompiera, ahora hay que restaurar los bytes originales y quedara así

006F24D3 > 55 PUSH EBP

006F24D4 8BEC MOV EBP,ESP

006F24D6 6A FF PUSH -1

006F24D8 68 20CB7100 PUSH MovieCol.0071CB20

006F24DD 68 10226F00 PUSH MovieCol.006F2210

Ahora vallamos a la dirección de memoria 006961E0 en el Dump

006961E0 00 00 00 00 ........

006961E8 00 00 00 00 00 00 00 00 ........

006961F0 00 00 00 00 00 00 00 00 ........

006961F8 00 00 00 00 00 00 00 00 ........

00696200 00 00 00 00 00 00 00 00 ........

Esa dirección ahora esta en ceros, pero como ya vimos ahí será el inicio de la tabla, así que pongamos un Hardware Breakpoint on write, dword en la dirección marcada, demos F9 y para aquí

77C12F43 F3:A5 REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS>

77C12F45 FF2495 5830C177 JMP DWORD PTR DS:[EDX*4+77C13058]

77C12F4C 8BC7 MOV EAX,EDI

77C12F4E BA 03000000 MOV EDX,3

77C12F53 83E9 04 SUB ECX,4

77C12F56 72 0C JB SHORT msvcrt.77C12F64

Este no nos interesa, demos otro F9 y

00FA9770 8B85 10D9FFFF MOV EAX,DWORD PTR SS:[EBP-26F0]

00FA9776 8B8D 64CAFFFF MOV ECX,DWORD PTR SS:[EBP-359C]

00FA977C 8908 MOV DWORD PTR DS:[EAX],ECX

00FA977E 8B85 10D9FFFF MOV EAX,DWORD PTR SS:[EBP-26F0] ; MovieCol.006961E0

00FA9784 83C0 04 ADD EAX,4

00FA9787 8985 10D9FFFF MOV DWORD PTR SS:[EBP-26F0],EAX

00FA978D ^E9 4DFCFFFF JMP 00FA93DF

00FA9792 FF15 9420FB00 CALL DWORD PTR DS:[FB2094] ; kernel32.GetTickCount

006961E0 CA 25 F4 77 3A 6B 29 00 Ê%ôw:k).

006961E8 52 6B 29 00 6A 6B 29 00 Rk).jk).

006961F0 86 6B 29 00 94 6B 29 00 †k).”k).

006961F8 A4 6B 29 00 B0 6B 29 00 ¤k).°k).

00696200 BE 6B 29 00 CE 6B 29 00 ¾k).Îk).

Como se puede ver ya se escribió el primer valor de la IAT, este valor es una entrada correcta, quitemos el Breakpoint que pusimos en 006961E0 y presionemos F8 hasta llegar a

00FA966B 8985 64CAFFFF MOV DWORD PTR SS:[EBP-359C],EAX

00FA9671 83BD 64CAFFFF 00 CMP DWORD PTR SS:[EBP-359C],0

00FA9678 75 42 JNZ SHORT 00FA96BC

00FA967A 0FB785 68CAFFFF MOVZX EAX,WORD PTR SS:[EBP-3598]

00FA9681 85C0 TEST EAX,EAX

00FA9683 74 0F JE SHORT 00FA9694

Este es el salto mágico, así que pongamos un Hardware Breakpoint on execution ahí y editemos el archivo IAT Script.osc

BABEL:

cmp eip, 00FA9678

jne FIN

mov !ZF, 1

La línea marcada tiene que ser editada para que el valor coincida con la dirección del salto mágico, ahora pongamos un Hardware Breakpoint on execution en el OEP que es 006890EC y ejecutemos el Script

Cuando el Script haya finalizado estaremos en el OEP aun encriptado, quitemos los dos Breakpoints, y vallamos al Dump en la dirección 006961E0

006961E0 CA 25 F4 77 90 56 F6 77 Ê%ôw Vöw

006961E8 DE 55 F6 77 45 A7 E5 77 ÞUöwE§åw

006961F0 CB 15 E6 77 72 AC E5 77 Ëæwr¬åw

006961F8 A0 60 E5 77 82 A6 E5 77  `åw‚¦åw

00696200 9B A2 E5 77 7F 61 E5 77 ›¢åwaåw

00696208 42 D1 E5 77 DF A7 E5 77 BÑåwߧåw

00696210 71 A6 E5 77 60 A6 E5 77 q¦åw`¦åw

00696218 44 7F E5 77 49 A9 E5 77 DåwI©åw

00696220 AF 9B E4 77 FC A7 E5 77 ¯›äwü§åw

Se puede observar que la IAT esta reparada, bajemos hasta llegar al final de la IAT que esta en

00696AF8 F8 12 A3 71 A7 12 A3 71 ø£q§£q

00696B00 7E 59 F9 00 D8 1A B0 76 ~Yù.Ø°v

00696B08 25 5A F9 00 A1 39 E5 77 %Zù.¡9åw

00696B10 2A 5A F9 00 6B 65 72 6E *Zù.kern

00696B18 65 6C 33 32 2E 64 6C 6C el32.dll

Este es el final de la IAT, así que

Final – Inicio = Tamaño

00696B10 – 006961E0 = 930

Abramos el ImpRec, elijamos el proceso hijo y pongamos como datos

OEP: 002890EC

RVA: 002961E0

Size: 00000930

Get Imports, Show Invalid, Cut thunk(s), Fix Dump, elegimos MovieCollector_dmp.exe, cerramos ambos Olly’s y ya tenemos nuestro ejecutable con la IAT reparada

Ahora vallamos sobre el tema del día; Nanomites

Sobre este tema también avanzare algo rápido ya que igual que la IAT, es un tema que ya se ha tocado y explicado mucho [Zilot, RNarvaja, TSRh TeaM, etc..] por lo cual me limitare a explicar las diferencias de mi método y digo mi método, por que yo lo diseñe con respecto a mi gusto de quedarme lo mas fuera y externo al proceso del Armadillo, al atacar solo las cosas que son menos factibles que cambien de versión en versión, esto también hará parecer al método mas feo de lo que es

Primero, lo primero, usaremos el N-Rec 1.7 [TSRh TeaM 2004] para obtener las tablas

Presionamos Process y nos dirá

Si la rutina de los nanomites no es encontrada intenten abrir el catalogo de prueba [si lo cerraron antes] o realizar funciones del programa, en la carpeta donde esta nuestra app se crearon los archivos

all_tbl_dump.dat

nano_addr.bin

nano_dest.bin

nano_size.bin

nano_type.bin

El archivo all_tbl_dump.dat podemos borrarlo ya que no lo usaremos, si notamos el la lista de errores del N-Rec nos dice

Esto quiere decir que tendremos que hallar manualmente el tipo de salto para cada nanotype, de esto no nos informa el N-Rec pero también es un error

Las entradas en el archivo nano_addr.bin están encriptadas el N-Rec las intenta desencriptar pero no lo logra, así que hay que hacerlo a mano, las demás tablas están bien

Una vez mas, al usar herramientas ya programadas, podemos ver si un proceso o esquema de protección realmente ha cambiado o solo le modificaron algunas cosas para que los patrones o funciones que buscase el N-Rec no fueran encontrados, así pues entre mas alejados nos mantengamos de lo especifico y optemos por un esquema generalizado, mas viabilidad tendremos para mutar a nuevos esquemas

Comencemos por el archivo nano_addr.bin, abrámoslo con el HexWorkshop y veremos

30BC 0100 D07D 2700 D37D F500 33BD 7B01 326C 9D01 506D 0F02 30FC 2F03

31FC 3703 906D 5703 323D 4704 337D 6D04 732D 7904 32AC F304 333C 4505

D2BD 7B05 30AC 7F05 907D FF05 11BC 8F06 D26D B906 927D D907 112C 7D20

30EC 7D20 732D 8F20 907D 2F23 13FC 3F23 126D A523 B2ED 1324 F1BD E324

707D 2325 512D 8525 10ED AF25 F16D FF25 703D 0926 133C 5526 336C 6F26

133D 3727 11EC FB27 B3ED 9F42 D3ED B142 D07D 0343 72ED 2743 917D 1944

73BD 2944 122C 6544 F0AD F544 927D F944 136C 3F45 F1AD 6545 F1AD E145

F1AD 3346 90AD B346 B2FD F546 D06D 2D60 307C 2D60 73BD 6D60 307C AD60

90ED D160 31AC 4563 723D 2164 D17D 3B64 717D 8B64 33BC AF64 32FD EB64

B3AD 4765 336D 5D65 D07D 6165 33BC 0966 936D 0D66 326C 8566 306D 1F67

33BD 2567 D1ED 7D67 B17D BB67 32FC E167 923D A580 31ED 7582 B36D E383

312C 2784 B1AD 2F84 30FD 3D84 B23D E984 D2AD 2385 502D 3985 F22D F585

B1ED 7586 326C 9D86 32FC F186 31FC 3DA0 12AD 89A0 322D 65A1 137C E3A1

B07D 39A2 F12D 4DA2 D27D E7A3 116D 0FA4 313C 11A4 12FC 11A4 32EC 1DA4

726D BDA4 11FD C1A6 B0FD 2FA7 517D 7FA7 93ED BBA7 12BC 23C0 90AD 75C0

Cada dword es una entrada, cada entrada corresponde al EIP donde se esta el Int3 [byte CC] + 1, ya que el ser ejecutado el Int3 el EIP apunta a la instrucción siguiente, estas dword se guardan en orden inverso, tal cual lo harían en memoria así pues el primer valor es 0001BC30, fácilmente se puede notar que esta entrada no esta dentro de la sección de código de nuestro ejecutable dumpeado que va desde 00401000 hasta 0068A000, si se siguen comparando entradas se vera que ninguna esta en el rango de la sección de código de nuestro dump, así que concluimos que este archivo esta encriptado

Hay un método para desencriptar este archivo y obtener el valor original de esta tabla, mas yo opte por un método mas radical, para este usaremos ArmTools en su sección NanoAddress

Le indicamos la ruta a nuestro exe dumpeado, donde inicia el código, el tamaño, presionamos Parsear, nos dice que el proceso ha terminado y nos da información extra

4152 es el numero de direcciones+1 donde se encontró el byte CC [Int3], en la carpeta donde esta el exe dumpeado se creo el archivo nano_padd.bin, que contiene estas 4152 entradas

Bien, pues al tener todas las direcciones+1 donde se encuentran los bytes CC, también tenemos todos los valores del archivo nano_addr.bin, solo hay que saber cual es cual, lo que haremos será encriptar el archivo nano_padd.bin y lo guardaremos como nano_pade.bin, compararemos una entrada encriptada de nano_pade.bin con cada una de nano_addr.bin y si son iguales entonces la reemplazamos por su equivalente no encriptado de nano_padd.bin, sin embargo habrá entradas en nano_addr.bin que no sean iguales a ninguna entrada de nano_pade.bin, ¿Qué significa esto? Significa que aunque esa entrada tenga un valor dentro del rango de la sección de código de nuestro dump, en esa dirección NO hay un byte CC por lo cual es falsa, así que no solo obtendremos el archivo nano_addr.bin desencriptado si no que también añadiremos un nuevo filtro anti-nanomites falsos

Bien, para fines de encripción usaremos el Script AddrEnc.osc, editémoslo

log VATable

mov [VATable], "D:\Documents and Settings\tenketsu\Escritorio\nano_padd.bin"

eval "push "

shl VACont, 2

dm VATable, VACont, "D:\Documents and Settings\tenketsu\Escritorio\nano_pade.bin"

ret

La primera marca debe ser editada para que apunte al archivo que acabamos de crear con el ArmTools, la segunda marca debe ser editada para que apunte al archivo resultante que deseemos que se guarde

Antes de seguir, el archivo OllyScript.dll, que es el plugin OllyScript v0.92 by SHaG, tiene un bug en la instrucción dm que provoca que la memoria que se dumpea al archivo especificado contenga bytes extra no deseados, adjunto a este tute viene un reemplazo a OllyScript.dll que corrige ese error, así que antes de usar este script, reemplaza el archivo OllyScript.dll que tengas por el que viene con este tute

Ya estamos listos para encriptar nuestro archivo, así que abramos el Olly, carguemos nuestra app [MovieCollector.exe], escondamos el dbg, quitemos el Hardware Breakpoint de OutputDebugStringA y reemplacémoslo con un bp normal, demos F9, parara en OutputDebugStringA, evitemos el desbordamiento, demos otro F9, una vez mas para en OutputDebugStringA, volvemos a evitar el desbordamiento, damos un Ctrl+F9, un F8, ejecutamos el Script, nos dice que el Script ha finalizado y se habrá creado el archivo con las entradas encriptadas en la ruta especificada en el Script

Si el Script no se inicia, intenta abrir el catalogo de prueba o usar las funciones del programa hasta que se ejecute algún nanomite

Cerramos el Olly, abrimos el ArmTools en su sección NanoAddress y

Presionamos Parchar, nos dice que le proceso ha terminado y nos da información extra

Aquí nos dice cuantas entradas había en el archivo nano_addr.bin y cuantas eran verdaderas, como se puede ver todas son verdaderas, por raro que parezca esto invariablemente es bueno, pronto sabrán por que, se habrá creado el archivo nano_addr.bin.bak y el archivo nano_ador.bin, el primero es una copia de seguridad del archivo nano_addr.bin, el segundo es los mismo que nano_addr.bin, solo que las entradas están ordenadas de menor a mayor y no se incluyen las entradas falsas, veamos estos archivos en el HexWorkshop

597E 6600 5826 5800 5981 5800 DA59 4400 D387 6600 D426 4A00 DE2E 6400

5E2B 6400 5625 5200 5814 4700 D900 4500 D151 4D00 50DD 6500 5B10 6700

DA5D 5900 D23D 6500 DAA5 5100 DCBA 6300 D5C7 5900 DFC5 5300 C131 6000

C12D 6400 C092 4E00 CE26 5000 CE0B 6000 4786 4000 404F 5700 48F8 5D00

4A66 4D00 43B2 4B00 C2AE 4100 C2A1 5D00 CD76 4F00 4D11 6300 C400 6500

4E13 4100 C6E9 6100 F48B 5600 75CB 5800 7E66 5A00 760E 4C00 F963 5300

F95A 4D00 7114 6100 71BD 5D00 F9C5 5100 F203 6100 7338 5D00 73F8 5D00

747B 5D00 74FF 5100 7D8D 5500 E126 5800 E926 6400 E918 4C00 E9A6 6400

61ED 5200 6738 6600 6956 4D00 E863 5900 E8E2 4F00 E89A 6500 E8CC 4500

Este es el archivo nano_addr.bin ya desencriptado, en este caso no hay entradas falsas, pero si las hubiese aun estarían aquí, se conservan por términos de simetría con las demás tablas

30BC 0100 D07D 2700 D37D F500 33BD 7B01 326C 9D01 506D 0F02 30FC 2F03

31FC 3703 906D 5703 323D 4704 337D 6D04 732D 7904 32AC F304 333C 4505

D2BD 7B05 30AC 7F05 907D FF05 11BC 8F06 D26D B906 927D D907 112C 7D20

30EC 7D20 732D 8F20 907D 2F23 13FC 3F23 126D A523 B2ED 1324 F1BD E324

707D 2325 512D 8525 10ED AF25 F16D FF25 703D 0926 133C 5526 336C 6F26

133D 3727 11EC FB27 B3ED 9F42 D3ED B142 D07D 0343 72ED 2743 917D 1944

73BD 2944 122C 6544 F0AD F544 927D F944 136C 3F45 F1AD 6545 F1AD E145

F1AD 3346 90AD B346 B2FD F546 D06D 2D60 307C 2D60 73BD 6D60 307C AD60

90ED D160 31AC 4563 723D 2164 D17D 3B64 717D 8B64 33BC AF64 32FD EB64

Este es nano_addr.bin.bak, es el archivo nano_addr.bin original, este se guarda por si se ofrece

ED11 4000 EF1C 4000 1121 4000 1C21 4000 8E28 4000 ED2A 4000 9440 4000

A955 4000 5F82 4000 5F84 4000 4786 4000 159D 4000 9FB1 4000 45B2 4000

19BC 4000 36E7 4000 25F4 4000 1A03 4100 F10D 4100 1412 4100 4E13 4100

7213 4100 BC13 4100 7F14 4100 1615 4100 232C 4100 4E2D 4100 B12F 4100

C939 4100 2169 4100 D077 4100 458E 4100 8D90 4100 D5A5 4100 F7A7 4100

EFAD 4100 72AE 4100 C2AE 4100 CDAE 4100 13B0 4100 45B1 4100 9EB7 4100

CFC4 4100 21D9 4100 C9DE 4100 9DE6 4100 5715 4200 F53C 4200 833D 4200

D83D 4200 4C3E 4200 6845 4200 E154 4200 9D6D 4200 096F 4200 1986 4200

BD86 4200 6688 4200 1C91 4200 F593 4200 99B8 4200 FAB9 4200 31BE 4200

8DC5 4200 26CF 4200 D8DA 4200 81DE 4200 8EDE 4200 B0DE 4200 73E1 4200

Este es nano_ador.bin, este archivo contiene solo las entradas verdaderas de nano_addr.bin y están ordenadas de menor a mayor

Este paso ya esta completo, ahora vallamos sobre los nanotypes

Abramos el ArmTools en su sección de NanoTypes y

Presionamos Parsear, nos dice que el proceso ha terminado y nos da información extra

Esto nos dice que en el archivo nano_type.bin solo hay 76 tipos diferentes de nanotypes, de 256 posibles, en la carpeta donde esta nano_type.bin se habrá creado el archivo nano_tpor.bin, veamos que contiene

0203 0405 0607 0809 0A0B 0C0D 0E0F 1011 1415 1F20 2122 2330 3637 3D43

474C 5152 5464 6972 7478 797C 8082 8388 8A94 9798 9CA0 A6AC AEB0 B3B6

BFC2 C3C5 C6CA D0D2 D7DB DCDD DFE3 E8EE EFF3 F8FA

Estos son todos los nanotypes ordenados de menor a mayor, para obtener el salto que corresponde a cada nanotype usaremos el Script ChekFlags.osc, editémoslo

log VANanTypTab

mov [VANanTypTab], "D:\Documents and Settings\tenketsu\Escritorio\nano_tpor.bin"

eval "push "

La línea marcada se tiene que editar para que apunte al archivo que acabamos de crear

Ya estamos listos para descifrar los misterios de los nanotypes, así que abramos el Olly, carguemos nuestra app [MovieCollector.exe], escondamos el dbg, pongamos un bp normal en OutputDebugStringA, demos F9, parara en OutputDebugStringA, evitemos el desbordamiento, demos otro F9, una vez mas para en OutputDebugStringA, volvemos a evitar el desbordamiento, damos un Ctrl+F9, un F8, ejecutamos el Script, realiza algunos cambios y nos dice

Presionamos Aceptar, vamos a la ventana Log, con el botón secundario del ratón elegimos la opción Log to file del menú emergente, lo guardamos como nanologFull.txt, vamos al menú Plugins, OllyScript, elegimos Resume, si pueden ver el log, se estarán escribiendo muchas líneas, después de unos segundos nos dirá que el Script ha terminado, así que cerremos el Olly

Ahora editemos el archivo nanologFull.txt en el UltraEdit y veremos

006E3C5C COND:

006E3CEC COND:

006E3D24 COND:

006E3D4E COND:

006E3C5C COND:

006E3CEC COND:

006E3D24 COND:

006E3D4E COND:

006E3C5C COND: 000000FA

006E3CEC COND: 00000FD6

006E3D24 COND:

006E3D4E COND:

006E3D90 Hardware breakpoint 1 at MovieCol.006E3D90

00400000 Unload D:\Archivos de programa\Collectorz.com\Movie Collector\MovieCollector.exe

77C40000 Unload D:\WINDOWS\system32\GDI32.dll

77D10000 Unload D:\WINDOWS\system32\USER32.dll

77DA0000 Unload D:\WINDOWS\system32\ADVAPI32.dll

77E40000 Unload D:\WINDOWS\system32\kernel32.dll

77F40000 Unload D:\WINDOWS\System32\ntdll.dll

78000000 Unload D:\WINDOWS\system32\RPCRT4.dll

Process terminated

End of session

Lo que esta marcado es lo único que nos interesa del Log, así que borremos todo lo demás para que quede así

000000FA

00000F97

000000FA

00000FD3

000000FA

00000FD6

Aquí se ve el inicio y el final, en la ultima línea del final del archivo NO debe haber espacios, ni líneas nuevas ni nada, debe ser el valor xxxxxxxx y nada mas

Ahora abramos el ArmTools en su sección NanoTypes y

Presionamos Parsear, nos dice que el proceso ha terminado y en la información extra nos dice que le numero de nanotypes era 76, si este numero difiere del anterior [nano_tpor.bin] es que algo anda mal, en la carpeta donde esta nanologFull.txt se habrá creado el archivo nano_jcdn.bin, veamos que contiene

0B 0C 060B 0706 0807 0908 0A0A 0B0C 0C08 0D09 0E00 0F10

1007 1100 140A 150A 1F00 200A 2100 2211 2310 3011 360C 3700 3D0A 430B

4700 4C0C 5106 520A 540C 640A 6911 7200 740F 7800 790A 7C0C 800A 8205

8300 8811 8A10 9411 9700 980A 9C11 A006 A60E AC0C AE0A B011 B306 B611

BF11 C205 C311 C500 C611 CA0A D00A D200 D710 DB00 DC11 DD00 DF11 E30C

E805 EE0C EF05 F30A F80B FA10

Este archivo se compone de parejas de bytes [Word], el primero [amarillo] es el nanotype, el segundo [verde] es el tipo de salto que le corresponde de acuerdo a la tabla

01 02 03 04 05 06 07 08

jmp jnp jno jo jecxz jc jle jnc jp

0A 0B 0C 0D 0E 0F 10 11

js jz jg jl jns ja jbe jge jnz

Como verán use el formato de la tabla JCDN del N-Rec solo que en binario, bien ahora ya tenemos todo para parchar nuestros nanomites

Abramos el ArmTools y en la sección de Nanomites

Presionamos Parchar, nos dice que el proceso ha terminado y nos da información extra

Si recuerdan todas las entradas de nano_addr.bin eran correctas, estas entradas corresponden al numero de nanomites [2031], pero de estos solo se han parchado 176 [menos del 9%], por eso les decía que invariablemente es bueno que todas las entradas de nano_addr.bin sean correctas ya que en la experiencia que tengo con los nanomites, esto siempre es así, si nano_addr.bin es totalmente correcto, los nanomites verdaderos serán realmente pocos

Ahora tenemos 2 archivos

MovieCollector_dmp_.exe <- Archivo con los Nanomites parchados

MovieCollector_dmp_.exe.bak <- Archivo con los Nanomites en forma original

Renombremos MovieCollector_dmp_.exe.bak a MovieCollector_.exe y carguémoslo en el Olly, dejémoslo en el OEP y abramos otra instancia del Olly, es esta nueva instancia carguemos el archivo que tiene los nanomites parchados [MovieCollector_dmp_.exe], seleccionemos desde 00401000 hasta 0068A000

00401000 04 10 ADD AL,10

00401002 40 INC EAX

00401003 0003 ADD BYTE PTR DS:[EBX],AL

00689FFD 55 PUSH EBP

00689FFE 55 PUSH EBP

00689FFF 55 PUSH EBP

Y démosle un Binary copy, se tardara un poco, ahora pasemos al otro Olly [MovieCollector_.exe], seleccionemos desde 00401000 hasta 0068A000, demos un Binary paste, se tardara un poco, ya podemos cerrar el segundo Olly [MovieCollector_dmp_.exe]

Ahora con un solo Olly [MovieCollector_.exe], posicionémoslos en 00401000, demos clic con el botón secundario del ratón, elijamos Search for, Modified command y nos mandara a

Este nanomite es verdadero así que demos Ctrl+L para repetir la búsqueda y nos mandara a

Este nanomite también es verdadero, sigamos presionando Ctrl+L hasta llegar al primer falso que esta en

Aquí presionemos Alt+BackSpace para que quede así

A continuación enumerare TODOS los nanomites falsos incluyendo al anterior

Y esos son todos [¡¡solo 6!!], ahora posicionados sobre el ultimo nanomite [que es verdadero], seleccionemos de ahí hasta 00401000

Desde

Hasta

Démosle un Copy to executable, Selection y guardémoslo como MovieCollector2.exe, cerramos el Olly, renombramos el archivo MovieCollector.exe a MovieCollector_or.exe, renombramos el archivo MovieCollector2.exe a MovieCollector.exe, lo ejecutamos y

Se ejecuta perfectamente, ahora quitemos ese feo BUY NOW

Desensamblamos el archivo MovieCollector.exe con el W32Dasm 8.93 + BratPatch 3.0 y vamos a

:0065714A A1881C6900  mov eax, dword ptr [00691C88]

:0065714F 8B00 mov eax, dword ptr [eax]

:00657151 8A4014 mov al, byte ptr [eax+14]

:00657154 2C01 sub al, 01

jb 00657160

je 00657172

:0065715A FEC8 dec al

:0065715C 7426 je 00657184

:0065715E EB34 jmp 00657194

* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:00657156(C)

* Possible StringData Ref from Code Obj ->"Trial Edition"

|

:00657160 BA44726500 mov edx, 00657244

:00657165 8B8398030000 mov eax, dword ptr [ebx+00000398]

:0065716B E8683AE3FF  call 0048ABD8

:00657170 EB22 jmp 00657194

* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:00657158(C)

* Possible StringData Ref from Code Obj ->"Standard Edition"

|

:00657172 BA5C726500 mov edx, 0065725C

:00657177 8B8398030000 mov eax, dword ptr [ebx+00000398]

:0065717D E8563AE3FF  call 0048ABD8

:00657182 EB10 jmp 00657194

* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:0065715C(C)

* Possible StringData Ref from Code Obj ->"Pro Edition"

|

:00657184 BA78726500  mov edx, 00657278

:00657189 8B8398030000 mov eax, dword ptr [ebx+00000398]

:0065718F E8443AE3FF  call 0048ABD8

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:

|:0065715E(U), :00657170(U), :00657182(U)

* Possible StringData Ref from Code Obj ->"https://www.collectorz.com/movie/support.php"

|

:00657194 BA8C726500 mov edx, 0065728C

:00657199 8B8318030000 mov eax, dword ptr [ebx+00000318]

:0065719F E8343AE3FF  call 0048ABD8

:006571A4 33C0 xor eax, eax

:006571A6 5A  pop edx

:006571A7 59  pop ecx

:006571A8 59  pop ecx

:006571A9 648910  mov dword ptr fs:[eax], edx

:006571AC 68C6716500  push 006571C6

* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:006571C4(U)

:006571B1 8D45E8  lea eax, dword ptr [ebp-18]

:006571B4 BA06000000  mov edx, 00000006

:006571B9 E88AE0DAFF  call 00405248

:006571BE C3  ret

La manera de llegar a ese código se las dejo a su consideración [mediante ‘About’ es muy fácil], ahora la línea amarilla es lo interesante si se puede observar es

:00657151 8A4014 mov al, byte ptr [eax+14]

Mueve un byte a AL, con las comprobaciones concluimos que

AL < 1 significa Trial Edition

AL = 1 significa Standard Edition

AL = 2 significa Pro Edition

AL > 2 significa error

Así pues carguemos nuestro exe en el Olly, pongamos un bp en 00657151, demos F9, ya cargada la app vallamos a About y parara aquí

0065714A A1 881C6900 MOV EAX,DWORD PTR DS:[691C88]

0065714F 8B00 MOV EAX,DWORD PTR DS:[EAX]

00657151 8A40 14 MOV AL,BYTE PTR DS:[EAX+14]

00657154 2C 01 SUB AL,1

00657156 72 08 JB SHORT MovieCol.00657160

00657158 74 18 JE SHORT MovieCol.00657172

La dirección de memoria donde se toma el byte a escribir en AL es

DS:[00F04AE0]=00

Así que pongamos un Hardware Breakpoint on write, byte en 00F04AE0, quitemos el bp de 00657151, cerremos el Olly, reabramos el Olly, carguemos la app, demos F9 y parara en el Hardware Breakpoint

00404312 F3:AB REP STOS DWORD PTR ES:[EDI]

00404314 59 POP ECX

00404315 83E1 03 AND ECX,3

00404318 F3:AA REP STOS BYTE PTR ES:[EDI]

Este no nos importa, demos otro F9

0059A9D0 C646 14 00 MOV BYTE PTR DS:[ESI+14],0

0059A9D4 8BC6 MOV EAX,ESI

0059A9D6 84DB TEST BL,BL

0059A9D8 74 0F JE SHORT MovieCol.0059A9E9

0059A9DA E8 E59CE6FF CALL MovieCol.004046C4

Este tiene buena cara, pero no es lo que buscamos, así que otro F9

0059AA42 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4]

0059AA45 E8 EE040000 CALL MovieCol.0059AF38

0059AA4A 8B55 FC MOV EDX,DWORD PTR SS:[EBP-4]

0059AA4D 8842 14 MOV BYTE PTR DS:[EDX+14],AL

0059AA50 33C0 XOR EAX,EAX

0059AA52 5A POP EDX

0059AA53 59 POP ECX

0059AA54 59 POP ECX

0059AA55 64:8910 MOV DWORD PTR FS:[EAX],EDX

0059AA58 EB 11 JMP SHORT MovieCol.0059AA6B

Exactamente lo que buscamos, la línea amarilla es donde para el Breakpoint, así que en la línea superior es donde se guarda el byte 00 en 00F04AE0, si observamos guarda al valor de AL, este valor se toma en la call que esta en verde, así que entremos y veremos

0059AF38 55 PUSH EBP

0059AF39 8BEC MOV EBP,ESP

0059AF3B 83C4 F8 ADD ESP,-8

0059AF3E 53 PUSH EBX

0059AF3F 56 PUSH ESI

0059AF40 33C9 XOR ECX,ECX

0059AF42 894D F8 MOV DWORD PTR SS:[EBP-8],ECX

0059AF45 8955 FC MOV DWORD PTR SS:[EBP-4],EDX

0059AF48 8BF0 MOV ESI,EAX

0059AF4A 33C0 XOR EAX,EAX

0059AF4C 55 PUSH EBP

0059AF4D 68 C1AF5900 PUSH MovieCol.0059AFC1

0059AF52 64:FF30 PUSH DWORD PTR FS:[EAX]

0059AF55 64:8920 MOV DWORD PTR FS:[EAX],ESP

0059AF58 33DB XOR EBX,EBX

0059AF5A 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4]

0059AF5D 8378 04 00 CMP DWORD PTR DS:[EAX+4],0

0059AF61 74 48 JE SHORT MovieCol.0059AFAB

0059AF63 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4]

0059AF66 8378 0C 00 CMP DWORD PTR DS:[EAX+C],0

0059AF6A 74 3F JE SHORT MovieCol.0059AFAB

0059AF6C 8D55 F8 LEA EDX,DWORD PTR SS:[EBP-8]

0059AF6F 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4]

0059AF72 E8 6DF3FFFF CALL MovieCol.0059A2E4

0059AF77 55 PUSH EBP

0059AF78 8B46 0C MOV EAX,DWORD PTR DS:[ESI+C]

0059AF7B 85C0 TEST EAX,EAX

0059AF7D 79 05 JNS SHORT MovieCol.0059AF84

0059AF7F E8 AC92E6FF CALL MovieCol.00404230

0059AF84 E8 D3FEFFFF CALL MovieCol.0059AE5C

0059AF89 59 POP ECX

0059AF8A 84C0 TEST AL,AL

0059AF8C 74 04 JE SHORT MovieCol.0059AF92

0059AF8E B3 01 MOV BL,1

0059AF90 EB 19 JMP SHORT MovieCol.0059AFAB

0059AF92 55 PUSH EBP

0059AF93 8B46 10 MOV EAX,DWORD PTR DS:[ESI+10]

0059AF96 85C0 TEST EAX,EAX

0059AF98 79 05 JNS SHORT MovieCol.0059AF9F

0059AF9A E8 9192E6FF CALL MovieCol.00404230

0059AF9F E8 B8FEFFFF CALL MovieCol.0059AE5C

0059AFA4 59 POP ECX

0059AFA5 84C0 TEST AL,AL

0059AFA7 74 02 JE SHORT MovieCol.0059AFAB

0059AFA9 B3 02 MOV BL,2

0059AFAB 33C0 XOR EAX,EAX

0059AFAD 5A POP EDX

0059AFAE 59 POP ECX

0059AFAF 59 POP ECX

0059AFB0 64:8910 MOV DWORD PTR FS:[EAX],EDX

0059AFB3 68 C8AF5900 PUSH MovieCol.0059AFC8

0059AFB8 8D45 F8 LEA EAX,DWORD PTR SS:[EBP-8]

0059AFBB E8 64A2E6FF CALL MovieCol.00405224

0059AFC0 C3 RETN

0059AFC1 ^E9 D69AE6FF JMP MovieCol.00404A9C

0059AFC6 ^EB F0 JMP SHORT MovieCol.0059AFB8

0059AFC8 8BC3 MOV EAX,EBX

Este código es el que decide que tipo de registro tenemos [Trial, Standard o Pro], los dos saltos en amarillo nos desvían al XOR EAX,EAX, lo que daría un registro Trial, así que cambiemos los 74xx a 7400, los 2 saltos en verde no modifican el flujo del código así que no los cambiemos, el salto en turquesa decide si poner un byte 1 [Standard] o un 2 [Pro] así que cambiemos el 7404 por EB04, el salto en fucsia decide si poner un byte 2 [Pro] o un byte 0 [Trial], así que cambiemos 7402 por 7400, estos cambios quedaran así

0059AF38 55 PUSH EBP

0059AF39 8BEC MOV EBP,ESP

0059AF3B 83C4 F8 ADD ESP,-8

0059AF3E 53 PUSH EBX

0059AF3F 56 PUSH ESI

0059AF40 33C9 XOR ECX,ECX

0059AF42 894D F8 MOV DWORD PTR SS:[EBP-8],ECX

0059AF45 8955 FC MOV DWORD PTR SS:[EBP-4],EDX

0059AF48 8BF0 MOV ESI,EAX

0059AF4A 33C0 XOR EAX,EAX

0059AF4C 55 PUSH EBP

0059AF4D 68 C1AF5900 PUSH MovieCol.0059AFC1

0059AF52 64:FF30 PUSH DWORD PTR FS:[EAX]

0059AF55 64:8920 MOV DWORD PTR FS:[EAX],ESP

0059AF58 33DB XOR EBX,EBX

0059AF5A 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4]

0059AF5D 8378 04 00 CMP DWORD PTR DS:[EAX+4],0

0059AF61 74 00 JE SHORT MovieCol.0059AF63

0059AF63 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4]

0059AF66 8378 0C 00 CMP DWORD PTR DS:[EAX+C],0

0059AF6A 74 00 JE SHORT MovieCol.0059AF6C

0059AF6C 8D55 F8 LEA EDX,DWORD PTR SS:[EBP-8]

0059AF6F 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4]

0059AF72 E8 6DF3FFFF CALL MovieCol.0059A2E4

0059AF77 55 PUSH EBP

0059AF78 8B46 0C MOV EAX,DWORD PTR DS:[ESI+C]

0059AF7B 85C0 TEST EAX,EAX

0059AF7D 79 05 JNS SHORT MovieCol.0059AF84

0059AF7F E8 AC92E6FF CALL MovieCol.00404230

0059AF84 E8 D3FEFFFF CALL MovieCol.0059AE5C

0059AF89 59 POP ECX

0059AF8A 84C0 TEST AL,AL

0059AF8C EB 04 JMP SHORT MovieCol.0059AF92

0059AF8E B3 01 MOV BL,1

0059AF90 EB 19 JMP SHORT MovieCol.0059AFAB

0059AF92 55 PUSH EBP

0059AF93 8B46 10 MOV EAX,DWORD PTR DS:[ESI+10]

0059AF96 85C0 TEST EAX,EAX

0059AF98 79 05 JNS SHORT MovieCol.0059AF9F

0059AF9A E8 9192E6FF CALL MovieCol.00404230

0059AF9F E8 B8FEFFFF CALL MovieCol.0059AE5C

0059AFA4 59 POP ECX

0059AFA5 84C0 TEST AL,AL

0059AFA7 74 00 JE SHORT MovieCol.0059AFA9

0059AFA9 B3 02 MOV BL,2

0059AFAB 33C0 XOR EAX,EAX

0059AFAD 5A POP EDX

0059AFAE 59 POP ECX

0059AFAF 59 POP ECX

0059AFB0 64:8910 MOV DWORD PTR FS:[EAX],EDX

0059AFB3 68 C8AF5900 PUSH MovieCol.0059AFC8

0059AFB8 8D45 F8 LEA EAX,DWORD PTR SS:[EBP-8]

0059AFBB E8 64A2E6FF CALL MovieCol.00405224

0059AFC0 C3 RETN

0059AFC1 ^E9 D69AE6FF JMP MovieCol.00404A9C

0059AFC6 ^EB F0 JMP SHORT MovieCol.0059AFB8

0059AFC8 8BC3 MOV EAX,EBX

0059AFCA 5E POP ESI

0059AFCB 5B POP EBX

0059AFCC 59 POP ECX

0059AFCD 59 POP ECX

0059AFCE 5D POP EBP

0059AFCF C3 RETN

Cuando el flujo llegue a la línea roja EBX, que ahora vale 2, se moverá a EAX, por lo que AL valdrá 2 y al salir de la call, después del RETN, nuestra aplicación estará registrada en Pro Edition

El método para escribir los bytes modificados lo dejo a su gusto, yo uso Copy to executable, Selection, pero hay otras maneras de hacerlo, como sea, ya tenemos nuestro programa registrado, sin CopyMemII, con la IAT reparada, sin ningún Nanomite y lo mas importante sin el Armadillo

Y así terminamos con el Armadillo 4.x y sus nuevos trucos, cabe preguntarnos que demonios pasa con la industria del soft estos días, como ven TODA la protección del MovieCollector fue delegada al Armadillo y después de eso, no hay nada

Francamente triste, es.

Cosas que hacen pensar en el retiro.

Saludos.


Document Info


Accesari: 2524
Apreciat: hand-up

Comenteaza documentul:

Nu esti inregistrat
Trebuie sa fii utilizator inregistrat pentru a putea comenta


Creaza cont nou

A fost util?

Daca documentul a fost util si crezi ca merita
sa adaugi un link catre el la tine in site


in pagina web a site-ului tau.




eCoduri.com - coduri postale, contabile, CAEN sau bancare

Politica de confidentialitate | Termenii si conditii de utilizare




Copyright © Contact (SCRIGROUP Int. 2024 )