Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

x86-16: Decompiler generates incorrect conditional expressions #7884

Open
swine-flu opened this issue Mar 7, 2025 · 0 comments
Open

x86-16: Decompiler generates incorrect conditional expressions #7884

swine-flu opened this issue Mar 7, 2025 · 0 comments
Assignees
Labels
Feature: Decompiler Status: Triage Information is being gathered

Comments

@swine-flu
Copy link

Describe the bug
Under certain circumstances decompiler might produce incorrect conditional expressions, as a result such expressions could change the semantics of composite expressions which include them. Sign extension via CWD instruction followed by two consecutive jump instructions JL/JG seems to be a common pattern which leads to generation of these excessive expressions.

To Reproduce

  1. x86 Assembly
    MOV        AX,[SWORD_1d2e_3350]
    XOR        DX,DX
    MOV        CX,AX
    MOV        BX,DX
    MOV        AX,[SWORD_1d2e_3356]
    CWD
    CMP        DX,BX
    JL         LAB_1000_218b
    JG         LAB_1000_218f
    CMP        AX,CX
    JNC        LAB_1000_218f
    LAB_1000_218b:
    ...	 
    LAB_1000_218f:
    Decompiler output
    bVar6 = SWORD_1d2e_3356 >> 0xf < 0;
    if ((bVar6) || ((-1 < SWORD_1d2e_3356 || bVar6 && ((uint)SWORD_1d2e_3356 < (uint)SWORD_1d2e_3350)))) {
    	// ...
    }
  2. x86 Assembly
    MOV        AX,[SWORD_1d2e_3350]
    XOR        DX,DX
    MOV        CX,AX
    MOV        BX,DX
    MOV        AX,[SWORD_1d2e_3356]
    CWD
    CMP        DX,BX
    JG         LAB_16d5_08a3
    JL         LAB_16d5_08a9
    CMP        AX,CX
    JBE        LAB_16d5_08a9
    LAB_16d5_08a3:
    ...
    LAB_16d5_08a9:
    Decompiler output
    bVar4 = -1 < SWORD_1d2e_3356 >> 0xf;
    if ((SWORD_1d2e_3356 < 0 && bVar4) || ((bVar4 && ((uint)SWORD_1d2e_3350 < (uint)SWORD_1d2e_3356)))) {
    	// ...
    }
  3. x86 Assembly
    MOV        AL,byte ptr [BP + local_1c0]
    XOR        AH,AH
    MOV        DI,AX
    SHL        DI,0x1
    MOV        AX,word ptr [BP + DI + 0xfe44]=>local_1bc
    CWD
    MOV        CX,AX
    MOV        BX,DX
    MOV        AX,[WORD_1d2e_3352]
    XOR        DX,DX
    CMP        DX,BX
    JL         LAB_16d5_39e0
    JG         LAB_16d5_39d6
    CMP        AX,CX
    JBE        LAB_16d5_39e0
    LAB_16d5_39d6:
    CMP        byte ptr [BP + local_1be],0x0
    JNZ        LAB_16d5_39e0
    JMP        LAB_16d5_3ab2
    LAB_16d5_39e0:
    ...
    LAB_16d5_3ab2:
    Decompiler output
    uVar2 = *(uint *)(&local_1be + (uint)local_1c0 * 2);
    bVar7 = 0 < (int)uVar2 >> 0xf;
    if ((bVar7) || (((-1 < (int)uVar2 || bVar7 && (WORD_1d2e_3352 <= uVar2)) || (local_1be != 0)))) {
    	// ...
    }

Expected behavior

  1. Disjunction -1 < SWORD_1d2e_3356 || bVar6 likely should've been decompiled as -1 < SWORD_1d2e_3356
  2. Conjunction SWORD_1d2e_3356 < 0 && bVar4 likely should've been decompiled as 0 < SWORD_1d2e_3356 >> 0xf
  3. Disjunction -1 < (int)uVar2 || bVar7 likely should've been decompiled as -1 < (int)uVar2

Note that semantics of composite expressions (1) and (3) doesn't reflect the underlying assembly, that is produced expressions are defective.

Environment (please complete the following information):

  • OS: Windows 10
  • Java Version: 21.0.5
  • Ghidra Version: 11.3.1
  • Ghidra Origin: locally built
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature: Decompiler Status: Triage Information is being gathered
Projects
None yet
Development

No branches or pull requests

3 participants