2017-07-05 2 views
3

J'ai écrit un programme (.DLL) qui doit être injecté dans process.exe.Débogage .DLL Injection Problème - Point d'arrêt sur le code d'exécution supposé ne pas être touché

DLL code injecteur:

Bool InjectDll(DWORD pID, const char* dllPath) { 
    Proc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pID); 
    if (!Proc) 
    { 
     return false; 
    } 
    void* LoadLibAddr = (void*)GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA"); 
    void* RemoteString = (void*)VirtualAllocEx(Proc, NULL, strlen(dllPath), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); 
    WriteProcessMemory(Proc, (LPVOID)RemoteString, dllPath, strlen(dllPath), NULL); 
    HANDLE ret = CreateRemoteThread(Proc, NULL, NULL, (LPTHREAD_START_ROUTINE)LoadLibAddr, (LPVOID)RemoteString, CREATE_SUSPENDED, NULL); 
    if (ret) { 
     return true; 
    } 
} 

fonction DllMain() de DLL à injecter:

#include <Windows.h> 

extern void vMain(); 

BOOL APIENTRY DllMain(HMODULE hModule, 
    DWORD ul_reason_for_call, 
    LPVOID lpReserved 
    ) 
{ 
    switch (ul_reason_for_call) { 
    case DLL_PROCESS_ATTACH: 
     CreateThread(0, 0, (LPTHREAD_START_ROUTINE)&vMain, 0, 0, 0); 
     return true; 
    } 
    return false; 
} 

vMain:

void vMain() { 
    CreateConsole();   
    std::cout << "vMain() has executed!\n"; 
} 

La DLL à injecter fonctionne très bien quand je le compile en studio visuel, mais quand je compile dans QT Creator, vMain() n'est jamais exécuté. L'injecteur, .DLL et le processus cible sont tous en 32 bits. J'ai donc essayé de déboguer le processus cible en faisant l'appel de l'injecteur .DLL CreateRemoteThread() avec le drapeau CREATE_SUSPENDED, de cette façon je peux définir un point d'arrêt sur LoadLibraryA(), reprendre le fil, effectuer l'exécution du point d'arrêt et afficher la valeur de retour. Cependant, mon point d'arrêt sur LoadLibraryA() n'est pas touché. J'ai donc débogué l'application de l'injecteur .DLL pour m'assurer que le thread distant était en cours de création. Je confirme qu'il est en appelant GetThreadID() sur la valeur de retour de CreateRemoteThread(), la sortie, et la visualisation que le fil dans la liste des fils du processus cible:

ThreadList

Gardez à l'esprit le fil est toujours suspendu. Après une inspection plus approfondie, EIP pointe vers la première instruction au _RtlUserThreadStart(). J'ai mis un point d'arrêt sur cette instruction. Je reprends ensuite le thread suspendu en appelant ResumeThread() à partir de mon programme d'injecteur .DLL. Le point d'arrêt n'est pas touché.

Il est à noter que l'application cible ne possède aucun mécanisme anti-breakpoint, et les points d'arrêt ont fonctionné correctement pour moi en dehors de cette instance.

Alors, comment puis-je savoir quel est le problème? Y at-il une raison pour laquelle mes points d'arrêt ne sont pas touchés? Y a-t-il un meilleur moyen de déboguer le problème?

+0

'dllPath' est-il un chemin d'accès complet? Si non, alors êtes-vous sûr qu'il peut être atteint lorsqu'il est exécuté à partir de Qt Creator? – Bogdan

Répondre

0

Lorsque vous effectuez la sortie de la console à l'intérieur d'une DLL, vous devrez peut-être rediriger stdout sur la console:

// AllocConsole() instead of CreateConsole() 
AllocConsole(); 
freopen("CONOUT$", "w", stdout); // <==== 
std::cout << "vMain() has executed!\n"; 

De plus, ce n'est pas une bonne idée de créer des fils à l'intérieur DllMain() et voici pourquoi:

question connexe:

Je me souviens que j'ai eu quelques problèmes avec elle dans le passé et je me suis arrêté de faire des choses telles que la création de fils/fenêtres à l'intérieur DllMain(), tel que recommandé.

Pourtant, il y a des cas où cela fonctionne, mais je ne ferais pas confiance. Cela étant dit, si ce qui précède ne fonctionne pas, essayez d'appeler votre vMain() directement sans fil et voir ce qui se passe.