Search code examples
c++winapiportable-executable

How to determine if a 'malloc' symbol came from the source or from the compiler?


Using Dll injection I was able to hook the malloc symbol from msvcrt.dll, and to print a log of all the calls to malloc from the injected process. The problem is that in the log I can found calls to malloc that are not in the target exe, see further example.

I believe there is a way to solve this, based on the returned addresses of the malloc calls that I found in the hooking process. Here is the log file for a target PE, compiled with tcc:

0 malloc(18)    memory allocated at: 10229112    the return adress is 74ab770a.
1 malloc(4096)  memory allocated at: 10232824    the return adress is 74ab770a.
2 malloc(15)    memory allocated at: 10229144    the return adress is 401022.
3 malloc(15)    memory allocated at: 10229168    the return adress is 401041.
4 malloc(15)    memory allocated at: 10229192    the return adress is 401060.

In the exe file, only the last three calls exists, and it's clear that the other came from a whole different PE.

How I can detect which calls from the exe file and which from different PE when printing the log? Thanks for any help.


Solution

  • when we hook function from dll, say msvcrt!malloc calls can be from different PE modules. we can take base address of calling module from returnAddress call GetModuleHandleExW with GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS flag. if we need detect are call was from exe we can compare this address with base address of exe which we can get via GetModuleHandleW

    code can look like

    HMODULE hmod;
    if (GetModuleHandleEx(
        GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS|
        GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (PCWSTR)_ReturnAddress(), &hmod))
    {
        static HMODULE hmodEXE = 0;
    
        if (!hmodEXE)
        {
            hmodEXE = GetModuleHandleW(0);
        }
    
        DbgPrint("%p: call %sfrom exe\n", _ReturnAddress(), hmodEXE == hmod ? "" : "not ");
    }
    else
    {
        DbgPrint("%p: call not from any PE\n", _ReturnAddress());
    }