Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to decode a Windows CE call stack?

Desktop Windows OSs have a "StackWalk64" function, upon which Jochen Kalmbach made a library for decoding the call stack into something human-readable.

I need a similar tool, but for Windows CE. WinCE has a function to get the call stack, GetThreadCallStack, but once I have the raw return addresses, how do I

  1. Determine the module (DLL or EXE) from each program counter?
  2. Determine the function that contains the address, using my .map or .pdb files?

PS. If it helps anyone, I also found OS-agnostic code for walking the ARM call stack. Apparently it's really hard to do reliably!

like image 696
Qwertie Avatar asked Jan 21 '23 04:01

Qwertie


1 Answers

Well, I figured out half of it. You need to call GetThreadCallStack...

CallSnapshot frames[100];

HANDLE hThread = GetCurrentThread();
SetLastError(ERROR_SUCCESS);
int funcCount = GetThreadCallStack(hThread, 100, frames, STACKSNAP_RETURN_FRAMES_ON_ERROR, 0);
bool success = GetLastError() == ERROR_SUCCESS;

but for some reason the header file for it is not included in Windows CE SDKs. Therefore you need to declare it manually:

extern "C" {
    typedef struct _CallSnapshot {
        DWORD dwReturnAddr;
    } CallSnapshot;

    typedef struct _CallSnapshotEx {
        DWORD dwReturnAddr;
        DWORD dwFramePtr;
        DWORD dwCurProc;
        DWORD dwParams[4];
    } CallSnapshotEx;

    ULONG GetThreadCallStack (HANDLE hThrd, ULONG dwMaxFrames, LPVOID lpFrames, DWORD dwFlags, DWORD dwSkip);
    ULONG GetCallStackSnapshot (ULONG dwMaxFrames, CallSnapshot lpFrames[], DWORD dwFlags, DWORD dwSkip);

    #define STACKSNAP_FAIL_IF_INCOMPLETE     1
    #define STACKSNAP_EXTENDED_INFO          2
    #define STACKSNAP_INPROC_ONLY            4
    #define STACKSNAP_RETURN_FRAMES_ON_ERROR 8
}

And then to decode the call stack you would have to (1) figure out the module (EXE or DLL) of each return address, and (2) figure out the function within that module.

I asked another question about getting the module from a code address; and in theory it would be possible to parse a map file to figure out which function (in that module) the address belongs to (thanks ctacke for the link).

like image 190
Qwertie Avatar answered Jan 29 '23 23:01

Qwertie