我有一个 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()
最佳答案
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 secondary_sequence_of_bytes
。您需要做的就是在原始 dll 中找到第一个字节序列并将其替换为第二个字节序列。我很确定差异只会在第一个字节中。
这将解决您的崩溃问题。
关于c++ - Visual Studio Express 2010 C++ 反汇编调试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9270369/