📜 ⬆️ ⬇️

How to remotely debug via WinDbg not including Windows debug mode

Sometimes when analyzing a paid program, Malvari happens that she does not want to work normally if there is a debugger in memory or Windows debugging mode is turned on.
Using a virtual machine with a debugger connected to it (for example, GDB or IDA) helps in such situations. This is if the program does not try to “break” in the virtual machine either.


If you are lucky, and the program does not mind running in a virtual machine, then using GDB you can walk along its guts and even compare them with the source code, if there are debug information in the binary format in DWARF.


We look at a kernel of Windows through WinDbg and GDB
')
If the program is compiled in Visual Studio, then GDB will not be able to display debugging information. You can also forget about the names of the Windows API functions in the listing. WinDbg could be useful here, but how can they connect to the virtual machine if the OS debugging mode does not suit us?

It would be great if in some virtual machine there was a remote debugging interface, similar to what GDB uses, we thought and wrote such a module for the QEMU virtual machine. Everything is laid out in the form of source codes and binaries for Windows , so that everyone can try to use it.

About remote debugging using WinDbg, there is already material on Habré . It describes how to enable the Windows debugging mode and use it to remotely connect WinDbg. The debugger connects via the virtual COM port associated with the Windows named pipe.


Normal powder vs. debug server built into QEMU

In our case, QEMU without a guest system will connect to this named pipe to give the debugger information about what is happening inside Windows. The operating system itself does not know that it is being debugged, so debugging turns out to be somewhat hidden.

To run QEMU in this mode, you need the -windbg switch:

qemu-system-i386.exe -windbg pipe:windbg -hda disk.qcow2 

After that, QEMU will wait for the debugger to connect. It needs to be run with the following command:

 windbg.exe -b -k com:pipe,baud=115200,port=\\.\pipe\windbg,resets=0 

When the emulation starts, select the mode of operation without the Windows debugging module:



After some time, the OS initializes everything that is needed for the debugger to work, it will stop the emulator and prompt you to enter commands:



WinDbg immediately writes that no symbolic information was found: Symbol search path is: *** Invalid *** download symbolic information about system libraries with a couple of .symfix and .reload commands.

The same can be done through the menu File -> Symbol File Path ..., where you can specify the paths to the temporary directory and server Microsoft srv * d: \ tmp * http: //msdl.microsoft.com/download/symbols



Now WinDbg will know the names of the internal structures and functions of Windows and the names of library functions. They are shown in listings, breakpoints can be attached to them, etc.

After that, we will continue loading the OS with the g command and launch the necessary applications there , and then break them . Now, if you press Ctrl + Break in the WinDbg window, the emulation stops, and the command line is turned on in the debugger, where you can do all sorts of useful things.

For example, the! Dlls command will show us the list of modules loaded in the current process:



The concept of "current process" appears when remote debugging. After all, the OS constantly switches virtual address spaces tied to tasks. The! Dml_proc command lists the running processes:



It can be seen that the CrashMe application is working in the system (I took it from www.windbg.info ). It did not find the debugger running in the system.



To populate this program, switch to its context using the .process command. Its parameter is the address of the EPROCESS structure, which is specified in the first column of the output of the! Dml_proc command. Check that everything turned out, you can command! Peb:



To make debugging comfortable, we will load symbolic information and indicate where the source texts of this program are stored. After this, the bp command can create a breakpoint:

 .sympath+ E:\QemuImages\CrashMe\debug .reload /user .srcpath+ E:\QemuImages\CrashMe\CrashMe bp CCrashMeDlg::OnBnClicked_CallingConvention g 

Now, when you click the "Test Calling Conventions" button on the application form, we will fall out into the debugger:



Then you can open the source file:



Check call stack:



Or explore local variables:



Another useful feature of WinDbg is event filters. You can set an interruption of work on various exceptions, on a module load event or an application launch. Usually, messages about such events are sent by the debugging server in the guest system, and in WinDbg, filters are configured for them in the Debug → Event Filters window:



Interception of events and exceptional situations, we have not yet implemented in any way.
If int 3 or dividing by 0 is fairly easy to understand at the emulator level, then much more work needs to be done to identify the creation of the process.

All other WinDbg functions should work well for 32-bit systems, and we haven’t really done 64-bit yet, now we are preparing patches so that all these functions are available to all QEMU users by default.

Links
  1. QEMU build under Windows with the possibility of hidden connection WinDbg can be downloaded here
  2. If you are satisfied with the debugging mode of Windows, it is written here how it can be used in QEMU
  3. And here is the same about VirtualBox with a focus on debugging drivers
  4. Description of some commands and extensions WinDbg
  5. Another list of commands
  6. A selection of links about WinDbg
  7. About debugging .NET applications in WinDbg

Source: https://habr.com/ru/post/327128/


All Articles