Armadillo 4.30a with Debug Blocker - manually unpacking

Sunday, October 02 2005 @ 03:19 PM CEST

Contributed by: haggar

Level : intermediate

====================================
Armadillo 4.30a with Debug Blocker - manually unpacking
====================================




Welcome to new, 5. tutorial in Armadillo serial! Today we will dealing Armadillo 4.30a with standard protection plus Debug Blocker feature, for those who are not familiar with terms - the infamous double process protection.






1. Tools and requirements

- Windows XP , MUST HAVE FOR THIS TUTORIAL;
- OllyDbg 1.10 (hide olly plugin or similar);
- LordPE;
- ImpREC;
- Hex editor;

- Target , here http://www.reversing.be/binaries/articles/20051002151522418.rar.


For following this tutorial you must know how to use above tools, you must have some knowledge about PE file structure and you must know how to unpack single process Armadillo.






2. Killing Debug Blocker - taking control of unpacking process


Acctually, defeating Debug Blocker is very easy, you just must be careful that you do not make some mistake because then you will have to it all again. First, ignore all exceptions in olly and add custom ones if stop on some during unpacking. Load target in Olly, then use plugin to hide Olly and place breakpoint on OutputDebugStringA API. Here is Entry Point of armadillo:

00456000 PUSHAD
00456001 CALL Armadill.00456006
00456006 POP EBP
00456007 PUSH EAX
00456008 PUSH ECX
00456009 BSWAP EDX
0045600B NOT EDX
0045600D PUSHFD
0045600E NOT EDX
00456010 BSWAP EDX
00456012 JMP SHORT Armadill.00456023
00456014 MOV ECX,EBB80FEB
00456019 POP ES
...
...
...

Now you need to place bp on WriteProcessMemory in kernel but armadillo is checking couple first opcodes for brakpoints so I will place bp on end of that API. Hardware breakpoints didn't worked for me neither. So click "go to" and enter WriteProcessMemory to land in kernel:

77E61A94 PUSH EBP <---------------------- Begining of API, you are here!
77E61A95 MOV EBP,ESP
77E61A97 PUSH ECX
77E61A98 PUSH ECX
77E61A99 MOV EAX,DWORD PTR SS:[EBP+C]
77E61A9C PUSH EBX
77E61A9D MOV EBX,DWORD PTR SS:[EBP+14]
77E61AA0 PUSH ESI
...
...
...
77E61B23 LEAVE
77E61B24 RETN 14 <---------------------- Place bp here!!!

Place bp where I told you and run target. You will break on your bp. Remove it and with F7 return to main module and then press Ctrl+A to analyse code. Scroll up and you will see:

