DLL Injection
-
nö weil ich den Code rauskopiert habe und der damals schon funktioniert hat also ist im Code kein Fehler:
Injector:#include <windows.h> #include <cstdio> typedef HINSTANCE (*fpLoadLibrary)(char*); typedef LPVOID (*fpGetProcAddress)(HINSTANCE, char*); typedef void (*fpFunktion)(void); struct INJECTSTRUCT { fpLoadLibrary LoadLibrary; fpGetProcAddress GetProcAddress; char path[255]; char func[255]; }; DWORD WINAPI threadstart(LPVOID addr) { HINSTANCE hDll; fpFunktion funktion; INJECTSTRUCT * is = (INJECTSTRUCT*)addr; hDll = is->LoadLibrary(is->path); funktion = (fpFunktion)is->GetProcAddress(hDll, is->func); funktion(); return 0; } void threadend() { } int main() { HANDLE hProc; LPVOID start, thread; DWORD funcsize, written; HINSTANCE hDll; INJECTSTRUCT is; DWORD id; hDll = LoadLibrary("KERNEL32"); is.LoadLibrary = (fpLoadLibrary)GetProcAddress(hDll, "LoadLibraryA"); is.GetProcAddress = (fpGetProcAddress)GetProcAddress(hDll, "GetProcAddress"); strcpy(is.path, "C:\\DLL.dll"); strcpy(is.func, "Funktion"); funcsize = (DWORD)threadend-(DWORD)threadstart; printf("ID: "); scanf("%d", &id); hProc = OpenProcess(PROCESS_ALL_ACCESS, false, id); printf("Prozess Handle: %x\n", hProc); start = VirtualAllocEx(hProc, 0, funcsize+sizeof(INJECTSTRUCT), MEM_COMMIT, PAGE_EXECUTE_READWRITE); printf("Memory: %x\n", start); WriteProcessMemory(hProc, start, (LPVOID)&is, sizeof(INJECTSTRUCT), NULL); thread = (LPVOID)((DWORD)start+sizeof(INJECTSTRUCT)); WriteProcessMemory(hProc, thread, (LPVOID)threadstart, funcsize, NULL); CreateRemoteThread(hProc, 0, 0, (LPTHREAD_START_ROUTINE)thread, start, 0, 0); CloseHandle(hProc); return 0; }
DLL
#include <windows.h> extern "C" void __declspec(dllexport) Funktion() { Beep(1000, 1000); } BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved) { return TRUE; }
natürlich ist die DLL in C\\ und beides ist mit Multi Byte Compiliert.
Wäre super wenn wer weiß woran das liegen könnte.
-
Hi,
wie wärs mit den Prozess Debuggen in den du die DLL läds!?
Gruß Pingu
-
Markymark schrieb:
audacia schrieb:
Markymark schrieb:
crashed der zielprozess. woran liegt das?
Du hast einen Fehler im Code.
**
nö weil ich den Code rauskopiert habe** und der damals schon funktioniert hatGenial! It compiles! Now ship it!
Markymark schrieb:
also ist im Code kein Fehler
Aber in den Kompilereinstellungen. Niemals vergessen: 99,95 % aller WinAPI-Funktionen sind __stdcall's.
-
Hi,
wie wärs mit den Prozess Debuggen in den du die DLL läds!?
Gruß Pingu
-
was muss ich den umstellen? WINAPI == __stdcall
-
Markymark schrieb:
... funcsize = (DWORD)threadend-(DWORD)threadstart; ..
Wollt nur noch schnell anmerken daste mit diesm Konstrukt ziemlich leicht auf die Schnauze fallen kannst.
z.B. wenn ich mit Visual C++ 2008 im Debug Modus zB. folgendes übersetzte:BOOL __declspec(naked) SetCursorPosA(int x, int y) { __asm { mov edi, edi push ebp mov ebp, esp jmp [DLLFunc] } } void blub() { printf("hallo"); return; } int main(int argc, TCHAR** argv) { unsigned char test = -1; printf("%c",test); SetCursorPosA(10,10); blub(); return 0; }
entsteht folgendes:
/*Main function*/ 00411AA2 |. E8 34F7FFFF CALL FindWind.004111DB 00411AA7 |. 83C4 08 ADD ESP,8 00411AAA |. E8 36F7FFFF CALL FindWind.004111E5 .... 004111D6 . /E9 D5010000 JMP FindWind.SetCursorPosA 004111DB $ |E9 D0010000 JMP FindWind.SetCursorPosA 004111E0 . |E9 2F020000 JMP FindWind.printf ; JMP to MSVCR90D.printf 004111E5 $ |E9 D6010000 JMP FindWind.blub
Gruß Pingu
-
wenn man die funktion als static deklariert, funktioniert das
(visual 2008 getestet)
-
Markymark schrieb:
was muss ich den umstellen? WINAPI == __stdcall
Falls das Fettgedruckte eine Kompilereinstellung ist, dann wäre sie genau die richtige.
Prinzipiell mußt du nur dafür sorgen, daß der Kompiler folgende Deklarationen
typedef HINSTANCE (*fpLoadLibrary) (char*); typedef LPVOID (*fpGetProcAddress)(HINSTANCE, char*);
als __stdcall's betrachtet und entsprechenden Assemblercode generiert. Genaueres dazu hier.
"Per Hand" geht das so:
typedef HINSTANCE __stdcall (*fpLoadLibrary) (char*); typedef LPVOID __stdcall (*fpGetProcAddress)(HINSTANCE, char*);
-
eher so
typedef HINSTANCE (__stdcall *fpLoadLibrary) (char*); typedef LPVOID (__stdcall *fpGetProcAddress)(HINSTANCE, char*);
-
vielen Dank für die Hilfe besonders an helferlein.
Mit deinem Code funktioniert es perfekt. Mich wundert es jedoch
da ich es früher nie so gemacht habe und es geklappt hat aber wayne.
Warum steht im Tutorial unten dass diese Methode bei nicht vielen Prozessen klappt und man darum noch das Fortgeschrittene Tut machen soll? Bei mir geht das überall
-
und warum läuft der Code nicht mit UNICODE?
Ich habe alle char durch TCHAR ersetzt unt strcpy durch die TCHAR routine.
Ich kann es zwar kompilieren aber der Zielprocess crashed mit unicode.
-
helferlein schrieb:
eher so
Hängt vom Kompiler ab. Meiner schluckt beides. "__stdcall" ist ja kein Schlüsselwort sondern nur eine Kompilererweiterung (oder auch -verwässerung).
Markymark schrieb:
Warum steht im Tutorial unten dass diese Methode bei nicht vielen Prozessen klappt ...
Hab das Tutorial zwar nicht gelesen aber das liegt nicht an der Methode sondern an WinXP sein Rechtemanagement.
Jemand der als "User" eingeloggt ist, hat z.B. nur Zugriff auf alle Prozesse, die er selbst gestartet hat usw.Markymark schrieb:
und warum läuft der Code nicht mit UNICODE?
Weil du die "A(nsi)"-Version von LoadLibrary benutzt. Probier das mal mit LoadLibraryW.
-
geht leider auch nicht aber dann muss ich wohl mit Ansi arbeiten.
Warum bekomme ich bei der DLL einen Linker Error, dass sie nicht ansi zeichen benutzt oder so und deshalb möglicherweiße nur auf meinem PC verwendet werden kann?#include <windows.h> extern "C" void __declspec(dllexport) Funktion() { Beep(1000, 1000); } BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved) { return TRUE; }
Habs mit Multi und Unicode probiert.
Und noch was: wie bekomme ich die Rückgabewerte der Funktion aus der Dll, bzw wie kann ich ihr Parameter aus dem Main programm übergeben?
-
Markymark schrieb:
geht leider auch nicht aber dann muss ich wohl mit Ansi arbeiten.
alle chars umgestellt? auch das kopieren mit strcpy?
prinzipiel sollte das auch mit unicode gehen.
Markymark schrieb:
Warum bekomme ich bei der DLL einen Linker Error, dass sie nicht ansi zeichen benutzt oder so und deshalb möglicherweiße nur auf meinem PC verwendet werden kann?
welchen fehler? poste den bitte ich kann leider nicht so gut hellsehen
Markymark schrieb:
Und noch was: wie bekomme ich die Rückgabewerte der Funktion aus der Dll, bzw wie kann ich ihr Parameter aus dem Main programm übergeben?
du musst einen weiteren speicherbereich in dem zielprozess VirtualAllociren,
die parameter reinschreiben und die addresse des bereiches an die funktion
übergeben. allerdings kannst du nicht auf daten des eigenen prozesses über
zeiger zuggreifen also alles was du brauchst kopieren.die addresse kannst du einfach als parameter übergeben, also der deklaration
in der DLL und in der main einfach ein parameter, z.b. void *, hinzufügen.dieser wert wiederrum wird auch in der INJECTSTRUCT gespeichert.
-
Markymark schrieb:
Und noch was: wie bekomme ich die Rückgabewerte [...]
Ganz einfach - GetExitCodeThread.
DWORD __stdcall RemoteThreadProc(MYDATA *data) { return 12345; // oder ExitThread(12345); } void inject() { HANDLE hThread = CreateRemoteThread(); DWORD dwExitCode; GetExitCodeThread(hThread, &dwExitCode); // dwExitCode = STILL_ACTIVE, also warte noch WaitForSingleObject(hThread, INFINITE); GetExitCodeThread(hThread, &dwExitCode); // dwExitCode ist 12345 }
Du kannst auch eine variable in MYDATA setzen um thread status (und mehr) mitteilen:
DWORD __stdcall RemoteThreadProc(MYDATA *data) { data->return_value = 12345; return 0; } void inject() { MYDATA data; void *pData = VirtualAllocEx(hProcess, 0, sizeof(MYDATA), MEM_COMMIT, PAGE_READ_WRITE); WriteProcessMemory(hProcess, pData, &data, sizeof(data), &cch); HANDLE hThread = CreateRemoteThread(..., pCode, pData, ...); WaitForSingleObject(hThread, INFINITE); ReadProcessMemory(hProcess, pData, &data, sizeof(data), &cch); // data.return_value ist 12345 }
-
ich glaube es war umsonst, kann man in DLLs keine Dialoge verwenden? Denn ich wollte mein ganzes Programm in diese DLL auslagern.
#include <windows.h> #include "resource.h" BOOL CALLBACK MainDlg(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); extern "C" void __declspec(dllexport) Funktion() { DialogBox(GetModuleHandle(0), MAKEINTRESOURCE(IDD_DIALOG1), 0, MainDlg); MessageBox(0, "lol", "lol", 0); // geht } BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved) { return TRUE; } BOOL CALLBACK MainDlg(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { switch(message) { case WM_INITDIALOG: Beep(2000, 4000); return TRUE; case WM_COMMAND: switch(LOWORD(wParam)) { case IDCANCEL: EndDialog(hDlg, 0); return TRUE; } } return FALSE; }
leider wird kein Dialog erzeugt oO er ist auf sichtbar gestellt usw.
aber warum sehe ich diesen nicht?
-
Leider GetModuleHandle(0) liefert EXE BASE und nicht DLL BASE. Du brauchst die hInst von DllMain in eine globale g_hinstance Variabe speichern, und dann...
DialogBox(g_hinstance,
Aber manchmal klappt das nicht, dann must du DialogBoxIndirect benutzen (mithilfe Find/Load/LockResource).
-
natüllich klappt das, wieso soll das nich klappen lolzen
-
dankeschön, dass klappt. Und noch was anderes:
kann ich wirklich mein ganzes Programm mit vielen Dialogen funktionen Threads usw von der DLL in den Prozess laden oder gibt es da eine begrenzung?
-
Markymark schrieb:
gibt es da eine begrenzung?
quatsch wieso sollte es