void CAPIHook::FixupNewlyLoadedModule(HMODULE hmod, DWORD dwFlags) { // If a new module is loaded, hook the hooked functions if ((hmod != NULL) && // Do not hook our own module (hmod != ModuleFromAddress(FixupNewlyLoadedModule)) && ((dwFlags & LOAD_LIBRARY_AS_DATAFILE) == 0) && ((dwFlags & LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE) == 0) && ((dwFlags & LOAD_LIBRARY_AS_IMAGE_RESOURCE) == 0) ) { for (CAPIHook* p = sm_pHead; p != NULL; p = p->m_pNext) { if (p->m_pfnOrig != NULL) { ReplaceIATEntryInAllMods(p->m_pszCalleeModName, p->m_pfnOrig, p->m_pfnHook); } else { #ifdef _DEBUG // We should never end up here wchar_t szPathname[MAX_PATH]; GetModuleFileNameW(NULL, szPathname, _countof(szPathname)); wchar_t sz[1024]; StringCchPrintfW(sz, _countof(sz), TEXT("[%4u - %s] impossible to find %S\r\n"), GetCurrentProcessId(), szPathname, p->m_pszCalleeModName); OutputDebugString(sz); #endif } } } }
CAPIHook::~CAPIHook() { // 取消对所有模块中函数的HOOK ReplaceIATEntryInAllMods(m_pszModName, m_pfnHook, m_pfnOrig, m_bExcludeAPIHookMod); CAPIHook *p = sm_pHeader; // 从链表中移除此对象 if (p == this) { sm_pHeader = p->m_pNext; } else { while (p != NULL) { if (p->m_pNext == this) { p->m_pNext = this->m_pNext; break; } p = p->m_pNext; } } }
// コンストラクタ CAPIHook::CAPIHook( PSTR pszModuleName, PSTR pszFuncName, PROC pfnHook) { m_pNext = sm_pHead; // 次のノードのアドレスを代入 sm_pHead = this; // このノードのアドレスを代入 // オリジナル関数のアドレスを取得 PROC pfnOrig = ::GetProcAddress( GetModuleHandleA(pszModuleName), pszFuncName); // フックに関するデータを保存 m_pszModuleName = pszModuleName; m_pszFuncName = pszFuncName; m_pfnOrig = pfnOrig; m_pfnHook = pfnHook; // プロセスIDが0ならDLLをマッピングする最初のプロセスと判断 // そのプロセスIDを共有メモリに保存 //if(g_dwCurrentProcessId == 0) // g_dwCurrentProcessId = GetCurrentProcessId(); // 起動元と同じプロセスならフックを行わない //if(g_dwCurrentProcessId != GetCurrentProcessId()) ReplaceIATEntryInAllMods(m_pszModuleName, m_pfnOrig, m_pfnHook); }
void APIHook(PCSTR pszModuleName, PCSTR pszFuncName, PROC pfnReplace, PROC* ppfnOrig) { PROC pfnOrig = ::GetProcAddress(GetModuleHandleA(pszModuleName), pszFuncName); if (pfnOrig == NULL) return; ReplaceIATEntryInAllMods( pszModuleName, pfnOrig, pfnReplace); *ppfnOrig = pfnOrig; }
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { PROC pfnOrig; pfnOrig = ::GetProcAddress( GetModuleHandleA("user32.dll"), "MessageBoxA"); ReplaceIATEntryInAllMods( "user32.dll", pfnOrig, (PROC)Hook_MessageBoxA); pfnOrig = ::GetProcAddress( GetModuleHandleA("user32.dll"), "MessageBoxW"); ReplaceIATEntryInAllMods( "user32.dll", pfnOrig, (PROC)Hook_MessageBoxW); MessageBox(GetActiveWindow(), _T("メッセージボックス表示のテスト"), _T("テスト"), MB_OK); return 0; }
CAPIHook::CAPIHook(LPSTR pszModName, LPSTR pszFuncName, PROC pfnHook, BOOL bExcludeAPIHookMod) { // 保存这个Hook函数的信息 m_bExcludeAPIHookMod = bExcludeAPIHookMod; m_pszModName = pszModName; m_pszFuncName = pszFuncName; m_pfnHook = pfnHook; m_pfnOrig = ::GetProcAddress(::GetModuleHandle(pszModName), pszFuncName); // 将此对象添加到链表中 m_pNext = sm_pHeader; sm_pHeader = this; // 在所有当前已加载的模块中HOOK这个函数 ReplaceIATEntryInAllMods(m_pszModName, m_pfnOrig, m_pfnHook, bExcludeAPIHookMod); }
CAPIHook::~CAPIHook() { // Unhook this function from all modules ReplaceIATEntryInAllMods(m_pszCalleeModName, m_pfnHook, m_pfnOrig); // Remove this object from the linked list CAPIHook* p = sm_pHead; if (p == this) { // Removing the head node sm_pHead = p->m_pNext; } else { BOOL bFound = FALSE; // Walk list from head and fix pointers for (; !bFound && (p->m_pNext != NULL); p = p->m_pNext) { if (p->m_pNext == this) { // Make the node that points to us point to our next node p->m_pNext = p->m_pNext->m_pNext; bFound = TRUE; } } } }
// デストラクタ CAPIHook::~CAPIHook() { // 起動元と同じプロセスなら解除の必要なし //if(g_dwCurrentProcessId != GetCurrentProcessId()) ReplaceIATEntryInAllMods(m_pszModuleName, m_pfnHook, m_pfnOrig); // ノードのトップを取得 CAPIHook *p = sm_pHead; // ノードのトップが自分ならば、次のノードをトップに据えて終了 if(p == this) { sm_pHead = p->m_pNext; return; } // もし自分ではないならば、ノードの中から検索して // 自分を連結から外す while(p->m_pNext != NULL) { if (p->m_pNext == this) { p->m_pNext = p->m_pNext->m_pNext; break; } p = p->m_pNext; } }
CAPIHook::CAPIHook(PSTR pszCalleeModName, PSTR pszFuncName, PROC pfnHook) { // Note: the function can be hooked only if the exporting module // is already loaded. A solution could be to store the function // name as a member; then, in the hooked LoadLibrary* handlers, parse // the list of CAPIHook instances, check if pszCalleeModName // is the name of the loaded module to hook its export table and // re-hook the import tables of all loaded modules. m_pNext = sm_pHead; // The next node was at the head sm_pHead = this; // This node is now at the head // Save information about this hooked function m_pszCalleeModName = pszCalleeModName; m_pszFuncName = pszFuncName; m_pfnHook = pfnHook; m_pfnOrig = GetProcAddressRaw(GetModuleHandleA(pszCalleeModName), m_pszFuncName); // If function does not exit,... bye bye // This happens when the module is not already loaded if (m_pfnOrig == NULL) { wchar_t szPathname[MAX_PATH]; GetModuleFileNameW(NULL, szPathname, _countof(szPathname)); wchar_t sz[1024]; StringCchPrintfW(sz, _countof(sz), TEXT("[%4u - %s] impossible to find %S\r\n"), GetCurrentProcessId(), szPathname, pszFuncName); OutputDebugString(sz); return; } #ifdef _DEBUG // This section was used for debugging sessions when Explorer died as // a folder content was requested // //static BOOL s_bFirstTime = TRUE; //if (s_bFirstTime) //{ // s_bFirstTime = FALSE; // wchar_t szPathname[MAX_PATH]; // GetModuleFileNameW(NULL, szPathname, _countof(szPathname)); // wchar_t* pszExeFile = wcsrchr(szPathname, L'\\') + 1; // OutputDebugStringW(L"Injected in "); // OutputDebugStringW(pszExeFile); // if (_wcsicmp(pszExeFile, L"Explorer.EXE") == 0) // { // DebugBreak(); // } // OutputDebugStringW(L"\n --> "); // StringCchPrintfW(szPathname, _countof(szPathname), L"%S", pszFuncName); // OutputDebugStringW(szPathname); // OutputDebugStringW(L"\n"); //} #endif // Hook this function in all currently loaded modules ReplaceIATEntryInAllMods(m_pszCalleeModName, m_pfnOrig, m_pfnHook); }