![]() |
|||
Windows CE ARM debugger primer This primer will show how we can debug applications for Windows CE devices. The sample input file we use can be downloaded here This is a sample Windows CE application prototype created by ljw1004 (whose original can be found at http://www.codeproject.com/ce/ce_cards.asp). In order to obtain the best disassembly possible, we start by copying the input file to our Windows machine and start a new PocketPC ARM executable (File, New):
After going through the wizard pages and accepting defaults, IDA will create a database and analyze the input file. Our first task will be to launch the program and examine the window procedure of its main window. In order to find the window procedure, we just scroll down a bit and find the following code:
The RegisterClassW() registers a new window class and specifies its procedure. IDA displays it as 'loc_11DB8'. We jump to it by double clicking on this name. To improve the listing, we will create a function there (right-click to obtain the contextual menu):
Then we rename it (press N):
And finally we create a software breakpoint at its beginning by pressing F2:
We are now ready to launch the debugger. It is very important to create breakpoints at appropriate locations before launching the debugger. Why? Because it is _really_ difficult to suspend (pause) a running process under Windows CE. If the process is executing the user code, then the debugger can suspend it by creating a breakpoint at the currently executed instruction. However, most of the time processes execute system code and the debugger can not suspend that because it can not modify the system area. Modifying system code will frequently crash or hang the PDA, that's why IDA does not let the user create breakpoints in the system areas. Currently all addresses above 0x80000000 and the code of coredll.dll are protected. To launch the debugger, we press F9 or select Debugger, Start process. IDA will connect to the PDA, download the debugger server to it if necessary and look for the input file. Usually the input file on PDA will be located on a different path than on the desktop machine, so atthe first debugger launch IDA will not find it and ask your permission to download it:
After pressing Yes IDA will download and run the program on the PDA. Our breakpoint will be triggered immediately:
To make the listing nicer, I renamed a local variable as 'Msg_copy' and replaced hexadecimal numbers with window message numbers (use the Edit, Operand types, Enum member command for that). Now if we look at the PDA screen, there are no changes there yet. Our program is still suspended. We press F9 to continue it but our breakpoint will be triggered again - WndProc() is called very often, this is normal. Since we want to have an idea of window messages processed by WndProc() but we do not want to press F9 after each of them, we will convert our breakpoint into a simple logger. For that we will right-click and select 'Edit breakpoint'. In the dialog box we enter the breakpoint condition and clear the 'Break' checkbox: Now if we press F9, the program will run without any interruptions and will display its main window in the PDA screen. The message window of IDA will display the window message numbers as we requested:
This is how we create and edit software breakpoints. Feel free to play with the sample application and see how our logger breakpoint works. You may also create more breakpoints and browse the process memory. The whole memory content is available to the debugger. You can have an idea of memory segments by pressing Ctrl-S. Now let's switch to hardware breakpoints. Sometimes we want to learn when a particular data item is modified. Suppose we want to learn who accesses the file name variable in our sample program:
We create a hardware breakpoint with the F2 key just as we created software breakpoints. Since the cursor is located on data, not code, IDA will display the following dialog box: We will set the 'Hardware breakpoint' checkbox and select the breakpoint mode. We are interested in Read and Write accesses. Now we resume the application (if it has been suspended) by pressing F9 and play with the application on the PDA. Tapping on a file name will trigger our breakpoint: Here is the code which activated the breakpoint:
We see that it is the wcscpy() function from the coredll.dll library. Since it is a system area, we can not create a breakpoint there. Even if we try, all we get is: Please note the breakpoint color. It is not red but orange, meaning that the breakpoint could not be set (the breakpoint colors can be set up using the Options, Colors, Debugger command). Since we can not set a breakpoint there, we will double click on the LR register. It contains the return address:
Fortunately, the return address is in the user code, we can create a breakpoint there and press F9 to gain control of the program. This is how we create and use hardware breakpoints. In this primer we learned how to debug a simple Windows CE application, set software and hardware breakpoints. Have fun!
|
|---|