全面建设x86汇编COM对象虚函数表 [英] Building a COM object vtable in x86 assembly

查看:230
本文介绍了全面建设x86汇编COM对象虚函数表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用NASM建立一个COM对象x86汇编。我理解COM得很好,我理解x86汇编pretty很好,但得到两目是让我挂了......(顺便说一下,如果你想尝试使用x86汇编劝阻我,请不要,我有我为什么在x86汇编建设这个非常特殊的原因!)

I am building a COM object in x86 assembly using NASM. I understand COM quite well and I understand x86 assembly pretty well, but getting the two to mesh is getting me hung up... (by the way, if you're thinking of attempting to dissuade me from using x86 assembly, please refrain, I have very particular reasons why I'm building this in x86 assembly!)

我想建立一个虚函数表在我的COM对象使用,但我不断收到陌生的指针,而非实际指向我的功能。 (我在想,我得到相对偏移量或NASM中嵌入有临时的价值观和他们没有正在与实际值在连接时替换)

I am trying to build a vtable to use in my COM object, but I keep getting strange pointers, rather than actual pointers to my functions. (I'm thinking that I'm getting relative offsets or that NASM is embedding temporary values in there and they're not being replaced with the real values during linking)

目前的界面,我试图建立的是的IClassFactory 界面,用code如下:

The current interface I'm trying to build is the IClassFactory interface, with code as follows:

%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

注意:这是不是所有的code,我有则DllGetClassObject,DllMain中,等在不同的文件

Note: This is not all of the code, I have DllGetClassObject, DllMain, etc. in a different file.

但是,当我组装(NASM使用: NASM -f win32的comobject.asm )和连接(使用MS链接:链接/ DLL /子系统:窗户/out:comobject.dll comobject.obj ),并检查使用OllyDbg的可执行文件,虚函数表出来奇怪值。例如,在我的最后一个版本,是函数的实际地址如下:

But when I assemble (using NASM: nasm -f win32 comobject.asm) and link (using MS Link: link /dll /subsystem:windows /out:comobject.dll comobject.obj), and examine the executable using OllyDbg, the vtable comes out with strange values. For example, in my last build, the actual addresses for the functions are as follows:


  • 的QueryInterface - 0x00381012

  • 的AddRef - 0x0038101A

  • 发布 - 0x00381020

  • 的CreateInstance - 0x00381026

  • LockServer - 0x0038102E

但虚函数表出来使用这些值:

But the vtable came out with these values:


  • 的QueryInterface - 0x00F51012

  • 的AddRef - 0x00F5101A

  • 发布 - 0x00F51020

  • 的CreateInstance - 0x00F51026

  • LockServer - 0x00F5102E

这些值气色好可疑......几乎像搬迁没拿。另外,虚表出来作为0x00F5104A,所有这些都是不可访问的存储器地址。 (参考,这些值出来不同的每次的)

These values look awfully suspicious... almost like the relocation didn't take. Also, the vtable comes out as 0x00F5104A, all of which are inaccessible memory addresses. (for informational purposes, these values come out different every time)

我尝试使用Visual Studio 2010的前preSS做同样的事情在C ++中,一切都出来罚款。所以我假定这只是东西,我错过了我的组装...

I tried doing the same thing in C++ using Visual Studio 2010 Express and everything comes out fine. So I'm assuming that it's just something that I'm missing in my assembly...



任何人都可以点出我为什么这些值不出来正常吗?


Can anyone point out to me why these values aren't coming out properly?

推荐答案

我必须道歉,这个问题竟然是我自己的错......在所有的扭打的建设的事情,我已经删除了 / DLL ,使其建设成为一个EXE,而不是一个DLL ...

I must apologize, the problem turned out to be my own fault... In all of the scuffle building the thing, I had removed the /dll from the linker invocation, causing it to be built as an EXE, not a DLL...



让我来解释谁碰到这个运行旁边的人这个好一点。


Let me explain this a little better for the next person who runs across this.

所有的Windows可执行文件都被认为是虚拟地址的可执行文件,一个基址将被装入。被加载到运行的进程在大多数情况下,可执行将不会在加载preferred基址,因为另一个DLL(或应用程序本身)可能已经占用的地址。为此,Windows PE的可执行程序使用一种被称为定位表。该定位表告诉Windows这在执行需要的位置,以便在拆迁时被重写为新基址

All Windows executables have a base address which is assumed to be the virtual address that the executable will be loaded into. Executables that are loaded into a running process in most cases will not be loaded at the "preferred" base address, because another DLL (or the application itself) is probably already occupying the address. For this reason, Windows PE executables use what is called a Relocation Table. The Relocation Table tells Windows which locations in the executable need to be rewritten in case of a relocation to a new base address.

然而,随着虚拟内存的来临,大多数的连接器会忽略从EXE文件重定位表作为优化,因为可执行将总是在它的基地址被加载(除非它与保留的内核的地址,在这种情况下,将无法加载全一起冲突)。所以,因为我停下编译为一个DLL,我的可执行文件没有被赋予了定位表并作为因此,将无法正确加载投入运行进程的地址空间。

However, with the advent of Virtual Memory, most linkers will omit the relocation table from EXEs as an optimization, because the executable will always be loaded at it's base address (unless it conflicts with the reserved kernel addresses, in which case it will fail to load all-together). So because I stopped compiling as a DLL, my executable was not being given a Relocation Table and as a result, would not load properly into running process' address space.

更新:

在默认情况下,只MSVC包括DLL项目搬迁的表,如所描述的 MSDN上

By default, MSVC only includes relocation tables in DLL projects, as described on MSDN:

By default, /FIXED:NO is the default when building a DLL, and /FIXED is the default for any other project type.

NO 切换到链接:

这行为可以通过提供 / FIXED来改变。非DLL项目默认为 / FIXED 告诉链接器,目标有一个固定的基地址和不需要重定位表。

This behavior can be changed by supplying the /FIXED:NO switch to the linker. The default for non-DLL projects is /FIXED which tells the linker that the target has a fixed base address and does not require a relocation table.

这篇关于全面建设x86汇编COM对象虚函数表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