Si j'ai une fonction foo()
que Windows a implémentée dans kernel32.dll et qu'elle retourne toujours true, puis-je avoir mon programme: "bar.exe" crochet/détourne cette fonction Windows et la fait retourner false pour tous processus à la place?
Ainsi, si mon svchost, par exemple, appelle foo()
, il retournera false au lieu de true. La même action doit être attendue pour tous les autres processus en cours d'exécution.
Si c'est le cas, comment? Je suppose que je cherche un crochet à l'échelle du système ou quelque chose.
Jetez un oeil à Détours , c'est parfait pour ce genre de choses.
Pour le raccordement à l'échelle du système, lisez cet article à partir de MSDN.
Commencez par créer un DLL qui gère le raccordement des fonctions. Cet exemple ci-dessous raccorde les fonctions d'envoi et de réception du socket.
#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;
}
Ensuite, créez un programme pour injecter le DLL dans l'application cible.
#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( GetModuleHandle( "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;
}
Cela devrait être plus que suffisant pour vous lancer!
EASYHOOK http://www.codeplex.com/easyhook
Dominez toutes les techniques susmentionnées en termes de simplicité, de flexibilité et de fonctionnalité.
Cela n'a pas été discuté précédemment sur Processus de hook non plus. J'ai lu toutes les feuilles de ce fil et avec une certitude absolue, EASYHOOK est largement supérieur. Peu importe si vous utilisez C, C++, CLR, peu importe.
Je vais coller un peu de la page d'accueil du codeplex, pour garantir que suffisamment d'omage soit payé.
Je suis heureux que mon talonneur connaisse encore quelques trucs en comparaison qui me font les garder. Mais pour être sûr, lorsque vous avez besoin d'un CROCHET, 99 fois sur 100, EASYHOOK'r vous y conduira plus rapidement. Et c'est assez activement maintenu.
Veuillez donner plus de détails sur la fonction que vous souhaitez accrocher! Il existe plusieurs façons d'obtenir votre propre code appelé dans un tel cas, par exemple:
Vous pouvez créer un faux DLL avec le même nom que le DLL qui contient la fonction que vous voulez accrocher (et la copier dans le dossier de foo.exe
). Cette bibliothèque exposerait exactement les mêmes fonctions que la DLL d'origine. Chaque fonction exposée contourne simplement l'appel à la DLL d'origine, à l'exception de la fonction que vous souhaitez accrocher.
Vous pouvez modifier la table des pointeurs de fonctions pendant l'exécution, par exemple avec le package (commercial) Detour mentionné par "kitchen". Cependant, faire un tel accrochage peut être fait facilement par vous-même, voir cet article pour savoir comment.
Vous pouvez savoir où la fonction spécifique est appelée dans foo.exe
et remplacez simplement le code Assembly qui appelle la fonction par un code qui "renvoie true
". Fondamentalement, vous corrigez "foo.exe
"..
Pour des fonctions spécifiques, Windows propose un raccordement automatique, par ex. pour les événements de touches et de souris. Vérifiez la fonction SetWindowsHook pour cela.
Cela dépend quelque peu de la version de Windows que vous souhaitez cibler. Néanmoins, si vous jouez sur Pre-Vista, vous pouvez simplement utiliser SetWindowsHookEx pour injecter votre DLL dans chaque processus en cours d'exécution. Votre DLL devra alors accrocher la fonction appropriée à l'aide de Détours ou similaire.