Appcall

The debugger’s Appcall feature effectively extends the capabilities of IDC or IDAPython to make any function in the active process callable from a script. There are an infinite number of uses for such a capability, including mapping additional memory into the process address space (by calling VirtualAlloc or similar) and injecting new libraries into the process being debugged (by calling LoadLibrary or by calling functions within the process to perform tasks you would rather perform manually, such as decoding blocks of data or computing hash values).

In order to make use of Appcall, the function you wish to invoke must be loaded in the address space of the process being debugged, and IDA must know or be informed of the function’s prototype so that parameters may be marshaled and unmarshaled properly. Any Appcall that you do make will be made in the context of the current debugger thread after first saving the thread’s state (essentially all registers associated with the thread). Once the Appcall completes, IDA restores the thread state, and the debugger is ready to resume execution as if no Appcall had ever taken place.

Let’s look at an example in which Appcall is used to allocate a 4096-byte block of memory into the current (Windows) process address space. In this case, the Windows API function that we wish to invoke is named VirtualAlloc and its prototype is shown here:

LPVOID WINAPI VirtualAlloc(LPVOID lpAddress, SIZE_T dwSize,
                           DWORD flAllocationType, DWORD flProtect);

The call that we wish to make using Appcall might look something like the following if we were to write it in C:

VirtualAlloc(NULL, 4096, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);

This function call ultimately translates into the following once all of the constants are resolved:

VirtualAlloc(0, 4096, 0x3000, 4);

Recall that while a Windows process is being debugged, IDA prefixes the name of every library function with the name of the library to which the function belongs. Thus, VirtualAlloc will be named kernel32_VirtualAlloc when the debugger is active, as shown is the following listing:

kernel32.dll:766B2FB6 ; ====== S U B R O U T I N E ========
kernel32.dll:766B2FB6
kernel32.dll:766B2FB6 ; Attributes: bp-based frame
kernel32.dll:766B2FB6
kernel32.dll:766B2FB6 kernel32_VirtualAlloc proc near

No type information is displayed because IDA’s type libraries know nothing about a function named kernel32_VirtualAlloc. Since Appcall requires knowledge of a function’s type signature, we must add the information into the database ourselves using the Set Function Type command. An exact type signature is not required as long as the signature we specify allows IDA to properly transfer our parameters to the function we are invoking. In this case, we supply the following signature:

kernel32.dll:766B2FB6 ; Attributes: bp-based frame
kernel32.dll:766B2FB6
kernel32.dll:766B2FB6 ; int __stdcall kernel32_VirtualAlloc(int, int, int, int)
kernel32.dll:766B2FB6 kernel32_VirtualAlloc proc near

At this point we are ready to use Appcall to have more memory allocated into our process. Using IDC, this is extremely easy because all we need to do is invoke the function just as if it was an IDC function. Entering the function call at the IDA command line and using the Message function to display the results yields the following output:

IDC>Message("%x
", kernel32_VirtualAlloc(0, 4096, 0x3000, 4));
3c0000

The result in this case is a new 4096-byte block allocated to the process at address 0x3c0000. In order to make the new memory block show up in IDA, we must use the Debugger ▸ Refresh memory command or wait for IDA to perform a refresh in conjunction with other debugger operations.

The syntax for performing an Appcall in Python is slightly different, making use of the Appcall variable defined in the idaapi module. However, the requirements to have a named function with an assigned type signature remain. When performed in Python, the same Appcall to VirtualAlloc would be done as follows:

Python>Message("%x
" % Appcall.kernel32_VirtualAlloc(0, 4096, 0x3000, 4))
3d0000

Additional information and examples related to Appcall and its uses may be found on the Hex-Rays blog.[243]

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.138.105.255