对LoadLibrary和GetModuleHandle的一些东西

从网上浏览到这个网页http://topic.okbase.net/201006/2010060410/3849330.html,从这里面发现几个知识点,特此整理:

主      题: 对于系统dll,LoadLibrary和GetModuleHandle效果是一样的?? 
作      者: Nospam 
回复次数: 1 
发表时间: 2010-6-4 10:29:21 
正文内容: 
    HINSTANCE hInst = LoadLibrary("Kernel32.dll"); 
    HINSTANCE hInst2=::GetModuleHandle("Kernel32.dll");

GetModuleHandle 还有个好处,不用FreeLibrary啥的
 
我分析这篇文的重点有两个,一是针对的系统DLL,在一个就是针对的loadllibray和getmodulehandle两个API函数。

首先说系统DLL,所谓的系统DLL,即是操作系统本身安装时自带的DLL文件,此类DLL与普通的DLL的区别主要在是由系统程序或服务调用的,当然这并不是说普通的用户程序不能调用系统DLL;就我个人理解而言,上面这位作者的本意应该是“对于已被系统服务或进程调用起来的系统DLL,LoadLibrary和GetModuleHandle效果是一样的”;

再说LoadLibrary和GetModuleHandle两个API,通过网络查询可以知道,LoadLibrary用来动态载入DLL文件,而GetModuleHandle则是用来得到指定模块的句柄,其实从这个两个API的定义就可以看出区别,LoadLibrary用来将一个普通的DLL文件载入到系统进程中,使之成为一个系统模块;而GetModuleHandle则是需要在DLL这个模块已经存在的情况下才能得到他的句柄;关于GetModuleHandle 的一些解释,从这个网页中即可看出 http://msdn.microsoft.com/en-us/library/windows/desktop/ms683199(v=vs.85).aspx,现摘录一下几个内容做为分析用:

Retrieves a module handle for the specified module. The module must have been loaded by the calling process.

意思是获得指定模块的模块句柄;此模块必须已经被调用进程载入; 这句话其实已经给出了提示,想获得一个已经被载入调用进程的模块的句柄。

对于GetModuleHandle有下面的说明:

This function must be used carefully in a multithreaded application. There is no guarantee that the module handle remains valid between the time this function returns the handle and the time it is used. For example, suppose that a thread retrieves a module handle, but before it uses the handle, a second thread frees the module. If the system loads another module, it could reuse the module handle that was recently freed. Therefore, the first thread would have a handle to a different module than the one intended.

重点就是说这个API在多线程下必须小心使用,因为他只是获得此模块的相关句柄,但并不会对此句柄的引用计数产生影响,相当于一个简单的get操作!

再回到上文作者提到的主题,按照我的理解,GetModuleHandle和LoadLibrary从本质上说不是一个原理,但是可以实现同样的效果,就是都能获得指定模块的句柄,但是区别还是很大的!


如果大家有什么意见,可以留言,将会非常感谢!


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
注入DLL通常需要在目标进程中创建一个远程线程,然后在远程线程中调用LoadLibrary函数加载DLL,最后调用DLL中的导出函数。以下是一个简单的C++注入DLL的示例代码: ``` #include <Windows.h> #include <TlHelp32.h> #include <iostream> int main() { // 获取目标进程的句柄 DWORD processId = 1234; // 目标进程ID HANDLE processHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processId); if (processHandle == NULL) { std::cout << "Failed to open process" << std::endl; return 1; } // 获取LoadLibrary函数的地址 LPVOID loadLibraryAddress = (LPVOID)GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA"); if (loadLibraryAddress == NULL) { std::cout << "Failed to get LoadLibrary address" << std::endl; return 1; } // 分配内存 LPVOID remoteMemory = VirtualAllocEx(processHandle, NULL, MAX_PATH, MEM_COMMIT, PAGE_READWRITE); if (remoteMemory == NULL) { std::cout << "Failed to allocate remote memory" << std::endl; return 1; } // 写入DLL路径到目标进程中 const char* dllPath = "C:\\path\\to\\your\\dll.dll"; if (!WriteProcessMemory(processHandle, remoteMemory, dllPath, strlen(dllPath) + 1, NULL)) { std::cout << "Failed to write DLL path to remote memory" << std::endl; return 1; } // 创建远程线程并调用LoadLibrary函数 HANDLE remoteThread = CreateRemoteThread(processHandle, NULL, 0, (LPTHREAD_START_ROUTINE)loadLibraryAddress, remoteMemory, 0, NULL); if (remoteThread == NULL) { std::cout << "Failed to create remote thread" << std::endl; return 1; } // 等待远程线程结束 WaitForSingleObject(remoteThread, INFINITE); // 获取导出函数地址并调用 const char* functionName = "YourExportFunction"; FARPROC functionAddress = GetProcAddress(GetModuleHandle("yourdll.dll"), functionName); if (functionAddress == NULL) { std::cout << "Failed to get function address" << std::endl; return 1; } // 调用导出函数 typedef int (*YourExportFunction)(); YourExportFunction yourFunction = (YourExportFunction)functionAddress; int result = yourFunction(); std::cout << "Result: " << result << std::endl; // 关闭句柄 CloseHandle(remoteThread); VirtualFreeEx(processHandle, remoteMemory, 0, MEM_RELEASE); CloseHandle(processHandle); return 0; } ``` 在上面的示例中,我们首先使用OpenProcess函数打开目标进程句柄,然后使用GetProcAddress函数获取LoadLibrary函数的地址。接下来,我们使用VirtualAllocEx函数在目标进程中分配内存,并使用WriteProcessMemory函数将DLL路径写入目标进程中。然后,我们使用CreateRemoteThread函数创建远程线程,并在远程线程中调用LoadLibrary函数来加载DLL。最后,我们使用GetProcAddress函数获取导出函数地址,并调用导出函数。 需要注意的是,在实际的注入过程中,你还需要处理一些异常情况,例如目标进程拥有较高的权限,或者DLL文件不存在等等。此外,在使用CreateRemoteThread函数创建远程线程时,你还需要指定一个适当的起始地址,并在远程线程中调用ExitThread函数结束远程线程。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值