1

I'm trying to decompile some singleplayer code for a game (C++ on X86 architecture Linux). I do this with the help of some already available source code, a file (compiled on linux) with debug information and Ida Pro (Mainly only using pseudo-c code conversion). So far everything has been going good up until now. There is a comparison going on which I can't make any sense of.

Below is a part of the function that is the problem:

if (v28)
{
    health_1 = Commands->Get_Health(obj);
    this->field_1C = health_1;
    v14 = health_1 < 0.0;
    v15 = 0;
    v16 = health_1 == 0.0;
    if ((HIBYTE(v13) & 0x45) == 64)
        v17 = this->field_20 - this->field_1C + this->field_24;
    else
        v17 = this->field_20 - this->field_1C;
    v18 = v17;
    v19 = ScriptImpClass::Get_Float_Parameter(&this->base, "Damage_multiplier") * v18;
    this->field_24 = v19 + this->field_24;
    v20 = this->field_20 - v19;
    Commands->Set_Health(obj, v20);
    this->field_20 = Commands->Get_Health(obj);
    this->field_1C = Commands->Get_Health(obj);
}

There is the following comparison:

if ((HIBYTE(v13) & 0x45) == 64)

I just cannot figure out what is being checked here. I believe that the if (v28) statement starts at address .text:084D16BF. Below is the complete bytecode of the function and the structure layout of M00_Damage_Modifier_DME

00000000 GameObjObserverClass struc; (sizeof = 0x8, mappedto_2746); XREF: ScriptClass / r
00000000 vPtr            dd ? ; offset
00000004 ID              dd ?
00000008 GameObjObserverClass ends

00000000 ScriptClass     struc; (sizeof = 0x8, mappedto_2767); XREF: ScriptImpClass / r
00000000 base            GameObjObserverClass ?
00000008 ScriptClass     ends

00000000 ScriptImpClass  struc; (sizeof = 0x1C, mappedto_2754)
00000000; XREF: _ZN17M08_Prison_Patrol7CreatedEP17ScriptableGameObj / r
00000000; _ZN10M08_Sniper7CreatedEP17ScriptableGameObj / r ...
00000000 base            ScriptClass ?
00000008 mOwner          dd ? ; offset
0000000C mArgC           dd ?
00000010 mArgV           dd ? ; offset
00000014 mFactory        dd ? ; offset
00000018 AutoVariableList dd ? ; offset
0000001C ScriptImpClass  ends

00000000 M00_Damage_Modifier_DME struc; (sizeof = 0x3C, mappedto_2798)
00000000 base            ScriptImpClass ?
0000001C field_1C        dd ?
00000020 field_20        dd ?
00000024 field_24        dd ?
00000028 killableByStar  dd ?
0000002C killableByNotStar dd ?
00000030 starModifier    dd ?
00000034 notStarModifier dd ?
00000038 enabled         db ?
00000039 pad_01          db ?
0000003A pad_02          db ?
0000003B pad_03          db ?
0000003C M00_Damage_Modifier_DME ends

.text:084D1582; void __cdecl M00_Damage_Modifier_DME::Damaged(M00_Damage_Modifier_DME *this, ScriptableGameObj *obj, ScriptableGameObj *damager, float amount)
.text:084D1582                 public _ZN23M00_Damage_Modifier_DME7DamagedEP17ScriptableGameObjS1_f; weak
.text:084D1582 _ZN23M00_Damage_Modifier_DME7DamagedEP17ScriptableGameObjS1_f proc near
.text:084D1582; DATA XREF : .data : 08659468o
.text:084D1582
.text:084D1582 var_5C = dword ptr - 5Ch
.text:084D1582 var_58 = dword ptr - 58h
.text:084D1582 var_43 = byte ptr - 43h
.text:084D1582 var_42 = byte ptr - 42h
.text:084D1582 var_41 = byte ptr - 41h
.text:084D1582 var_40 = dword ptr - 40h
.text:084D1582 pos_1 = Vector3 ptr - 3Ch
.text:084D1582 pos = Vector3 ptr - 2Ch
.text:084D1582 this = dword ptr  4
.text:084D1582 obj = dword ptr  8
.text:084D1582 damager = dword ptr  0Ch
.text:084D1582 amount = dword ptr  10h
.text:084D1582
.text:084D1582                 push    ebp
.text:084D1583                 push    edi
.text:084D1584                 push    esi
.text:084D1585                 push    ebx
.text:084D1586                 sub     esp, 3Ch
.text:084D1589                 mov     edi, [esp + 4Ch + this]
.text:084D158D                 mov     ebp, [esp + 4Ch + obj]
.text:084D1591                 cmp     byte ptr[edi + 38h], 0
.text:084D1595                 jz      loc_84D184B
.text:084D159B                 mov[esp + 4Ch + var_41], 0
.text:084D15A0                 cmp     dword ptr[edi + 30h], 0
.text:084D15A4                 jnz     short loc_84D15DD
.text:084D15A6                 sub     esp, 0Ch
.text:084D15A9                 mov     esi, Commands
.text:084D15AF                 lea     ebx, [esp + 58h + pos]
.text:084D15B3                 sub     esp, 10h
.text:084D15B6                 mov     eax, [edi]
.text:084D15B8                 push    edi
.text:084D15B9                 call    dword ptr[eax + 48h]
.text:084D15BC                 add     esp, 8
.text:084D15BF                 push    eax
.text:084D15C0                 push    ebx
.text:084D15C1                 call    dword ptr[esi + 40h]
.text:084D15C4                 add     esp, 10h
.text:084D15C7                 push    ebx
.text:084D15C8                 call    dword ptr[esi + 110h]
.text:084D15CE                 add     esp, 10h
.text:084D15D1                 cmp[esp + 4Ch + damager], eax
.text:084D15D5                 jnz     short loc_84D15DD
.text:084D15D7                 cmp     dword ptr[edi + 28h], 0
.text:084D15DB                 jnz     short loc_84D161A
.text:084D15DD
.text:084D15DD loc_84D15DD : ; CODE XREF : M00_Damage_Modifier_DME::Damaged(ScriptableGameObj *, ScriptableGameObj *, float) + 22j
.text:084D15DD; M00_Damage_Modifier_DME::Damaged(ScriptableGameObj *, ScriptableGameObj *, float) + 53j
.text:084D15DD                 cmp     dword ptr[edi + 34h], 0
.text:084D15E1                 jnz     short loc_84D161F
.text:084D15E3                 sub     esp, 0Ch
.text:084D15E6                 mov     esi, Commands
.text:084D15EC                 lea     ebx, [esp + 58h + pos_1]
.text:084D15F0                 sub     esp, 10h
.text:084D15F3                 mov     eax, [edi]
.text:084D15F5                 push    edi
.text:084D15F6                 call    dword ptr[eax + 48h]
.text:084D15F9                 add     esp, 8
.text:084D15FC                 push    eax
.text:084D15FD                 push    ebx
.text:084D15FE                 call    dword ptr[esi + 40h]
.text:084D1601                 add     esp, 10h
.text:084D1604                 push    ebx
.text:084D1605                 call    dword ptr[esi + 110h]
.text:084D160B                 add     esp, 10h
.text:084D160E                 cmp[esp + 4Ch + damager], eax
.text:084D1612                 jz      short loc_84D161F
.text:084D1614                 cmp     dword ptr[edi + 2Ch], 0
.text:084D1618                 jz      short loc_84D161F
.text:084D161A
.text:084D161A loc_84D161A : ; CODE XREF : M00_Damage_Modifier_DME::Damaged(ScriptableGameObj *, ScriptableGameObj *, float) + 59j
.text:084D161A                 mov[esp + 4Ch + var_41], 1
.text:084D161F
.text:084D161F loc_84D161F : ; CODE XREF : M00_Damage_Modifier_DME::Damaged(ScriptableGameObj *, ScriptableGameObj *, float) + 5Fj
.text:084D161F; M00_Damage_Modifier_DME::Damaged(ScriptableGameObj *, ScriptableGameObj *, float) + 90j ...
.text:084D161F                 cmp[esp + 4Ch + var_41], 0
.text:084D1624                 jz      short loc_84D163B
.text:084D1626                 sub     esp, 0Ch
.text:084D1629                 push    ebp
.text:084D162A                 mov     eax, Commands
.text:084D162F                 call    dword ptr[eax + 0DCh]
.text:084D1635                 fstp    dword ptr[edi + 20h]
.text:084D1638                 add     esp, 10h
.text:084D163B
.text:084D163B loc_84D163B : ; CODE XREF : M00_Damage_Modifier_DME::Damaged(ScriptableGameObj *, ScriptableGameObj *, float) + A2j
.text:084D163B                 mov[esp + 4Ch + var_42], 0
.text:084D1640                 cmp     dword ptr[edi + 30h], 0
.text:084D1644                 jz      short loc_84D167D
.text:084D1646                 sub     esp, 0Ch
.text:084D1649                 mov     esi, Commands
.text:084D164F                 lea     ebx, [esp + 58h + pos_1]
.text:084D1653                 sub     esp, 10h
.text:084D1656                 mov     eax, [edi]
.text:084D1658                 push    edi
.text:084D1659                 call    dword ptr[eax + 48h]
.text:084D165C                 add     esp, 8
.text:084D165F                 push    eax
.text:084D1660                 push    ebx
.text:084D1661                 call    dword ptr[esi + 40h]
.text:084D1664                 add     esp, 10h
.text:084D1667                 push    ebx
.text:084D1668                 call    dword ptr[esi + 110h]
.text:084D166E                 add     esp, 10h
.text:084D1671                 cmp[esp + 4Ch + damager], eax
.text:084D1675                 jnz     short loc_84D167D
.text:084D1677                 cmp     dword ptr[edi + 28h], 0
.text:084D167B                 jnz     short loc_84D16BA
.text:084D167D
.text:084D167D loc_84D167D : ; CODE XREF : M00_Damage_Modifier_DME::Damaged(ScriptableGameObj *, ScriptableGameObj *, float) + C2j
.text:084D167D; M00_Damage_Modifier_DME::Damaged(ScriptableGameObj *, ScriptableGameObj *, float) + F3j
.text:084D167D                 cmp     dword ptr[edi + 34h], 0
.text:084D1681                 jz      short loc_84D16BF
.text:084D1683                 sub     esp, 0Ch
.text:084D1686                 mov     esi, Commands
.text:084D168C                 lea     ebx, [esp + 58h + pos]
.text:084D1690                 sub     esp, 10h
.text:084D1693                 mov     eax, [edi]
.text:084D1695                 push    edi
.text:084D1696                 call    dword ptr[eax + 48h]
.text:084D1699                 add     esp, 8
.text:084D169C                 push    eax
.text:084D169D                 push    ebx
.text:084D169E                 call    dword ptr[esi + 40h]
.text:084D16A1                 add     esp, 10h
.text:084D16A4                 push    ebx
.text:084D16A5                 call    dword ptr[esi + 110h]
.text:084D16AB                 add     esp, 10h
.text:084D16AE                 cmp[esp + 4Ch + damager], eax
.text:084D16B2                 jz      short loc_84D16BF
.text:084D16B4                 cmp     dword ptr[edi + 2Ch], 0
.text:084D16B8                 jz      short loc_84D16BF
.text:084D16BA
.text:084D16BA loc_84D16BA : ; CODE XREF : M00_Damage_Modifier_DME::Damaged(ScriptableGameObj *, ScriptableGameObj *, float) + F9j
.text:084D16BA                 mov[esp + 4Ch + var_42], 1
.text:084D16BF
.text:084D16BF loc_84D16BF : ; CODE XREF : M00_Damage_Modifier_DME::Damaged(ScriptableGameObj *, ScriptableGameObj *, float) + FFj
.text:084D16BF; M00_Damage_Modifier_DME::Damaged(ScriptableGameObj *, ScriptableGameObj *, float) + 130j ...
.text:084D16BF                 cmp[esp + 4Ch + var_42], 0
.text:084D16C4                 jz      loc_84D1758
.text:084D16CA                 sub     esp, 0Ch
.text:084D16CD                 push    ebp
.text:084D16CE                 mov     eax, Commands
.text:084D16D3                 call    dword ptr[eax + 0DCh]
.text:084D16D9                 fst     dword ptr[edi + 1Ch]
.text:084D16DC                 add     esp, 10h
.text:084D16DF                 fldz
.text:084D16E1                 fxch    st(1)
.text:084D16E3                 fucompp
.text:084D16E5                 fnstsw  ax
.text:084D16E7                 and     ah, 45h
.text:084D16EA                 xor     ah, 40h
.text:084D16ED                 jnz     short loc_84D16FA
.text:084D16EF                 fld     dword ptr[edi + 20h]
.text:084D16F2                 fsub    dword ptr[edi + 1Ch]
.text:084D16F5                 fadd    dword ptr[edi + 24h]
.text:084D16F8                 jmp     short loc_84D1700
.text:084D16FA; -------------------------------------------------------------------------- -
.text:084D16FA
.text:084D16FA loc_84D16FA : ; CODE XREF : M00_Damage_Modifier_DME::Damaged(ScriptableGameObj *, ScriptableGameObj *, float) + 16Bj
.text:084D16FA                 fld     dword ptr[edi + 20h]
.text:084D16FD                 fsub    dword ptr[edi + 1Ch]
.text:084D1700
.text:084D1700 loc_84D1700 : ; CODE XREF : M00_Damage_Modifier_DME::Damaged(ScriptableGameObj *, ScriptableGameObj *, float) + 176j
.text:084D1700                 fstp[esp + 4Ch + var_40]
.text:084D1704                 sub     esp, 8
.text:084D1707                 push    offset aDamage_multi_0; "Damage_multiplier"
.text:084D170C                 push    edi; this
.text:084D170D                 call    _ZN14ScriptImpClass19Get_Float_ParameterEPKc; ScriptImpClass::Get_Float_Parameter(char const*)
.text:084D1712                 fmul[esp + 5Ch + var_40]
.text:084D1716                 fld     st
.text:084D1718                 fadd    dword ptr[edi + 24h]
.text:084D171B                 fstp    dword ptr[edi + 24h]
.text:084D171E                 add     esp, 4
.text:084D1721                 fsubr   dword ptr[edi + 20h]
.text:084D1724                 fstp[esp + 58h + var_58]
.text:084D1727                 push    ebp
.text:084D1728                 mov     eax, Commands
.text:084D172D                 call    dword ptr[eax + 0E4h]
.text:084D1733                 mov[esp + 5Ch + var_5C], ebp
.text:084D1736                 mov     eax, Commands
.text:084D173B                 call    dword ptr[eax + 0DCh]
.text:084D1741                 fstp    dword ptr[edi + 20h]
.text:084D1744                 mov[esp + 5Ch + var_5C], ebp
.text:084D1747                 mov     eax, Commands
.text:084D174C                 call    dword ptr[eax + 0DCh]
.text:084D1752                 fstp    dword ptr[edi + 1Ch]
.text:084D1755                 add     esp, 10h
.text:084D1758
.text:084D1758 loc_84D1758 : ; CODE XREF : M00_Damage_Modifier_DME::Damaged(ScriptableGameObj *, ScriptableGameObj *, float) + 142j
.text:084D1758                 mov[esp + 4Ch + var_43], 0
.text:084D175D                 cmp     dword ptr[edi + 30h], 0
.text:084D1761                 jz      short loc_84D179A
.text:084D1763                 sub     esp, 0Ch
.text:084D1766                 mov     esi, Commands
.text:084D176C                 lea     ebx, [esp + 58h + pos_1]
.text:084D1770                 sub     esp, 10h
.text:084D1773                 mov     eax, [edi]
.text:084D1775                 push    edi
.text:084D1776                 call    dword ptr[eax + 48h]
.text:084D1779                 add     esp, 8
.text:084D177C                 push    eax
.text:084D177D                 push    ebx
.text:084D177E                 call    dword ptr[esi + 40h]
.text:084D1781                 add     esp, 10h
.text:084D1784                 push    ebx
.text:084D1785                 call    dword ptr[esi + 110h]
.text:084D178B                 add     esp, 10h
.text:084D178E                 cmp[esp + 4Ch + damager], eax
.text:084D1792                 jnz     short loc_84D179A
.text:084D1794                 cmp     dword ptr[edi + 28h], 0
.text:084D1798                 jz      short loc_84D17D7
.text:084D179A
.text:084D179A loc_84D179A : ; CODE XREF : M00_Damage_Modifier_DME::Damaged(ScriptableGameObj *, ScriptableGameObj *, float) + 1DFj
.text:084D179A; M00_Damage_Modifier_DME::Damaged(ScriptableGameObj *, ScriptableGameObj *, float) + 210j
.text:084D179A                 cmp     dword ptr[edi + 34h], 0
.text:084D179E                 jz      short loc_84D17DC
.text:084D17A0                 sub     esp, 0Ch
.text:084D17A3                 mov     esi, Commands
.text:084D17A9                 lea     ebx, [esp + 58h + pos]
.text:084D17AD                 sub     esp, 10h
.text:084D17B0                 mov     eax, [edi]
.text:084D17B2                 push    edi
.text:084D17B3                 call    dword ptr[eax + 48h]
.text:084D17B6                 add     esp, 8
.text:084D17B9                 push    eax
.text:084D17BA                 push    ebx
.text:084D17BB                 call    dword ptr[esi + 40h]
.text:084D17BE                 add     esp, 10h
.text:084D17C1                 push    ebx
.text:084D17C2                 call    dword ptr[esi + 110h]
.text:084D17C8                 add     esp, 10h
.text:084D17CB                 cmp[esp + 4Ch + damager], eax
.text:084D17CF                 jz      short loc_84D17DC
.text:084D17D1                 cmp     dword ptr[edi + 2Ch], 0
.text:084D17D5                 jnz     short loc_84D17DC
.text:084D17D7
.text:084D17D7 loc_84D17D7 : ; CODE XREF : M00_Damage_Modifier_DME::Damaged(ScriptableGameObj *, ScriptableGameObj *, float) + 216j
.text:084D17D7                 mov[esp + 4Ch + var_43], 1
.text:084D17DC
.text:084D17DC loc_84D17DC : ; CODE XREF : M00_Damage_Modifier_DME::Damaged(ScriptableGameObj *, ScriptableGameObj *, float) + 21Cj
.text:084D17DC; M00_Damage_Modifier_DME::Damaged(ScriptableGameObj *, ScriptableGameObj *, float) + 24Dj ...
.text:084D17DC                 cmp[esp + 4Ch + var_43], 0
.text:084D17E1                 jz      short loc_84D184B
.text:084D17E3                 sub     esp, 0Ch
.text:084D17E6                 push    ebp
.text:084D17E7                 mov     eax, Commands
.text:084D17EC                 call    dword ptr[eax + 0DCh]
.text:084D17F2                 fstp    dword ptr[edi + 1Ch]
.text:084D17F5                 add     esp, 8
.text:084D17F8                 fld     dword ptr[edi + 20h]
.text:084D17FB                 fsub    dword ptr[edi + 1Ch]
.text:084D17FE                 fstp[esp + 54h + var_40]
.text:084D1802                 push    offset aDamage_multi_0; "Damage_multiplier"
.text:084D1807                 push    edi; this
.text:084D1808                 call    _ZN14ScriptImpClass19Get_Float_ParameterEPKc; ScriptImpClass::Get_Float_Parameter(char const*)
.text:084D180D                 fmul[esp + 5Ch + var_40]
.text:084D1811                 add     esp, 4
.text:084D1814                 fsubr   dword ptr[edi + 20h]
.text:084D1817                 fstp[esp + 58h + var_58]
.text:084D181A                 push    ebp
.text:084D181B                 mov     eax, Commands
.text:084D1820                 call    dword ptr[eax + 0E4h]
.text:084D1826                 mov[esp + 5Ch + var_5C], ebp
.text:084D1829                 mov     eax, Commands
.text:084D182E                 call    dword ptr[eax + 0DCh]
.text:084D1834                 fstp    dword ptr[edi + 20h]
.text:084D1837                 mov[esp + 5Ch + var_5C], ebp
.text:084D183A                 mov     eax, Commands
.text:084D183F                 call    dword ptr[eax + 0DCh]
.text:084D1845                 fstp    dword ptr[edi + 1Ch]
.text:084D1848                 add     esp, 10h
.text:084D184B
.text:084D184B loc_84D184B : ; CODE XREF : M00_Damage_Modifier_DME::Damaged(ScriptableGameObj *, ScriptableGameObj *, float) + 13j
.text:084D184B; M00_Damage_Modifier_DME::Damaged(ScriptableGameObj *, ScriptableGameObj *, float) + 25Fj
.text:084D184B                 add     esp, 3Ch
.text:084D184E                 pop     ebx
.text:084D184F                 pop     esi
.text:084D1850                 pop     edi
.text:084D1851                 pop     ebp
.text:084D1852                 retn
.text:084D1852 _ZN23M00_Damage_Modifier_DME7DamagedEP17ScriptableGameObjS1_f endp
.text:084D1852
.text:084D1852; -------------------------------------------------------------------------- -

I tried looking up the opcodes at that area, but it didn't help me solve it either. I'm a complete noob when it comes to assembly.

  • 1
    hibyte means it is checking ax,or bx or cxxxxx etc look for and reg ,const – blabb Sep 6 '17 at 2:50
2

The line in question seems to correspond to this sequence:

.text:084D16DF                 fldz
.text:084D16E1                 fxch    st(1)
.text:084D16E3                 fucompp
.text:084D16E5                 fnstsw  ax
.text:084D16E7                 and     ah, 45h
.text:084D16EA                 xor     ah, 40h

This performs comparison of the FPU stack values, then copies FPU flags to ax and checks its value (probably to determine the result of comparison). Since the Hex-Rays decompiler supports FPU instructions (including comparisons) since at least version 1.1, you either have a too old version or have hit on a bug. Try to update to the latest version or report it if it's still present.

  • Where I am working I cannot upgrade IDA. Would you happen to know how this piece of code would translate to c code? If not, I thank you for your help and will accept your answer anyway. Edit: I cant check the version right now but I will Asap. Also I did find that out what you said (the opcodes) but I still dont really know how that would translate to C. – Neijwiert Sep 6 '17 at 9:25
  • I believe I have version 6.8 of IDA. So I guess its a bug – Neijwiert Sep 6 '17 at 10:30
  • 6.8 is not the latest (it was released in 2015) – Igor Skochinsky Sep 6 '17 at 11:31
  • I've found out what the comparison is. It checks if health_1 == 0. I've found a similar line somewhere else, where I was able to identify it. – Neijwiert Sep 7 '17 at 19:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.