heXc, May 2002 published by +Tsehp
|Chapter I - Theory|
if you don't already got them, download microsoft's embedded visual tools from microsoft.com: (http://download.microsoft.com/download/wince/Install/3.0/W9X2K/EN-US/EN_WINCE_EMBDVTOOLS30.exe)
run 'Microsoft's Active Sync' and connect your handheld or pocket device
to your computer.
then run embedded visual c++ click File / Open and choose 'Executable
Files' as the file type you wanna display, browse for the file you want
to debug (the one you just downloaded from your device) and load it into
the ide. next step is to configure the debugger in order to upload your
targets exe-file to the right location on your WinCE device. therefor
click onto Project / Settings inside the evc++ ide and go to tab: Debug.
In the field 'Download directory' enter the path to your targets executable
file on the wince device. For example:
done all that, hit F11 and evc++ ide will automatically upload the target's .exe-file and the debugger to your device. (i sometimes encountered problems while connecting to ma pocketPC. after resetting it and repeating all the steps described above it worked without any problems.) after the upload's finished you're prolly gonna get some messages telling you that the executable file will not run on that kind of device and that no debug information could be found .. please, just ignore that, we're not gonna need them! ;) after a while the debugger breaks and you got the target absolutely naked in front of you!
examine the debug-toolbar a bit before you start. you'd better set your breakpoints before you let the app run cause when the app's already running it takes ages to scroll or to set a breakpoint (at least when your device's connected via serial cable). e.g. if you wanted to set a breakpoint at a location you got from an ida disassembly you would just move the cursor to the corresponding offset and hit F9. by hitting F5 the app runs till it reaches a breakpoint.
well, i think that's it .. just examine the debug-toolbar a bit to learn more about the debugger. it offers everything you'll need .. registers window, data window, the possibility to single step and on and on ... just try the example below if you need more details ;)
|Chapter II - A wee example|
.text:0001A960 00 00 84 15 STRNE R0, [R4] .text:0001A964 E8 44 1F E5 LDR R4, =unk_2BA70 ; R4 now points to the serial .text:0001A968 04 00 A0 E1 MOV R0, R4 ; we entered. .text:0001A96C A0 2E 00 EB BL strlen ; strlen is called. .text:0001A970 0A 00 50 E3 CMP R0, #0xA ; is the serial 10 chars long? .text:0001A974 10 01 00 2A BCS loc_1ADBC ; yes? then jump! .text:0001A978 14 3A 1F E5 LDR R3, =__rt_sdiv .text:0001A97C 1E 10 4B E2 SUB R1, R11, #0x1E .text:0001A980 0E 00 A0 E3 MOV R0, #0xE .text:0001A984 00 30 93 E5 LDR R3, [R3] .text:0001A988 0F E0 A0 E1 MOV LR, PC .text:0001A98C 03 F0 A0 E1 MOV PC, R3 .text:0001A990 ; ----------------------------------------------------------------- .text:0001A990 00 00 50 E3 CMP R0, #0 .text:0001A994 00 00 A0 43 MOVMI R0, #0 .text:0001A998 09 00 50 E3 CMP R0, #9 .text:0001A99C 09 00 A0 C3 MOVGT R0, #9 .text:0001A9A0 0A 20 A0 E3 MOV R2, #0xA .text:0001A9A4 34 10 8D E2 ADD R1, SP, #0x34 .text:0001A9A8 6A 2E 00 EB BL _itoa .text:0001A9AC 34 10 8D E2 ADD R1, SP, #0x34 .text:0001A9B0 04 00 A0 E1 MOV R0, R4 .text:0001A9B4 8B 2E 00 EB BL strcat .text:0001A9B8 FF 00 00 EA B loc_1ADBC .text:0001A9BC ; -----------------------------------------------------------------
well, nothing very special happens here. the length of the serial is checked, if it is 10 chars long we jump to address 0x1ADBC if not the last char we entered is added to the serial. so let's have a look at the other place where 'strlen' is called:
.text:0001E660 FC 60 9F E5 LDR R6, =unk_2BA70 ; <- offset to our serial .text:0001E664 06 00 A0 E1 MOV R0, R6 .text:0001E668 61 1F 00 EB BL strlen ; get the length of the serial .text:0001E66C EC 80 9F E5 LDR R8, =unk_2DCF0 .text:0001E670 0A 00 50 E3 CMP R0, #0xA ; is the serial 10 chars long? .text:0001E674 27 00 00 1A BNE loc_1E718 ; jump if it is not. .text:0001E678 00 00 A0 E3 MOV R0, #0 .text:0001E67C D4 50 D6 E1 LDRSB R5, [R6,#4] ; here begins the calculation of .text:0001E680 04 00 C6 E5 STRB R0, [R6,#4] ; the right serial number ... .text:0001E684 0A 20 A0 E3 MOV R2, #0xA .text:0001E688 34 10 8D E2 ADD R1, SP, #0x34 .text:0001E68C 06 00 A0 E1 MOV R0, R6 .text:0001E690 21 1F 00 EB BL COREDLL_1404 .text:0001E694 C0 70 9F E5 LDR R7, =unk_73E60 .text:0001E698 0A 20 A0 E3 MOV R2, #0xA .text:0001E69C 34 10 8D E2 ADD R1, SP, #0x34 .text:0001E6A0 04 50 C6 E5 STRB R5, [R6,#4] .text:0001E6A4 00 00 87 E5 STR R0, [R7] .text:0001E6A8 04 00 86 E2 ADD R0, R6, #4 .text:0001E6AC 1A 1F 00 EB BL COREDLL_1404 .text:0001E6B0 00 70 97 E5 LDR R7, [R7] .text:0001E6B4 61 3B A0 E3 MOV R3, #loc_18400 .text:0001E6B8 17 30 83 E3 ORR R3, R3, #0x17 .text:0001E6BC 94 10 9F E5 LDR R1, =unk_73E64 .text:0001E6C0 07 20 A0 E1 MOV R2, R7 .text:0001E6C4 92 03 03 E0 MUL R3, R2, R3 .text:0001E6C8 F9 2C A0 E3 MOV R2, #0xF900 .text:0001E6CC 00 50 A0 E1 MOV R5, R0 .text:0001E6D0 53 20 82 E3 ORR R2, R2, #0x53 .text:0001E6D4 00 50 81 E5 STR R5, [R1] .text:0001E6D8 02 10 83 E0 ADD R1, R3, R2 .text:0001E6DC CC 32 1F E5 LDR R3, =__rt_sdiv .text:0001E6E0 3D 09 A0 E3 MOV R0, #0xF4000 .text:0001E6E4 00 30 93 E5 LDR R3, [R3] .text:0001E6E8 09 0D 80 E3 ORR R0, R0, #0x240 .text:0001E6EC 0F E0 A0 E1 MOV LR, PC .text:0001E6F0 03 F0 A0 E1 MOV PC, R3 .text:0001E6F4 ; ----------------------------------------------------------------- .text:0001E6F4 01 00 55 E1 CMP R5, R1 ; yay, here's the comparison! .text:0001E6F8 00 50 9A E5 LDR R5, [R10] .text:0001E6FC 01 30 A0 03 MOVEQ R3, #1 .text:0001E700 00 30 88 05 STREQ R3, [R8]
all rite now .. let's trace through this part of the code now and see if we can figure out a working serial number.
run the microsoft embedded visual c++ IDE, click File / Open. As file-type choose 'Executable Files' and open 'Strategic assault.exe'. now we have to configure the debugger to run Strategic Assault in the right location on our handheld device. Therefor click onto Project / Settings and go to tab: Debug. In the field 'Download directory' enter Strategic Assault's install directory on your handheld device. In my case this is '\Program Files\Strategic Assault'. Otherwise the game wouldn't run because neccessary dll files couldn't be found. Leave this dialog and hit F11 to upload the game to the device and step straight into it. just ignore all messages you get, like 'this file will not run on your handheld device' a. s. o. When the debugger asks you for the local file name of a certain remote file just click cancel or browse for the file on your local machine if you've already downloaded it from your device. if you don't download these files and add them here you will have many ???s in the disassembly!!!
Next thing is to set a breakpoint at the rite location. in this case i would suggest
.text:0001E678 00 00 A0 E3 MOV R0, #0
because that doesn't break before the serial is not 10 chars yet. as you can't set a breakpoint by just entering it's offset you will now have to move the cursor to that location. (bah, scrolling around takes ages). in my case i moved the cursor to offset 2001E678 and hit F9 to set a breakpoint there (don't mind if rite now you can only see ???s!). Last thing to do before we let the app run is to show all neccessary windows inside the embedded visual c++ IDE. therefor use the 'debug toolbar' and click the buttons: Disassembly, Memory and Registers, if these windows are not already shown.
now comes the funny part. hit F5 and let the app run! go to the 'register' dialog and enter some serial number till the debugger breaks. then step through the code to see what happens. if you wanna have a look at certain places in memory just enter the offset or the name of the register that holds that value in the Address field of the memory window.
ok, in order to keep the story short: step down to address
2001E6F4 E1550001 cmp r5, r1
where our serial is compared with the rite one. as you can see from the code R5 holds the value of the serial we entered, R1 holds the rite one that was calculated in the past few lines of code. so just see in 'Registers' window what value is stored in R1 and replace your serial with the right one. Sure, the value you can see in R1 is in hexadecimal and you gotta calculate a decimal number outta it. this integer value is only 6 chars long as it is based on the first 4 digits of your serial. so, guess what you gotta do with these 6 digits now! :]
|Chapter III - And in the end ...|
ok, time for some 'THANK YOUs'.
mum and iri5, all ma pals here in and around moellbrooklyn, the #wohnzimmer crowd, the lz0tribe, corepda, especially toni and nutty and finally tsehp for telling me bout strategic assault and for publishing ma work!
don't hesitate to contact me on irc or wherever and have a beautiful
ken whot a mean?