Button in Fremdes Programm einfügen
-
Hey,
ich habe vor einen kleinen Button in ein fremdes PRogramm einzufügen.Hier mal der Code der DLL die iniziert wird:
// dllmain.cpp : Definiert den Einstiegspunkt für die DLL-Anwendung. #include "stdafx.h" #include <iostream> #include <fstream> #include <sstream> #include <time.h> using namespace std; static HWND hWnd; LONG p; static int hWndI = 0; LRESULT CALLBACK NewWndProc (HWND, UINT, WPARAM, LPARAM); BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: hWnd = FindWindowA(0, "AceDB 2.0"); p = GetWindowLong(hWnd, GWL_WNDPROC); SetWindowLongA(hWnd, GWL_WNDPROC, (long)NewWndProc); break; case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; } LRESULT CALLBACK NewWndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { static HWND hButton; switch(message) { case WM_COMMAND: if (lParam == (LPARAM)hButton) { return 0; } else { return CallWindowProcA((WNDPROC)p,hwnd, message,wParam, lParam); } case WM_CREATE: hButton = CreateWindowA("Button","OBJ", BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE, 10, 20, 100,100,hWnd,NULL,((LPCREATESTRUCT) lParam) -> hInstance,NULL); hWndI++; return CallWindowProcA((WNDPROC)p,hwnd, message,wParam, lParam); } return CallWindowProcA((WNDPROC)p,hwnd, message,wParam, lParam); }
Aber der Button will einfach nicht erscheinen
Was muss ich tun dass der Button sichtbar wird?
MFG!
-
Probier mal UpdateWindow()
-
DU meinst so?:
case WM_CREATE: hButton = CreateWindowA("Button","OBJ", BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE, 10, 20, 100,100,hWnd,NULL,((LPCREATESTRUCT) lParam) -> hInstance,NULL); hWndI++; UpdateWindow(hWnd); return CallWindowProcA((WNDPROC)p,hwnd, message,wParam, lParam);
Geht auch nicht
-
An ein bereits exestieredes Fenster wird niemals WM_CREATE gesendet!
Erstell den Button vor SetWindowLong().
-
Ok, aber wenn ich das so mache entsteht ein Fehler bei dem Parameter
((LPCREATESTRUCT) lParam) -> hInstance
Wie kann ich das dann beheben?
PS:
switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: hWnd = FindWindowA(0, "AceDB 2.0"); p = GetWindowLong(hWnd, GWL_WNDPROC); hButton = CreateWindowA("Button","OBJ", BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE, 10, 20, 100,100,hWnd,NULL,((LPCREATESTRUCT) lParam) -> hInstance,NULL); SetWindowLongA(hWnd, GWL_WNDPROC, (long)NewWndProc); ... ...
Ich denke du meinst an dieser Stelle.
-
hWnd+GetWindowLong+GWL_HINSTANCE
-
Ok, ich habe es jetzt so:
static LONG h; h = GetWindowLong(hWnd, GWL_HINSTANCE); HWND hWnd = FindWindowA(0, "..."); hButton = CreateWindowA("Button","OBJ", BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE, 10, 20, 100,100,hWnd,NULL,(HINSTANCE)h,NULL);
Funktioniert aber immernoch nicht... Der Button erscheint nicht
EDIT:
Ich habe jetzt noch
ShowWindow(hWnd, SW_SHOW); ShowWindow(hButton, SW_SHOW); UpdateWindow(hWnd); UpdateWindow(hButton);
drangehängt, wenn ich jetzt die DLL injiziere erscheint der Button für ca. ne halbe Sekunde und verschwindet wieder
-
Weiß denn garniemand was ich tun muss dass der Button bleibt??
-
vieleich einfach das richtige Instance-Handle übergeben? Welches hWnd benutz du den mit GWL_HINSTANCE?
-
Ich hole mir das Handle von dem Programm, dann die Instanz und dann erstelle ich den Button:
HWND hWnd = FindWindowA(0, "Programm"); //Handle LONG h = GetWindowLong(hWnd, GWL_HINSTANCE); //Instanz hButton = CreateWindowA("Button","OBJ", BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE, 10, 20, 100,100,hWnd,NULL,(HINSTANCE)h,NULL);
-
Hier ist der Fehler mal reproduziert:
format PE GUI 4.0 DLL entry start include 'win32a.inc' section '.code' code readable executable start: cmp byte [esp+8],DLL_PROCESS_ATTACH jnz .fin push 0 push 0 push 0 push thread push 0 push 0 call [CreateThread] .fin: mov eax,1 retn 0Ch thread: push 0 push _class call [FindWindow] mov edi,eax push wndproc push GWL_WNDPROC push edi call [SetWindowLongW] mov [oldwndproc],eax push GCL_HMODULE push edi call [GetClassLongW] push eax push 0 push eax push 0 push edi push 18 push 50 push 4 push 4 push WS_CHILD+WS_VISIBLE push _xyz push _button push 0 call [CreateWindowEx] mov [hButton],eax push eax call [GetLastError] push eax push _fmt push _buffer call [wsprintf] add esp,14h push MB_OK push 0 push _buffer push 0 call [MessageBox] retn proc wndproc hwnd,msg,wparam,lparam cmp [msg],WM_COMMAND jnz .def ;mov eax,[hButton] ;cmp [lparam],eax ;jnz .def cmp word [wparam+2],BN_CLICKED jnz .def push [hButton] call [IsWindow] push eax push _fmt2 push _buffer call [wsprintf] add esp,0Ch push MB_OK push 0 push _buffer push [hwnd] call [MessageBox] xor eax,eax jmp .fin .def: push [lparam] push [wparam] push [msg] push [hwnd] push [oldwndproc] call [CallWindowProcW] .fin: ret endp section '.data' data readable writeable _title db '',0 _class db 'Notepad',0 _button db 'button',0 _xyz db 'xyz',0 _fmt db 'error: %d button: %d hinstance: %x',0 _fmt2 db 'IsWindow: %d',0 _buffer rb 255 oldwndproc dd ? hButton dd ? section '.idata' import data readable library kernel32,'KERNEL32.DLL',\ user32,'USER32.DLL' include 'api\kernel32.inc' include 'api\user32.inc' section '.reloc' fixups discardable
mit FASM assemblieren und die Dll dann ins Notepad injizieren.
Die erste MessageBox berichtet
error: 0 button: 4462904 hinstance: 120000
und die zweite
IsWindow: 0Heisst also, dass CreateWindow zwar funktioniert, der Button erstellt wird und das Handle kurzzeitig valid ist, aber anscheinend unmittelbar danach dann nicht mehr
-
Hmm, aber wie kann das sein? Ich hab's doch als static erstellt
-
Killur schrieb:
Ich hab's doch als static erstellt
Killur schrieb:
... HWND hWnd = FindWindowA(0, "Programm"); //Handle ...
Was, bitteschön, hast Du als static erstellt?
Ich sehe da nix, aber ich sehe wo static erforderlich wäre
Na, ist Dir ein Licht dabei aufgegangen?HTH,
Martin
-
Die DLL gehört mit eigener Instanz zur Anwendung. Jedenfalls im Datenbereich ist das so. Wenn du über die Daten hinaus in der Anwendung etwas veranlassen willst, empfiehlt sich eine userdefined Message mit SendMessage der DLL an die Anwendung. Dafür musst du der DLL das Handle HWND der Anwendung mitteilen.
-
Dir ist klar, dass ein Fenster immer zu einem Thread gehört. Sobald Dein Thread aufhört zu existieren wird auch das Fenster vernichtet.
Mit CreateRemoteThread kann es folgerichtig niemals klappen.
Wie injiziert Du die DLL?
-
Killur schrieb:
... HWND hWnd = FindWindowA(0, "Programm"); //Handle ...
Was, bitteschön, hast Du als static erstellt?
Ich sehe da nix, aber ich sehe wo static erforderlich wäre
Na, ist Dir ein Licht dabei aufgegangen?HTH,
MartinBei mir siehts so aus:
static HWND hWnd; ... ... hWnd = FindWindow....
Ich injiziere die DLL wie in diesem Tutorial beschrieben:
KlickAber dort wird CreateRemoteThread benutzt.. Wie kann ich es ohne machen? Hat jmd ein Link zu einem guten Tutorial?
-
Du kannst in keinem Fall CreateRemoteThread verwenden.
Wie die Funktion schon sagt, es wird ein eigener Thread erzeugt und dieser müsste dann so lange leben wie Dein fenster und eine eigene Message-Loop haben.Du müsstest einen Hook verwenden, der dann im Threadkontext aufgerufen wird.
z.B. WH_GETMESSAGE/WH_CALLWNDPROC etc.Werde Dir bitte erstmal klar, wie Fenster, Prozess und Threads in einem Windows System funktionieren.
-
Kannst du mir erklären wie ich das mit WH_GETMESSAGE mache?
-
Nein. Das kann und will ich nicht. Warum auch (siehe unten).
Siehe SetWindowsHook Doku:
http://msdn.microsoft.com/en-us/library/ms644990(VS.85).aspx
und mindestens 100 Beiträge dazu hier und woanders im Netz.Und es ist immer wieder toll was man so findet:
http://lmgtfy.com/?q=wh_getmessage+sampleDer zweite Link ist ein vollständiges Beispiel einer entsprechenden Injection incl. einer kompletten Beschreibung.
Irrsinnig wie tief man im Netzt graben muss um zu finden was Du suchst, oder ?