question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

MSVC float (conditional) division and multiplication not decompiled correctly

See original GitHub issue

Describe the bug De-compiling code that uses conditional float division and multiplication will not show these operations. It also does not recognize the _ftol function and the conversion from float to dword.

Thanks

To Reproduce Using standard options to decompile some code. The code was presumably compiled using Visual Studio 6.0

Expected behavior A clear and concise description of what you expected to happen.

Screenshots If applicable, add screenshots to help explain your problem.

Attachments

Listing of the function

                             **************************************************************
                             *                          FUNCTION                          *
                             **************************************************************
                             float10 __stdcall FUN_01008f03(PVec3 * vec3, PVec2 * dest)
             float10           ST0:10         <RETURN>
             PVec3 *           Stack[0x4]:4   vec3                                    XREF[1]:     01008f0f(R)  
             PVec2 *           Stack[0x8]:4   dest                                    XREF[1]:     01008f53(R)  
             undefined4        Stack[-0x8]:4  local_8                                 XREF[2]:     01008f1c(R), 
                                                                                                   01008f3c(R)  
             undefined4        Stack[-0xc]:4  local_c                                 XREF[1]:     01008f50(R)  
             undefined4        Stack[-0x10]:4 local_10                                XREF[2]:     01008f0b(*), 
                                                                                                   01008f3f(R)  
                             FUN_01008f03                                    XREF[1]:     FUN_01015c08:01015c47(c)  
        01008f03 8b ff           MOV        EDI,EDI
        01008f05 55              PUSH       EBP
        01008f06 8b ec           MOV        EBP,ESP
        01008f08 83 ec 0c        SUB        ESP,0xc
        01008f0b 8d 45 f4        LEA        EAX=>local_10,[EBP + -0xc]
        01008f0e 50              PUSH       EAX
        01008f0f ff 75 08        PUSH       dword ptr [EBP + vec3]
        01008f12 68 60 81        PUSH       PMat4X3_01028160                                 = 
                 02 01
        01008f17 e8 32 fe        CALL       Math_mul_mat4x3_vec3                             undefined Math_mul_mat4x3_vec3(P
                 ff ff
        01008f1c d9 45 fc        FLD        dword ptr [EBP + local_8]
        01008f1f dd 05 f8        FLD        qword ptr [DAT_010016f8]
                 16 00 01
        01008f25 da e9           FUCOMPP
        01008f27 df e0           FNSTSW     AX
        01008f29 f6 c4 44        TEST       AH,0x44
        01008f2c 7a 08           JP         LAB_01008f36
        01008f2e d9 05 18        FLD        dword ptr [DAT_01001718]                         = FEh
                 17 00 01
        01008f34 eb 09           JMP        LAB_01008f3f
                             LAB_01008f36                                    XREF[1]:     01008f2c(j)  
        01008f36 d9 05 40        FLD        dword ptr [DAT_01028140]                         = ??
                 81 02 01
        01008f3c d8 75 fc        FDIV       dword ptr [EBP + local_8]
                             LAB_01008f3f                                    XREF[1]:     01008f34(j)  
        01008f3f d9 45 f4        FLD        dword ptr [EBP + local_10]
        01008f42 56              PUSH       ESI
        01008f43 d8 c9           FMUL       ST1
        01008f45 d8 05 3c        FADD       dword ptr [DAT_0102813c]                         = ??
                 81 02 01
        01008f4b e8 16 82        CALL       _ftol                                            undefined _ftol()
                 01 00
        01008f50 d9 45 f8        FLD        dword ptr [EBP + local_c]
        01008f53 8b 75 0c        MOV        ESI,dword ptr [EBP + dest]
        01008f56 d8 c9           FMUL       ST1
        01008f58 89 06           MOV        dword ptr [ESI],EAX
        01008f5a d8 05 38        FADD       dword ptr [DAT_01028138]                         = ??
                 81 02 01
        01008f60 e8 01 82        CALL       _ftol                                            undefined _ftol()
                 01 00
        01008f65 dd d8           FSTP       ST0
        01008f67 d9 05 1c        FLD        dword ptr [DAT_0100171c]
                 17 00 01
        01008f6d 89 46 04        MOV        dword ptr [ESI + 0x4],EAX
        01008f70 5e              POP        ESI
        01008f71 c9              LEAVE
        01008f72 c2 08 00        RET        0x8
        01008f75 cc              ??         CCh
        01008f76 cc              ??         CCh
        01008f77 cc              ??         CCh
        01008f78 cc              ??         CCh
        01008f79 cc              ??         CCh

Result of decompilation


float10 FUN_01008f03(PVec3 *vec3,PVec2 *dest)

{
  float fVar1;
  PVec3 local_10;
  
  Math_mul_mat4x3_vec3(&PMat4X3_01028160,vec3,&local_10);
  fVar1 = (float)_ftol();
  dest->x = fVar1;
  fVar1 = (float)_ftol();
  dest->y = fVar1;
  return (float10)1.00000000;
}

Environment (please complete the following information):

  • OS: Windows 10
  • Java Version: 1.8.0_162
  • Ghidra Version: 9.1

Issue Analytics

  • State:open
  • Created 4 years ago
  • Reactions:3
  • Comments:9

github_iconTop GitHub Comments

2reactions
Jaguar83commented, Feb 24, 2020

As a general note, it would seem that the analyser would need to pick up the signature of __ftol to fix this issue in the long term. However, as this function uses a non-standard calling convention, I don’t think it would fit under standard analysis rules, so a special rule would need to added for this function. Not sure if this is possible, as I haven’t had a look at the relevant source code yet.

2reactions
Jaguar83commented, Feb 24, 2020

Storage for param_1 needs to be ST0 - the FPU register, not Stack[0x0]

Read more comments on GitHub >

github_iconTop Results From Across the Web

/fp (Specify floating-point behavior) | Microsoft Learn
Specifies how the compiler treats floating-point expressions, optimizations, ... The /fp:contract option is new in Visual Studio 2022.
Read more >
Floating point division vs floating point multiplication
Yes, many CPUs can perform multiplication in 1 or 2 clock cycles but division always takes longer (although FP division is sometimes faster...
Read more >
Hex-Rays Decompiler: News
This is a bugfix release, fixing various minor issues in the original 1.8 release. BUGFIX: ARM: functions with epilog of form LDMDB R11,...
Read more >
Reverse Engineering for Beginners
Unlike MSVC 2010, MSVC 2013 allocated a/b/c variables in function f2() in reverse order. And this is completely correct, because C/C++ standards has...
Read more >
Reverse Engineering for Beginners
Multiplication,division . ... Working with float point numbers using SIMD in x ... But if everything is fine, conditional jump will not be...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found