Decompiler misinterprets `if (double_param != 0) {...}` as dead code
See original GitHub issueDescribe the bug If a function takes a 64-bit float parameter and then proceeds to compare it to 0 (MOVSD->UCOMISD->LAHF->TEST->JNP), Ghidra considers the non-0 branch to be dead code and for parameter to be unused.
To Reproduce
- Compile the following DLL from a fresh unmanaged C++ DLL project in VS2019 with platform tools v142 and targeting x86:
#include "pch.h"
extern "C" __declspec(dllexport) void __cdecl test(double enable, HWND hwnd) {
if (enable != 0) {
MessageBoxA(hwnd, "Not 0!", "", MB_OK);
} else {
MessageBoxA(hwnd, "0!", "", MB_OK|MB_ICONERROR);
}
}
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
return TRUE;
}
- Create a Ghidra project, add the DLL to it, and run analyzer with default settings
- Navigate to the
test
function in Exports and take a look at decompile view.
You get this:
void __cdecl _test(undefined4 param_1,undefined4 param_2,HWND param_3)
{
/* 0x1000 1 test
Symbol Ref: _test */
if (false) {
MessageBoxA(param_3,"Not 0!","",0);
return;
}
MessageBoxA(param_3,"0!","",0x10);
return;
}
(then-branch is considered to be dead code; 8-byte parameter is interpreted as two unknown4s)
Expected behavior Recognizing MOSD/UCOMISD as a sign of the parameter being a 64-bit float, or, failing that, showing a comparison to literal’s raw floating-point value.
Attachments Pre-compiled version of the sample DLL
Environment (please complete the following information):
- OS: Win10, build 17134
- Java Version: 12.0.1
- Ghidra Version: 9.0.4
Additional context
The shared trait between this and my original code is use of MOVSD+UCOMISD for value != 0
comparisons, perhaps this is the source of trouble
10001000 55 PUSH EBP
10001001 8b ec MOV EBP,ESP
10001003 f2 0f 10 MOVSD XMM0,qword ptr [EBP + param_1]
45 08
10001008 66 0f 2e UCOMISD XMM0,qword ptr [__real@0000000000000000]
05 b0 20
00 10
10001010 9f LAHF
10001011 f6 c4 44 TEST AH,0x44
10001014 7b 17 JNP LAB_1000102d
...
(from sample)
Issue Analytics
- State:
- Created 4 years ago
- Comments:5 (3 by maintainers)
This problem was caused by the parity flag not being modeled for x86. This is now fixed in master and the upcoming 9.2
I think mine might be the same thing as this previously described issue https://github.com/NationalSecurityAgency/ghidra/issues/122