NASMを使用してx86アセンブリでCOMオブジェクトを構築しています。私はCOMを非常によく理解しており、x86アセンブリをかなりよく理解していますが、2つをメッシュ化すると、ハングアップします...(ちなみに、x86アセンブリの使用を思いとどまらせることを考えている場合は、ご遠慮ください。これをx86アセンブリで構築するのには特別な理由があります!)
COMオブジェクトで使用するvtableを作成しようとしていますが、関数への実際のポインターではなく、奇妙なポインターを取得し続けています。(相対的なオフセットを取得しているか、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として出力され、これらはすべてアクセスできないメモリアドレスです。(情報提供の目的で、これらの値は毎回異なります)
Visual Studio 2010Expressを使用してC++で同じことを試してみましたが、すべてうまくいきました。だから私はそれが私のアセンブリに欠けているものだと思います...
これらの値が適切に出力されない理由を誰かが私に指摘できますか?