一个不使用导入表的程序

来源:互联网 发布:icq聊天软件 编辑:程序博客网 时间:2024/06/05 23:30

 

一个不使用导入表的程序
 
作者:SunLine                lisunlin0@yahoo.com.cn 
日期:2008年5月
代码下载: http://download.csdn.net/user/lisunlin0
关键字: 重定位代码, 无导入表程序, exe without import table, relocable code
摘要:
让自己的程序既可以当EXE运行, 又可以作为Dll使用.
原理:
       win32是平坦内存模式的,此时相对地址的call指令可以寻址4G内存空间的。
实现:
在编写ShowImport工程的时候, 希望ShowImport程序既可以当EXE运行, 又可以作为Dll使用. 为了达到这个要求, 仔细比较了用LoadLibrary()函数加载一个.exe文件时与加载一个.dll的系统的不同动作. 终于完成了不使用导入表程序的模板.

       在VC/VS下,关闭“增量链接”选项后,程序内的有源文件的函数调用默认使用 call offset 指令编译。就是说:
[code=C/C++]int a(int n)
{
   return ++n;
}
int b(void)
{
   a(0);
   a(1);
}
void c(void){}[/code]
这样的代码本身就是相对地址的,可以将(LPBYTE)c - (LPBYTE)a之间的机器码拷贝到栈或堆里运行(栈内存本身具有page_execute属性,而堆不具有,需要指定可执行的属性)。
    小结一下,在关闭“增量链接”选项前提下,全局变量,win API必须重定位;库函数,不在同一个源文件中的函数调用可能需要重定位;同一文件中的函数调用,栈变量,函数参数都不需要重定位,而堆变量必须要有指针才能使用(指针本身也是变量),不存在重定位说法。
    重定位是汇编的强项,但在不考虑可移植性的前提下,c/c++也可以实现重定位,辅以少量的汇编,可以完成复杂的重定位工作。
    本人写的小程序ShowImport就是主要c/c++再辅以少量汇编的重定位程序,有兴趣可以看看。