void TestHookWndProc(__in Deviare2::INktSpyMgr *lpSpyMgr) { CComPtr<Deviare2::INktHook> cHook; HRESULT hRes; SIZE_T i, k, nCount2; typedef struct { DWORD dwProcId; LPVOID lpWndProc; } WND_INFO; TNktArrayList<WND_INFO> aWndInfoList; CComVariant cVt; BSTR bstr; WND_INFO sWndInfo; long lTemp, nFlags; for (i=0; i<sCmdLineParams.sWndProc.nCount; i++) { if (::IsWindow(sCmdLineParams.sWndProc.hWnds[i]) == FALSE) { wprintf_s(L"Error: Cannot find desired window.\n"); return; } ::GetWindowThreadProcessId(sCmdLineParams.sWndProc.hWnds[i], &(sWndInfo.dwProcId)); LogPrintNoTick(L"Window %lu => process id: %Iu\n", (SIZE_T)(sCmdLineParams.sWndProc.hWnds[i]), sWndInfo.dwProcId); if (sWndInfo.dwProcId == 0) { wprintf_s(L"Error: Cannot find desired window's process.\n"); return; } //lpWndProc = (LPVOID)::GetWindowLongPtr(hWnd, GWLP_WNDPROC); sWndInfo.lpWndProc = (LPVOID)::GetClassLongPtr(sCmdLineParams.sWndProc.hWnds[i], GCLP_WNDPROC); LogPrintNoTick(L"Window %Iu => WndProc: 0x%p\n", (SIZE_T)(sCmdLineParams.sWndProc.hWnds[i]), sWndInfo.lpWndProc); if (sWndInfo.lpWndProc == NULL) { wprintf_s(L"Error: Cannot retrieve WndProc address.\n"); return; } if (aWndInfoList.AddElement(sWndInfo) == FALSE) { err_nomem: wprintf_s(L"Error: Not enough memory.\n"); return; } } nFlags = (sCmdLineParams.bAsyncCallbacks != FALSE) ? Deviare2::flgAsyncCallbacks : 0; nFlags |= Deviare2::flgDontCheckAddress; for (i=0; i<sCmdLineParams.sWndProc.nCount; i++) { //create hook cHook.Release(); bstr = ::SysAllocString(L"DefWindowProcW"); if (bstr == NULL) goto err_nomem; hRes = lpSpyMgr->CreateHookForAddress((size_t)(aWndInfoList[i].lpWndProc), bstr, nFlags, &cHook); ::SysFreeString(bstr); LogPrintNoTick(L"CNktDvEngine::CreateHook (Window %Iu) => %08X\n", (SIZE_T)(sCmdLineParams.sWndProc.hWnds[i]), hRes); //add custom handlers lTemp = Deviare2::flgChDontCallIfLoaderLocked; if (sCmdLineParams.bCustomHandlerDebug != FALSE) lTemp |= Deviare2::flgChDisableExceptionChecks; nCount2 = sCmdLineParams.aCustomHandlers.GetCount(); for (k=0; k<nCount2 && SUCCEEDED(hRes); k++) { bstr = ::SysAllocString(sCmdLineParams.aCustomHandlers[k]); if (bstr == NULL) goto err_nomem; hRes = cHook->AddCustomHandler(bstr, lTemp, L""); ::SysFreeString(bstr); } //activate hooks if (SUCCEEDED(hRes)) { cVt = (LONG)(aWndInfoList[i].dwProcId); hRes = cHook->Attach(cVt, VARIANT_TRUE); if (SUCCEEDED(hRes)) hRes = cHook->Hook(VARIANT_TRUE); LogPrintNoTick(L"CNktDvHook::Hook (Window %Iu) => %08X\n", (SIZE_T)(sCmdLineParams.sWndProc.hWnds[i]), hRes); } } //wait for exit key while (IsExitKeyPressed() == FALSE) ::Sleep(100); return; }
void TestHookExecOrAttach(__in Deviare2::INktSpyMgr *lpSpyMgr) { CComPtr<Deviare2::INktProcess> cProc; CComPtr<Deviare2::INktHooksEnum> cHooksEnum; CComPtr<Deviare2::INktHook> cHook; TApiList aApiList; HRESULT hRes; CComVariant cVt, CVtContinueEv; BSTR bstr; SIZE_T i, k, nCount, nCount2; long lTemp, nFlags; if (LoadHooks(aApiList) == FALSE) return; //create hooks nFlags = (sCmdLineParams.bAsyncCallbacks != FALSE) ? Deviare2::flgAsyncCallbacks : 0; nFlags |= Deviare2::flgAutoHookChildProcess; //nFlags |= Deviare2::flgRestrictAutoHookToSameExecutable; nCount = aApiList.GetCount(); hRes = lpSpyMgr->CreateHooksCollection(&cHooksEnum); for (i=0; i<nCount && SUCCEEDED(hRes); i++) { cHook.Release(); cVt.bstrVal = ::SysAllocString(aApiList[i]); if (cVt.bstrVal == NULL) { err_nomem: LogPrintNoTick(L"Error: Not enough memory.\n"); return; } cVt.vt = VT_BSTR; hRes = lpSpyMgr->CreateHook(cVt, nFlags, &cHook); cVt.Clear(); //add custom handlers lTemp = Deviare2::flgChDontCallIfLoaderLocked; if (sCmdLineParams.bCustomHandlerDebug != FALSE) lTemp |= Deviare2::flgChDisableExceptionChecks; nCount2 = sCmdLineParams.aCustomHandlers.GetCount(); for (k=0; k<nCount2 && SUCCEEDED(hRes); k++) { bstr = ::SysAllocString(sCmdLineParams.aCustomHandlers[k]); if (bstr == NULL) goto err_nomem; hRes = cHook->AddCustomHandler(bstr, lTemp, L""); ::SysFreeString(bstr); } if (SUCCEEDED(hRes)) hRes = cHooksEnum->Add(cHook); LogPrintNoTick(L"CNktDvEngine::CreateHook (%s) => %08X\n", aApiList[i], hRes); } //load process if (sCmdLineParams.nTestType == ttTestHookExec && SUCCEEDED(hRes)) { bstr = ::SysAllocString((LPWSTR)(sCmdLineParams.sExec.cStrExeFileNameW)); if (bstr == NULL) goto err_nomem; hRes = lpSpyMgr->__CreateProcess(bstr, VARIANT_TRUE, &CVtContinueEv, &cProc); ::SysFreeString(bstr); LogPrintNoTick(L"CNktDvProcess::Create => %08X\n", hRes); } //attach hooks to process if (SUCCEEDED(hRes)) { switch (sCmdLineParams.nTestType) { case ttTestHookExec: if (sCmdLineParams.bBatchMode == FALSE) { nCount = (SUCCEEDED(cHooksEnum->get_Count(&lTemp))) ? (SIZE_T)(ULONG)lTemp : 0; for (i=0; i<nCount && SUCCEEDED(hRes); i++) { cHook.Release(); hRes = cHooksEnum->GetAt((LONG)i, &cHook); if (SUCCEEDED(hRes)) { cVt = cProc; hRes = cHook->Attach(cVt, VARIANT_TRUE); cVt.Clear(); } LogPrintNoTick(L"CNktDvHook::AddProcess (%s) => %08X\n", aApiList[i], hRes); } } else { cVt = cProc; hRes = cHooksEnum->Attach(cVt, VARIANT_TRUE); cVt.Clear(); LogPrintNoTick(L"CNktDvHooksEnumerator::AddProcess => %08X\n", hRes); } break; case ttTestHookAttach: //attach to running processes for (k=0; k<sCmdLineParams.sAttach.nCount && SUCCEEDED(hRes); k++) { cProc.Release(); hRes = lpSpyMgr->ProcessFromPID((long)(sCmdLineParams.sAttach.dwPids[k]), &cProc); LogPrintNoTick(L"CNktDvProcess::CreateFromPID (%lu) => %08X\n", sCmdLineParams.sAttach.dwPids[k], hRes); if (SUCCEEDED(hRes)) { if (sCmdLineParams.bBatchMode == FALSE) { nCount = (SUCCEEDED(cHooksEnum->get_Count(&lTemp))) ? (SIZE_T)(ULONG)lTemp : 0; for (i=0; i<nCount && SUCCEEDED(hRes); i++) { cHook.Release(); hRes = cHooksEnum->GetAt((LONG)i, &cHook); if (SUCCEEDED(hRes)) { cVt = cProc; hRes = cHook->Attach(cVt, VARIANT_TRUE); cVt.Clear(); } LogPrintNoTick(L"CNktDvHook::AddProcess (%s) => %08X\n", aApiList[i], hRes); } } else { cVt = cProc; hRes = cHooksEnum->Attach(cVt, VARIANT_TRUE); cVt.Clear(); LogPrintNoTick(L"CNktDvHooksEnumerator::AddProcess => %08X\n", hRes); } } } break; } } //activate hooks if (SUCCEEDED(hRes)) { if (sCmdLineParams.bBatchMode == FALSE) { nCount = (SUCCEEDED(cHooksEnum->get_Count(&lTemp))) ? (SIZE_T)(ULONG)lTemp : 0; for (i=0; i<nCount && SUCCEEDED(hRes); i++) { cHook.Release(); hRes = cHooksEnum->GetAt((LONG)i, &cHook); if (SUCCEEDED(hRes)) hRes = cHook->Hook(VARIANT_TRUE); LogPrintNoTick(L"CNktDvHook::Hook (%s) => %08X\n", aApiList[i], hRes); } } else { hRes = cHooksEnum->Hook(VARIANT_TRUE); LogPrintNoTick(L"CNktDvHooksEnumerator::Hook => %08X\n", hRes); } } //continue process if (sCmdLineParams.nTestType == ttTestHookExec && CVtContinueEv.vt != VT_EMPTY) { hRes = lpSpyMgr->ResumeProcess(cProc, CVtContinueEv); } //wait for exit key while (IsExitKeyPressed() == FALSE) ::Sleep(100); return; }