C++ 實現 , 獲取指定模塊在該進程中的基址
1、流程:
獲取進程的所有模塊信息–>遍歷模塊列表
2、實現:
// 我自己定義的
typedef struct moudle_date_ {HANDLE mhandle; // 句柄char mname[64]; // 名稱char* date; // 數據DWORD mdword; // 基址
}moudle_date;// 傳入該進程的 pid 、需要查找模塊的名稱
moudle_date* getMoudle(DWORD pid, const char* name) {moudle_date* date = nullptr;/*CreateToolhelp32Snapshot()->獲取指定進程以及這些進程使用的堆、模塊和線程的快照。TH32CS_SNAPALL -> 包括系統中的所有進程和線程,以及 pid 中指定的進程的堆和模塊。return value : 如果函數成功,它將返回指定快照的打開句柄。如果函數失敗,它將返回 INVALID_HANDLE_VALUE*/HANDLE handle = CreateToolhelp32Snapshot( TH32CS_SNAPALL, pid );std::cout << "getMoudle::handle :" << std::hex<<handle << std::endl;if ( handle == INVALID_HANDLE_VALUE) {std::cout << "Error CreateToolhelp32Snapshot" << std::endl;return nullptr;}/*MODULEENTRY32:Windows API 中定義的一個結構體,用于存儲模塊的信息。*/MODULEENTRY32 info;memset(&info, 0, sizeof(info));// dwSize 結構體的大小,一定要設置,為 Module32First、Module32Next做準備info.dwSize = sizeof(MODULEENTRY32);char sname[256];strcpy_s(sname, sizeof(sname) , name);/*循環遍歷模塊 ,找到基址Module32First() : 檢索與進程關聯的第一個模塊的相關信息。傳入參數: CreateToolhelp32Snapshot返回的進程句柄、info(MODULEENTRY32)返回值 : bool類型,成功返回true. 失敗返回false.*/bool ret = Module32First( handle, &info);if (!ret) {/*GetLastError(): 獲取錯誤代碼.返回類型 DWORD.*/DWORD err = GetLastError();std::cout << "getMoudle::GetLastError : "<<err << std::endl;return nullptr;}while ( ret ) {// szModule -> 模塊的名稱// 注意: szModule的類型是 wchar_t 寬字節// 我們傳入的模塊名稱 類型是 char ,所以需要進行類型轉換,才能夠比較if ( strcmp( UnicodeToUtf8(info.szModule) , sname)== 0 ) {date = new moudle_date;// modBaseAddr ->MODULEENTRY32結構體中的成員,模塊的基址date->mdword = (DWORD)info.modBaseAddr;CloseHandle(handle); // 清理資源return date;}/*Module32Next(): 獲取下一個模塊的信息*/ret = Module32Next( handle, &info);}return nullptr;
}
補充:UnicodeToUtf8 -> 如何將寬字符字符串轉換為 UTF-8 編碼的字符串UnicodeToUtf8
這些你可以不需要知道怎么實現的,直接拿來用就好了,沒有人會去記這些東西。
char* UnicodeToUtf8(const wchar_t* lpszStr)
{char* lpUtf8;int nLen;if (NULL == lpszStr)return NULL;nLen = ::WideCharToMultiByte(CP_UTF8, 0, lpszStr, -1, NULL, 0, NULL, NULL);if (0 == nLen)return NULL;lpUtf8 = new char[nLen + 1];if (NULL == lpUtf8)return NULL;memset(lpUtf8, 0, nLen + 1);nLen = ::WideCharToMultiByte(CP_UTF8, 0, lpszStr, -1, lpUtf8, nLen, NULL, NULL);if (0 == nLen){delete[]lpUtf8;return NULL;}return lpUtf8;
}
希望對你有所幫助