00437CD3 PUSH EAX ; /pBytesWritten = 00000001
00437CD4 PUSH 2 ; |BytesToWrite = 2
00437CD6 LEA ECX,DWORD PTR SS:[EBP-8] ; |
00437CD9 PUSH ECX ; |Buffer = 0012D83C
00437CDA MOV EDX,DWORD PTR SS:[EBP+10] ; |Armadill.<ModuleEntryPoint>
00437CDD PUSH EDX ; |Address = 7FFE0304
00437CDE MOV EAX,DWORD PTR SS:[EBP+8] ; |
00437CE1 MOV ECX,DWORD PTR DS:[EAX] ; |
00437CE3 PUSH ECX ; |hProcess = 0012D83C
00437CE4 CALL DWORD PTR DS:[<&KERNEL32.WriteProce>; WriteProcessMemory
00437CEA JO SHORT Armadill.00437CF3 <------------------------------------ You are here!!!!
00437CEC JL SHORT Armadill.00437CF1
00437CEE JMP SHORT Armadill.00437CF5
00437CF0 DB E8
00437CF1 JE SHORT Armadill.00437CEE
00437CF3 JMP SHORT Armadill.00437CEE
00437CF5 JMP SHORT Armadill.00437D56
00437CF7 LEA EDX,DWORD PTR SS:[EBP-4]
00437CFA PUSH EDX ; /pBytesWritten = 7FFE0304
00437CFB PUSH 2 ; |BytesToWrite = 2
00437CFD PUSH Armadill.0046E4A4 ; |Buffer = Armadill.0046E4A4
00437D02 MOV EAX,DWORD PTR SS:[EBP+10] ; |Armadill.<ModuleEntryPoint>
00437D05 PUSH EAX ; |Address = 1
00437D06 MOV ECX,DWORD PTR SS:[EBP+8] ; |
00437D09 MOV EDX,DWORD PTR DS:[ECX] ; |ntdll.77F75BD1
00437D0B PUSH EDX ; |hProcess = 7FFE0304
00437D0C CALL DWORD PTR DS:[<&KERNEL32.WriteProce>; WriteProcessMemory <------ Place bp here and run!!!

You see two calls to WriteProcessMemory and you have just returned from first one. What did this first one done, I don't know, but for us is important second call. Place bp it and run. A new process will will start, now you have two processes in task manager. When you break, remove bp and take a look closer what we have here:

/pBytesWritten = 0000004C
|BytesToWrite = 2 <-------------- Two bytes are written.
|Buffer = Armadill.0046E4A4 <---- This is buffer where bytes are. Follow this in dump!!!
|Armadill.<ModuleEntryPoint>
|Address = 456000 <-------------- This is where bytes will be written!
|
|
|hProcess = 0000004C
WriteProcessMemory

You see that arm will write two bytes from buffer to 456000 address. That address is entry point of armadillo itself. Folow that buffer in dump window (immediate constant):

0046E4A4 60 E8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 `...............
0046E4B4 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0046E4C4 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

Now change those bytes to EB FE which is hex value for infinite jump. This will make armadillo second process to loop forever. Remember original bytes or write them down because later you will need to restore them. Changes are:

0046E4A4 EB FE 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0046E4B4 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0046E4C4 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

Now press F9 to start target. Your CPU usage will grow because infinite jump. Dont mind for that. In a command bar type "bp WaitForDebugEvent" and place bp. You will break in kernel on that API:

77EB5B98 >PUSH EBP
77EB5B99 MOV EBP,ESP
77EB5B9B SUB ESP,68
77EB5B9E PUSH ESI
77EB5B9F PUSH DWORD PTR SS:[EBP+C]
77EB5BA2 LEA EAX,DWORD PTR SS:[EBP-8]
...
...

Remove that bp and return to armadillo code. You shoud be here (EAX should be=0):

0043328D TEST EAX,EAX
0043328F JE Armadill.00435CA5
00433295 MOV EAX,DWORD PTR SS:[EBP-204]
0043329B AND EAX,0FF
004332A0 TEST EAX,EAX
004332A2 JE SHORT Armadill.004332B7
004332A4 MOV ECX,DWORD PTR DS:[46E5B4]
004332AA CMP DWORD PTR DS:[ECX+20],0
004332AE JE SHORT Armadill.004332B7
004332B0 MOV BYTE PTR SS:[EBP-204],0
004332B7 PUSH Armadill.0046E4A8 ; /pCriticalSection = Armadill.0046E4A8
004332BC CALL DWORD PTR DS:[<&KERNEL32.EnterCriti>; EnterCriticalSection
004332C2 PUSHAD
004332C3 XOR EAX,EAX
...
...

Now we need to deatach processes. First you must know what proces is armadillo debugger process and what process is being debugged. That is very easy; process that is created later is debugger. But we must know it's PID. It is also not hard; open window for attaching to active process in olly and you will see two indentical processes. One that is RED, is our first proces. Second process is one that is created later and we need his PID. For my example that PID is 510. It will be different for you (it is different every time you start program). Remember that PID. Now we will make patch that will kill debug blocker. On our line of code assemble next opcodes:

0043328D PUSH 510 <----------------------------- 510=my PID, your will be different!
00433292 CALL kernel32.DebugActiveProcessStop <- To stop debugging. Only WinXP has this API!!!
00433297 NOP <---------------------------------- Then place bp here and run!!!
00433298 NOP
00433299 NOP
0043329A NOP
0043329B AND EAX,0FF
004332A0 TEST EAX,EAX
004332A2 JE SHORT Armadill.004332B7
004332A4 MOV ECX,DWORD PTR DS:[46E5B4]
004332AA CMP DWORD PTR DS:[ECX+20],0
004332AE JE SHORT Armadill.004332B7
004332B0 MOV BYTE PTR SS:[EBP-204],0
004332B7 PUSH Armadill.0046E4A8 ; /pCriticalSection = Armadill.0046E4A8
004332BC CALL DWORD PTR DS:[<&KERNEL32.EnterCriti>; EnterCriticalSection
004332C2 PUSHAD
004332C3 XOR EAX,EAX
...
...

PUSH opcode will have value of your PID. Then add CALL DebugActiveProcessStop, place bp on NOP below it and run. When olly break on your bp, Debug Blocker is defeated, two armadillo processes are separated now! Congratulations ;) DebugActiveProcessStop is reason why you must have Windows XP to kill Debug Blocker, only XP has this API that we need to deatach processes. Do you know what you can do now? You can close your Olly, that will kill just first proces. Armadillo second proces is looping forever in memory, you can see that in task manager. Read next chapter to see what's next.







3. Attaching and unpacking Armadillo


You have killed Debug Blocker, but now you need to unpack target. Without debug blocker, we have buisness with common armadillo and I have already explained how to unpack armadillo with single process tricks. But we must do one thing more. Our two processes are still there and we need only one. While your first olly is still working, open another one and attach to one of our two processes. You need attach to one that has PID that we have pushed, ie. second process. In my example it was 510 one.

When you attach, you will break in ntdll.dll on system breakpoint. Press F9 to run it and then press F12 to pause program. You will break here:

00456000 >JMP SHORT Armadill.<ModuleEntryPoint> <------- Here!!!
00456002 ADD BYTE PTR DS:[EAX],AL
00456004 ADD BYTE PTR DS:[EAX],AL
00456006 POP EBP
00456007 PUSH EAX
00456008 PUSH ECX
00456009 BSWAP EDX
0045600B NOT EDX
0045600D PUSHFD
0045600E NOT EDX
00456010 BSWAP EDX
00456012 JMP SHORT Armadill.00456023
00456014 MOV ECX,EBB80FEB
00456019 POP ES
0045601A MOV ECX,EB900FEB
0045601F OR CH,BH
00456021 JMP SHORT Armadill.0045602E
00456023 PREFIX REPNE:
00456024 JMP SHORT Armadill.0045601B
00456026 JMP SHORT Armadill.0045601E
...
...
...


Very good. Naw you can close first olly. Do you see infinite jump at Entry Point? You need restore original bytes there. Those where 60e8, restore them and you'll see usuall armadiillo entry point:

00456000 >PUSHAD
00456001 CALL Armadill.00456006
00456006 POP EBP
00456007 PUSH EAX
00456008 PUSH ECX
00456009 BSWAP EDX
0045600B NOT EDX
0045600D PUSHFD
0045600E NOT EDX
00456010 BSWAP EDX
00456012 JMP SHORT Armadill.00456023
00456014 MOV ECX,EBB80FEB
00456019 POP ES
0045601A MOV ECX,EB900FEB
0045601F OR CH,BH
00456021 JMP SHORT Armadill.0045602E
00456023 PREFIX REPNE:
00456024 JMP SHORT Armadill.0045601B
00456026 JMP SHORT Armadill.0045601E
...
...
...


And now you have armadillo with standard protection, just usual IAT problem. You can unpack it normal as any other single process armadillo. Use script that I give you in archive to unpack it if you are lazy, but it would be better that you practice a little. Dump and fix IAT with ImpREC. You can also reduce file size with LordPE.






4. Final words


What to say? See you in the next tutorial ;)


Greets to all folks on BIW.




4 comments



http://www.reversing.be/article.php?story=20051002151932648