Question

Si j'ai une fonction que Windows a foo() mis en œuvre dans kernel32.dll et il retourne toujours vrai, je peux avoir mon programme: crochet / détour « de bar.exe » cette fonction Windows et le faire revenir faux pour tous les processus à la place?

Alors, si mon svchost, par exemple, appelle <=>, il retournera faux au lieu de vrai. La même action devrait être prévue pour tous les autres processus en cours d'exécution.

Si oui, comment? Je suppose que je suis à la recherche d'un crochet système ou quelque chose.

Était-ce utile?

La solution

Jetez un oeil à Detours , il est parfait pour ce genre de choses.


Pour crochetage l'échelle du système, lisez cet article de MSDN.


Tout d'abord, créez une DLL qui gère les fonctions d'accrochage. Cet exemple crochets ci-dessous l'envoi de prise et de réception.

#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 la 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 aider à démarrer!

Autres conseils

EASYHOOK http://www.codeplex.com/easyhook

Dominez de toutes les techniques de simpleicty décrits cidessus, flexability et fonctionnalité.

Il n'a pas été discuté précédemment sur processus de crochet soit. Je l'ai lu de ce fil de toutes les feuilles et certanty absolue, EASYHOOK est largement superiour. Peu importe si vous utilisez C, C ++, CLR, peu importe.

Je vais coller un peu de la page d'accueil CodePlex, afin d'assurer Omage suffisamment être payé.

Ce qui suit est une liste non exhaustive des caractéristiques:

  1. Un soi-disant « Thread Deadlock barrière » va se débarrasser de nombreux problèmes de base lors du branchement des API inconnus; cette technologie est unique à EasyHook
  2. Vous pouvez écrire géré les gestionnaires de crochet pour les API non gérés
  3. Vous pouvez utiliser tout le confort de code managé fournit, comme NET Remoting, WPF et WCF par exemple
  4. Une documentation, API pure crochetage non géré
  5. Prise en charge de 32 bits et crochetage en mode noyau 64 bits (vérifier aussi mon chauffeur de dérivation PatchGuard 3 qui se trouve dans la liste de presse)
  6. Aucune fuite de ressources ou mémoire sont laissés dans la cible
  7. mécanisme d'injection furtif expérimentale qui n'attirer l'attention de tout logiciel AV actuelle
  8. EasyHook32.dll et EasyHook64.dll sont des modules non gérés purs et peuvent être utilisés sans cadre NET installé!
  9. Toutes les crochets sont installés et automatiquement supprimé de manière stable
  10. Support pour Windows Vista SP1 x64 et Windows Server 2008 SP1 x64 en utilisant les API totalement sans papier, pour permettre encore accrochage dans une session de terminal.
  11. trace géré / empilement modulaire non géré à l'intérieur d'un gestionnaire de crochet
  12. Faites des appels module managé / non géré dans un gestionnaire de crochet
  13. Créer une pile personnalisé traces à l'intérieur d'un gestionnaire de crochet
  14. Vous serez en mesure d'écrire des bibliothèques d'injection et les processus d'accueil compilés pour AnyCPU, qui vous permettra d'injecter du code dans 32- et les processus 64 bits de 64- et les processus 32 bits en utilisant le même assemblage dans tous les cas.
  15. EasyHook supporte RIP-adressage relatif relocalisation pour les cibles 64-bit.
  16. Pas de déballage / l'installation nécessaire.
  17. Le Visual Studio redistribuable n'est pas nécessaire.

Je suis heureux que mon Hooker sait encore quelques trucs en comparaison qui me fait les conserver. Mais pour être sûr, quand vous avez besoin d'un HOOK, 99 fois 100, EASYHOOK'r vous y plus vite. Et il est tout à fait activement maintenu.

S'il vous plaît donner plus de détails sur la fonction que vous voulez brancher! Il y a plusieurs façons d'obtenir votre propre code appelé dans un tel cas, par exemple:

  • Vous pouvez construire une DLL faux avec le même nom que la DLL qui contient la fonction que vous voulez accrocher (et le 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 court-circuite simplement l'appel à la DLL d'origine, à l'exception de la fonction que vous voulez brancher.

  • Vous pouvez changer la table de pointeur de fonction pendant l'exécution, par exemple avec le (commercial) forfait Detour qui a été mentionné par « cuisine ». Cependant, faire un tel accrochage peut se faire facilement par vos propres, voir cet article savoir comment.

  • Vous pouvez savoir où la fonction spécifique est appelé et il suffit de remplacer true le code assembleur qui appelle la fonction avec un code qui « renvoie <=> ». En gros, vous patcher "<=>" ..

  • Pour les fonctions spécifiques, Windows offre accrochage automatique, par exemple pour les clés et les événements de souris. Vérifiez la fonction SetWindowsHook pour cela.

Cela dépend un peu de la version de Windows que vous vouloir cibler. Quoi qu'il en soit, si vous jouez sur le pré-Vista, vous pouvez simplement utiliser SetWindowsHookEx pour injecter votre DLL dans tous les processus en cours d'exécution. Votre DLL aurait alors besoin de brancher la fonction appropriée à l'aide Detours ou similaire.

Si vous écrivez votre crochet dans l'assemblage et ne pas utiliser Detours (quelle qu'en soit la raison), alors vous avez besoin des informations clés sur returing FAUX:

  • Win32, mis EAX à 0
  • Win64, mis RAX à 0

Vous devez définir EAX ou RAX (selon la plate-forme) à zéro que la dernière chose que la fonction que vous n'accrochage. Cela se traduira par le code d'appel reçu 0 comme la valeur de retour (en supposant qu'ils retournent une valeur int ou pointeur).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top