前言
生成exe后如果我们想要把它改成dll然后调用里面的函数的话,我们需要改掉PE头里的Characteristics属性,表明这是一个dll,然后改掉可选头里的入口点属性,让它在被LoadLibrary函数加载到内存的时候不去找DllMain函数,然后添加一个节区,把数据目录表中重定位表的RVA填上,然后手动构造重定位信息,然后再把各个size的统计信息给填上,就ojbk了,至于导出表,没有啥必要去构建,直接通过加载基址加偏移,调用就完事了。
正文
首先看下面的例子,编译成exe 测试的时候在项目属性->链接器->高级中关闭随机基址
#include#includevoid fuck(){ MessageBoxA(0,0,0,0);}int main(){ fuck(); return 0;}
这里fuck函数中需要重定位的只有调用MessageBoxA这里
PE头Characteristics属性
首先如图所示,把PE文件头里的Characteristics改为0x2102,表示这是一个dll文件
扩展PE头的AddressOfEntryPoint属性
如图所示把这个属性改为0x00表示没有入口点,这样在dll加载的时候就只是加载dll,不会去执行dll里的代码
构建重定位信息
首先如图用addpebbytes这个工具增加一个区段
然后添加若干字节
然后可以看到最后一个区段的RVA是0x5000
如图所示我们在数据目录表里的重定位这一项里把RVA改成0x5000 这样就可以在最后一个节起始的位置构造重定位信息了,至于size属性,我们构造好了重定位信息再回来填上
这里我们第一个四字节填入基地址,我们fuck函数的起始RVA就是0x1000,然后后面一个四字节是这一个重定位表的大小,四字节加四字节加后面的一个word类型的typeoffset就是10字节,最后一个word类型的成员包括4位的类型,这里是0x3,和一个12位的偏移,这里如下图数一下是8+2=10
填好以后回去把数据目录表里的重定位项的size属性给填上,是0xA 如此填好,就可以实现链接了 新建一个工程,把改好的dll放进工程目录
#include#includeint main(){ HANDLE h=LoadLibrary(L"test.dll"); ((void(*)())((char*)h+0x1000))(); return 0;}