Hi ! I'm back to reverse trapflag's
new reme. Let's first take a look at the text file included in the zip.
Your task is to make the reverseme
to show its full commandline.
No patching is allowed (and no memory
patching) and no api hooks or whatever.
.. and by the way, for a working version,
windows shouldn't reboot ;-)
When i saw that, i felt really disapointed
:) How could we reverse something without patching ? The best thing is
to dissassemble the exe, and then to see what's going on, and HOW we could
make it do what we want. 10 minutes of IDA, and, here's the result :
0040100C
push dword_403020
00401012 6A 00
push 0
00401014 E8 D5 00 00 00
call j_GlobalAlloc
00401019 A3 1C 30 40 00
mov dword_40301C, eax
0040101E 85 C0
test eax, eax
00401020 0F 84 9C 00 00+
jz loc_4010C2
00401026 68 0E 30 40 00
push offset dword_40300E
0040102B 68 3F 00 1F 00
push 1F003Fh
00401030 6A 00
push 0
00401032 68 00 30 40 00
push offset str__FickenMach ; "ficken\\MACHT\\"
00401037 68 02 00 00 80
push 80000002h
0040103C E8 BF 00 00 00
call j_RegOpenKeyExA
00401041 85 C0
test eax, eax
00401043 75 7D
jnz short loc_4010C2
00401045 68 20 30 40 00
push offset dword_403020
0040104A FF 35 1C 30 40+
push dword_40301C
00401050 68 18 30 40 00
push offset unk_403018
00401055 6A 00
push 0
00401057 68 12 30 40 00
push offset str__Laune ; "laune"
0040105C FF 35 0E 30 40+
push dword_40300E
00401062 E8 9F 00 00 00
call j_RegQueryValueExA
00401067 85 C0
test eax, eax
00401069 75 57
jnz short loc_4010C2
0040106B FF 35 0E 30 40+
push dword_40300E
00401071 E8 84 00 00 00
call j_RegCloseKey
00401076 A1 1C 30 40 00
mov eax, dword_40301C
0040107B 50
push eax
0040107C 66 81 38 E9 FB
cmp word ptr [eax], 0FBE9h
00401081 75 3F
jnz short loc_4010C2
00401083 FF D0
call eax
00401085 58
pop eax
00401086 3B 05 1C 30 40+
cmp eax, dword_40301C
0040108C 75 46
jnz short loc_4010D4
0040108E 81 78 23 64 65+
cmp dword ptr [eax+23h], 69666564h
00401095 75 3D
jnz short loc_4010D4
00401097 81 78 17 64 65+
cmp dword ptr [eax+17h], 69666564h
0040109E 75 34
jnz short loc_4010D4
004010A0 33 C9
xor ecx, ecx
004010A2 8A 48 4B
mov cl, [eax+4Bh]
004010A5 8A 68 3B
mov ch, [eax+3Bh]
004010A8 32 CD
xor cl, ch
004010AA C1 E1 0A
shl ecx, 0Ah
004010AD 66 0B 48 5E
or cx, [eax+5Eh]
004010B1 C1 C9 11
ror ecx, 11h
004010B4 33 88 9D 00 00+
xor ecx, [eax+9Dh]
004010BA 3B 88 FA 00 00+
cmp ecx, [eax+0FAh]
004010C0 75 12
jnz short loc_4010D4
004010C2
004010C2
loc_4010C2:
; CODE XREF: start+14j
004010C2 FF 35 1C 30 40+
; start+37j ...
004010C2 00
push dword_40301C
004010C8 E8 27 00 00 00
call j_GlobalFree
004010CD 6A 00
push 0
004010CF E8 0E 00 00 00
call j_ExitProcess
004010D4
004010D4
loc_4010D4:
; CODE XREF: start+80j
004010D4 68 AD DE 00 00
; start+89j ...
004010D4
push 0DEADh
004010D9 6A 04
push 4
004010DB E8 2C 00 00 00
call j_ExitWindowsEx
004010E0 EB E0
jmp short loc_4010C2
004010E0
start endp
After a quick reading, we see that trapflag seems to use the registery, so, in a first time, let's identify where the key should be. Let's take a look at the first Reg API : RegOpenKeyExA.
00401026 68 0E 30 40 00
push offset dword_40300E
0040102B 68 3F 00 1F 00
push 1F003Fh
00401030 6A 00
push 0
00401032 68 00 30 40 00
push offset str__FickenMach ; "ficken\\MACHT\\"
00401037 68 02 00 00 80
push 80000002h
0040103C E8 BF 00 00 00
call j_RegOpenKeyExA
Take a quick look at the win32.hlp file, to see that 80000002h is the handle of the key, that ficken\\MACHT is the name of the subkey. But, what does 80000002h equals to ? At this time you have to open your windows.inc file (in any win32 compiler), to see that 80000002h is the HKEY_LOCAL_MACHINE. Now let's take a look at the next reg API : RegQueryValueExA.
00401045 68 20 30 40 00
push offset dword_403020
0040104A FF 35 1C 30 40+
push dword_40301C
00401050 68 18 30 40 00
push offset unk_403018
00401055 6A 00
push 0
00401057 68 12 30 40 00
push offset str__Laune ; "laune"
0040105C FF 35 0E 30 40+
push dword_40300E
00401062 E8 9F 00 00 00
call j_RegQueryValueExA
So, trapflag is going to read the key located at HKEY_LOCAL_MACHINE\\ficken\\MACHT\\laune, and store it at the address pointed by 40301C. If you look at the deadlist, you'll see that 40301C contains a pointer to an part of memory allocated by GlobalAlloc. Then comes what really surprised me.
00401076 A1 1C 30 40 00
mov eax, dword_40301C
0040107B 50
push eax
0040107C 66 81 38 E9 FB
cmp word ptr [eax], 0FBE9h
00401081 75 3F
jnz short loc_4010C2
00401083 FF D0
call eax
00401085 58
pop eax
Everything seemed fine until this "Call
eax". But, why does trapflag calls the data we created in the registery
? 2s later, it struck me. THAT'S WERE WE ARE GOING TO DO OUR JOB ! In fact
the reme calls the data we inserted, so, we can put our code there, and
it will be executed. Before jumping, it checks that the 2 first bytes are
E9 and FB. Now, let's go, and create that key. Go into HKEY_LOCAL_MACHINE,
create the key ficken\MACHT\laune. The laune key must be a "Binary chain"
(hem, sorry for that, my windows is in french, so, it's a poor translation
:-). Now we can start filling it : put the E9,FB at first.But what does
E9,FB mean ? Run HIEW, and type E9,FB,00 anywhere, just to see what instruction
it is. It's a jump to FEh bytes after. So, write zero's until you are at
100h, and then starts our code. But what do we have to do ?
Switch back to IDA and note the addresses
of the API we need (hopefully, trapflag imported them) :
GetCommandLineA 402018h
MessageBoxA
402024h
Now we have to determine what we are going to write into the "laune" key. HIEW will help us again.Open any text file, or create a new one, and code that :
call d,[402018] ;GetCommandlineA
push 0
push 0
push eax
push 0
call d,[402024]
;MessageBoxA
retn
Now, go to the "laune" key,at 100h, and copy the hex corresponding to the instructions you created in hiew. Well, that's all we need to do to display the command line used. But, trapflag put another small trick after the call eax :
0040108E 81 78 23 64 65+
cmp dword ptr [eax+23h], 69666564h
00401095 75 3D
jnz short loc_4010D4
00401097 81 78 17 64 65+
cmp dword ptr [eax+17h], 69666564h
0040109E 75 34
jnz short loc_4010D4
So, if the dword located at 23h and
17h isn't 69666564h, the program will reboot the computer (ExitWindowsEx).
So, to have a complete solution, put "defi" at 23h and 17h, and, everything's
fine. You don't have to care about the next lines, if you simply put 0's
everywhere else, those tests are passed.
If you have comments, suggestions,
or problems with this essay or another, contact me :
On EFNET : #immortaldescendants
By Mail : extasy@immortaldescendants.org
THANKS : all ID members, SantMat, amante,
Crudd, Volatility, grugq, vrom, FBJ, promethee, CD_Knight, Tam, Technich,
MagicRaph, ep-180, everone in #starsystem and #win32asm