日期:2014-05-16  浏览次数:21362 次

windows系统静态链接具体原理(涉及 PE)在线等
void main()
{
CreateFile();
}
CreateFILE放在KERNAL32.DLL中

我的观点:
1、从KERNAL32.DLL中找到CreateFile直接编译进去,Kernal32.dll不加载进去虚拟地址空间
2.加载CREATEFILE是怎么进行的啊?还是查IAT

------解决方案--------------------
PE加载的时候,为将动态链接库函数的地址放入IAT中。
然后 call 地址。
     jmp  API地址
------解决方案--------------------
静态链接:在编译时链接进你的可执行文件中。(比如静态链接的函数,会加进你的可执行文件)
动态链接:在运行时通过你编译的可执行文件的信息获得所需要的动态链接库,由加载器将动态链接库映射到你的进程间,并将你调用的动态链接库中的函数地址,写入你的可执行文件中的相应的导入表中。
比如:你的代码中有:MessageBoxA(0, 0, 0, 0);编译后的汇编代码为:
push 0
push 0
push 0
push 0
call dword ptr [__imp__MessageBoxA];
你并不知道MessageBoxA这个函数的地址。
__imp__MessageBoxA 这个符号的地址,就在导入表中,加载器会把这个地址修改为直正的MessageBoxA这个函数的地址。从而正确跳到MessageBoxA这个函数中。

------解决方案--------------------
1、不是直接编译进去的,这特定的方法貌似是动态链接的,我没见过kernel静态链接库
2、在构建可执行文件的链接阶段,链接程序将kernel32.lib里的相关内容整合到可执行文件中,而这部分内容也就是CreateFile这个方法的修饰名及其在kernel32.dll里的地址偏移值,同时kernel32.dll的信息也会添加到PE文件的导入表。程序运行时用到CreateFile方法时,发现该方法对应的地址无效(因为kernel32.dll尚未加载到进程地址空间),就查找导入表,知道该地址对应的函数是在kernel32.dll里,便去加载这个dll(由于windows系统中kernel32.dll对于所有的应用程序都是可共享的,所以直接将物理内存中共享的这个kernel32.dll映射到进程地址空间的特定位置,从而不必再从磁盘加载,大大提高了速度)。之后就能正常运行了
------解决方案--------------------
1、从KERNAL32.DLL中找到CreateFile直接编译进去,Kernal32.dll不加载进去虚拟地址空间
不会将CreateFile()编译进去的,这个和静态链接不一样。调用CreateFile函数的程序中留了导入信息。

2.加载CREATEFILE是怎么进行的啊?还是查IAT
是的,还是查IAT