📄 win9xconhook.c
字号:
return 0; } while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } /* Tag again as deleted, just in case we missed WM_DESTROY */ monitor_hwnd = NULL; return 0;}/* This is the WndProc procedure for our invisible window. * When our subclasssed tty window receives the WM_CLOSE, WM_ENDSESSION, * or WM_QUERYENDSESSION messages, the message is dispatched to our hidden * window (this message process), and we call the installed HandlerRoutine * that was registered by the app. */static LRESULT CALLBACK ttyConsoleCtrlWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){ if (msg == WM_CREATE) { tty_info *tty = (tty_info*)(((LPCREATESTRUCT)lParam)->lpCreateParams); SetWindowLong(hwnd, gwltty_phandler, (LONG)tty->phandler); SetWindowLong(hwnd, gwltty_ttywnd, (LONG)tty->parent);#ifdef DBG DbgPrintf("A proc %8.8x created %8.8x %s for tty wnd %8.8x\r\n", GetCurrentProcessId(), hwnd, tty->name, tty->parent);#endif if (tty->parent) { SetProp(tty->parent, hookwndprop, hwnd); PostMessage(tty->parent, hookwndmsg, tty->type, (LPARAM)tty->parent); } return 0; } else if (msg == WM_DESTROY) { HWND parent = (HWND)GetWindowLong(hwnd, gwltty_ttywnd);#ifdef DBG DbgPrintf("A proc %8.8x destroyed %8.8x ttyConHookChild\r\n", GetCurrentProcessId(), hwnd);#endif if (parent) { RemoveProp(parent, hookwndprop); SendMessage(parent, hookwndmsg, 0, (LPARAM)parent); } monitor_hwnd = NULL; } else if (msg == WM_CLOSE) { PHANDLER_ROUTINE phandler = (PHANDLER_ROUTINE)GetWindowLong(hwnd, gwltty_phandler); LRESULT rv = phandler(CTRL_CLOSE_EVENT);#ifdef DBG DbgPrintf("A proc %8.8x invoked CTRL_CLOSE_EVENT " "returning %d\r\n", GetCurrentProcessId(), rv);#endif if (rv) return !rv; } else if ((msg == WM_QUERYENDSESSION) || (msg == WM_ENDSESSION)) { if (lParam & ENDSESSION_LOGOFF) { PHANDLER_ROUTINE phandler = (PHANDLER_ROUTINE)GetWindowLong(hwnd, gwltty_phandler); LRESULT rv = phandler(CTRL_LOGOFF_EVENT);#ifdef DBG DbgPrintf("A proc %8.8x invoked CTRL_LOGOFF_EVENT " "returning %d\r\n", GetCurrentProcessId(), rv);#endif if (rv) return ((msg == WM_QUERYENDSESSION) ? rv : !rv); } else { PHANDLER_ROUTINE phandler = (PHANDLER_ROUTINE)GetWindowLong(hwnd, gwltty_phandler); LRESULT rv = phandler(CTRL_SHUTDOWN_EVENT);#ifdef DBG DbgPrintf("A proc %8.8x invoked CTRL_SHUTDOWN_EVENT " "returning %d\r\n", GetCurrentProcessId(), rv);#endif if (rv) return ((msg == WM_QUERYENDSESSION) ? rv : !rv); } } return (DefWindowProc(hwnd, msg, wParam, lParam));}/* The following internal helpers are invoked by the hooked tty and our app */ /* Register or deregister the current process as a Windows9x style service. * Experience shows this call is ignored across processes, so the second * arg to RegisterServiceProcess (process group id) is effectively useless. */static LRESULT WINAPI RegisterWindows9xService(BOOL set_service){ static HINSTANCE hkernel; static DWORD (WINAPI *register_service_process)(DWORD, DWORD) = NULL; BOOL rv; if (set_service == is_service) return 1;#ifdef DBG DbgPrintf("R %s proc %8.8x as a service\r\n", set_service ? "installing" : "removing", GetCurrentProcessId());#endif if (!register_service_process) { /* Obtain a handle to the kernel library */ hkernel = LoadLibrary("KERNEL32.DLL"); if (!hkernel) return 0; /* Find the RegisterServiceProcess function */ register_service_process = (DWORD (WINAPI *)(DWORD, DWORD)) GetProcAddress(hkernel, "RegisterServiceProcess"); if (register_service_process == NULL) { FreeLibrary(hkernel); return 0; } } /* Register this process as a service */ rv = register_service_process(0, set_service != FALSE); if (rv) is_service = set_service; if (!is_service) { /* Unload the kernel library */ FreeLibrary(hkernel); register_service_process = NULL; } return rv;}/* * This function only works when this process is the active process * (e.g. once it is running a child process, it can no longer determine * which console window is its own.) */static BOOL CALLBACK EnumttyWindow(HWND wnd, LPARAM retwnd){ char tmp[8]; if (GetClassName(wnd, tmp, sizeof(tmp)) && !strcmp(tmp, "tty")) { DWORD wndproc, thisproc = GetCurrentProcessId(); GetWindowThreadProcessId(wnd, &wndproc); if (wndproc == thisproc) { *((HWND*)retwnd) = wnd; return FALSE; } } return TRUE;}/* The remaining code all executes --in the tty's own process context-- * * That means special attention must be paid to what it's doing... *//* Subclass message process for the tty window * * This code -handles- WM_CLOSE, WM_ENDSESSION and WM_QUERYENDSESSION * by dispatching them to the window identified by the hookwndprop * property atom set against our window. Messages are then dispatched * to origwndprop property atom we set against the window when we * injected this subclass. This trick did not work with simply a hook. */static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){ WNDPROC origproc = (WNDPROC) GetProp(hwnd, origwndprop); if (!origproc) return 0; if (msg == WM_NCDESTROY || (msg == hookwndmsg && !LOWORD(wParam) && (HWND)lParam == hwnd)) { if (is_subclassed) {#ifdef DBG DbgPrintf("W proc %08x hwnd:%08x Subclass removed\r\n", GetCurrentProcessId(), hwnd);#endif if (is_service) RegisterWindows9xService(FALSE); SetWindowLong(hwnd, GWL_WNDPROC, (LONG)origproc); RemoveProp(hwnd, origwndprop); RemoveProp(hwnd, hookwndprop); is_subclassed = FALSE; //if (hmodLock) // FreeLibrary(hmodLock); //hmodLock = NULL; } } else if (msg == WM_CLOSE || msg == WM_ENDSESSION || msg == WM_QUERYENDSESSION) { HWND child = (HWND)GetProp(hwnd, hookwndprop); if (child) {#ifdef DBG DbgPrintf("W proc %08x hwnd:%08x forwarded msg:%d\r\n", GetCurrentProcessId(), hwnd, msg);#endif return SendMessage(child, msg, wParam, lParam); } } return CallWindowProc(origproc, hwnd, msg, wParam, lParam);}/* HookProc, once installed, is responsible for subclassing the system * tty windows. It generally does nothing special itself, since * research indicates that it cannot deal well with the messages we are * interested in, that is, WM_CLOSE, WM_QUERYSHUTDOWN and WM_SHUTDOWN * of the tty process. * * Respond and subclass only when a WM_NULL is received by the window. */int HookProc(int hc, HWND *hwnd, UINT *msg, WPARAM *wParam, LPARAM *lParam){ if (is_tty == -1 && *hwnd) { char ttybuf[8]; HWND htty; hwtty = *hwnd; while (htty = GetParent(hwtty)) hwtty = htty; is_tty = (GetClassName(hwtty, ttybuf, sizeof(ttybuf)) && !strcmp(ttybuf, "tty"));#ifdef DBG if (is_tty) DbgPrintf("H proc %08x tracking hwnd %08x\r\n", GetCurrentProcessId(), hwtty);#endif } if (*msg == hookwndmsg && *wParam && *lParam == (LPARAM)hwtty && is_tty) { WNDPROC origproc = (WNDPROC)GetWindowLong(hwtty, GWL_WNDPROC); //char myname[MAX_PATH]; //if (GetModuleFileName(hmodThis, myname, sizeof(myname))) // hmodLock = LoadLibrary(myname); SetProp(hwtty, origwndprop, origproc); SetWindowLong(hwtty, GWL_WNDPROC, (LONG)WndProc); is_subclassed = TRUE;#ifdef DBG DbgPrintf("H proc %08x hwnd:%08x Subclassed\r\n", GetCurrentProcessId(), hwtty);#endif if (LOWORD(*wParam) == 2) RegisterWindows9xService(TRUE); } return -1;}/* * PostMessage Hook: */LRESULT __declspec(dllexport) CALLBACK GetMsgProc(INT hc, WPARAM wParam, LPARAM lParam){ PMSG pmsg; pmsg = (PMSG)lParam; if (pmsg) { int rv = HookProc(hc, &pmsg->hwnd, &pmsg->message, &pmsg->wParam, &pmsg->lParam); if (rv != -1) return rv; } /* * CallNextHookEx apparently ignores the hhook argument, so pass NULL */ return CallNextHookEx(NULL, hc, wParam, lParam);}/* * SendMessage Hook: */LRESULT __declspec(dllexport) CALLBACK CallWndProc(INT hc, WPARAM wParam, LPARAM lParam){ PCWPSTRUCT pcwps = (PCWPSTRUCT)lParam; if (pcwps) { int rv = HookProc(hc, &pcwps->hwnd, &pcwps->message, &pcwps->wParam, &pcwps->lParam); if (rv != -1) return rv; } /* * CallNextHookEx apparently ignores the hhook argument, so pass NULL */ return CallNextHookEx(NULL, hc, wParam, lParam);}#ifdef DBGVOID DbgPrintf( LPTSTR fmt, ... ){ static HANDLE mutex; va_list marker; TCHAR szBuf[256]; DWORD t; HANDLE gDbgOut; va_start(marker, fmt); wvsprintf(szBuf, fmt, marker); va_end(marker); if (!mutex) mutex = CreateMutex(NULL, FALSE, "Win9xConHookDbgOut"); WaitForSingleObject(mutex, INFINITE); gDbgOut = CreateFile("COM1", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_WRITE_THROUGH, NULL); WriteFile(gDbgOut, szBuf, strlen(szBuf), &t, NULL); CloseHandle(gDbgOut); ReleaseMutex(mutex);}#endif#endif /* WIN32 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -