Bochs plugin goes alpha

Bochs emulator
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:

  • SEH support: we try to mimic Windows as much as possible, for example the ICEBP instruction is a privileged instruction, but Windows report back a single step exception. Similarly Windows does not distinguish between 0xCC and 0xCD 0×03, so when an exception occurs, it reports that the exception address is always one byte before the trap. So if it was an INT 0×3 (CD03) then exception address will point to the 0×03 (in the middle of the instruction). We behave the same as Windows.
  • TLS callbacks: TLS callbacks are normally parsed by IDA and presented as entry points (ctrl+E), so you can put breakpoints there and run your program.
  • Extendible API emulation: you can provide implementation of a given API using scripting facilities, 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=0×10
    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:

  • This entry was posted in IDA Pro. Bookmark the permalink.

    6 Responses to Bochs plugin goes alpha

    1. Eric Fry says:

      Hi Guys,
      I was just wondering if the new debugger handles stepping through 16bit x86 code.
      My IDA Dosbox (MSDOS Emulator) plugin currently needs to convert CS:IP into EIP before sending the value to IDA. I was wondering if the new IDA version can handle debugging with CS:IP instead of just EIP for 16bit targets.
      Regards,
      Eric

    2. Ilfak Guilfanov says:

      Currently it is the same – since the interface between the debugger module and the IDA kernel does not foresee seg:off pairs, it is difficult to fix. In any case we will see if this can be fixed somehow. For example, if the debugger module always returns a linear address and IDA is intelligent enough to parse it into seg:off, then the problem might disappear. We have to check this.

    3. Canacourse says:

      Another great addition to IDA. Can Function arguments also be passed? IE could I provide arg_0 & arg_4 to test the simple function below?
      GetPeer proc near
      arg_0= dword ptr 8
      arg_4= dword ptr 0Ch
      push ebp
      mov ebp, esp
      push ebx
      mov eax, [ebp+arg_0]
      xor ebx, ebx
      push eax
      etc….

    4. Elias Bachaalany says:

      Hi Canacourse,
      I am not sure I get your question fully, but here are two possible answers:
      1. Bochs debugger addition will work as a debugger (similar to win32 debugger). So in normal cases, if you got code like:
      push 123 Hi Canacourse,
      I am not sure I get your question fully, but here are two possible answers:
      1. Bochs debugger addition will work as a debugger (similar to win32 debugger). So in normal cases, if you got code like:
      push 123 <– eip is here
      push 456
      call GetPeer
      Then, as you step over the call you will get the return value in EAX.
      2. You could still call arbitrary functions in the debuggee process space without really tracing or setting up the stack.
      You can use the BochsCall() IDC function, and in that case, it could be something like:
      BochsCall(LocByName(“GetPeer”), 123, 456);
      Then GetPeer will be evaluated with the given parameters.

    5. Canacourse says:

      Thanks for the answer.
      I am just trying to feed parameters to functions manually to confirm my analysis of the funtion. If I can get this working it would a great help for this and other projects.
      I cannot run this code in a debugger as it was not written for the windows nor linux. Aditionally The code I am working on is large and multi threaded.
      Option two looked like it would work.
      However i wrote an idc script and then get.
      “Could not call Bochs function; failed to return to control breakpoint”
      Am I using Bochs as intended?
      Thanks for your help

    6. Elias Bachaalany says:

      Hi
      We cannot really troubleshoot problems through the blog. It is preferred that you email us to support at hex-rays.com with more details about your problem and we will assist you.
      Thank you.