Windows Commander
v4.51
|
|||
published by Tsehp, July 2000 |
|||
Subject: Unpacking/ Cracking |
|||
This essay is for knowledge purposes only!! Software developers spend much time in making their programs. They live from the money we give them! Please buy good software!! |
|||
I. Introduction | |||
Windows Commander: the beloved tool of us crackers. It's a very powerful 'Norton-Commander'-alike program that outperforms Microsoft Explorer with ease. Admitted, its look and lay-out is somewhat unprofessional-looking.....but the results count, not the look! This essay will be pretty long in comparison with most of my other essays, so I did a lot of work on it. Enjoy and learn. And oh yea, before you start: note that this essay is not really suitable for real newbies. Some cracking experience is really needed. |
|||
II. About the protection | |||
Packed: ASPack - CRC check - Keyfile - Nag | |||
III. Cracking it | |||
I did not try to make a valid keyfile for the program as the wincmd.key file must be 1024 bytes long and is encrypted and organised in a quite complex way.....in other words, I couldn't manage to make a valid keyfile. Maybe you can :-) So.....I took this approach: Step1: Manually unpacking Step1: Manually unpacking WINCMD is packed with ASPack. Note that
it's not ASProtect. In order to avoid problems later, open Procdump
PE Editor and set characteristics of the .CODE section to E0000060. Now, what has happened? Location 4E8562 is
an instruction of the main WINCMD program. As long as the unpacker hasn't
finished his job, that location or that instruction does not exist yet!
Therefore, if we set a breakpoint on memory access, SoftICE will break on
the moment the unpacker unpacks the instruction at location 4E5862. When SoftICE has popped, you should see an
instruction like "REPZ MOVSD" or something like that. You could
now go and trace, trace, trace, trace, avoiding unpacker loopies, etc... .
That would work, but again.....it's slow. Start partial code 0137:0059A4F3 POPAD 0137:0059A4F4 JNZ 0059A4FE 0137:0059A4F6 MOV EAX,00000001 0137:0059A4FB RET 000C 0137:0059A4FE PUSH 00000000 0137:0059A503 RET End partial code Now this is actually kinda strange. The PUSH instruction should push the OEP value on the stack......but it seems that it only pushes 00000000 onto the stack. Well, set a breakpoint on 0059A4F3 POPAD , exit SoftICE, and SoftICE will pop on the POPAD instruction. And now you see this: Start partial code 0137:0059A4F3 POPAD 0137:0059A4F4 JNZ 0059A4FE <- This jumps 0137:0059A4F6 MOV EAX,00000001 0137:0059A4FB RET 000C 0137:0059A4FE PUSH 005329B0 <- OEP 0137:0059A503 RET <- Leave unpacker code, start main code End partial code Seems like the OEP is written at the end
of the unpacking routine. Maybe to mislead us crackers? If it is, it's
kinda lame actually :-) Keep in your mind: OEP=5329B0.
Click OK, exit Procdump and try to run IMAGE.EXE.......it works! Let's move on to the next step: Step2: Finding the instructions that should be cracked In this step the real cracking of Windows Commander is explained. First ask yourself: "What has to be cracked?". If you never used WINCMD, the only thing you can see is a nagscreen with three annoying buttons. But if you're used to it, you know it also has an annoying CRC check and that it displays that it's unregistered. When I was cracking for a few months (i.e.
when I was a newbie), I failed to remove the nagscreen of WINCMD. (I
failed the rest too tho). The difficulty is that you don't have to try
setting breakpoints on UpdateWindow or ShowWindow or any other of these
NAG-applicable API calls, as it won't work. WINCMD first checks if a file
named WINCMD.KEY is present, then it will decide whether is should display
the nag or not. First make the file WINCMD.KEY. There should be nothing in
it.....just make sure the file exists. Start partial code 0137:004CE12B MOV EAX,ESI 0137:004CE12D CALL 0043C02C 0137:004CE132 JMP 004CE13F 0137:004CE134 XOR EBX,EBX 0137:004CE136 MOV WORD PTR [EBP-011E],0000 0137:004CE13F CMP WORD PTR [EBP-011E],0080 0137:004CE148 SETZ BYTE PTR [0053E6B9] <- If valid key a '1' will be set End partial code And now it's just a matter of trial-and-error to find the 'jump-to-nag' instruction. Disable all breakpoints and start tracing. Note that pressing F12 about two times will fasten the process. While tracing you can see appear the splashscreen, and after a while you suddenly see that the splashscreen changes into a fixed window with the caption "Windows Commander". Scroll a bit up in the code and......do you see the conditional jump? :) I do........ Start partial code 0137:004CBF8A TEST AL,AL <- Registered? 0137:004CBF8C JZ 004CBFB4 <- If registered, don't jump 0137:004CBF8E MOV EAX,[005366CC] 0137:004CBF93 MOV EAX,[EAX+28] 0137:004CBF96 MOV DL,01 0137:004CBF98 CALL 0041D5CC 0137:004CBF9D MOV BYTE PTR [00534C7C],01 0137:004CBFA4 MOV BYTE PTR [00534C80],01 0137:004CBFAB MOV EAX,EBX 0137:004CBFAD CALL 00418E9C 0137:004CBFB2 JMP 004CBFF2 0137:004CBFB4 MOV DL,01 0137:004CBFB6 MOV EAX,[0053E6B0] 0137:004CBFBB CALL 00416E10 0137:004CBFC0 MOV EDX,00000001 0137:004CBFC5 MOV EAX,[EBX+000001B0] 0137:004CBFCB CALL 0042FFE0 <- If you trace over this call , you see the nag appear. End partial code It's not difficult: you trace and trace until you trace over the call 004CBFCB
CALL 0042FFE0. Then, you see that nag appear which tells you that
you're too far. Scroll up and you see this conditional jump 004CBF8C
JZ 004CBFB4 . If we would apply this patch now, we would
get a CRC error. Therefore we won't patch yet, just keep the location we
have to patch in mind. Just change a little unimportant byte to trigger
the CRC error. As you can see, the CRC error appears when WINCMD is loaded
for about 30 seconds. I set a breakpoint on the MessageboxA that appears,
set a breakpoint on readfile, etc etc.... but nothing worked. It was very
strange that there was no ReadFile anymore, as if a program CRC checks
itself, it has to open itself with ReadFile. Start partial code 0137:00451E41 MOV [EBP-10],EAX 0137:00451E44 CALL 00403508 0137:00451E49 CMP DWORD PTR [EAX+0000000C],00 0137:00451E50 JZ 00451E65 0137:00451E52 LEA EAX,[EBP-0124] End partial code Start tracing (F10) and notice how many loops are executed, and how many MOVZX instructions are executed. Looks suspicious! Keep on tracing and avoid loops by placing a breakpoint just outside them (like you would avoid loops when tracking an unpacker) until you see this......and the XOR makes it feel suspicious: Start partial code 0137:00451EF1 MOV EAX,[EBP-18] 0137:00451EF4 MOV EAX,[EAX] 0137:00451EF6 XOR EAX,2A67BE65 <- CRC gets encoded 0137:00451EFB MOV [EBP-08],EAX <- Encoded CRC into [EBP-08] 0137:00451EFE PUSH EBP 0137:00451EFF CALL 00451D68 <- This call calculates the CRC the file now has End partial code If you look at EAX it should contain the value: F5BE0EFF Start partial code 0137:00451D8E MOV EDX,[EBP+08] 0137:00451D91 MOV EDX,[EDX+08] 0137:00451D94 MOV [EDX],EAX 0137:00451D96 MOV EAX,[EBP+08] 0137:00451D99 XOR DWORD PTR [EAX-04],F5A3E289 <- Encoded CRC into [EAX-04] End partial code I found out that the CRC in [EBP-08] is the fixed CRC as calculated
when the file is not patched. The fixed CRC at [EBP-08] gets compared with
the CRC at [EAX-04]. This is the newly calculated CRC. If the file is
patched, [EAX-04] will contain another value then [EBP-08]. To patch, we
will move the fixed CRC (=F5BE0EFF) into
[EAX-04]. XOR DWORD PTR [EAX-04],F5A3E289 by Keep in mind that you can't apply the patch yet as WINCMD is packed. I will deal with that at the end. You can see the comparisons if you set a bpm on EAX-04. Last thing to patch is the "UNREGISTERED" string on the
splashscreen and the Windows Commander caption. I did this by making
WINCMD believe our keyfile is valid. Of course it is not valid, we
just make WINCMD believe it is ;-) Start partial code 0137:004CE13F CMP WORD PTR [EBP-011E],0080 0137:004CE148 SETZ BYTE PTR [0053E6B9] <- If valid key a '1' will be set 0137:004CE14F MOV BYTE PTR [EBP-011F],01 0137:004CE156 TEST BL,BL 0137:004CE158 JZ 004CE448 <- If valid key then jump End partial code Changing this JZ into a JMP will do the job. If you're new to code insertion it may be a good time now to read my essay on ACDSee. (if you're not on my page, this link won't work....first go to my page: http://blackb.tsx.org You can find the essay in the "Essays" section.) However, if you have experience doing this stuff or if you just FEEL like you can do this, read on... Step3: Patching the file with code insertion Here's a basic scheme on how code insertion works and how we will apply it:
Let's take a look the end of our unpacking routine: Start partial code 0137:0059A4F3 POPAD 0137:0059A4F4 JNZ 0059A4FE 0137:0059A4F6 MOV EAX,00000001 0137:0059A4FB RET 000C 0137:0059A4FE PUSH 005329B0 0137:0059A503 RET End partial code The JNZ 0059A4FE and all instructions
below will suite perfectly to put a jump to our insertion code. Let's find
the location of that jump in the packed .exe: open Wincmd32.exe in a hex
editor and search for following hex values: 6800000000C3. These are the
hex values for the instruction PUSH 0000000 (=6800000000) and RET
(=C3)......I hope you do remember that it's PUSH 00000000 we're looking
for and not PUSH 005329B0, because that is only added at the end of
the unpacking routine! Next thing to do is finding an empty
loaction we can use to insert our patching code. In most cases I always
find much zero marked space at the end of the file. I decided to use
offset location 8BC10 to insert our code.
Open up HIEW, load Wincmd32.exe into it, press F4, then F3 to go to
assembly mode, press F5(=goto offset) and type 83CF4.
Enter. So far so good. Before we start inserting our code, we gotta
know: [Locations to patch] 004CBF8C JZ 004CBFB4 to 004CBF8C JNZ 004CBFB4 [Data changes] 74 becomes 75
at 4CBF8C Note that the 90 in E9EB02000090 is to NOP out an unneeded byte. The change from JZ to JMP caused a decrease of 1 byte. If you don't NOP that out, Windows Commander may crash, or do unexpected things. All righty....goto your code insertion location in the Wincmd32.exe: 8BC10 and insert following code:
Some explanation and comments: C740FCFF0EBEF5 is 7 bytes long. And we can
only move a maximum of 4 bytes at a time. Thats why I first move 4 bytes
(d= double word= 4 bytes) then I move 2 bytes (w= word= 2 bytes) and then
finally the last 1 byte (b= byte= 1 byte). Also notice that the order of
bytes is reversed, as the last byte will get stored first. So if you want
to store EA10 into a certain location you type: mov w, [location], 010EA That's it. If you did everything right, Windows Commander should run fine, without a nag and just like you're really registered. |
|||
IV. In the end | |||
Questions, bugs, other comments about this essay are welcome at
cracking@softhome.net greets The Blackbird |
|||
Essay written by The Blackbird © 1999-2000 This essay can be freely distributed/ published/ printed etc... as long as no modifications are made. |