【问题标题】:Visual Studio Express 2010 C++ Disassembly DebuggingVisual Studio Express 2010 C++ 反汇编调试
【发布时间】:2012-02-15 05:13:02
【问题描述】:

我有一个 C++ 程序,当我使用 Visual Studio 在调试器中运行它时,它会因访问冲突而崩溃。问题是,在过去,它通常会将我带到发生这种情况的线路,但对于这个问题,它说没有可用的资源并带我去反汇编。我不知道如何破译它并获得任何有用的信息。它带我到以下行:

0000000057A93F0F  cmp         dword ptr [rcx+11BCh],0  

然后,如果我再次运行它,它将停在:

0000000058673F0F  cmp         dword ptr [rcx+11BCh],0  

然后,如果我再次运行它,它会在第一个停止,如果我重新运行它,它会再次停止在第二个......它只是继续在这个循环中。我发现这很奇怪,这发生在不同的地址交替时间,但我什至不知道这是否是确定的地址。

我如何使用这些信息来查找问题?

(我会发布代码,但我不知道是哪个部分导致了问题,所以不知道该发布什么......我不应该尝试使用 x64 平台编译 flash-to-directx)。

谢谢

编辑

这是崩溃发生前的几行:

0000000057A93EF3  test        dl,1  
0000000057A93EF6  je          0000000057A93EFD  
0000000057A93EF8  call        0000000057FC8024  
0000000057A93EFD  mov         rax,rbx  
0000000057A93F00  add         rsp,20h  
0000000057A93F04  pop         rbx  
0000000057A93F05  ret  
0000000057A93F06  int         3  
0000000057A93F07  int         3  
0000000057A93F08  sub         rsp,28h  
0000000057A93F0C  mov         ecx,r8d  

然后崩溃发生在:

0000000057A93F0F  cmp         dword ptr [rcx+11BCh],0  

我的调用堆栈上的最后一项是:

Flash64_11_1_102.ocx!0000000058673f0f()

【问题讨论】:

  • 它在尝试从 [rcx+11BCh] 读取时崩溃。现在,如果这是对 C++ 类成员函数的调用,RCX 应该包含 this 指针,并且您正在尝试访问类实例中的某些内容。首先是看看此时RCX是什么。
  • 所以当我运行它并且如果我将鼠标悬停在RCX 上它会停止它显示4278034432 的值。这个值是多少?我如何弄清楚该值是什么?感谢您的帮助!
  • 在崩溃线之前显示 7 或 8 行也是有帮助的。这样我们也许可以确定 rcx 是否是从其他地方传来的垃圾。
  • Michael 我在上面的帖子中也直接在崩溃前编辑了我的帖子。谢谢。
  • 4278034432 = 0xFEFDA000 内存地址。 0xFEFDA000 + 0x11BC = 0xFEFDB1BC。检查您在这些地址上拥有什么。

标签: c++ debugging assembly directx


【解决方案1】:

Adobe Flash dll 中的经典 64 位指针截断。可能某些函数通过某种结构接收DWORD userData 而不是void* userData,然后将其转换为对象指针。这在 32 位环境下工作正常,但在 64 位环境下崩溃。

说明

mov         ecx,r8d

第一个操作仅将低 32 位从 R8D 复制到 ECX(ECX 是 32 位)。

cmp         dword ptr [rcx+11BCh],0

第二次操作访问 64 位寄存器,其中低 32 位包含正确的地址,高 32 位包含一些垃圾。当然会导致崩溃。

如何解决

这很容易,如果您不介意使用十六进制编辑器编辑 dll。您将需要一个老式的 MASM.exe(您可以从 Microsoft 网站获得一个)。

创建 .asm 文件,或从示例中获取并修改,代码如下:

nop
nop
nop

mov ecx,r8d
cmp dword ptr [rcx+11BCh],0

nop
nop
nop

mov rcx,r8d   // I've replaced ecx with rcx here
cmp dword ptr [rcx+11BCh],0

通过将其提交给 MASM 创建 .obj 文件。使用任何十六进制编辑器打开生成的文件并注意序列90 90 90 first_sequence_of_bytes 90 90 90 second_sequence_of_bytes。您需要做的就是在原始 dll 中找到第一个字节序列并将其替换为第二个字节序列。我很确定差异只会出现在第一个字节上。

这将解决您的崩溃问题。

【讨论】:

  • 很抱歉,我对汇编语言一点也不熟悉...我的 .asm 文件究竟应该是什么样子?我尝试了一些不同的方法,但不断收到诸如“未定义符号 rcx”之类的错误。我很确定我做的不对。
  • 我终于得到了它来编译和构建我的 test.obj ......但现在我无法在 flash ocx 中找到序列。我查看了 flash ocx 和 flash dll。我做错了什么?
  • 您需要在ActiveX版本的Adobe Flash dll中搜索。这个是在您使用 Internet Explorer 时安装的(或者只是使用 Adob​​e 网站上的Other operating system or browser 按钮)。另外,请记住 64 位 Windows 系统上的阴影。获得 64 位 dll 并不容易。我使用 Total Commander 来访问它。
  • 是的,谢谢我终于明白了。那是真正的问题... Windows 让我很困惑,很难找到真正的 64 位版本。我最终只是将它复制并粘贴到与 DOS 不同的目录中,然后修改该目录并加载它。
【解决方案2】:

我不确定 Express 有什么功能,但如果它可以让您查看寄存器,我敢打赌 rcx 是零(一个 NULL 指针)。您还应该能够查看调用堆栈。如果是这样,您可能会在堆栈上找到您的代码,并且您可能能够看到哪个函数正在传递 NULL 指针。

【讨论】:

  • 我不确定如何准确查看寄存器。当它中断时,我可以看到rcx 的值为4278034432,但我不确定这意味着什么。是那个寄存器吗?此外,我的调用堆栈中的最后一件事是> Flash64_11_1_102.ocx!0000000058673f0f()。这是否意味着问题出在 ocx 中的一个函数?谢谢。
  • 是的,rcx 是寄存器。由于它不为零,它可能来自未初始化的变量或释放的内存。尝试查看调用堆栈。在常规 VisualStudio 上,它由 Debug->Windows->Call Stack 打开。
  • 我发现调用堆栈上的最后一项是Flash64_11_1_102.ocx!0000000058673f0f()。这让我相信 flash ocx 中出了点问题。我应该提到这个问题只发生在 64 位构建期间。使用 32 位没有问题。也许 Flash64*.ocx 不是 64 位的,尽管它的名字是 64?我认为这是因为 Flash 在我的 64 位浏览器中运行良好。
【解决方案3】:

对于这类问题,我要做的第一件事就是尽可能地完成重现问题所需的任何步骤。一旦我尽可能接近,我打开所有异常处理(ctrl+alt+e,勾选出现的对话框中的所有复选框),并重现崩溃。您应该进入代码中未处理第一次机会异常的位置,并且它应该至少为您提供一些导致转储的上下文。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-30
    • 2011-03-20
    相关资源
    最近更新 更多