PIN_Backtrace() does not return addresses beyond shellcode?

Viewed 14

I'm writing a pintool that backtrace when a specific file is read by a Linux malware:

typedef struct CALLSTACK {
    int depth;
    VOID **return_addresses;
} CALLSTACK;

CALLSTACK get_callstack(const CONTEXT *context) {
    CALLSTACK callstack;
    callstack.return_addresses = new VOID *[BACKTRACE_MAX_SIZE];

    PIN_LockClient();
    callstack.depth =
        PIN_Backtrace(context, callstack.return_addresses, BACKTRACE_MAX_SIZE);

    VOID *raw_address_callstack[BACKTRACE_MAX_SIZE];
    for (int i = 0; i < callstack.depth; i++) {
        raw_address_callstack[i] = callstack.return_addresses[i];
    }
    callstack.return_addresses =
        (VOID **)backtrace_symbols(raw_address_callstack, callstack.depth);

    PIN_UnlockClient();

    return callstack;
}

The malware is using shellcode located in heap to read such file and PIN_Backtrace() does not return anything beyond than the API call (only libc addresses returned). When I use gdb to debug the malware, the callstack returned by bt command at the point of file-reading is still full so it must be something wrong with my pintool.

My question is: Why does that happen and What can I do to retrieve the full callstack using pintool?

0 Answers
Related