有没有人能读一下这个,纠正我的错误/回答我的问题?这是我到目前为止的理解:
在编译时已知的导入,当可执行文件被加载到内存中时被加载到内存中。指向这些函数的指针存储在导入地址表中,当一个进程想要调用一个函数时,它必须从导入地址表中检索指针(我理解IAT,INT,H/N表等之间的关系)。
当一个函数在运行时被LoadLibrary
和GetProcAddress()
加载时,动态链接器会获取一个指针;例如,当一个进程调用MessageBoxA时,操作系统加载器会将DLL Kernel 32加载到内存中,并返回一个指向这个特定函数的指针。
- 据我所知,操作系统加载的第一个库根据定义是ntdll.dll,第二个是更抽象的 Package 器Kernel32.dll。我想知道的是..当一个进程在运行时调用MessageBoxA或MessageFileA时,DLL不需要加载到内存中对吗?因为这些函数是已经加载的库的一部分,即Kernel 32。
- 动态链接器是否将指向动态加载函数的指针存储在某种缓存中或..?据我所知,它不会更新导入地址表,那么当进程再次调用函数时会发生什么,它是否需要再次调用
GetProcAddress
来解析虚拟地址,或者是否有更有效的方法? - 当我想挂接动态加载的函数时,我是否需要在运行时挂接
GetProcAddress
,并使用shim函数的跳转指令更改返回指针(并存储原始函数指针,以便之后使用原始参数调用原始函数/)。
1条答案
按热度按时间hof1towb1#
当一个进程想要调用一个函数时,它必须从导入地址表中检索指针。
这听起来有点麻烦,但确实如此:对导入函数的调用被编译为对IAT的调用,其中有一个JMP [Address]指令,当库加载时,该指令会与实际函数地址进行修补。
当一个函数在运行时通过LoadLibrary和GetProcAddress()加载时,动态链接器会检索一个指针;例如,当一个进程调用MessageBoxA时,操作系统加载器会在内存中加载DLL Kernel 32,并返回一个指向该特定函数的指针。
LoadLibrary
将dll加载到内存中。GetProcAddress
返回一个指向特定导出函数的指针。不是上面的存根,而是模块中实际函数的地址。当一个进程在运行时调用MessageBoxA或MessageFileA时,DLL不需要加载到内存中,对吗?
MessageBoxA
实际上驻留在user32.dll中,但对于KERNELFileA,您是正确的,kernel32.dll已经加载。动态链接器是否将指向动态加载函数的指针存储在某种缓存中或..?
加载模块的地址记录在内核对象中。据我所知,单个函数的地址不会被缓存。
据我所知,它不会更新导入地址表,那么当进程再次调用该函数时会发生什么,它是否需要再次调用GetProcAddress来解析虚拟地址,或者是否有更有效的方法?
通常情况下,如果需要多次使用
GetProcAddress
,您可以将其返回的内容存储在变量中。当我想挂接动态加载的函数时,我是否需要在运行时挂接GetProcAddress,并使用跳转指令更改返回指针到我挂接的函数(并存储原始函数指针,以便之后使用原始参数调用原始函数/)。
是的,没错。