简体   繁体   中英

Analyzing diassembled c++ code that crashes

The code below crashes when the control leaves '}'. If I replace FieldByName()->AsString with a variable or if I remove the else if that is not executed, it doesn't crash. '==' was replaced by SameText, when the AV started to occur.

bool __fastcall TJwsSalesMethods::IsPORequiredForOrderAndCustomer(const String& OrderID, const String& CustomerID)
{
  bool PORequired = false;

  if (IsOrderCustomerPositioned(FqryWork01, CustomerID, OrderID)) // This function executes an SQL statement using FqryWork01->Open()
  {
    //String RequirePO = FqryWork01->FieldByName("RequirePO")->AsString; // Using variable instead will solve
    if (SameText(FqryWork01->FieldByName("RequirePO")->AsString, "Y"))
    {
      PORequired = true; // This block is executed
    }
    else if (SameText(FqryWork01->FieldByName("RequirePO")->AsString, "N"))
    {
      PORequired = false;
    }
    else
    {
      PORequired = IsPORequiredForCustomer(CustomerID);
    }
  } //AV occurs here

  return PORequired;
}

Looking at the disassembly,

0053a40c       public JwsSalesUtil.cpp.TJwsSalesMethods.IsPORequiredForOrderAndCustomer:  ; function entry point
0053a40c 11784   push    ebp
0053a40d         mov     ebp, esp
0053a40f         add     esp, -$54
0053a412         mov     [ebp-$48], ecx
0053a415         mov     [ebp-$44], edx
0053a418         mov     [ebp-$40], eax
0053a41b         mov     eax, $7cf0e0
0053a420         call    +$18c497 ($6c68bc)     ; __InitExceptBlockLDTC
0053a425 11786   mov     byte ptr [ebp-$49], 0
0053a429 11791   push    dword ptr [ebp-$44]
0053a42c         mov     ecx, [ebp-$48]
0053a42f         xor     edx, edx
0053a431         mov     eax, [ebp-$40]
0053a434         call    -$1ec9d ($51b79c)      ; JwsSalesUtil.cpp.TJwsSalesMethods.IsOrderCustomerPositioned
0053a439         test    al, al
0053a43b         jz      loc_53a586
0053a441 11794   mov     word ptr [ebp-$2c], $c
0053a447         mov     edx, $7c1544           ; 'RequirePO'
0053a44c         lea     eax, [ebp-4]
0053a44f         call    +$18ef14 ($6c9368)     ; System.UnicodeString.Create
0053a454         inc     dword ptr [ebp-$20]
0053a457         mov     edx, [eax]
0053a459         mov     ecx, [ebp-$40]
0053a45c         mov     eax, [ecx+$80]
0053a462         call    +$20285d ($73ccc4)     ; Data.Db.TDataSet.FieldByName (dbrtl180.bpl)
0053a467         mov     [ebp-$50], eax
0053a46a         lea     eax, [ebp-8]
0053a46d         call    -$135786 ($404cec)     ; ustring.h.System.UnicodeString.Create
0053a472         mov     edx, eax
0053a474         inc     dword ptr [ebp-$20]
0053a477         mov     eax, [ebp-$50]
0053a47a         mov     ecx, [eax]
0053a47c         call    dword ptr [ecx+$84]
0053a482         lea     edx, [ebp-8]
0053a485         push    dword ptr [edx]
0053a487         mov     edx, $7c154e
0053a48c         lea     eax, [ebp-$c]
0053a48f         call    +$18eed4 ($6c9368)     ; System.UnicodeString.Create
0053a494         inc     dword ptr [ebp-$20]
0053a497         mov     edx, [eax]
0053a499         pop     eax
0053a49a         call    +$20109d ($73b53c)     ; System.Sysutils.SameText (rtl180.bpl)
0053a49f         push    eax
0053a4a0         dec     dword ptr [ebp-$20]
0053a4a3         lea     eax, [ebp-$c]
0053a4a6         mov     edx, 2
0053a4ab         call    +$18f120 ($6c95d0)     ; System.UnicodeString.Destroy
0053a4b0         dec     dword ptr [ebp-$20]
0053a4b3         lea     eax, [ebp-4]
0053a4b6         mov     edx, 2
0053a4bb         call    +$18f110 ($6c95d0)     ; System.UnicodeString.Destroy
0053a4c0         pop     ecx
0053a4c1         test    cl, cl
0053a4c3         jz      loc_53a4ce
0053a4c5 11796   mov     byte ptr [ebp-$49], 1
0053a4c9 11797   jmp     loc_53a566

snip else if and else and continuing from location 53a566

0053a566 11806   dec     dword ptr [ebp-$20]
0053a569         lea     eax, [ebp-$14]
0053a56c         mov     edx, 2
0053a571       > call    +$18f05a ($6c95d0)     ; System.UnicodeString.Destroy
0053a576         dec     dword ptr [ebp-$20]
0053a579         lea     eax, [ebp-8]
0053a57c         mov     edx, 2
0053a581         call    +$18f04a ($6c95d0)     ; System.UnicodeString.Destroy
0053a586 11812   mov     al, [ebp-$49]
0053a589         mov     edx, [ebp-$3c]
0053a58c         mov     fs:[0], edx
0053a593 11813   mov     esp, ebp
0053a595         pop     ebp
0053a596         ret

The AV occurs where '>' is shown. My question is, why is there 3 creates and only 2 destroys in the first block and in the bottom there are extra 2? So if I total the executed code there are 3 creates and 4 destroys. I also don't seem to know which string corresponds to which Create and Destroy. I can figure out "RequirePO", AsString and "Y" constitutes the three Create and also one of the create points to a different address. Maybe I am not reading it right.

Help appreciated.

Regards, Mathew Joy

Looks like a codegen bug in the compiler to me. The bit of code at 0x0053a566 is calling System.UnicodeString.Destroy with the address of [ebp-$14] as an argument. However, [ebp-$14] doesn't seem to have been initialized anywhere.

I'll bet that [ebp-$14] will be initialized by a call to System.UnicodeString.Create in the stretch of code you elided (that corresponds to the else if and else clauses) which is jumped around.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM