Extasy's Solution to Amante Remeverseme
www.immortaldescendants.org
Tools:
Usual reversers ones (HIEW, IDA, Softice
,
HexWorkShop)
+ A compilator (i use MASM)
(+ some utils about the PE if you
don't know of to do it by hand)
Hi all ! I'm happy to come back to solve amante's new (and first) reverseme. It were pretty hard to reverse this one, because it's about a topic that i didn't know : The ressources creation and structures. As the main goal of this is to learn a bit on this subject, i choosed to do all that on my own, wich means that i didn't search the web for info on this. If you're a ressource professional, or, simply someone who has a better knowledge of this, please don't send me insults mails or things like that :). All the vocabulary i'll use is created as i'm typing this.
NB: In most of this essay i'm
speaking of DWORDS, so make the inversion when you have to write them or
read them in a file.
I Getting familiar with the ressources
As our goal is to manage all the amante's
file with only a hexeditor, we have to understand how all this works. Here's
how i managed to learn :
I used my compilator to create 2 files
: one with only a dialog box, and a second one with 2 dialogboxes. Here
is THE ONLY "LIST" you will find in this essay.
0000 00000000
00000000 00000000 00000100 ................
0010 05000000
18000080 00000000 00000000 ................
0020 00000000
02000000 90000080 38000080 ............8...
0030 88000080
50000080 00000000 00000000 ....P...........
0040 00000000
00000100 09040000 68000000 ............h...
0050 00000000
00000000 00000000 00000100 ................
0060 09040000
78000000 40410000 9A000000 ....x...@A......
0070 00000000
00000000 A0400000 9A000000 .........@......
0080 00000000
00000000&nbs
p; 03005400 55005400 ..........T.U.T.
0090 03004200
4F004200 00000000 00000000 ..B.O.B.........
00A0 C408CA90
00000000 02002B00 3C001301 ..........+.<...
00B0 66000000
00004400 6F006E00 67006500 f.....D.o.n.g.e.
00C0 6F006E00
20007600 31002E00 30000000 o.n. .v.1...0...
00D0 08004D00
53002000 53006100 6E007300 ..M.S. .S.a.n.s.
00E0 20005300
65007200 69006600 00000000 .S.e.r.i.f.....
00F0 00000250
00000000 29000800 3C000800 ...P....)...<...
0100 FFFFFFFF
82005400 65007800 74000000 ......T.e.x.t...
0110 00000000
00000150 00000000 6A004300 .......P....j.C.
0120 32000E00
6500FFFF 80004200 75007400 2...e.....B.u.t.
0130 74006F00
6E000000 00000000 00000000 t.o.n...........
0140 C408CA90
00000000 02002B00 3C001301 ..........+.<...
0150 66000000
00004400 6F006E00 67006500 f.....D.o.n.g.e.
0160 6F006E00
20007600 31002E00 30000000 o.n. .v.1...0...
0170 08004D00
53002000 53006100 6E007300 ..M.S. .S.a.n.s.
0180 20005300
65007200 69006600 00000000 .S.e.r.i.f.....
0190 00000250
00000000 29000800 3C000800 ...P....)...<...
01A0 FFFFFFFF
82005400 65007800 74000000 ......T.e.x.t...
01B0 00000000
00000150 00000000 6A004300 ...
....P....j.C.
01C0 32000E00
6500FFFF 80004200 75007400 2...e.....B.u.t.
01D0 74006F00
6E000000 00000000 00000000 t.o.n...........
All that will follow now is an exploitation
of this "dead list". Eh, where can we start our big carrier ? By
just looking quickly looking at that, we can see that there are structures
of 6 DWORDs. So i started to take couples of 6 DW. So, the first is 3x0,
followed by 10000, then 5, and 8000000018.Mmmh ? 18 ? corresponds exactly
to the next Dword group. After playing a little with the numbers and a
ressource viewer, i determined that the 5 was the ressource type, like
a menu, an incon, .... The 3 zero's and the 10000 were fine, so i decided
to let them like this and continue. Let's move to the next group. Here,
again 3 zeros, a
nd then a 2, followed by 90,38,88,50 (forget those 800000
:). One more time take a look at what they are pointing. 90 and 88 are
the name's preceded by their lengh. 38 is just next to this group, and
50 is 38 + 6 DW. We can start to create some kind of resume.
HEADER: | 3 zero's | 10000 | Ressource Type | Ressource Pointer |
Ressource table :
| 3 zero's | Number of ressources | Ressource 1 name
| Ressource 1 pointer |
| Ressource 2 name | Ressource 2 pointer |
We're advancing :). Let's continue
like this :). Look now in 38
and compare it to 50. Again those 3 zero's
(if some good soul knows something about the mistery of the three zero's,
mail me :)). Then we find 10000, 409, 68. I tried to play with 409, and
it doesn't seem to be essential as we can delete it, change it to everything
we want. Let's set this to 0 now :). What do we find at 50 ? 3 zero's,
10000, 409, 78. So wtf can we find at 68 and 78 ? VA's : 4140 and 40A0.
Run HIEW, just to confirm what you already know :) It's OK, they point
to the dialog's binary. We can see a second DW, wich is the lengh of that
dialog (check if it you want :)
HEADER: | 3 zero's | 10000 | Ressource Type | Ressource Pointer |
Ressource table :
| 3 zero's | Number of ressources&n
bsp; | Ressource 1 name
| Ressource 1 pointer |
| Ressource 2 name | Ressource 2 pointer |
Ressource 1
:
| 3 zero's | 10000 | 409 | Pointer
to Ressource Binary |
Ressource 2
:
| 3 zero's | 10000 | 409 | Pointer
to Ressource Binary |
Ressource 1 binary:
| VA of the binary&
nbsp; | lengh of binary |
Ressource 2 binary:
| VA of the binary | lengh of binary |
II 2 + 1 = 4 :)
It's fine, we know how dialogboxes
are built by the ressources builders. But isn't there a second problem
? Of course :): We need to add an icon too. And trust me, it's not that
easy. So add an icon to your previous program, and goooo ! I'll just show
you the "analysed" form.
HEADER: | 3
zero's | 30000&
nbsp; | 3 | 28 |
Icon
| 5 | 40 | Dialog Boxes
| 0E | 60 | ?
Ressource table :
ICON
| 3 zero's | 10000 | 1 | 78
|
DIALOGS |
3 zero's | 2 &nb
sp; | 102 | 90
|
| 118 | A8 |
?
| 3 zero's | 10000 | 2 | C0
|
Ressources :
ICON : |
3 zero's | 10000 | 409 | D8 |
DIALOG1: | 3 zero's
| 10000 | 409 | E8 |
DIALOG2: | 3 zero's
| 10000 | 409 | F8 |
? :
| 3 zero's | 10000 | 409 | 108 |
Binaries :
ICON : |
5270 | 568 |
DIALOG1: | 51D0
| 9A |
DIALOG2: | 5130
| 9A |
? :
| 57D8 | 14 |
What about this "?" I tried alot of
things with this one :). I tried to delete it, to change it, .... It finally
came to be the icon properties. I mean, if the icon has 256 colors, 16x16,
... As amante didn't provided the icon properties, i decided to recopy
it to the new exe.
<
BR>
III Amante_reme1.exe, Get READYYY
Now that we understand how the icon and dialogboxes work, we need to play with the target exe. Let's start by creating a new section, with a lenght of A00, at 5000, named .rsrc. If you read all before, you can easily fill all the properties. You just have to re-translate everything that's just before. Or worse, copy/paste your exe, except from the binaries of course. For me the whole header (all without the binaries) was ended at 5130 (in HIEW :)) or D30 (offest this time). After that paste the binaries themselves (from the separate .dump files). Dialog 1 at D30 (5130). Dialog 2 at E50(5260), Icon at F10(5310),Properties at 13F0(57F0). IF you're asking yourself why the fuck i'm givin g you both offset and VA each time, scroll up some lines and you'll find your answer :). If you're a lame copy/paster, don't forget to change the VA's and size of the new ressources. If you try now to use a ressource editor to see if your changes worked, it won't. SO, WTF did we forget ? *ten minutes later* We didn't filled the directory of the PE ! Take procdump and change the Ressource in the Directory to 405000. And now ???? Yes !!! It works.
So we're done on the very special part
of this reverseme. As we need to create some dialogs, i choosed to code
them at once on my program (the one i used for the ressource).
Here's just the dialog proc part.
Notice that we need to add 2 nop's after the invokes, because in the reversed
one, we will put dword call, instead of normal ones, wich means 1 byte
more, the second is for an eventual CC to debug. You need of course to
create a full source, to be able to compile,
but i won't insert it here,
because it's quite standard.
DlgProc proc hWnd:HWND, uMsg:UINT,
wParam:WPARAM, lParam:LPARAM
.IF uMsg==WM_INITDIALOG
.ELSEIF uMsg==WM_CLOSE
invoke EndDialog, hWnd,NULL
.ELSEIF uMsg==WM_COMMAND
mov eax,wParam
mov edx,wParam
shr edx,16
.if dx==BN_CLICKED
.IF ax==IDC_BUTTON
invoke EndDialog,hWnd,0
nop
nop
invoke DialogBoxParam,hInstance,
ADDR DlgName2,NULL,addr DlgProc2,NULL
nop
nop
.ENDIF
.ENDIF
.ELSE
mov eax,FALSE
ret
.ENDIF
mov eax,TRUE
ret
DlgProc endp
But before inserting this to the target, we need to add our imports. The APIs we needs are GetModuleHandleA, EndDialog, D ialogBoxParamA. The first is from KERNEL32.DLL, and the two others from USER32.DLL. You can use the excellent IidKing to add them. I saw that we can't add api's from 2 different dll's. So make it add the 2 from USER32.DLL, and we'll ad the other by hand.
If you don't know how to add imports manually, it's not here that you'll learn :(.
Here's just a quick sommary of what i did. Configure Iidking to add 200 bytes to the target. To add some new imports of kernel32, we need to enter a new "group". So you need to add 5 DW = 14h bytes at the offset 1628. We have to correct all the addresses, though. Start at 1614, and add 14 to all the DWORDS until 1668. (603C -> 6050, ...). Now we have enough space to add our import. fill at 1628 the DW with those : 60A0, 0 , 0 , 60B0, A860. Then put at 16A0 60BE, at 60A8 60BE, at 06B0 the string "kernel32.dll", at 60C0 the string "GetModuleHandleA".
If the program runs, your changes worked,
if it crashes with a messagebox from window, you must have mistyped something
(probably in the correction).
Take your paper and note the list
of the Api's :
40605C DialogBoxParam
406060 EndDialog
4060AE GetModuleHandle
We're now ready to assemble :). Run HIEW. Go to 401000 and assemble this :
push 0
call d,[4060ae]
mov [406200],eax
push 0
push 401030
push 0
push 406210
push d,[406200]
call d,[40605c]
push eax
call d,[403030]
Then we need to put at 406210 the string "BOB" wich is the dialog name and at 406218 the string "TUT". Now we can paste at 630 the dialog proc we created before. In this we only need to change the api calls. Run one more time hiew to change the calls to dword calls to our freshly imported apis. Don't forget to change the ID of the button (the cmp ax,3 to a cmp ax,1 at 667). Cross your fingers, run it :))))))))))))) It's ok !!! Now simply copy/paste the whole proc at 6C0. Change the dialogboxparam call in the first procedure pushes. Change it to that :
push 0
push 4010c0
pu
sh 0
push 406218
push d,[406200]
call d,[40605c]
Now the dialogboxparam call points to the second dialogbox. Go nopping that call into the second procedure so that only the enddialog call lasts. THIS TIME WE'RE OK. The reverseme is reversed :).
Thanks fly to :
Santmat, Crudd, MagicRaph,Edy,Tam,C_DKnight,ep-180,promethee,
V-Rom,to everyone from
[ID], #c4n, #crack.fr. And of course
amante :).