分析崩溃的反汇编 C++ 代码

Analyzing diassembled c++ code that crashes

本文关键字:C++ 代码 反汇编 崩溃      更新时间:2023-10-16

当控件离开"}"时,下面的代码崩溃。如果我用变量替换 FieldByName()->AsString,或者如果我删除 else 如果未执行,它不会崩溃。当AV开始出现时,"=="被SameText取代。

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;
}

看着拆解,

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

截取其他 if 和 else 并从位置 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

AV 出现在显示">"的位置。我的问题是,为什么第一个区块中有 3 个创建而只有 2 个破坏,而在底部有额外的 2 个?因此,如果我合计执行的代码,则有 3 次创建和 4 次销毁。我似乎也不知道哪个字符串对应于哪个创建和销毁。我可以弄清楚"RequirePO",AsString和"Y"构成了三个创建点,也是指向不同地址的创建点之一。也许我没看错。

感谢帮助。

问候马修·乔伊

对我来说看起来像

编译器中的一个代码生成错误。 0x0053a566处的代码位是使用[ebp-$14]地址作为参数调用System.UnicodeString.Destroy。 但是,[ebp-$14]似乎没有在任何地方初始化。

我敢打赌,[ebp-$14]将通过调用您省略的代码段(对应于else ifelse子句)中的System.UnicodeString.Create来初始化。