MASM修复DLL中的64位截断问题。

13

我正在使用 Adobe Flash ocx,将其加载到我的 C++ 程序中。该 ocx 应该是64位的,但出现了一些问题,当我使用 x64 平台编译时会崩溃。根据我的研究,可能是某些函数通过某些结构体接收了 DWORD userData 而不是 void* userData,然后将其转换为对象指针。这在32位环境下可以工作正常,但在64位环境下会导致崩溃。

导致崩溃的 ocx 内部函数调用的反汇编代码如下:

mov         ecx,r8d 

第一个操作只从R8D复制低32位到ECX(ECX为32位)。

cmp         dword ptr [rcx+11BCh],0 

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

解决方案

我了解到一种可能的解决方案是执行以下步骤:

  1. 创建一个包含以下代码的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 
    
  2. 使用此asm文件和MASM.exe构建一个obj文件

  3. 用十六进制编辑器打开obj文件并定位代表nop的90s
  4. 在Flash ocx中,查找nops之间的第一个字节字符串,并用跟在nops之后的新字节字符串替换它。这将把它从32位变成64位函数调用。

问题

我尝试通过创建以下asm文件并使用ml64.exe进行构建(我没有masm.exe,但我认为ml.exe是它的新32位版本,而且这个代码只能使用ml64.exe构建,可能是因为它支持64位操作符?):

TITLE: Print String Assembly Program (test.asm)

.Code
main Proc
nop 
nop 
nop 

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

nop 
nop 
nop 

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

main ENDP
END

在第二部分中,我一直遇到指令长度不匹配的错误,直到我将r8d更改为r8,才成功构建它。

我已经成功构建了该obj文件,并使用十六进制编辑器定位了两个字节字符串。但是我的问题在于,当我搜索应该出现在flash ocx中的第一个字节字符串时,却找不到它。它不存在,因此我无法用第二个字节字符串替换它。

我做错了什么?

谢谢!


2
你可能是这里 Flash 社区中最聪明的人。嘿 - Jonathan Dunlap
你是说你通过手动编辑Flash OCX文件解决了问题? - Gabe
3
嘿,我是 Flash Player 团队的成员。虽然我们不官方地支持在 IE 之外使用 ocx,但这看起来像是一个严重的 bug,我真的很想知道你正在修补哪个函数,以便我可以适当地修复它。我有点困惑这是否是一个一般性的 ocx 问题还是 Flash 内部的问题。 - starmole
我正在使用一堆回调函数来在Flash中传输数据。我需要进行一些调试,以确定哪个确切的函数是罪魁祸首。之前很难看到它,因为调用堆栈上只有flash.ocx!some numberes(),所以我知道问题出在64位ocx中。一旦我找到更多信息,我会让你知道(我这周很忙,可能需要几天时间)。感谢您的关注。 - M. Laing
@starmole 从他的最终答案来看,我觉得他使用了错误的ocx。至于他在“将41更改为49”的解决方案,你的猜测和我的一样好... - unixman83
显示剩余3条评论
1个回答

0
  1. 创建一个包含以下代码的asm文件:

    nop 
    nop 
    nop 
    
    mov ecx,r8d 
    cmp dword ptr [rcx+11BCh],0 
    
    nop 
    nop 
    nop 
    
    mov rcx,r8d   // 我在这里用rcx替换了ecx 
    cmp dword ptr [rcx+11BCh],0 
    
  2. 使用MASM.exe构建一个obj文件

  3. 使用十六进制编辑器打开obj文件,找到代表nop的90
  4. 在Flash ocx中,定位nops之间的第一个字节字符串,并将其替换为nops之后的新字节字符串。这将把它从32位更改为64位函数调用。
我创建了以下汇编文件并使用 ml64.exe 进行构建。
TITLE: Print String Assembly Program (test.asm)

.Code
main Proc
nop 
nop 
nop 

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

nop 
nop 
nop 

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

main ENDP
END

我得到了这个要构建的对象,并使用十六进制编辑器打开它,成功找到了两个字节字符串。我在Flash OCX中找到了第一个字节字符串,并将其更改为第二个字节字符串。(实际上唯一的更改是字符串中的41变成了49)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接