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
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
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
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
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
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
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
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
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
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
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
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 >
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
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
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
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
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
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]
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
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
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
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
003ADE64 3D 47 00 04 00 7D 78 6A =G. .}xj
003ADE6C 04 68
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
003ADE64 3D 47 00 04 00 7D 78 6A =G. .}xj
003ADE6C 04 68
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
Vallamos a la dirección de memoria 0012CD90 en el Dump y veremos
0012CD90 01 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
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
0012CD98 T..h...
0012CDA0 00 D0 FD
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
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
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
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]
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]
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]
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
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
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
Así que
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
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
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
006961F8 A0 60 E5 77 82 A6 E5 77 `åw‚¦åw
00696200 9B A2 E5 77
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
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
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
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
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
006961F8 A0 60 E5 77 82 A6 E5 77 `åw‚¦åw
00696200 9B A2 E5 77
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
00696220 AF 9B E4 77 FC A7 E5 77 ¯›äwü§åw
Se puede
observar que
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
Este es el final
de
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
Ahora vallamos sobre el tema del día; Nanomites
Sobre este tema también
avanzare algo rápido ya que igual que
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
31FC 3703 906D 5703 323D
4704 337D 6D04 732D 7904 32AC F304
D2BD 7B05 30AC 7F05 907D
FF05 11BC 8F06 D26D B906 927D D907
30EC 7D20 732D 8F20 907D 2F23 13FC 3F23 126D A523 B2ED 1324 F1BD E324
707D 2325 512D 8525 10ED
AF25 F16D FF25 703D 0926
133D 3727 11EC FB27 B3ED 9F42 D3ED B142 D07D 0343 72ED 2743 917D 1944
73BD 2944
F1AD 3346 90AD B346 B2FD
F546 D06D 2D60
90ED D160 31AC 4563 723D 2164 D17D 3B64 717D 8B64 33BC AF64 32FD EB64
B3AD 4765 336D 5D65 D07D
6165 33BC 0966 936D 0D66
33BD 2567 D1ED 7D67 B17D BB67 32FC E167 923D A580 31ED 7582 B36D E383
B1ED 7586
B07D 39A2 F12D 4DA2 D27D
E7A3 116D 0FA4
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
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
31FC 3703 906D 5703 323D
4704 337D 6D04 732D 7904 32AC F304
D2BD 7B05 30AC 7F05 907D
FF05 11BC 8F06 D26D B906 927D D907
30EC 7D20 732D 8F20 907D 2F23 13FC 3F23 126D A523 B2ED 1324 F1BD E324
707D 2325 512D 8525 10ED
AF25 F16D FF25 703D 0926
133D 3727 11EC FB27 B3ED 9F42 D3ED B142 D07D 0343 72ED 2743 917D 1944
73BD 2944
F1AD 3346 90AD B346 B2FD
F546 D06D 2D60
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
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
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
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
1007 1100 140A 150A 1F00
200A 2100 2211 2310 3011
4700 4C0C 5106 520A
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
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,
: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,
: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]
00657151 8A40 14 MOV AL,BYTE PTR DS:[EAX+14]
00657154
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
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
0059AF6A 74
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
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
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
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
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.
|