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?