* Abusing Microsoft's EVT as a debugger *

heXc, May 2002 published by +Tsehp



Chapter I - Theory

i've already spent hours crawling the web in order to find a debugger that is capable of debugging apps running on my little ipaq, not knowing that there's a neat one straigt in front of me! now, a few days ago i found out where it is hiding and how to use it, by accident. i always thougt that the debugger that comes with microsoft's evt can only be used for apps that i've got the source code for; but instead you can use it to debug any exe file you want with it. and this is how you do it:

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.
continue with installing your target application that is to be debugged on your WindowsCE device and remember the path to the executable file on the device! next step is to copy THAT executable file to your local 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:

if you've installed some app on your handheld device and the path to it's executable file is: '\Program Files\SomeApp\theexecutable.exe' then enter
'\Program Files\SomeApp'. Otherwise the app may not run while you're debugging it, if some library functions are not in the same directory together with the executable. (i know, it sounds stupid to first download the .exe file and afterwards upload it back to the handheld device, but that's the only way you can use the evc++ ide to debug an app!)

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

Let's now play a bit with this debugger. Download the game Strategic Assault from http://www.strategicassault.com (i actually got version 1.8), install it, copy the file 'strategic assault.exe' to your local computer and load it into ida.

examining ida's 'names window' you will find out that there are not many obvious hooks, nor can you find any interesting string resources inside the .exe file itself. so we need another hook; let's play the game a bit and see if there's something useful for us. Inside the game tap Menu / Register. Entering an invalid serial gets us nowhere .. no MessageBox no nothing. All we find out is that the serial should be 10 chars long.

switch back to ida now and see if you can find the place where the length of the serial is checked. open the 'functions window' and look for e.g. 'strlen'. this function's called twice. first location's:


.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 ...

well... that's it. as you (hopefuly) could see, the debugger works fine even though it's not as comfortable as SICE and it's brothers. before you attempt to use the debugger you'd better create a backup of the info stored on your handheld device because at least i screwed up ma system many times while debugging and had to reset it. ;]

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 day ...
ken whot a mean?