0

The assembly file has multiple variables which both use the rax register. The decompiler did recognize that at least somewhat, since it did create two variables which use the rax register. However, it did not split up the use of each one properly. Here is the assembly and decompilation, along with a couple comments on what would be a more accurate decompilation.

.text:000000014052DDA0 String__moveTextBackwards proc near
.text:000000014052DDA0                                         ; CODE XREF: sub_14003E380+86↑p
.text:000000014052DDA0                                         ; sub_1403CC850+19D2↑p ...
.text:000000014052DDA0                 mov     rax, [rcx+18h]
.text:000000014052DDA4                 movsxd  r10, r8d
.text:000000014052DDA7                 mov     r9, rcx
.text:000000014052DDAA                 lea     r8, [r10+rdx]
.text:000000014052DDAE                 cmp     r8, rax
.text:000000014052DDB1                 jnz     short loc_14052DDBA
.text:000000014052DDB3                 mov     rax, [rcx]
.text:000000014052DDB6                 jmp     qword ptr [rax+20h]
.text:000000014052DDBA ; ---------------------------------------------------------------------------
.text:000000014052DDBA
.text:000000014052DDBA loc_14052DDBA:                          ; CODE XREF: String__moveTextBackwards+11↑j
.text:000000014052DDBA                 ja      short loc_14052DDDF
.text:000000014052DDBC                 mov     rdx, r10
.text:000000014052DDBF                 neg     rdx
.text:000000014052DDC2
.text:000000014052DDC2 loc_14052DDC2:                          ; CODE XREF: String__moveTextBackwards+3D↓j
.text:000000014052DDC2                 mov     rax, [r9+8]
.text:000000014052DDC6                 inc     r8
.text:000000014052DDC9                 lea     rcx, [rax+rdx*2]
.text:000000014052DDCD                 movzx   eax, word ptr [rax+r8*2-2]
.text:000000014052DDD3                 mov     [rcx+r8*2-2], ax
.text:000000014052DDD9                 cmp     r8, [r9+18h]
.text:000000014052DDDD                 jbe     short loc_14052DDC2
.text:000000014052DDDF
.text:000000014052DDDF loc_14052DDDF:                          ; CODE XREF: String__moveTextBackwards:loc_14052DDBA↑j
.text:000000014052DDDF                 sub     [r9+18h], r10
.text:000000014052DDE3                 retn
.text:000000014052DDE3 String__moveTextBackwards endp

This gets decompiled to

{
  wchar_t *stringLength; // rax
  __int64 numBytesCopy; // r10
  String *thisCopy; // r9
  unsigned __int64 v6; // r8
  wchar_t *pText; // rax
  wchar_t *pMovedText; // rcx

  stringLength = (wchar_t *)this->stringLength; // This should really be an __int64, but since the compiler assumed this was the same variable that gets returned, it is forced to a wchar_t*
  numBytesCopy = numBytes;
  thisCopy = this;
  v6 = numBytes + a2;
  if ( (wchar_t *)v6 == stringLength )
    return (wchar_t *)((__int64 (__fastcall *)(String *, __int64, unsigned __int64, String *))this->vftbl_0_0000000140B4F448->sub_14052DB70)(
                        this,
                        a2,
                        v6,
                        this);
  if ( v6 <= (unsigned __int64)stringLength )
  {
    do
    {
      pText = thisCopy->pString;
      ++v6;
      pMovedText = &pText[-numBytesCopy];
      stringLength = (wchar_t *)pText[v6 - 1];  // From here until the end, the instances where stringLength is used would better be described as pText. But since both pText and stringLength use rax, it decided to use the wrong one here.
      pMovedText[v6 - 1] = (unsigned __int16)stringLength;
    }
    while ( v6 <= thisCopy->stringLength );
  }
  thisCopy->stringLength -= numBytesCopy;
  return stringLength;
}

Is there a way to change which variable Hex Rays uses in the instances where it chose to use the wrong variable? It has made mistakes similar to this one in other parts of this string class, too.

Your Answer

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

Browse other questions tagged or ask your own question.