Я строю COM-объект в сборке x86, используя NASM. Я достаточно хорошо понимаю 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 выходит со странными значениями. Например, в моей последней сборке фактические адреса для функций были следующими:
- QueryInterface - 0x00381012
- AddRef - 0x0038101A
- Релиз - 0x00381020
- CreateInstance - 0x00381026
- LockServer - 0x0038102E
Но vtable вышел со следующими значениями:
- QueryInterface - 0x00F51012
- AddRef - 0x00F5101A
- Релиз - 0x00F51020
- CreateInstance - 0x00F51026
- LockServer - 0x00F5102E
Эти значения выглядят ужасно подозрительно ... почти так же, как и перемещение. Кроме того, vtable выходит как 0x00F5104A, все из которых являются адресами недоступной памяти. ( в информационных целях, эти значения каждый раз различаются )
Я попытался сделать то же самое в C ++, используя Visual Studio 2010 Express, и все получилось хорошо. Поэтому я предполагаю, что это просто то, чего мне не хватает в моей сборке ...
Может кто-нибудь указать мне, почему эти значения не выходят должным образом?