ARMADILLO - Manually unpacking
**** by Zilot ****
November 27, 2003
This tutorial should be appendix on Crusader's tutorial on Armadillo unpacking. This doesn't mean I have to add something on his observation because something was wrong there, not at all. When he wrote tut, there was version 2.60 of Armadillo, and in the mean time they improved a little bit protector, so there are several new things here, not covered by Crusader's tut . Second reason I wrote this is Olly Debugger Armadillo tuts invasion. Good looking pictures, with Olly screens shoots, may leave impression how Olly debugger becomes better that Soft-Ice, and newbies will use rather it than SI, especially those who never did serious unpacking before. So Olly is not better, and Soft-Ice is absolute king in our profession. I hope next lines will convince readers in my claim.
Tools used:
Soft Ice on win2k
LordPe Deluxe
ImpRec 1.6 Final
IDA 4.30 Pro
Target :
Trojan Remover 6.1.2 Download
Packer Improvements
New versions of Armadillo have some obfuscated part injected into code. This is done to avoid easy code analyses with disassemblers (IDA, Wdasm etc....). So if you see something like:
.text:005BFF74 9C pushf
.text:005BFF75 60 pusha
..................
..................
.text:005BFFA6 61 popa
.text:005BFFA7 9D popf
it means that. First registers are placed on stack, and some dumb jumps are executed, with registers altering all that time. After popf registers and flags are like before and execution is continued as usually. Conclusion is that this part serves to nothing, and is here to screw disassembler during code analyses. You can nop such parts (this can be done in memory, when SI breaks), just to be more readable.
Defeating copy-mem II
This part is more or less similar to Crusader's explanation. Obfuscations made this part slightly difficult for analyzing. First of all we must find code where packer calls decryption, and after encryption. This can be done by WriteProcessMemory API intercepting (be carefully with breakpoint placing, because Armadillo will detect bpx break points on WriteProcessMemory, so the best way is to break on GetVersion on the beginning, and to place bpmb WriteProcessMemory x, immediately after GetVersion break). When you do that, wait on third WriteProcessMemory occurence, (first two times he writes something to process we are not interested). So on third occurence press F12, after that F12 again and you will see something like this:
.text:005C1563
6A 00
push 0
.text:005C1565 8B 4D 0C
mov ecx, [ebp+0Ch]
.text:005C1568 51
push ecx
.text:005C1569 8B 55 08
mov edx, [ebp+8]
.text:005C156C 52
push edx
.text:005C156D E8 47 03 00 00 call loc_5C18B9
.text:005C1572 83 C4 0C
add esp, 0Ch <==== AFTER
F12 TWO TIMES YOU'LL FIND YOURSELF HERE
On this place he is calling decryption/encryption (005C18B9) routine with parameters to do decryption. So this is decryption procedure. More difficult part is to find encryption procedure. As it is explained in Crusader's tut there is maximum of decrypted pages that Armadillo allows to be in memory, if number exceeds that critical value he will do their encryption. In this case during program loading that critical value will not be reached and that routine will not be executed. We must find that routine, because when we force packer to unpack all pages we will hit critical value and our job will fail. After some looking around I succeeded to find that that routine. To be honest I searched file by signature. Here is that encryption routine:
.text:005C17FA 8B 04 8A
mov eax, [edx+ecx*4]
.text:005C17FD 99
cdq
.text:005C17FE B9 1C 00 00 00
mov ecx, 1Ch
.text:005C1803 F7 F9
idiv ecx
.text:005C1805 8B CA
mov ecx, edx
.text:005C1807 D3 EF
shr edi, cl
.text:005C1809 83 E7 0F
and edi, 0Fh
.text:005C180C 03 F7
add esi, edi
.text:005C180E 8B 15 44 C0 5E 00
mov edx, dword_5EC044
.text:005C1814 8D 04 B2
lea eax, [edx+esi*4]
text:005C1817 50
push eax
.text:005C1818 8B 0D 58 C0 5E 00
mov ecx, dword_5EC058
.text:005C181E 8B 15 5C C0 5E 00
mov edx, dword_5EC05C
.text:005C1824 8B 04 8A
mov eax, [edx+ecx*4]
.text:005C1827 50
push eax
.text:005C1828 E8 8C 00 00 00
call loc_5C18B9 <==== HERE
HE CALLS DECRYPTION/ENCRYPTION ROUTINE
.text:005C182D 83 C4 0C
add esp, 0Ch
On this place he is calling decryption/encryption (005C18B9) routine with parameters to do encryption. So this is encryption procedure. How to find it in the future if signature method fail. When you find decryption routine (in our case 005C1563) remember the address of decryption/encryption (005C18B9), put bpmb 005C18B9 x if (*esp!=005C1572 ) after forcing protector to decrypt all pages. Why this ? on stack after reaching 005C18B9 is return address, because we want to know place where this routine is called because encryption, we must avoid every break because decryption. After breaking you'll see 005C182D (of course afterr dd esp).
Now we must find why this call (005C1828) is executed at all. If you scroll up for a while you'll see this:
.text:005C16E2
8B 15 58 C0 5E 00 mov edx, dword_5EC058
.text:005C16E8 3B 15 94 66 5E 00
cmp edx, dword_5E6694
.text:005C16EE 0F 8E BC 01 00 00
jle loc_5C18B0
Here is magic place where Armadillo is checking for decrypted pages. Location dword_5E6694 comprise maximum of decrypted pages, and if current number is greater that allowed jle loc_5C18B0 will not be executed and we will have encryption. This location (005C16EE ) is essential in making loop. So you maus find this place and remember its address, if you fail in this step everything will go to hell. LordPe will not grab process memory.
Now
comes part with locating place to make infinite loop for whole client code
decryption. I found it by searching code signatures.
.text:005BF30E 8B 8D D8 F5 FF FF
mov ecx, [ebp-0A28h]
.text:005BF314 3B 0D 54 C0 5E 00
cmp ecx, dword_5EC054
.text:005BF31A 0F 8D 2F 02 00 00
jge loc_5BF54F
.text:005BF320 8B 95 48 F6 FF FF
mov edx, [ebp-9B8h]
.text:005BF326 81 E2 FF 00 00 00
and edx, 0FFh
.text:005BF32C 85 D2
test edx, edx
.text:005BF32E 0F 84 AD 00 00 00
jz loc_5BF3E1
...........................................................................................................
...........................................................................................................
...........................................................................................................
.text:005BF3C1 8D 04 B2
lea eax, [edx+esi*4]
.text:005BF3C4 50
push eax
.text:005BF3C5 8B 8D D8 F5 FF FF
mov ecx, [ebp-0A28h]
.text:005BF3CB 51
push ecx
.text:005BF3CC E8 62 1D 00 00
call loc_5C1133
.text:005BF3D1 83 C4 0C
add esp, 0Ch
.text:005BF3D4 25 FF 00 00 00
and eax, 0FFh
What is going on here is already explained in Crusader tutorial. I'll clarify steps you must do after finding this place. Our start location is 005BF301, and our end location is 005BF3D4. First of all this is starting place of all your unpacking job. Everything I described above is to find critical places, to find it you'll use IDA, Soft-Ice, and will start and quit program several time. When you find all of this places you'll put bpx GetVersion in Soft-Ice, run program double clicking on desktop icon, break once on GetVersion to get into Trojan Remover context and do next:
F12 after break on GetVersion
bc*
bpmb 005BF30E x
Press F5
Soft-Ice will break on 005BF30E
Now all stop, this is critical step !!!!!!!!
First you have to patch 005C16EE . How ?
In SI command line type :
a 005C16EE
jmp 5C18B0
With this we will prevent again encryption, and force protector to
jump always over critical encryption call
Second you have to patch 005BF3D4. How ?
In SI command line type :
a 005BF3D4
inc dword ptr [ebp-0A28h]
jmp 005BF30E
With this we are making infinite loop, and force protector to decrypt
all pages.
Third you have you patch location 005BF54F. How ?
In SI command line type :
a 005BF54F
jmp 005BF54F
With this we will lock program. Why this location ? This is where protector
will jump after all pages decryption
from address 005BF31A .
Fourth you have to edit memory location where is info about
current page decryption. How ?
In SI command line type :
ed ebp-0A28h
and then type 0 eight times. So on location that points ebp-0A28h
you'll have zero.
This is maybe the most important part, if you don't update this location,
everything will be screwed.
When you did all of this (once again you are doing all four
steps after SI pop-up when eip is 005BF30E, and when everything is stopped),
now it is time to clear all breakpoints (bc*), and to leave protector to
decrypt all pages. so do:
bc*
F5
Now you have to run LordPe. Do it and you'll find two same processes in process list. Look the bottom of processes list, you'll se LordPe, and two of Trojan Remover processes. You have to dump younger one, because he is created after server process is started. If you get "Can't grab process memory" something went wrong, you have to repeat steps.
Have one advice for you. Because locking process your comp might become very slow, so open Task Manager (Ctrl+Alt+Delete) and reduce both Trojan Remover processes priority to low. This will increase your comp speed.
Have nothing more to add about dumping, this should be all.
Good Luck !!!!!!!
Rebuild Import data
Nothing new here. First you have to find some API address used by client process, i.e ShowWindow. When client process (that what you see when program show his window) is opened put bpx ShowWindow and press for example help, or something that will show you window. When SI pops up instead pbx put bpmb eip x, so do bc*, and type bpmb eip x. After this SI will break again, but you will have calling address reference bc* again and put that calling address bpmb, so you'll do bpmb Calling_Address x. In that way SI will break next time on that calling address. When you are there (it is usually jmp [xxxxxxxx], or call [xxxxxxxx], you have to find xxxxxxxx address. Type code on and read instructon bytes in reverse order, and xxxxxxxx address will be infront of you. Then remember this address, and restart program, again break in Trojan Remover context with GetVersion, clear all break points (bc*), and type bpmb xxxxxxxx w, (xxxxxxxx is what you have remembered). And you'll break in IAT space updating. Trace a little bit, and will se what Crusader mentioned, there are 2 different APIs regular and redirected. I found condition for redirection was on E4B466. When you find this restart program and put bpmb E4B466 x when you are in Trojan Remover context. When SI breaks patch this jz with jmp. Be carefull there is CRC in high memory. There are two ways, leave to be caught on CRC, but when get screen about that don't close program, run ImpRec and rebuild IAT, all APIs should be resolved. There will be some redirections on boundaries between libraries, just cut them (show invalid thunks, and then press cut thunks in ImpRec), second approach to avoid CRC is to put bpmb Last_Writen_APIAddress w, and to wait SI to pop-up, after that you have to restore E4B466 instruction.
This is everything about IAT.
Good Luck !!!!!!!!!!!!
Nanomites
This is part where biggest changes has been accomplished since Crusader time. As in Crusader's case there are 4 tables for getting right jump. First of them is address table, second is jump type table, third is instructions length table, and forth is table of distances where to jump. But some of these tables are different.
Jump
distances table is crypted, so you can't do the same as in Crusader's way.
Hence there is one more table I call it key table and its purpose is to to
be used for jumps distances decryption.
Address
table doesn't picture real situation about replaced jumps in original file.
What does it mean. Protector will do next:
First he will take some jumps (not all of them) from original file, calculate their types, length, jump distances, and replace taken jumps with CCh bytes
Second
he will scan protected file, and wherever he find CCh bytes he will
update address table of nanomites with that address. It means that
you'll have in address table even those addresses where actually you
haven't jumps. For example in push 40CC31 he will calculate the address
of CCh byte and write that in address table. So if you use Crusader's
way to fix nanomite you'll screw your exe with fake jumps. Of course
protector will, when find such address of fake jump, update all other
tables with some dummy values, because this int3 s will actually never
happen, and he doesn't care about them.
Because all of this I recoded Crusader's utility for nanomite fixing. And add once more for jump distances decrypting. So there are 2 utilities together. Why two ?. Maybe the decryption way will be changed, so then you'll have to repair just that utility.
How to find all those 5 tables (4 standard + key table). Put bpx on GetThreadContext. After break press F12, scroll down for a while and you'll see next:
.text:005C0010
8B 85 6C EC FF FF
mov eax, [ebp-1394h]
.text:005C0016 89 85 B0 EB FF FF
mov [ebp-1450h], eax
Here in eax is address just behind occured int 3
.text:005C001C C7 85 AC EB FF FF 00 00 00 00
mov dword ptr [ebp-1454h], 0
.text:005C0026 8B 0D 74 C0 5E 00
mov ecx, dword_5EC074
Here in ecx is address table length (B06 in dwords)
.text:005C0032
8B 95 AC EB FF FF
mov edx, [ebp-1454h]
.text:005C0038 3B 95 84 EE FF FF
cmp edx, [ebp-117Ch]
.text:005C003E 7D 54
jge short loc_5C0094
When find address of interrupt he will proceed to 5C0094
.text:005C0040 8B 85 84 EE FF FF
mov eax, [ebp-117Ch]
.text:005C0046 2B 85 AC EB FF FF
sub eax, [ebp-1454h]
.text:005C004C 99
cdq
.text:005C004D 2B C2
sub eax, edx
.text:005C004F D1 F8
sar eax, 1
.text:005C0051 8B 8D AC EB FF FF
mov ecx, [ebp-1454h]
.text:005C0057 03 C8
add ecx, eax
.text:005C0059 89 8D A8 EB FF FF
mov [ebp-1458h], ecx
.text:005C005F 8B 95 A8 EB FF FF
mov edx, [ebp-1458h]
.text:005C0065 A1 18 C0 5E 00
mov eax, dword_5EC018 <== ADDRESS TABLE
START IN EAX
---------------------------------------
---------------------------------------
.text:005C0094 60
pusha
At 005C0094 you'll have in eax int 3 displacement in address table. You don't have to remember this. Now when he found jump address he will try to find jump type in jump type table.
For address jump table I got next values:
START of jump address table at AAA738 ( may be different in your case)
END of jump address table at AAD34C ( may be different in your case)
After some tracing below 5C0094, you'll find where he is checking for jump type. Something like:
.text:005C012F
8D 8D B4 EB FF FF
lea ecx, [ebp-144Ch]
.text:005C0135 51
push ecx
.text:005C0136 8B 15 24 C0 5E 00
mov edx, dword_5EC024 <== JUMP TYPE
TABLE START IN EDX
.text:005C013C 03 95 AC EB FF FF
add edx, [ebp-1454h]
.text:005C0142 8A 02
mov al, [edx]
.text:005C0144 50
push eax
.text:005C0145 E8 0B 28 00 00
call loc_5C2955
.text:005C014A 83 C4 08
add esp, 8
.text:005C014D 25 FF 00 00 00
and eax, 0FFh
.text:005C0152 85 C0
test eax, eax
.text:005C0154 0F 84 84 00 00 00
jz loc_5C01DE <== if eax = 0 go to on not jump, whether if
eax = 1 go to on jump
For jump type table I got next values:
START of jump type table at AAD360 ( may be different in your case)
END of jump type table at AADE65 ( may be different in your case)
Call at 005C0145 is place where protector calculates jump type (from table on AAD360 he gets just coded info about that) and as a result in eax we will get whether jump will happen or not (for example if we have jz xxxxxxxx, and if zero flag is set in eax on 005C0152 we will have eax = 1, if zero flag is not set we will have eax = 0). So you can put bpmb 005C0154 x if (eax = = 0) and when break tracing will lead you to the place where protector calculate how long is jump instruction decoded in call at 005C2955, because it is decided that jump will not be executed. So protector has to update eip of client process as bytes forward as jump instruction is long. In this case you'll find something like this:
.text:005C0212
8B 15 2C C0 5E 00
mov edx, dword_5EC02C<== JUMP LENGTH TABLE
START IN EDX
.text:005C0218 03 95 AC EB FF FF
add edx, [ebp-1454h]
.text:005C021E 33 C0
xor eax, eax
.text:005C0220 8A 02
mov al, [edx]
.text:005C0222 8B 8D 6C EC FF FF
mov ecx, [ebp-1394h]
.text:005C0228 03 C8
add ecx, eax
.text:005C022A 89 8D 6C EC FF FF
mov [ebp-1394h], ecx
For jump instruction length table I got next values:
START of jump instruction length table at CD6EA0 ( may be different in your case)
END of jump instruction length table at CD79A5 ( may be different in your case)
Ok, when you find this clear previou break point and put next bpmb 005C0154 x if (eax = = 1), in this case you'll break at 005C0154 when jump will happen. After some tracing through obfuscation you'll hit next:
.text:005C0180
8B 85 AC EB FF FF
mov eax, [ebp-1454h] ; Jump
displacement is in eax (its relative value in address table)
.text:005C0186 33 D2
xor edx, edx
.text:005C0188 B9 10 00 00 00
mov ecx, 10h
.text:005C018D F7 F1
div ecx
.text:005C018F 8B 85 AC EB FF FF
mov eax, [ebp-1454h]
.text:005C0195 8B 0D 14 C0 5E 00
mov ecx, dword_5EC014 <== JUMP
CRYPTED DISTANCES TABLE START IN
.text:005C019B 8B 04 81
mov eax, [ecx+eax*4]
ECX
.text:005C019E 33 84 95 98 EE FF FF
xor eax, [ebp+edx*4-1168h]<== JUMP
KEY TABLE START (EBP-1168 h)
.text:005C01A5 8B 8D 6C EC FF FF
mov ecx, [ebp-1394h]
.text:005C01AB 03 C8
add ecx, eax
.text:005C01AD 89 8D 6C EC FF FF
mov [ebp-1394h], ecx
This is the most interesting place with tables. Here is where stuff differs from described in Crusader's tut. What's going here. Jump distance table is crypted and there is key how to decrypt that. First on 005C018D jump relative displacement in address table is divided with 10h (reminder can be less or equal to 0Fh, can be 00h, 01h, 02h, ................. 0Ch, 0Dh, 0Eh, 0Fh). Then on 005C019B crypted distance of our jump is placed in eax, after that on 005C019E it is being decrypted. If you look better 005C019E, there is ebp+edx*4-1168h, edx is reminder after division, and ebp-1168h is start of key table. So you have to remember this address, and its length is 10h dwords (4x10h in bytes). Can't be less or bigger because whole decryption procedure.
For jump crypted distances table I got next values:
START of jump crypted distances table at CD79B8 ( may be different in your case)
END of jump crypted distances table at CDA5CC ( may be different in your case)
For jump key table I got next values:
START of jump key table at 12E438 ( may be different in your case)
END of jump key table at 12E474 ( may be different in your case)
Because this I coded small utility (I called it JumpDistance_Decryptor) to decrypt distances table. I used source from Crusader's tut and did some modifications. Everything you have to do is to dump jump crypted distances table and jump key table. Then you have to attach in address fields (BROWSE button) those two tables, and in Decrypted Distances Table field you have to attach same size file as in Crypted Distances Table (that will be out file), the best way to do that is to copy your dumped jump crypted distances table with different name into same place. When you press FIX IT you'll have decypted distances table. You will see values like 00 00 00 00e, 00 00 00 05, etc......Now it looks like described in Crusader's tut.
If you remember when I described what is new in nanomites managing, I mentioned that protector first takes jumps from original exe, replace them with CCh, and then search whole exe again, and where ever find CCh (whether it is replaced in previous or not) he will update jump address table, and all other 3 tables. So if we don't think in that way and start to recover all CCh places we will screw our dumped_.exe. So I recoded Crusader's tool for fixing nanomites. I added int3 Log address field. What is that ?. Because we don't know which CCh in dumped_.exe is jump which is not, somehow we have to filter CCh addresses. And int3Log is actually CCh addresses filter. So all other 5 fields are same, this one differs, and NanomiteFixer will replace just those CCh addresses which he finds in int3Log file. If you put in int3Log field same file as in address field he will does as in Crusader's way. Now there is a question how to generate int3Log. We have to record all int3 occurences and to dump them to file. Better way in whole this strategy would be to make Armadillo files loader, to work as debugger. And then we don't care about that which CCh is jump which not, I mean loader to work everything that protector does when int3 is reached. But I hadn't time for that.
So let's make int3Log. As you remember on 005C0016 in eax we had address of int3, this is the place where we will redirect our protector work. First where to find space for extra code, in this case it is easy, there are lot pushfd/popfd pushad/popad pairs with a lot of garbage code between them, so first you can nop such place and then write next I'll show. First of all restart program, break on GetVersion and put bpmb 005C0016 x. When you reach it all stop. Remember 6 bytes of this instruction (89 85 B0 EB FF FF ), now you can nop first pushad till you find popad (included both). You can start from 005C0094 and finish at 005C00BA, and start from 005C00D5 and finish at 005C012F, we need a lot of space for code I'll describe. So when you are at 005C0016 type, a eip; jmp 005C00D7, but don't execute anything. Now we need some memory space to store our int3Log, so we need to allocate that space, because I couldn't find somewhere in process memory such amount of space. So now type next:
a 005C0096
.text:005C0096
60
pusha
.text:005C0097 6A 10
push 10h
<==== I made mistake here instead 10h put 1000h
.text:005C0099 6A 00
push 0
.text:005C009B E8 7A 90 8D 77 call near ptr 77E9911Ah
<==== GlobalAlloc
.text:005C00A0 50
push eax
.text:005C00A1 E8 FD CB 8C 77 call near ptr 77E8CCA3h
<==== GlobalLock
.text:005C00A6 61
popa
.text:005C00A7 EB 2E
jmp short loc_5C00D7
To explain this (when do a eip you'll type just instruction pushad.......popad). We started nopping from 005C0094 and now we are writting from 005C0096, why ? On 005C0094 we had pushad and there we will put jmp 005C00BA (do it like a 005C0094; jmp 005C00BA) , that's immediately after popad we just nopped. And now what does this code do, GlobalAlloc (to write this in Soft-Ice type call KERNEL32!GlobalAlloc, same for GlobalLock) will arrange some memory space, and will return handle to that space, GlobalLock will return starting memory address of that space in eax, with me it was eax = 00133468 after 005C00A1. Remember this value it is important for next code we will write. So now when you finished with this writing (everything is stopped still and you are at 005C0016 with your eip) type r eip 005C0096, why to jump in this way, because we will never do this code again, jusy once we will arrange memory space and after we will from 005C0096 go on 005C00D7. Ok now when you are at 005C0096 with F10 execute line by line until you reach 005C00A6, when eip is 005C00A6 remember eax (memory allocated starting address), execute 005C00A7 and when eip is 005C00D7 all stop again. Location 005C00D5 was previously pushad we nopped and now we must put jump here on place after popad it is 005C012F, so when you are at eip = 005C00D7 type a 005C00D5; jmp 005C012F.
Now we have to edit code on 005C00D7 to make int3Log, so type next:
a eip
.text:005C00D7
60
pusha
.text:005C00D8 BE 68 34 13 00
mov esi, 133468h
.text:005C00DD 8B 0E
mov ecx, [esi]
.text:005C00DF 83 F9 00
cmp ecx, 0
.text:005C00E2 74 0A
jz short loc_5C00EE
If we don't have that value (we serached whole table) we will append
.text:005C00E4 3B 04 0E
cmp eax, [esi+ecx]
In eax is our int3 address
.text:005C00E7 74 0C
jz short loc_5C00F5
If we already have that value we will exit
.text:005C00E9 83 E9 04
sub ecx, 4
.text:005C00EC EB F1
jmp short loc_5C00DF
.text:005C00EE 83 06 04
add dword ptr [esi], 4
.text:005C00F1 03 36
add esi, [esi]
.text:005C00F3 89 06
mov [esi], eax
.text:005C00F5 61
popa
.text:005C00F6 89 85 B0 EB FF FF mov [ebp-1450h], eax
.text:005C00FC E9 1B FF FF FF jmp loc_5C001C
When you typed all of this ( you are still at 005C00D7) you must do one thing manually, type ed 00133468 and write all zeros there, why to do that, on this location we will keep number of int3 happened during work. Now because some int3 are happening many times it is dumb to have several times same value, so we will search first our int3Log to find if there we already have such address and if don't we will just append at the end of our table that address and update addresses number, if we have we will exit with no addresses number at 00133468 updating. At 005C00F5 we will restore all registers like before our patch, on 005C00F6 we will execute that what we missed because redirection, and on 005C00FC we will jump to instruction after 005C0016, it is 005C001C. Now clear break points and let program run. When program open main dialog you have to try to do everything with program you can, to scan directories to change options, just everything that program can do to make sure you have passed whole program code and stored all program jumps. But don't exit program. When you did that (program is still running) open LordPe and dump Region with Int3Log (in my case it is location 133468 with size 1000 h) you'll choose protector process because that's where you allocated memory space. Now you have int3Log, you previously dumped all other tables and now open NanomiteFixer (utility I attached) and with browse button attach all tables you dumped, and our dumped_.exe file with fixed IAT. Press FIX IT and all nanomites should be fixed.
If you failed to locate some nanomite, and if experience some bug, just remember what you did to achieve that bug, in Soft-Ice type int3 here on repeat procedure for bug catching and when Soft-Ice pops up remember address immediately after int 3, then you can add that address into int3Log and fix your dumped_.exe again.
There is no limitation how many times you can repeat that. But to avoid that boring job it is better to try all options you can during making patch I described above. Once again there should be better to make Armadillo files loader, maybe someone will write that soon.
I didn't mentioned how I resolved jump types, it is covered by Crusader's tut (trace in call at 5C2955) I'll just show how many jumps I found (there were just several with this version of armadillo and this program, in nanomite fixer I didn't take care about others, they stayed as Crusader put, if you want do it by yourself)
Jump Type |
Instruction |
JBE | |
1 | |
7 | JB |
9 | |
JLE | |
B | JNZ |
C | JMP |
D | |
JA | |
E |
JZ |
I didn't say how to find OEP, you can set bpmb SetProcessWorkingSetSize x, after
second break in Trojan Remover context put bpmb GetCurrentThreadId x, after
first break clear all break points, trace for a while with F10 and will see call
edi, in edi is OEP = 582A44h
Good Luck !!!!!!!!!
One more trick
After everything you did dumped_.exe will refuse to run normally. Main screen will appear but cancel, scan buttons remain inactive. After some time will close without your activity. So put bpx GetEnvironmentVariableA and when break in dunmped_.exe context press F12 ,trace with F10 until you return from call and you will see some check test eax, eax; jnz xxxxxxxx, you have to put jmp. That will happen several times, everywhere you see some branching after return from routine where GetEnvironmentVariableA was invoked, you have to update that jumps. You can compare how original (protected file) does in such situations, and make your dumped_.exe to do same.
UTILITIES
Fixed File (should be all working)
END