[DLL Injection] Firefox.exe
-
Liebe Kollegen und Kolleginnen,
Ich versuche mich gerade in die Thematik DLL Injection einzuarbeiten und habe folgendes Script gefunden, welches ich leicht modifiziert habe:
#include <iostream> #include <string> #include <windows.h> #include <tlhelp32.h> using namespace std; DWORD GetProcID(string ProcName); DWORD WINAPI GetCurrentProcessId(void); bool ProcessExists(string process); int main() { char* DLLName="dll.dll"; char* ProcessName="firefox.exe"; bool CloseAfterCorrectInjection=true; DWORD procID = 0; system("color a"); cout << "My DLL Injector\n" <<endl; cout << "Library: " << DLLName << "\n"; cout << "Process: " << ProcessName << "\n\n"; int nBufferLength = 100; char awBuffer[100]; GetCurrentDirectory(nBufferLength, awBuffer) ; strcat(awBuffer,"\\"); strcat(awBuffer,DLLName); string dll = awBuffer; HMODULE hLocKernel32 = GetModuleHandle("Kernel32"); FARPROC hLocLoadLibrary = GetProcAddress(hLocKernel32, "LoadLibraryA"); HANDLE hToken; TOKEN_PRIVILEGES tkp; if(OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY | PROCESS_ALL_ACCESS, &hToken)) { LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tkp.Privileges[0].Luid); tkp.PrivilegeCount = 1; tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; AdjustTokenPrivileges(hToken, 0, &tkp, sizeof(tkp), NULL, NULL); } HANDLE hProc = INVALID_HANDLE_VALUE ; cout << "Waiting for " << ProcessName << "...\n"; while (!ProcessExists(ProcessName)){ } cout << "Process detected!\n\n"; procID = GetProcID(ProcessName); hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, procID); cout << "PID: " << procID << "\n\n"; cout << "Injecting " << DLLName << "...\n\n"; dll += '\0'; LPVOID hRemoteMem = VirtualAllocEx(hProc, NULL, dll.size(), MEM_COMMIT, PAGE_READWRITE); DWORD numBytesWritten; WriteProcessMemory(hProc, hRemoteMem, dll.c_str(), dll.size(), &numBytesWritten); HANDLE hRemoteThread = CreateRemoteThread(hProc, NULL, 0, (LPTHREAD_START_ROUTINE)hLocLoadLibrary, hRemoteMem, 0, NULL); bool res = false; if (hRemoteThread) { res = (bool)WaitForSingleObject(hRemoteThread, 10000) != WAIT_TIMEOUT; if (res) { cout << "Dll succesfully injected!\n"; } else { cout << "Injection failed\n" << GetLastError() <<endl; } VirtualFreeEx(hProc, hRemoteMem, dll.size(), MEM_RELEASE); CloseHandle(hProc); } else { cout << "Injection failed\n"; system("PAUSE"); return 0; } if (!CloseAfterCorrectInjection) { system("PAUSE"); } system("PAUSE"); return 0; } DWORD GetProcID(string ProcName) { HANDLE hProcessSnap; PROCESSENTRY32 pe32; hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); pe32.dwSize = sizeof(PROCESSENTRY32); //** I had problems for weeks until I realized this was missing -.- do { //cout << pe32.szExeFile <<"\n"; if(pe32.szExeFile == ProcName) { DWORD ProcId = pe32.th32ProcessID; CloseHandle(hProcessSnap); return ProcId; } } while(Process32Next(hProcessSnap, &pe32)); CloseHandle(hProcessSnap); return 0; } bool ProcessExists(string process) { HANDLE hProcessSnap; PROCESSENTRY32 pe32; hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); pe32.dwSize = sizeof(PROCESSENTRY32); do { if(pe32.szExeFile == process) { CloseHandle(hProcessSnap); return true; } } while(Process32Next(hProcessSnap, &pe32)); CloseHandle(hProcessSnap); return false; }
Die DLL Datei sieht folgendermassen aus:
/* Replace "dll.h" with the name of your header */ #include "dll.h" #include <windows.h> DllClass::DllClass() { } DllClass::~DllClass () { } BOOL APIENTRY DllMain (HINSTANCE hInst /* Library instance handle. */ , DWORD reason /* Reason this function is being called. */ , LPVOID reserved /* Not used. */ ) { switch (reason) { case DLL_PROCESS_ATTACH: MessageBox(HWND_DESKTOP, "Inection succeeded", "DLL Injection", MB_OK); break; case DLL_PROCESS_DETACH: MessageBox(HWND_DESKTOP, "Inection succeeded", "DLL Injection", MB_OK); break; case DLL_THREAD_ATTACH: MessageBox(HWND_DESKTOP, "Inection succeeded", "DLL Injection", MB_OK); break; case DLL_THREAD_DETACH: MessageBox(HWND_DESKTOP, "Inection succeeded", "DLL Injection", MB_OK); break; } /* Returns TRUE on success, FALSE on failure */ return TRUE; }
Nun lasse ich den das Injector Script ablaufen udn bekomme aus Ausgabe:
My DLL Injector
Library: dll.dll
Process: firefox.exeWaiting for firefox.exe...
Process detected!PID: 6092
Injecting dll.dll...
Dll succesfully injected!
Drücken Sie eine beliebige Taste . . .Leider erscheint die MessageBox jedoch nicht. Firefox läuft normal weiter (keinen Crash) und auch sonst passiert nichts grossartiges.
Hat hierbei vl jemand eine Idee?
Vielen Dank und schöne GrüsseP.S.
Windows 7 - 64 Bit als OS
-
Dieser Thread wurde von Moderator/in Martin Richter aus dem Forum MFC (Visual C++) in das Forum WinAPI verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.
-
PUSH - ich darf doch, oder?
-
WaitForSingleObject ist kein brauchbarer Weg um zu prüfen ob die Injection geklappt hat.
Lieber GetExitCodeThread bemühen um den Rückgabewert des remote Threads abzufragen, der enthält nämlich den Rückgabewert von LoadLibraryA.Mein Tipp: Falscher Pfad, schon mal mit einem absolutem Pfad probiert? Dürft ja nicht vergessen dass das Ganze in Firefox's Kontext läuft, dh. auch in seinem working directory.
-
GetModuleHandle("kernel32.dll") anstatt von GetModuleHandle("kernel32") ?
Edit: msdn sagt das default .dll wird ergänzt, naja war ne Idee.
-
- nur weil der Thread erstellt wurde, heißt das noch lange nicht, dass auch die DLL geladen wurde
- eventuell: Du weißt, das man keine 32Bit DLL's in einen 64Bit Prozess laden kann?
- PROCESS_ALL_ACCESS: brachst das wirklich - meiner Erfahrung nach nicht.
- Allgemein: das Prog. schon mal als Admin. gestartet?
-
Update:
Habe die DLL folgendermassen umgebaut:/* Replace "dll.h" with the name of your header */ #include "dll.h" #include <windows.h> DllClass::DllClass() { } DllClass::~DllClass () { } // All startup code goes in OnInitialize extern "C" __declspec(dllexport) void __cdecl Initialize(void) { // Real Code MessageBox(NULL, "Injection succeeded", "DLL Injection", 0); Beep(1000, 1000); } BOOL APIENTRY DllMain(HMODULE hModule, DWORD ulReason, LPVOID lpReserved) { MessageBox(NULL, "Injection succeeded", "DLL Injection", 0); Beep(1000, 1000); // Get rid of warnings hModule; lpReserved; ulReason; // We do not need to know about Threaded events, so disable them (reduces overhead) DisableThreadLibraryCalls(hModule); // Load the DLL return TRUE; }
Nun passiert was eigenartiges:
Die MessageBox wird nicht angezeigt, aber nach einer bestimmten Zeitspanne (meistens 1-3 Minuten) gibt der Computer den beep() Ton von sich...Kann sich das wer erklären?
Danke und lg
-
questionär schrieb:
- nur weil der Thread erstellt wurde, heißt das noch lange nicht, dass auch die DLL geladen wurde
- eventuell: Du weißt, das man keine 32Bit DLL's in einen 64Bit Prozess laden kann?
- PROCESS_ALL_ACCESS: brachst das wirklich - meiner Erfahrung nach nicht.
- Allgemein: das Prog. schon mal als Admin. gestartet?1. Stimmt.
2. Ja, aber firefox ist ein 32 Bit Prozess..
3. Habe es schon mit und ohne versucht.
4. Ja. Keine VeränderungenGruss
-
Meinen Tipp befolgt? Was sagt GetExitCodeThread?
-
Ethon schrieb:
Meinen Tipp befolgt? Was sagt GetExitCodeThread?
Kannst du mir bitte kurz erklären wie ich den einbauen muss?
Danke & lg
-
Hab den Code nun angepasst:
DWORD lpExitCode; GetExitCodeThread(hRemoteThread,&lpExitCode); if(STILL_ACTIVE == lpExitCode) cout << "Thread is still active..." <<endl; else cout << "Thread has been closed..." <<endl; cout << "[information] Got GetExitCodeThread: " <<lpExitCode <<endl;
Das Ergebnis:
path is: C:\Dev-Cpp\projects\dll.dll
Waiting for firefox.exe...
Process detected!PID: 1736
Injecting dll.dll...
Thread has been closed...
[information] Got GetExitCodeThread: 1628176384
Dll succesfully injected!
Drücken Sie eine beliebige Taste . . .
-
PUSH again
-
Wie wäre damit selber mal das Gehirn einzuschalten?
Thread has been closed...
[information] Got GetExitCodeThread: 1628176384
Dll succesfully injected!Dein Loadlibrary Aufruf war offensichtlich erfolgreich. Die DLL wurde im Zielprozess an Adresse 0x610C0000 geladen.
-
Ja?
Aber es passiert offensichtlich nichts - darum frage ich mich wo der Fehler liegt.
-
Woher sollen wir das wissen?
Firefox ist äußerst komplex und startet beim Initialisieren eine Menge Threads. Möglicherweise gibt es da irgendwelche Seiteneffekte mit Deiner hässlichen MessageBox.Probiere doch erst einmal einen einfachen Prozess zu injecten! Wie wäre es zum Beispiel mit Notepad.exe? Ist das wirklich so schwer auch mal einen Schritt zurück zu gehen?
-
Hallo,
Das war ein Kommunikationsfehler - meine Schuld.
Natürlich habe ich es schon bei folgenden Programmen versucht:
- Firefox
- IE
- calc
- explorer
- pinball (das Game)
- NotepadBei allen leider die selbe Problematik...
Darum bin ich ja so verwundert.Danke und lg
-
Vl noch zur Info:
Habe es am Beispiel von DeepBurner auch getestet:
My DLL Injector
Library: dll.dll
Process: DeepBurner.exepath is: C:\Dev-Cpp\projects\dll.dll
Waiting for DeepBurner.exe...
Process detected!PID: 1136
Injecting dll.dll...
Thread has been closed...
[information] Got GetExitCodeThread: 1628176384
Dll succesfully injected!
Drücken Sie eine beliebige Taste . . .Dann habe ich es für Notepad getestet, und siehe da:
My DLL Injector
Library: dll.dll
Process: notepad.exepath is: C:\Dev-Cpp\projects\dll.dll
Waiting for notepad.exe...
Process detected!PID: 6032
Injecting dll.dll...
Injection failed
Drücken Sie eine beliebige Taste . . .GetLastError()
Gibt auch kein Ergebnis
-
Ich gehe mal davon aus das Dein Injector schon läuft bevor Du den Targetprozess startest?
Falls das so ist: Bevor Du injectes solltest Du unbedingt ein bisschen Zeit vergehen lassen, bis sich der Prozess vollständig initialisiert hat.Das hier
while (!ProcessExists(ProcessName)){ }
Ist übrigens auch Mist und verbrät viel Rechenzeit.
Mach mal so:while (!ProcessExists(ProcessName)){ Sleep(1000);} // zu Testzwecken: // zusätzlich Zeit einräumen für das starten des Prozesses Sleep(5000);
-
Hallo,
Danke für deine Antwort.
Nein ich lasse den Prozess in der Regel 1-2 Minuten laufen, bevor ich injecte...HAbe den Code mal angepasst - leider auch keine Änderungen.
Gruss
-
In Deinem Code waren noch einige komische Dinge.
So wie hier unten geht es bei mir problemlos. Achtung ich habe hier mit wchar_t gearbeitet.Natürlich ohne Gewähr.
// Injector.cpp : Definiert den Einstiegspunkt für die Konsolenanwendung. // #include "stdafx.h" #include <iostream> #include <string> #include <windows.h> #include <tlhelp32.h> using namespace std; DWORD GetProcID(wstring ProcName) { HANDLE hProcessSnap; PROCESSENTRY32 pe32; hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); pe32.dwSize = sizeof(PROCESSENTRY32); //** I had problems for weeks until I realized this was missing -.- do { //cout << pe32.szExeFile <<"\n"; if(pe32.szExeFile == ProcName) { DWORD ProcId = pe32.th32ProcessID; CloseHandle(hProcessSnap); return ProcId; } } while(Process32Next(hProcessSnap, &pe32)); CloseHandle(hProcessSnap); return 0; } bool ProcessExists(wstring process) { HANDLE hProcessSnap; PROCESSENTRY32 pe32; hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); pe32.dwSize = sizeof(PROCESSENTRY32); do { if(pe32.szExeFile == process) { CloseHandle(hProcessSnap); return true; } } while(Process32Next(hProcessSnap, &pe32)); CloseHandle(hProcessSnap); return false; } int _tmain(int argc, wchar_t* argv[]) { wstring DLLName = L"InjectorDll.dll"; //wstring ProcessName = L"firefox.exe"; wstring ProcessName = L"notepad.exe"; //bool CloseAfterCorrectInjection=true; DWORD procID = 0; system("color a"); wcout << L"My DLL Injector\n" << endl; wcout << L"Library: " << DLLName << endl; wcout << L"Process: " << ProcessName << endl << endl; wchar_t awBuffer[MAX_PATH]; GetCurrentDirectory(MAX_PATH, awBuffer) ; wstring dll = awBuffer; dll.append(L"\\"); dll.append(DLLName); HMODULE hLocKernel32 = GetModuleHandle(L"Kernel32.dll"); FARPROC hLocLoadLibrary = GetProcAddress(hLocKernel32, "LoadLibraryW"); HANDLE hToken; TOKEN_PRIVILEGES tkp; if(OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY | PROCESS_ALL_ACCESS, &hToken)) { LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tkp.Privileges[0].Luid); tkp.PrivilegeCount = 1; tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; AdjustTokenPrivileges(hToken, 0, &tkp, sizeof(tkp), NULL, NULL); } HANDLE hProc = INVALID_HANDLE_VALUE; wcout << L"Waiting for " << ProcessName << L"..." << endl; while (!ProcessExists(ProcessName)){Sleep(1000);} wcout << L"Process detected!" << endl << endl; procID = GetProcID(ProcessName); wcout << L"PID: " << procID << endl << endl; Sleep(2500); wcout << L"Injecting " << dll << "..." << endl << endl; LPVOID hRemoteMem = NULL; hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, procID); if (hProc != INVALID_HANDLE_VALUE) { hRemoteMem = VirtualAllocEx(hProc, NULL, (dll.size() + 1) * sizeof(wchar_t), MEM_COMMIT, PAGE_READWRITE); if (hRemoteMem != NULL) { DWORD numBytesWritten; WriteProcessMemory(hProc, hRemoteMem, dll.c_str(), (dll.size() + 1) * sizeof(wchar_t), &numBytesWritten); HANDLE hRemoteThread = CreateRemoteThread(hProc, NULL, 0, (LPTHREAD_START_ROUTINE)hLocLoadLibrary, hRemoteMem, 0, NULL); bool res = false; if (hRemoteThread != 0) { DWORD lpExitCode; Sleep(1000); GetExitCodeThread(hRemoteThread, &lpExitCode); wcout << L"[information] Got GetExitCodeThread: " << lpExitCode << L" " << hex << lpExitCode <<endl; if (lpExitCode != 0) { wcout << L"Dll succesfully injected!" << endl; } else { wcout << L"Injection failed " << GetLastError() << endl; } CloseHandle(hRemoteThread); } else { wcout << L"Injection failed " << GetLastError() << endl; } } else { wcout << L"Injection failed " << GetLastError() << endl; } } else { wcout << L"Injection failed " << GetLastError() << endl; } if (hProc != INVALID_HANDLE_VALUE) { if (hRemoteMem != NULL) VirtualFreeEx(hProc, hRemoteMem, (dll.size() + 1) * sizeof(wchar_t), MEM_RELEASE); CloseHandle(hProc); } system("PAUSE"); return 0; }