我正在使用 NASM 在 x86 程序集中构建一个 COM 对象。我非常了解 COM,我也非常了解 x86 程序集,但是让两者相互融合让我挂断了……(顺便说一句,如果你想劝阻我不要使用 x86 程序集,请不要,我有非常特殊的原因为什么要在 x86 程序集中构建它!)
我正在尝试构建一个 vtable 以在我的 COM 对象中使用,但我不断收到奇怪的指针,而不是指向我的函数的实际指针。(我在想我得到了相对偏移量,或者 NASM 在其中嵌入了临时值,并且在链接期间它们没有被实际值替换)
我目前正在尝试构建的接口是IClassFactory
接口,代码如下:
%define S_OK 0x00000000
%define E_NOINTERFACE 0x80004002
section .text
; All of these have very simple shells rather than implementations, but that is just until I can get the vtable worked out
ClassFactory_QueryInterface:
mov eax, E_NOINTERFACE
retn 12
ClassFactory_AddRef:
mov eax, 1
retn 4
ClassFactory_Release:
mov eax, 1
retn 4
ClassFactory_CreateInstance:
mov eax, E_NOINTERFACE
retn 16
ClassFactory_LockServer:
mov eax, S_OK
retn 8
global ClassFactory_vtable
ClassFactory_vtable dd ClassFactory_QueryInterface, ClassFactory_AddRef, ClassFactory_Release, ClassFactory_CreateInstance, ClassFactory_LockServer
global ClassFactory_object
ClassFactory_object dd ClassFactory_vtable
注意:这不是所有代码,我在不同的文件中有 DllGetClassObject、DllMain 等。
但是当我组装(使用 NASM: nasm -f win32 comobject.asm
)和链接(使用 MS Link: link /dll /subsystem:windows /out:comobject.dll comobject.obj
),并使用 OllyDbg 检查可执行文件时,vtable 会出现奇怪的值。例如,在我上次构建中,函数的实际地址如下:
- 查询接口 - 0x00381012
- AddRef - 0x0038101A
- 发布 - 0x00381020
- 创建实例 - 0x00381026
- LockServer - 0x0038102E
但是 vtable 有这些值:
- 查询接口 - 0x00F51012
- AddRef - 0x00F5101A
- 发布 - 0x00F51020
- 创建实例 - 0x00F51026
- 锁定服务器 - 0x00F5102E
这些值看起来非常可疑......几乎就像搬迁没有采取一样。此外,vtable 显示为 0x00F5104A,所有这些都是不可访问的内存地址。(出于信息目的,这些值每次都不同)
我尝试使用 Visual Studio 2010 Express 在 C++ 中做同样的事情,一切都很好。所以我假设这只是我在装配中缺少的东西......
谁能向我指出为什么这些值没有正确显示?