Bochs debugger plugin is in alpha stage now, all of the 3 loaders mentioned in the
previous blog entry, are now complete.
Since we demonstrated briefly the IDB loader last time, we will demonstrate the PE loader this time,
which will allow you to debug PE executables. For this we continue using the same malware however
using the PE loader instead. Throughout the video you will see numerous tricks used by this malware
and you will see how the debugger works smoothly with them.
Here are some of the features supported by it:
a privileged instruction, but Windows report back a single step exception. Similarly Windows
does not distinguish between 0xCC and 0xCD 0x03, so when an exception occurs, it reports that
the exception address is always one byte before the trap. So if it was an INT 0x3 (CD03) then
exception address will point to the 0x03 (in the middle of the instruction). We behave the same as Windows.
so you can put breakpoints there and run your program.
for example, in the video you see a call to GlobalAlloc, here is how it is actually implemented (from api_kernel32.idc):
///func=GlobalAlloc entry=k32_GlobalAlloc purge=8 static k32_GlobalAlloc() { eax = BochsVirtAlloc(0, BX_GETPARAM(2), 1); return 0; } ///func=GlobalFree entry=k32_GlobalFree purge=4 static k32_GlobalFree() { eax = BochsVirtFree(BX_GETPARAM(1), 0); return 0; }
A simple MessageBoxA replacement can be (from api_user32.idc):
///func=MessageBoxA entry=messagebox purge=0x10 static messagebox() { auto param2; param2 = BX_GETPARAM(2); Message("I am messagebox function; %s\n", GetString(param2, -1, ASCSTR_C)); eax = 1; // continue execution return 0; }
Use your own code: You can also write your own DLL and map it into the process’ space. You can then redirect
existing APIs to your own functionality, for example:
///func=GetProcAddress entry=bochsys.BxGetProcAddress purge=8 ///func=ExitProcess entry=bochsys.BxExitProcess purge=4 ///func=GetModuleFileNameA entry=bochsys.BxGetModuleFileNameA purge=12 ///func=GetModuleHandleA entry=bochsys.BxGetModuleHandleA purge=4
We redirect some functions to bochsys.dll which will do the job inside the process’ space.
Less demanding PE loader: by that you can for example load any PE file, including system drivers or dlls.
Given that you emulate the API calls, you can theoretically trace such targets too.
Dependency resolution: You don’t have to emulate all APIs to use this plugin, by default if an API
is not present, then a stub will be generated for it. For example, you can define a stub that will
always return 0 for CreateFileA call, as:
///func=CreateFileA retval=0
Since CreateFileA is recognized by IDA’s IDS files, no need to specify the “purge” value, otherwise a full definition would look like:
///func=FuncName purge=N_bytes retval=VALUE
NT structures emulation: Some malware don’t use GetProcAddress or GetModuleHandle() for example, instead they try to
parse the system structures and deduce these values.
For this we also provide and build the basic structure of PEB and PEB_LDR_DATA, LDR_MODULE(s) and RTL_USER_PROCESS_PARAMETERS.
If you need to inspect PEB structure of Win32 programs, then remember to grab
the ldrmodule.idc script from IDA’s download area.
Here’s the video: