Is it Some Anti-Disassembly Tricks (8.3.0 34220) menu

User Tag List

Page 1 of 2 12 LastLast
Results 1 to 15 of 16
  1. #1
    SailorMars's Avatar Member
    Reputation
    8
    Join Date
    Oct 2015
    Posts
    49
    Thanks G/R
    0/7
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Is it Some Anti-Disassembly Tricks (8.3.0 34220)

    I tried to disassemble ClosestUnitPosition() and found that it is calling something that cannot be disassembled. Wondering whether it was my mistake or I just encountered some anti-disassembly tricks.
    This is ClosestUnitPosition() which calls the routine (sub_7FF61D763040 ) in question. It is not rebased, and module base is at 0x7FF61CA60000. It can be found easily by the string shown.
    Code:
    .text:00007FF61E0D8F40 ClosestUnitPosition proc near           ; DATA XREF: .data:00007FF61F258DF8o
    .text:00007FF61E0D8F40
    .text:00007FF61E0D8F40 var_38          = dword ptr -38h
    .text:00007FF61E0D8F40 var_34          = dword ptr -34h
    .text:00007FF61E0D8F40 var_28          = qword ptr -28h
    .text:00007FF61E0D8F40 var_20          = dword ptr -20h
    .text:00007FF61E0D8F40 var_1C          = dword ptr -1Ch
    .text:00007FF61E0D8F40 var_18          = qword ptr -18h
    .text:00007FF61E0D8F40 var_10          = dword ptr -10h
    .text:00007FF61E0D8F40 arg_0           = qword ptr  8
    .text:00007FF61E0D8F40
    .text:00007FF61E0D8F40                 push    rbx
    .text:00007FF61E0D8F42                 sub     rsp, 50h
    .text:00007FF61E0D8F46                 mov     edx, 1
    .text:00007FF61E0D8F4B                 mov     rbx, rcx
    .text:00007FF61E0D8F4E                 call    lua_isnumber
    .text:00007FF61E0D8F53                 mov     rcx, rbx
    .text:00007FF61E0D8F56                 test    eax, eax
    .text:00007FF61E0D8F58                 jnz     short loc_7FF61E0D8F6E
    .text:00007FF61E0D8F5A                 lea     rdx, aUsageClosestun ; "Usage: ClosestUnitPosition(creatureID)"
    .text:00007FF61E0D8F61                 call    sub_7FF61E418B40
    .text:00007FF61E0D8F66                 xor     eax, eax
    .text:00007FF61E0D8F68                 add     rsp, 50h
    .text:00007FF61E0D8F6C                 pop     rbx
    .text:00007FF61E0D8F6D                 retn
    .text:00007FF61E0D8F6E ; ---------------------------------------------------------------------------
    .text:00007FF61E0D8F6E
    .text:00007FF61E0D8F6E loc_7FF61E0D8F6E:                       ; CODE XREF: ClosestUnitPosition+18j
    .text:00007FF61E0D8F6E                 mov     edx, 1
    .text:00007FF61E0D8F73                 mov     [rsp+58h+arg_0], rdi
    .text:00007FF61E0D8F78                 call    lua_tonumber
    .text:00007FF61E0D8F7D                 cvttsd2si edi, xmm0
    .text:00007FF61E0D8F81                 call    sub_7FF61D763040 ; //this cannot be disassembled
    .text:00007FF61E0D8F86                 test    rax, rax
    .text:00007FF61E0D8F89                 jz      loc_7FF61E0D902E
    .text:00007FF61E0D8F8F                 movss   xmm0, cs:dword_7FF61EB438D4
    .text:00007FF61E0D8F97                 lea     rdx, [rsp+58h+var_28]
    .text:00007FF61E0D8F9C                 lea     rcx, sub_7FF61E0DE820
    .text:00007FF61E0D8FA3                 movss   [rsp+58h+var_10], xmm0
    .text:00007FF61E0D8FA9                 mov     [rsp+58h+var_28], rax
    .text:00007FF61E0D8FAE                 mov     [rsp+58h+var_20], 20h
    .text:00007FF61E0D8FB6                 mov     [rsp+58h+var_1C], edi
    :
    :
    And this is sub_7FF61D763040 , it contains some odd db, and a "rbp+38"
    Code:
    .text:00007FF61D763040 ; =============== S U B R O U T I N E =======================================
    .text:00007FF61D763040
    .text:00007FF61D763040 ; Attributes: bp-based frame
    .text:00007FF61D763040
    .text:00007FF61D763040 sub_7FF61D763040 proc near              ; CODE XREF: sub_7FF61CBE1EE0+33p
    .text:00007FF61D763040                                         ; sub_7FF61CBEAF50+E5p ...
    .text:00007FF61D763040
    .text:00007FF61D763040 var_38B70333    = byte ptr -38B70333h
    .text:00007FF61D763040 var_50          = qword ptr -50h
    .text:00007FF61D763040 var_48          = qword ptr -48h
    .text:00007FF61D763040 var_28          = qword ptr -28h
    .text:00007FF61D763040 var_20          = qword ptr -20h
    .text:00007FF61D763040 arg_0           = qword ptr  40h
    .text:00007FF61D763040 arg_8           = qword ptr  48h
    .text:00007FF61D763040 arg_10          = qword ptr  50h
    .text:00007FF61D763040
    .text:00007FF61D763040 ; FUNCTION CHUNK AT .text:00007FF61D76DA6E SIZE 000000B1 BYTES
    .text:00007FF61D763040
    .text:00007FF61D763040                 push    rbp
    .text:00007FF61D763042                 push    rbx
    .text:00007FF61D763043                 push    rsi
    .text:00007FF61D763044                 push    rdi
    .text:00007FF61D763045                 push    r12
    .text:00007FF61D763047                 push    r14
    .text:00007FF61D763049                 push    r15
    .text:00007FF61D76304B                 mov     rbp, rsp
    .text:00007FF61D76304E                 sub     rsp, 70h
    .text:00007FF61D763052                 mov     rdx, [rbp+38h]  ; where is rbp+38?
    .text:00007FF61D763056                 db      66h, 66h   ;????????????? what are these?
    .text:00007FF61D763056                 nop     word ptr [rax+rax+00000000h]
    .text:00007FF61D763060                 stc
    .text:00007FF61D763061                 mov     bl, bl
    .text:00007FF61D763063                 jbe     short near ptr loc_7FF61D7630C3+4
    .text:00007FF61D763065                 sub     al, 0E5h
    .text:00007FF61D763068                 push    rax
    :
    :

    Is it Some Anti-Disassembly Tricks (8.3.0 34220)
  2. #2
    ejt's Avatar Contributor
    Reputation
    209
    Join Date
    Mar 2008
    Posts
    166
    Thanks G/R
    3/111
    Trade Feedback
    0 (0%)
    Mentioned
    4 Post(s)
    Tagged
    0 Thread(s)
    Yes it is obfuscated. In runtime it will take the jump at 00007FF61D763063 so the opcodes after that jump is unreachable code which will screw up the stack frame. This kind of obfuscation is used all over by the way.

    You can follow the jump to 7FF61D7630C3, undefine the opcodes at that location using U shortcut then at 7FF61D7630C3+4 you press C to disassemble the code at that location to see whats really going on. When you can separate the relevant code from the irrelevant code you can then NOP out the irrelevant code. If you chose to do this know that this is a long and tedious task.

    A better solution is to look at pre-legion dumps and see if you can find what you're looking for there.

    Edit: Opening a WOD dump reveals this:

    Code:
    signed int __cdecl Script_ClosestUnitPosition(int a1)
    {
      signed int result; // eax
      signed int v2; // esi
      int v3; // eax
      __int64 v4; // st7
      int v5; // [esp+14h] [ebp-20h]
      int v6; // [esp+18h] [ebp-1Ch]
      int v7; // [esp+1Ch] [ebp-18h]
      int v8; // [esp+20h] [ebp-14h]
      float v9; // [esp+24h] [ebp-10h]
      float v10; // [esp+28h] [ebp-Ch]
      __int64 v11; // [esp+2Ch] [ebp-8h]
    
      if ( lua_isnumber(a1, 1) )
      {
        v2 = lua_tonumber(a1, 1);
        v3 = ClntObjMgrGetActivePlayerObj();
        if ( v3 && (v8 = 0, v5 = v3, v6 = 8, v7 = v2, v9 = -1.0, ClntObjMgrEnumVisibleObjectsPtr(sub_3B6B61, &v5), v8) )
        {
          (*(*v8 + 168))(&v10);
          v10 = sub_7F041(v10 * 10.0) * 0.1;
          *&v11 = sub_7F041(*&v11 * 10.0) * 0.1;
          lua_pushnumber(a1, *&v10);
          lua_pushnumber(a1, COERCE__INT64(*&v11));
          *&v4 = sqrt(v9);
          lua_pushnumber(a1, v4);
          result = 3;
        }
        else
        {
          result = 0;
        }
      }
      else
      {
        LuaL_error(a1, "Usage: ClosestUnitPosition(creatureID)");
        result = 0;
      }
      return result;
    }
    Which is pretty much the same as current so its safe to say it hasn't changed.
    Last edited by ejt; 05-13-2020 at 09:41 AM.

  3. #3
    SailorMars's Avatar Member
    Reputation
    8
    Join Date
    Oct 2015
    Posts
    49
    Thanks G/R
    0/7
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by ejt View Post
    Yes it is obfuscated. In runtime it will take the jump at 00007FF61D763063 so the opcodes after that jump is unreachable code which will screw up the stack frame. This kind of obfuscation is used all over by the way.

    You can follow the jump to 7FF61D7630C3, undefine the opcodes at that location using U shortcut then at 7FF61D7630C3+4 you press C to disassemble the code at that location to see whats really going on. When you can separate the relevant code from the irrelevant code you can then NOP out the irrelevant code. If you chose to do this know that this is a long and tedious task.
    .
    I'm confused. What specific kind of anti-disassembly trick did they used?

    From Script_ClosestUnitPosition(), the entry point for the ClntObjMgrGetActivePlayerObj() is really sub_7FF61D763040 which starts with many normal 'push's then 'mov', but then it will execute the 'db 66h, 66h', 'nop word ptr [rax+rax+00000000h]' . What is the result of this execution?

    Code:
    :
    .text:00007FF61D763052                 mov     rdx, [rbp+38h]  ; where is rbp+38?
    .text:00007FF61D763056                 db      66h, 66h   ;????????????? what are these?
    .text:00007FF61D763056                 nop     word ptr [rax+rax+00000000h]
    :
    Last edited by SailorMars; 05-13-2020 at 02:46 PM.

  4. #4
    ejt's Avatar Contributor
    Reputation
    209
    Join Date
    Mar 2008
    Posts
    166
    Thanks G/R
    3/111
    Trade Feedback
    0 (0%)
    Mentioned
    4 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by SailorMars View Post
    I'm confused. From Script_ClosestUnitPosition(), the entry point for the ClntObjMgrGetActivePlayerObj() is really sub_7FF61D763040 which starts with many 'push's then 'mov' then it will execute the 'db 66h, 66h', 'nop word ptr [rax+rax+00000000h]' . What is the result of this execution?
    The 'db 66h, 66h' and 'nop word ptr [...]' are dead opcodes which does nothing.

    The 'push' and 'mov' sets up the stack for the function, arguments and such. Take a look at x86 Disassembly/Calling Conventions - Wikibooks, open books for an open world that's for x86 but its pretty much the same, x64 got more registers to work with.

    The function is heavily obfuscated and by the looks of your questions you're not very familiar with assembly so I'd suggest you just leave the function alone for now as it require a intermediate understanding of the assembly language to reverse engineer. You'd have to find all the jump bytes and remove all the obfuscated code to get a good understanding of what that function does, or like I said go back to a pre-legion dump and see what it does because its very similar.

  5. #5
    doityourself's Avatar ★ Elder ★
    Reputation
    1424
    Join Date
    Nov 2008
    Posts
    843
    Thanks G/R
    35/448
    Trade Feedback
    0 (0%)
    Mentioned
    6 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by SailorMars View Post
    I'm confused. What specific kind of anti-disassembly trick did they used?

    From Script_ClosestUnitPosition(), the entry point for the ClntObjMgrGetActivePlayerObj() is really sub_7FF61D763040 which starts with many normal 'push's then 'mov', but then it will execute the 'db 66h, 66h', 'nop word ptr [rax+rax+00000000h]' . What is the result of this execution?

    Code:
    :
    .text:00007FF61D763052                 mov     rdx, [rbp+38h]  ; where is rbp+38?
    .text:00007FF61D763056                 db      66h, 66h   ;????????????? what are these?
    .text:00007FF61D763056                 nop     word ptr [rax+rax+00000000h]
    :
    Just in case you are interested in the hex rays output
    This is just the code flow fixed.
    Code:
    // positive sp value has been detected, the output may be wrong!
    unsigned __int64 sub_140D03040()
    {
     // RETURN ADDRESS CHECK STARTS HERE
      v28 = *(_QWORD *)&savedregs[48];
      if ( *(_QWORD *)&savedregs[48] < (unsigned __int64)textSectionStart
        || *(_QWORD *)&savedregs[48] >= (unsigned __int64)textSectionStart + (unsigned int)textSectionSize )
      {
        goto LABEL_32;
      }
      v0 = *(_BYTE *)(*(_QWORD *)&savedregs[48] - 5i64);
      if ( v0 != -24 )
      {
        v1 = *(_BYTE *)(*(_QWORD *)&savedregs[48] - 6i64);
        v2 = *(_BYTE *)(*(_QWORD *)&savedregs[48] - 7i64) == -1 && ((v1 & 0x38) == 16 || (v1 & 0x38) == 24);
        v3 = v1 == -1 && !(((v0 & 0x38) - 16) & 0xF7);
        v4 = *(_BYTE *)(*(_QWORD *)&savedregs[48] - 3i64);
        v5 = v2 || v3;
        if ( *(_BYTE *)(*(_QWORD *)&savedregs[48] - 4i64) == -1 && ((v4 & 0x38) == 16 || (v4 & 0x38) == 24) )
          v5 = 1;
        v6 = v4 == -1;
        v7 = *(_BYTE *)(*(_QWORD *)&savedregs[48] - 2i64);
        v8 = v6 && ((v7 & 0x38) == 16 || (v7 & 0x38) == 24);
        v9 = v8 | v5;
        if ( (v7 != -1 || ((*(_BYTE *)(*(_QWORD *)&savedregs[48] - 1i64) & 0x38) - 16) & 0xF7) && !v9 )
        {
    LABEL_32:
          while ( 1 )
          {
            *(_BYTE *)v28 = v28 / 0;
            memset(&v29, 0, 0x1000ui64);
          }
        }
      } 
     // RETURN ADDRESS CHECK ENDS HERE
      v31 = 0xE3A2F0F102160666i64;
      v23 = 0x1DD2F8DF59A655D3i64;
      sub_1400B0CCC(&v23, &v31);                    // "Calculates" stuff + ret address check
      v10 = v23 ^ ((unsigned int)qword_14297C508 | ((unsigned int)qword_14297C508 | qword_14297C508 & 0xFFFFFFFF00000000ui64 ^ ((unsigned __int64)(unsigned int)(2 * qword_14297C508 - 0x4CABA6B3) << 32)) & 0xFFFFFFFF00000000ui64 ^ ((unsigned __int64)(unsigned int)((*(_QWORD *)((char *)&unk_1428E7BD0 + (v31 >> 52)) >> 32) - qword_14297C508) << 32));
      v11 = (unsigned int)v23 ^ (unsigned int)qword_14297C508 | v10 & 0xFFFFFFFF00000000ui64 ^ ((unsigned __int64)(unsigned int)(2 * __ROR4__(*(_QWORD *)((char *)&unk_1428E7BD0 + (v31 & 0xFFF)), 3) - v10) << 32);
      if ( (unsigned int)v11 | v11 & 0xFFFFFFFF00000000ui64 ^ ((unsigned __int64)((unsigned int)v11 ^ 0xE22D0720) << 32) )
      {
        v32 = 0xE3A2F0F102160666i64;
        v24 = 0x1DD2F8DF59A655D3i64;
        sub_1400B0CCC(&v24, &v32);
        v12 = v24 ^ ((unsigned int)qword_14297C508 | ((unsigned int)qword_14297C508 | qword_14297C508 & 0xFFFFFFFF00000000ui64 ^ ((unsigned __int64)(unsigned int)(2 * qword_14297C508 - 1286317747) << 32)) & 0xFFFFFFFF00000000ui64 ^ ((unsigned __int64)(unsigned int)((*(_QWORD *)((char *)&unk_1428E7BD0 + (v32 >> 52)) >> 32) - qword_14297C508) << 32));
        v13 = v32;
      }
      else
      {
        Protection::RetCheck3((__int64)&v29);
        v17 = Protection::RetCheck2(v16, 128);
        v25 = 0xE3A2F0F102160666i64;
        v26 = 0x1DD2F8DF59A655D3i64;
        v18 = v17;
        sub_1400B0CCC(&v26, &v25);
        v19 = (unsigned int)v18 | v18 & 0xFFFFFFFF00000000ui64 ^ ((unsigned __int64)((unsigned int)v18 ^ 0xE22D0720) << 32);
        v20 = v26 ^ ((unsigned int)v19 | v19 & 0xFFFFFFFF00000000ui64 ^ ((unsigned __int64)(unsigned int)(2 * __ROR4__(*(_QWORD *)((char *)&unk_1428E7BD0 + (v25 & 0xFFF)), 3) - v19) << 32));
        v21 = (unsigned int)v20 | v20 & 0xFFFFFFFF00000000ui64 ^ ((unsigned __int64)(unsigned int)((*(_QWORD *)((char *)&unk_1428E7BD0 + (v25 >> 52)) >> 32)
                                                                                                 - v20) << 32);
        v22 = 0xE3A2F0F102160666i64;
        v27 = 0x1DD2F8DF59A655D3i64;
        qword_14297C508 = (unsigned int)v21 | v21 & 0xFFFFFFFF00000000ui64 ^ ((unsigned __int64)(unsigned int)(2 * v21 - 0x4CABA6B3) << 32);
        sub_1400B0CCC(&v27, &v22);
        v12 = v27 ^ ((unsigned int)qword_14297C508 | ((unsigned int)qword_14297C508 | qword_14297C508 & 0xFFFFFFFF00000000ui64 ^ ((unsigned __int64)(unsigned int)(2 * qword_14297C508 - 0x4CABA6B3) << 32)) & 0xFFFFFFFF00000000ui64 ^ ((unsigned __int64)(unsigned int)((*(_QWORD *)((char *)&unk_1428E7BD0 + (v22 >> 52)) >> 32) - qword_14297C508) << 32));
        v13 = v22;
      }
      v14 = (unsigned int)v12 | v12 & 0xFFFFFFFF00000000ui64 ^ ((unsigned __int64)(unsigned int)(2
                                                                                               * __ROR4__(
                                                                                                   *(_QWORD *)((char *)&unk_1428E7BD0 + (v13 & 0xFFF)),
                                                                                                   3)
                                                                                               - v12) << 32);
      return (unsigned int)v14 | v14 & 0xFFFFFFFF00000000ui64 ^ ((unsigned __int64)((unsigned int)v14 ^ 0xE22D0720) << 32);
    }
    The 'calculation':
    Code:
    void __fastcall sub_1400B0CCC(_QWORD *a1, _QWORD *a2)
    {
      _QWORD *v2; // rsi
      _QWORD *v3; // r8
      unsigned __int64 v4; // r9
      bool v5; // dl
      char v6; // cl
      __int64 *v7; // rax
      char *retaddr; // [rsp+8h] [rbp+0h]
      __int64 *i; // [rsp+20h] [rbp+18h]
    
      v2 = a2;
      v3 = a1;
      v4 = __readgsqword(0x60u);
      if ( (unsigned __int64)retaddr < 0x140001000i64 )
        goto LABEL_13;
      v5 = *(retaddr - 3) == -1 || *(retaddr - 2) == -1;
      if ( *(retaddr - 4) == -1 )
        v5 = 1;
      v6 = *(retaddr - 6) == -1 || v5;
      if ( *(retaddr - 5) == -24 )
        v6 = 1;
      if ( !((*(retaddr - 7) == -1) | (unsigned __int8)v6) || (unsigned __int64)retaddr > 0x1420CC044i64 )
      {
    LABEL_13:
        v7 = (__int64 *)__readgsqword(0x60u);
        for ( i = v7; ; qmemcpy(v7, &i, 0x1000ui64) )
          ;
      }
      *v2 = (char *)sub_1400B0CCC - *v2;
      *v3 ^= *(_QWORD *)(v4 + 56) ^ 0xA5B8540CA4ECB78Aui64;
    }
    Last edited by doityourself; 05-13-2020 at 03:43 PM.

  6. #6
    SailorMars's Avatar Member
    Reputation
    8
    Join Date
    Oct 2015
    Posts
    49
    Thanks G/R
    0/7
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thx for the help. I decided to dig around in the AMD manuals and finally in the Software Optimization Guide (56305) (section 2.8.3.1) there is a list of variable size NOPs and one of which is "66 66 0F 1F 84 00 00 00 00 00".
    Last edited by SailorMars; 05-14-2020 at 12:55 PM.

  7. #7
    doityourself's Avatar ★ Elder ★
    Reputation
    1424
    Join Date
    Nov 2008
    Posts
    843
    Thanks G/R
    35/448
    Trade Feedback
    0 (0%)
    Mentioned
    6 Post(s)
    Tagged
    0 Thread(s)
    Note: things like mov bl, bl can also be seen as nops ;D. there is much stuff in it that doesnt do anything

  8. #8
    ejt's Avatar Contributor
    Reputation
    209
    Join Date
    Mar 2008
    Posts
    166
    Thanks G/R
    3/111
    Trade Feedback
    0 (0%)
    Mentioned
    4 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by king48488 View Post
    Note: things like mov bl, bl can also be seen as nops ;D. there is much stuff in it that doesnt do anything
    From what I understood 'mov bl,bl' sets the lower bits of rbx register to 0. If its basically a nop op that does nothing I've learned something new xd
    Last edited by ejt; 05-14-2020 at 10:33 PM.

  9. #9
    doityourself's Avatar ★ Elder ★
    Reputation
    1424
    Join Date
    Nov 2008
    Posts
    843
    Thanks G/R
    35/448
    Trade Feedback
    0 (0%)
    Mentioned
    6 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by ejt View Post
    From what I understood 'mov bl,bl' sets the lower bits of rbx register to 0. If its basically a nop op that does nothing I've learned something new xd
    Well it depends on how you see it. on 32 bit it does nothing on 64 bit it zeroes 32 bits. However in these cases (blizz trash code) you can see it as kind of a nop

  10. #10
    Jadd's Avatar 🐸 Premium Seller
    Reputation
    1511
    Join Date
    May 2008
    Posts
    2,432
    Thanks G/R
    81/333
    Trade Feedback
    1 (100%)
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by ejt View Post
    From what I understood 'mov bl,bl' sets the lower bits of rbx register to 0. If its basically a nop op that does nothing I've learned something new xd
    Why wouldn't mov bl, bl just do nothing? I think you're thinking of xor bl, bl unless there's something I'm missing.

  11. #11
    ejt's Avatar Contributor
    Reputation
    209
    Join Date
    Mar 2008
    Posts
    166
    Thanks G/R
    3/111
    Trade Feedback
    0 (0%)
    Mentioned
    4 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by Jadd View Post
    Why wouldn't mov bl, bl just do nothing? I think you're thinking of xor bl, bl unless there's something I'm missing.
    You're right, I got 'mov' and 'xor' confused

  12. #12
    SailorMars's Avatar Member
    Reputation
    8
    Join Date
    Oct 2015
    Posts
    49
    Thanks G/R
    0/7
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I am trying to manually fix the code flow until the decompiler can recognize the code. My first attempt is to manually follow the flow and fix those jumps that are actually executed. However, I'm facing some weird results that i cannot comprehend. Did I make any mistake?

    Code:
    .text:00007FF61D763040                       ; =============== S U B R O U T I N E =======================================
    .text:00007FF61D763040
    .text:00007FF61D763040                       ; Attributes: bp-based frame
    .text:00007FF61D763040
    .text:00007FF61D763040                       ClntObjMgrGetPointerToActivePlayer_ proc near
    .text:00007FF61D763040                                                               ; CODE XREF: sub_7FF61CBE1EE0+33p
    .text:00007FF61D763040                                                               ; sub_7FF61CBEAF50+E5p ...
    .text:00007FF61D763040
    .text:00007FF61D763040                       var_38B70333= byte ptr -38B70333h
    .text:00007FF61D763040                       var_50= qword ptr -50h
    .text:00007FF61D763040                       var_48= qword ptr -48h
    .text:00007FF61D763040                       var_28= qword ptr -28h
    .text:00007FF61D763040                       var_20= qword ptr -20h
    .text:00007FF61D763040                       arg_0= qword ptr  40h
    .text:00007FF61D763040                       arg_8= qword ptr  48h
    .text:00007FF61D763040                       arg_10= qword ptr  50h
    .text:00007FF61D763040
    .text:00007FF61D763040                       ; FUNCTION CHUNK AT .text:00007FF61D76DA6E SIZE 000000B1 BYTES
    .text:00007FF61D763040
    .text:00007FF61D763040 000 40 55              push    rbp
    .text:00007FF61D763042 008 53                 push    rbx
    .text:00007FF61D763043 010 56                 push    rsi
    .text:00007FF61D763044 018 57                 push    rdi
    .text:00007FF61D763045 020 41 54              push    r12
    .text:00007FF61D763047 028 41 56              push    r14
    .text:00007FF61D763049 030 41 57              push    r15
    .text:00007FF61D76304B 038 48 8B EC           mov     rbp, rsp
    .text:00007FF61D76304E 038 48 83 EC 70        sub     rsp, 70h
    .text:00007FF61D763052 0A8 48 8B 55 38        mov     rdx, [rbp+38h]                 ; [rbp+38]=caller's return address
    .text:00007FF61D763056                        db      66h, 66h
    .text:00007FF61D763056 0A8 66 66 0F 1F 84 00+ nop     word ptr [rax+rax+00000000h]   ; '66 66 0f 1f 84 00 00 00 00' = variable length nop
    .text:00007FF61D763060 0A8 F9                 stc                                    ; carry=1
    .text:00007FF61D763061 0A8 8A DB              mov     bl, bl                         ; nop
    .text:00007FF61D763063 0A8 76 62              jbe     short loc_7FF61D7630C7         ; always jump since carry=1
    :
    :
    Here i fixed the jmp to "jbe short loc_7FF61D7630C7". Tracing from there i reached text:00007FF61D7630E2, but found some weird code. Here, i'm not sure if the ".text:00007FF61D7630E2 jno short near ptr unk_7FF61D7630C1" should jump or not since the carry flag relies on the value of ECX whose value is not defined when the function is called. Note, that the function should be called by many different places and the callers are not passing a valid ecx value. So I assume the function is taking no arguments, but then what should be this "jno short near ptr unk_7FF61D7630C1"

    Code:
    .text:00007FF61D7630C1 0B0 FF                unk_7FF61D7630C1 db 0FFh                ; CODE XREF: ClntObjMgrGetPointerToActivePlayer_+A2j
    .text:00007FF61D7630C2 0B0 BE                 db 0BEh ; 
    .text:00007FF61D7630C3 0B0 F6                 db 0F6h ; 
    .text:00007FF61D7630C4 0B0 B7                 db 0B7h ; 
    .text:00007FF61D7630C5 0B0 82                 db  82h ; 
    .text:00007FF61D7630C6 0B0 7C                 db  7Ch ; |
    .text:00007FF61D7630C7                       ; ---------------------------------------------------------------------------
    .text:00007FF61D7630C7
    .text:00007FF61D7630C7                       loc_7FF61D7630C7:                       ; CODE XREF: ClntObjMgrGetPointerToActivePlayer_+23j
    .text:00007FF61D7630C7 0B0 48 8B 3D 72 F1 3D+ mov     rdi, cs:off_7FF61EB42240
    .text:00007FF61D7630CE 0B0 66 90              xchg    ax, ax                         ; nop
    .text:00007FF61D7630D0
    .text:00007FF61D7630D0                       loc_7FF61D7630D0:                       ; CODE XREF: ClntObjMgrGetPointerToActivePlayer_+29j
    .text:00007FF61D7630D0 0B0 84 EC              test    ah, ch
    .text:00007FF61D7630D2 0B0 73 67              jnb     short loc_7FF61D76313B         ; no jump as carry=1, ==nop
    .text:00007FF61D7630D4 0B0 81 C1 76 7D 9C D7  add     ecx, 0D79C7D76h        ; what is ecx?
    .text:00007FF61D7630DA 0B0 F6 DE              neg     dh                             ; recall rdx=[rbp+38]
    .text:00007FF61D7630DC 0B0 80 EB 66           sub     bl, 66h         ;carry=unknown
    .text:00007FF61D7630DF 0B0 83 C1 A6           add     ecx, 0FFFFFFA6h                ; carry=unknown!
    .text:00007FF61D7630E2 0B0 71 DD              jno     short near ptr unk_7FF61D7630C1 ; jmp to invalid opcode
    .text:00007FF61D7630E4 0B0 0F 84 12 9F 00 00  jz      loc_7FF61D76CFFC
    .text:00007FF61D7630EA 0B0 81 E8 24 6E 46 B2  sub     eax, 0B2466E24h
    .text:00007FF61D7630F0 0B0 C6 C7 16           mov     bh, 16h
    :
    :
    What should be the correct flow when it reaches ".text:00007FF61D7630E2 jno short near ptr unk_7FF61D7630C1"?

  13. #13
    ejt's Avatar Contributor
    Reputation
    209
    Join Date
    Mar 2008
    Posts
    166
    Thanks G/R
    3/111
    Trade Feedback
    0 (0%)
    Mentioned
    4 Post(s)
    Tagged
    0 Thread(s)
    Like I said earlier, that function is heavily obfuscated and require a higher than intermediate understanding of assembly to understand fully.

    I don't do much assembly as of late so I'm a little rusty but at a quick glance:

    Code:
    .text:00007FF61D7630D0 0B0 84 EC              test    ah, ch
    .text:00007FF61D7630D2 0B0 73 67              jnb     short loc_7FF61D76313B         ; no jump as carry=1, ==nop
    It should take the jump because the 'test' resets the carry flag to 0, look at TEST (x86 instruction) - Wikipedia

    Give up on reversing that function or at least stop posting here for every other line you don't understand.

  14. #14
    doityourself's Avatar ★ Elder ★
    Reputation
    1424
    Join Date
    Nov 2008
    Posts
    843
    Thanks G/R
    35/448
    Trade Feedback
    0 (0%)
    Mentioned
    6 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by ejt View Post
    Like I said earlier, that function is heavily obfuscated and require a higher than intermediate understanding of assembly to understand fully.

    I don't do much assembly as of late so I'm a little rusty but at a quick glance:

    Code:
    .text:00007FF61D7630D0 0B0 84 EC              test    ah, ch
    .text:00007FF61D7630D2 0B0 73 67              jnb     short loc_7FF61D76313B         ; no jump as carry=1, ==nop
    It should take the jump because the 'test' resets the carry flag to 0, look at TEST (x86 instruction) - Wikipedia

    Give up on reversing that function or at least stop posting here for every other line you don't understand.
    It's more like trash code that you see for the control flow now not a real obfuscation.
    Don't forget to also patch all these conditional jumps to a jmp (EB). You should skip all the trash code since these parts will never execute.

    Like 7FF61D763063 is a jmp
    07FF61D7630D2 is also a jmp.

    Just EB it
    The most broken jumps you see or weird asm code is caused by broken ida analysis due to the trash code that never gets executed.
    Often the weird looking conditional jumps are just something like that: if (var1 && !var1) if you look at both. You always take the first one, undefine/define the instructions where it jumps to and patch it to a simple jmp

  15. #15
    SailorMars's Avatar Member
    Reputation
    8
    Join Date
    Oct 2015
    Posts
    49
    Thanks G/R
    0/7
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    king48488,

    thx for your advice. I EB all the fake conditional jumps to hard jmps. But end up encountering an infinite loop starting at offset D037E0 (.text:00007FF61D7637E0 since my base is at 0x7FF61CA60000). The jmp will just ultimately loop back to this offset. As a result IDA says it cannot analyse the sp showing this in the disassembly:

    .text:00007FF61D763860 ClntObjMgrGetPointerToActivePlayer_ endp ; sp-analysis failed
    The decompiler says 'stack frame too big'. I am not sure if this is another anti-reversing trick used. Did u encounter this when u generated the listing u posted previously?

    Code:
    .text:00007FF61D7637E0                       loc_7FF61D7637E0:        ; CODE XREF: ClntObjMgrGetPointerToActivePlayer_+8B1j
    .text:00007FF61D7637E0 0B0 84 E9              test    cl, ch          ; carry =0
    .text:00007FF61D7637E2 0B0 8A D2              mov     dl, dl
    .text:00007FF61D7637E4 0B0 EB 02              jmp     short loc_7FF61D7637E8
    .text:00007FF61D7637E4                       ; ---------------------------------------------------------------------------
    .text:00007FF61D7637E6 0B0 81                 db  81h ; u
    .text:00007FF61D7637E7 0B0 C5                 db 0C5h ; +
    .text:00007FF61D7637E8                       ; ---------------------------------------------------------------------------
    .text:00007FF61D7637E8
    .text:00007FF61D7637E8                       loc_7FF61D7637E8:        ; CODE XREF: ClntObjMgrGetPointerToActivePlayer_+7A4j
    .text:00007FF61D7637E8 0B0 EB 56              jmp     short loc_7FF61D763840
    .text:00007FF61D7637EA                       ; ---------------------------------------------------------------------------
    .text:00007FF61D7637EA 0B0 34 77              xor     al, 77h
    .text:00007FF61D7637EC 0B0 79 48              jns     short near ptr loc_7FF61D763832+4
    .text:00007FF61D7637EE 0B0 F6 D8              neg     al
    .text:00007FF61D7637F0 0B0 0F 84 81 AB 00 00  jz      near ptr loc_7FF61D76E376+1
    .text:00007FF61D7637F6 0B0 81 C0 50 B1 EC 10  add     eax, 10ECB150h
    .text:00007FF61D7637FC 0B0 E8 38 6D 00 00     call    near ptr loc_7FF61D76A536+3
    .text:00007FF61D763801 0B0 C7 C2 96 FD FD F9  mov     edx, 0F9FDFD96h
    .text:00007FF61D763807
    .text:00007FF61D763807                       loc_7FF61D763807:        ; CODE XREF: .text:00007FF61D76386Ej
    .text:00007FF61D763807 0B0 83 C3 E1           add     ebx, 0FFFFFFE1h
    .text:00007FF61D76380A 0B0 80 C0 70           add     al, 70h
    .text:00007FF61D76380D 0B0 C6 C0 0A           mov     al, 0Ah
    .text:00007FF61D763810 0B0 0F 31              rdtsc
    .text:00007FF61D763812 0B0 81 E8 0C 9E 3E 7B  sub     eax, 7B3E9E0Ch
    .text:00007FF61D763818 0B0 F6 DB              neg     bl
    .text:00007FF61D76381A 0B0 81 E9 76 78 CA 3F  sub     ecx, 3FCA7876h
    .text:00007FF61D763820 0B0 6A A6              push    0FFFFFFFFFFFFFFA6h
    .text:00007FF61D763822 0B8 F6 DD              neg     ch
    .text:00007FF61D763824 0B8 5E                 pop     rsi
    .text:00007FF61D763825 0B0 0F 31              rdtsc
    .text:00007FF61D763827 0B0 56                 push    rsi
    .text:00007FF61D763828 0B8 0F 87 24 D3 00 00  ja      near ptr loc_7FF61D770B50+2
    .text:00007FF61D76382E 0B8 70 12              jo      short near ptr loc_7FF61D763840+2
    .text:00007FF61D763830
    .text:00007FF61D763830                       loc_7FF61D763830:        ; CODE XREF: ClntObjMgrGetPointerToActivePlayer_:loc_7FF61D763830j
    .text:00007FF61D763830 0B8 75 FE              jnz     short loc_7FF61D763830
    .text:00007FF61D763832
    .text:00007FF61D763832                       loc_7FF61D763832:        ; CODE XREF: ClntObjMgrGetPointerToActivePlayer_+7ACj
    .text:00007FF61D763832 0B8 E8 43 CE 01 00     call    near ptr loc_7FF61D780677+3
    .text:00007FF61D763837 0B8 F6 D8              neg     al
    .text:00007FF61D763839 0B8 57                 push    rdi
    .text:00007FF61D763839                       ; ---------------------------------------------------------------------------
    .text:00007FF61D76383A 0C0 F6                 db 0F6h ; ÷
    .text:00007FF61D76383B 0C0 82                 db  82h ; e
    .text:00007FF61D76383C 0C0 27                 db  27h ; '
    .text:00007FF61D76383D 0C0 AF                 db 0AFh ; ?
    .text:00007FF61D76383E 0C0 29                 db  29h ; )
    .text:00007FF61D76383F 0C0 98                 db  98h ; y
    .text:00007FF61D763840                       ; ---------------------------------------------------------------------------
    .text:00007FF61D763840
    .text:00007FF61D763840                       loc_7FF61D763840:        ; CODE XREF: ClntObjMgrGetPointerToActivePlayer_:loc_7FF61D7637E8j
    .text:00007FF61D763840                                                ; ClntObjMgrGetPointerToActivePlayer_+7EEj
    .text:00007FF61D763840 0C0 4C 89 45 40        mov     [rbp+arg_0], r8
    .text:00007FF61D763844 0C0 33 D2              xor     edx, edx
    .text:00007FF61D763846 0C0 48 8B 45 40        mov     rax, [rbp+arg_0]
    .text:00007FF61D76384A 0C0 48 89 45 40        mov     [rbp+arg_0], rax
    .text:00007FF61D76384E 0C0 48 8B 4D 40        mov     rcx, [rbp+arg_0]
    .text:00007FF61D763852 0C0 48 8B 7D E0        mov     rdi, [rbp+var_20]
    .text:00007FF61D763856 0C0 48 8B C7           mov     rax, rdi
    .text:00007FF61D763859 0C0 48 F7 F1           div     rcx
    .text:00007FF61D76385C 0C0 88 07              mov     [rdi], al
    .text:00007FF61D76385E 0C0 66 90              xchg    ax, ax
    .text:00007FF61D763860 0C0 EB 08              jmp     short loc_7FF61D76386A
    .text:00007FF61D763860                       ClntObjMgrGetPointerToActivePlayer_ endp ; sp-analysis failed <--------------ERROR 
    :
    :
    The jmps ultimately lead to this:
    Code:
    :
    :
    .text:00007FF61D76389B                       loc_7FF61D76389B:        ; CODE XREF: .text:loc_7FF61D763865j
    .text:00007FF61D76389B                                                ; ClntObjMgrGetPointerToActivePlayer_:loc_7FF61D76386Aj
    .text:00007FF61D76389B 0C0 48 C7 45 40 31 07+ mov     [rbp+arg_0], 731h
    .text:00007FF61D7638A3 0C0 48 8D 7D E8        lea     rdi, [rbp+var_18]
    .text:00007FF61D7638A7 0C0 48 8B 45 40        mov     rax, [rbp+arg_0]
    .text:00007FF61D7638AB 0C0 48 05 85 F8 FF FF  add     rax, 0FFFFFFFFFFFFF885h
    .text:00007FF61D7638B1 0C0 48 89 45 40        mov     [rbp+arg_0], rax
    .text:00007FF61D7638B5 0C0 48 8B 45 40        mov     rax, [rbp+arg_0]
    .text:00007FF61D7638B9 0C0 48 05 4A 10 00 00  add     rax, 104Ah
    .text:00007FF61D7638BF 0C0 48 89 45 40        mov     [rbp+arg_0], rax
    .text:00007FF61D7638C3 0C0 48 C7 45 48 31 F7+ mov     [rbp+arg_8], 0FFFFFFFFFFFFF731h
    .text:00007FF61D7638CB 0C0 48 8B 45 48        mov     rax, [rbp+arg_8]
    .text:00007FF61D7638CF 0C0 48 05 85 F8 FF FF  add     rax, 0FFFFFFFFFFFFF885h
    .text:00007FF61D7638D5 0C0 48 89 45 48        mov     [rbp+arg_8], rax
    .text:00007FF61D7638D9 0C0 48 8B 45 48        mov     rax, [rbp+arg_8]
    .text:00007FF61D7638DD 0C0 48 05 4A 10 00 00  add     rax, 104Ah
    .text:00007FF61D7638E3 0C0 48 89 45 48        mov     [rbp+arg_8], rax
    .text:00007FF61D7638E7 0C0 48 8B 4D 40        mov     rcx, [rbp+arg_0]
    .text:00007FF61D7638EB 0C0 48 8B 45 48        mov     rax, [rbp+arg_8]
    .text:00007FF61D7638EF 0C0 F3 AA              rep stosb
    .text:00007FF61D7638F1 0C0 E9 EA FE FF FF     jmp     loc_7FF61D7637E0 //<-------------INFINITE LOOP 
    .text:00007FF61D7638F1                       ; END OF FUNCTION CHUNK FOR ClntObjMgrGetPointerToActivePlayer_

Page 1 of 2 12 LastLast

Similar Threads

  1. Replies: 0
    Last Post: 09-07-2017, 09:10 PM
  2. Replies: 0
    Last Post: 12-23-2008, 07:30 AM
  3. Is it possible to set up glider to only pick up certain fish?
    By RichyG in forum World of Warcraft General
    Replies: 1
    Last Post: 07-15-2006, 06:36 PM
  4. Glider...where is it consistant?
    By Yano in forum World of Warcraft General
    Replies: 3
    Last Post: 07-04-2006, 04:44 PM
  5. Is there some trick to not having your corpse disappear?
    By Jeesk in forum World of Warcraft General
    Replies: 2
    Last Post: 05-29-2006, 09:24 AM
All times are GMT -5. The time now is 03:31 PM. Powered by vBulletin® Version 4.2.3
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved. User Alert System provided by Advanced User Tagging (Pro) - vBulletin Mods & Addons Copyright © 2024 DragonByte Technologies Ltd.
Digital Point modules: Sphinx-based search