如果我有一个函数foo()
,窗口已经在kernel32.dll中实现,它总是返回true,我可以有我的程序:“bar.exe”钩/绕道Windowsfunction,并使所有进程返回false?
所以,如果我的svchost,例如,调用foo()
,它将返回false而不是true。 对于当前正在运行的所有其他进程,也应该采取同样的行动
如果是这样,怎么样? 我想我正在寻找一个全系统的钩子什么的。
看看Detours吧 ,这对于这类东西来说是完美的。
对于全系统挂钩,请阅读MSDN上的这篇文章 。
首先,创建一个处理挂钩函数的DLL。 下面的这个例子钩住了套接字的发送和接收功能。
#include <windows.h> #include <detours.h> #pragma comment( lib, "Ws2_32.lib" ) #pragma comment( lib, "detours.lib" ) #pragma comment( lib, "detoured.lib" ) int ( WINAPI *Real_Send )( SOCKET s, const char *buf, int len, int flags ) = send; int ( WINAPI *Real_Recv )( SOCKET s, char *buf, int len, int flags ) = recv; int WINAPI Mine_Send( SOCKET s, const char* buf, int len, int flags ); int WINAPI Mine_Recv( SOCKET s, char *buf, int len, int flags ); int WINAPI Mine_Send( SOCKET s, const char *buf, int len, int flags ) { // .. do stuff .. return Real_Send( s, buf, len, flags ); } int WINAPI Mine_Recv( SOCKET s, char *buf, int len, int flags ) { // .. do stuff .. return Real_Recv( s, buf, len, flags ); } BOOL WINAPI DllMain( HINSTANCE, DWORD dwReason, LPVOID ) { switch ( dwReason ) { case DLL_PROCESS_ATTACH: DetourTransactionBegin(); DetourUpdateThread( GetCurrentThread() ); DetourAttach( &(PVOID &)Real_Send, Mine_Send ); DetourAttach( &(PVOID &)Real_Recv, Mine_Recv ); DetourTransactionCommit(); break; case DLL_PROCESS_DETACH: DetourTransactionBegin(); DetourUpdateThread( GetCurrentThread() ); DetourDetach( &(PVOID &)Real_Send, Mine_Send ); DetourDetach( &(PVOID &)Real_Recv, Mine_Recv ); DetourTransactionCommit(); break; } return TRUE; }
然后,创建一个程序将DLL注入到目标应用程序中。
#include <cstdio> #include <windows.h> #include <tlhelp32.h> void EnableDebugPriv() { HANDLE hToken; LUID luid; TOKEN_PRIVILEGES tkp; OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken ); LookupPrivilegeValue( NULL, SE_DEBUG_NAME, &luid ); tkp.PrivilegeCount = 1; tkp.Privileges[0].Luid = luid; tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; AdjustTokenPrivileges( hToken, false, &tkp, sizeof( tkp ), NULL, NULL ); CloseHandle( hToken ); } int main( int, char *[] ) { PROCESSENTRY32 entry; entry.dwSize = sizeof( PROCESSENTRY32 ); HANDLE snapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, NULL ); if ( Process32First( snapshot, &entry ) == TRUE ) { while ( Process32Next( snapshot, &entry ) == TRUE ) { if ( stricmp( entry.szExeFile, "target.exe" ) == 0 ) { EnableDebugPriv(); char dirPath[MAX_PATH]; char fullPath[MAX_PATH]; GetCurrentDirectory( MAX_PATH, dirPath ); sprintf_s( fullPath, MAX_PATH, "%s\\DllToInject.dll", dirPath ); HANDLE hProcess = OpenProcess( PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE, FALSE, entry.th32ProcessID ); LPVOID libAddr = (LPVOID)GetProcAddress( GetmoduleeHandle( "kernel32.dll" ), "LoadLibraryA" ); LPVOID llParam = (LPVOID)VirtualAllocEx( hProcess, NULL, strlen( fullPath ), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE ); WriteProcessMemory( hProcess, llParam, fullPath, strlen( fullPath ), NULL ); CreateRemoteThread( hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)libAddr, llParam, NULL, NULL ); CloseHandle( hProcess ); } } } CloseHandle( snapshot ); return 0; }
这应该足以让你开始!
EASYHOOK http://www.codeplex.com/easyhook
统治的所有上述技术在简单,灵活性和功能。
以前没有讨论Hook过程 。 我已经读过这个主题的所有叶子,并且绝对是合格的, EASYHOOK是非常优秀的。 无论你使用C,C ++,CLR,不管。
我会从codeplex主页上粘贴一下,以确保足够的omage被支付。
我很高兴,我的妓女仍然知道一些比较的技巧,使我保持他们周围。 但是可以肯定的是,当你需要一个HOOK时,100次的99次,EASYHOOK'r会让你更快。 这是相当积极的维护。
请给出你想挂钩的功能的更多细节! 在这种情况下,有几种方法可以调用自己的代码,例如:
您可以使用与包含您要挂钩的函数的DLL相同的名称构建一个假DLL(并将其复制到foo.exe
文件夹中)。 这个库将暴露与原始DLL完全相同的功能。 每个暴露的函数都会绕过对原始DLL的调用,除了要挂钩的函数之外。
您可以在运行时更改函数指针表,例如使用“kitchen”中提到的(商业)Detour软件包。 但是,做这样的挂钩可以很容易地由你自己完成,看到这篇文章来学习如何。
你可以找到在foo.exe
调用特定函数的foo.exe
,只需用“返回true
”的代码替换调用该函数的汇编代码即可。 基本上,你正在修补“ foo.exe
”..
对于特定的功能,Windows提供自动挂钩,例如用于按键和鼠标事件。 检查函数SetWindowsHook为此。
这在一定程度上取决于您想要定位的Windows版本。 尽管如此,如果你在Pre-Vista上玩,你可以简单地使用SetWindowsHookEx来将你的DLL注入到每个正在运行的进程中。 然后您的DLL需要使用Detours或类似的钩子适当的功能。
如果你在汇编中编写你的钩子而不使用Detours(无论出于何种原因),那么你需要一些关于returing FALSE的关键信息:
您需要将EAX或RAX(取决于平台)设置为零,作为您所连接的功能的最后一件事情。 这将导致调用代码接收0作为返回值(假设它们返回一个int或指针类型值)。