Call to stdcall functions through virtual tables causes issues with the stack analysis
See original GitHub issueDescribe the bug On 32bit X86 when calling __stdcall functions through virtual tables (Microsoft interfaces for instance) the stack analysis is breaking down.
To Reproduce Steps to reproduce the behavior:
- compile the test_stdcall.c file (contained in the provided zip archive using gcc:
gcc -m32 -fno-pic test_stdcall.c -o test_stdcall -O1
- import into ghidra
- create correct function types and correctly set global variables types.
- the call_func procedure is incorrectly analyzed
Expected behavior As calling conventions have been correctly specified for the function pointers I would expect the stack analysis to be performed correctly.
Screenshots
This is the observed behavior:
And here is the original function code:
void call_func(int a, int b, int c) {
(*(*pObj)->f1)(pObj, 0, a);
(*(*pObj)->f1)(pObj, 1, b);
(*(*pObj)->f1)(pObj, 2, c);
}
Attachments The attachment contains the complete minimal source file as well as the completed Ghidra zip file. test_stdcall.zip
Environment (please complete the following information):
- OS: Win10
- Java Version: open-jdk 11.0.2
- Ghidra Version: 9.0.2
- gcc Version: (Ubuntu 7.3.0-27ubuntu1~18.04) 7.3.0
Additional context I used Ubuntu for windows for the test case but I know of binaries compiled with visual studio that display this behavior.
Issue Analytics
- State:
- Created 4 years ago
- Reactions:2
- Comments:7 (2 by maintainers)
The problem seems to be that the call stack adjustment (ActionExtraPopSetup) is handled before resolving the indirect function type (ActionDeindirect). I came up with the following patch which fixes the problem for my small test case (FUN_0040100d should end with
return param_2 + iVar1 + param_1
).fix_indirect_stdcall.patch
decompind.zip
Yes the __stdcall convention is set. I also checked in the debug XML file: stdcall_win_debug.zip and the flag appears in the function type definition.
Thanks again for looking into it.