Handle erhalten
-
Hallo Leute,
ich benutze SetWindowsHookEx, um eine DLL nachträglich in meinen Prozess zu injezieren. Mein Problem ist, dass wenn sich der Injector beendet, wird auch die DLL entladen. Klar, Windows ruft implizit UnhookWindowsHookEx auf, da der Prozess beendet wird. Aber ich will nicht meinen Injector im Hintergrund stundenlang laufen lassen. Ich habe schon DuplicateHandle probiert um dieses an den Prozess in den injeziert wurde zu übergeben aber das klappt nicht. Hätte jemand ne Idee, wie ich es schaffen kann, dass mein Hook nicht entfernt wird, obwohl der Loader beendet wird? Ich persönlich glaube das geht nicht, darum wollte ich hier nochmal sichergehen. Danke
-
Injecte doch anders. Stichwort: CreateRemoteThread & LoadLibrary
-
CreateRemoteThread ist halt wieder das Problem, dass man in WinMain kaum was machen darf und wenn ich wieder ne Funktion calle nach WinMain wird das wieder so ein elendiges gefrickel wie auf habo wiki.
Eventuell sollte ich Code injezieren, welcher dann SetWindowsHookEx aufruft dann wäre das Handle im Zielprozess wenns anders nicht geht
-
Das auf Habo ist großer Schrott, so ein Gefrickel brauchst du nicht anfangen

Hier mal eben aus meiner C++-Lib kopiert, nur damit du siehst wie es schön geht

Ich habe die komplette Library im Laufe der letzten Tage neu geschrieben und werde sie bald veröffentlichen, falls es dich interessiert.void Process::injectModuleAndCallExport(const std::wstring& dllPath, const std::wstring& exportName, LPVOID functionParam) const { //Write path into targets memory SafeRemoteMemory remotePathBuffer(allocateMemory((dllPath.length() + 1) * sizeof(wchar_t)), processHandle_); writeWideString(remotePathBuffer, dllPath); //Load kernel32.dll to get LoadLibraryW address SafeModule kernel32(LoadLibraryW(L"kernel32.dll")); if(!kernel32) throw WinException("Process::injectModuleAndCallExport()", "LoadLibraryW()", GetLastError()); //Get LoadLibraryW address DWORD_PTR addressLoadLibaryW = reinterpret_cast<DWORD_PTR>(customGetProcAddress(kernel32, "LoadLibraryW")); if (!addressLoadLibaryW) throw std::runtime_error("Process::injectModuleAndCallExport Error : customGetProcAddress() failed"); //Create remote Thread and wait until its finished SafeHandle remoteThread(createThread(addressLoadLibaryW, remotePathBuffer, false, INFINITE)); //Get remote threads exit code DWORD threadExitCode = 0; if (!GetExitCodeThread(remoteThread, &threadExitCode)) throw WinException("Process::injectModuleAndCallExport()", "GetExitCodeThread()", GetLastError()); //Its zero, LoadLibraryW failed if(!threadExitCode) throw std::runtime_error("Process::injectLibraryAndCallExport Error : LoadLibraryW() in remote process failed"); //Call the export, if wanted if(!exportName.empty() && exportName != L" ") callExport(dllPath, exportName, functionParam); }
-
der ist schon mal nicht so gut, weil die DLLS bei Win 7 kernel nicht immer an gleicher stelle sind, somit ist auch LoadLibrary nicht immer an gleicher Stelle.
-
Dass die Addresse der Kernel32.dll sich von Prozess zu Prozess unterscheiden würde kann ich absolut nicht bestätigen. Ich benutze Win7 64bit seit RC1 und habe das noch nie beobachten können.
Du musst es ja nicht so machen, war nur ein gutgemeinter Tipp welcher, zumindest für mich, perfekt funktioniert

-
hmm das habe ich mal gehört ansonsten sieht das schon Top aus

dürfte ich bitte die call export Funktion sehenß
-
Was mir gerade einfällt, selbst wenn die Ladeaddresse des Moduls varieren würde, könnte man immer noch ganz einfach die Modul-Liste des Zielprozesses abwandern und einfach die Ladeadresse der Kernel32.dll abgreifen

Den Code zu callExport finde ich gerade nicht, aber sie funktioniert so:
1. Modul im lokalen Prozess per LoadLibrary laden, mit GetProcAddress die Addresse des Exports bestimmen.
2. Das Offset des Exports bestimmen indem man schlicht die Baseaddress der DLL von der Addresse des Exports substrahiert.
3. Die Modul-Liste des Zielprozesses abwandern und das Modul suchen, Offset addieren und einfach CreateRemoteThread darauf loslassen.
-
danke für die Erklärung.
Aber was ich nicht so ganz verstehe, dann hat man ja 2 neue Threads, in einem läuft dann WinMain und in einem die Funktion?
-
Cruelreaver schrieb:
danke für die Erklärung.
Aber was ich nicht so ganz verstehe, dann hat man ja 2 neue Threads, in einem läuft dann WinMain und in einem die Funktion?DllMain läuft nur zum Initialisieren der DLL und wird von LoadLibrary miterledigt. Dh. der eine Thread ist praktisch sofort beendet. Jetzt ist es halt Geschmackssache ob man seinen eigenen Thread in der DllMain startet oder in einem Export. Allerdings sollte man zweiteres tun, Microsoft rät vom erstellen von Threads in der DllMain ab.

-
cool danke dann werde ich das auch mal so versuchen.
-
Ich erstelle einen Prozess mit CREATE_SUSPENDET.
Und möchte dann meine Dll injecten.Nur warum kann man nicht die Moduleliste abwandern wenn er suspendet ist?
Module32First gibt dann no more modules beim 1. mal schon zurück.
Das ist doch blödsinn oder? kernel32.dll müsste auch wenn er suspendet gestartet wird bereits im Prozess sein? Oder geht das mit dieser Methode nicht?
-
in der MSDN steht ja auch
"Ensure that the target process was not started suspended" beim CreateSnapshot.
Aber wie soll man die Modulliste des Prozesses sonst abwalken? Das geht dann nicht?
-
Icematix
ok das war Blödsinn, die Adressen sind am gleichen Ort.
Dachte das ist so wegen imagebase randomization.
Aber das ist nur bei PC neustart so.Jedenfalls ist mir noch was anderes aufgefallen.
Man braucht für die base Adresse von dem Modul nicht extra die Prozessliste abwandern, weil die GetExitCodeThread zurückgibt.
Dann ist es noch etwas effizienter.Ansonsten nochmal vielen Dank für die Hilfe das alles klappt super.
-
Cruelreaver schrieb:
in der MSDN steht ja auch
"Ensure that the target process was not started suspended" beim CreateSnapshot.
Aber wie soll man die Modulliste des Prozesses sonst abwalken? Das geht dann nicht?Wenn es wirklich nicht mit der tlhelp api will musst du eben die double linked list im peb walken. Den process environment block bekommst du mit NtQueryInformationProcess mit ProcessBasicInformation als information-class [1].
Damit kannst du dann auf den PEB bzw. über den PEB auf die PEB_LDR_DATA struct zugreifen [2] welche dann die Liste mit den geladenen Modulen enthält.[1]: http://msdn.microsoft.com/en-us/library/ms684280(VS.85).aspx
[2]: http://undocumented.ntinternals.net/UserMode/Structures/PEB_LDR_DATA.html