Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi CreateWindow('Static'... aus injizierter DLL (https://www.delphipraxis.net/102535-createwindow-static-aus-injizierter-dll.html)

Kati2608 30. Okt 2007 16:06


CreateWindow('Static'... aus injizierter DLL
 
Hallo Leute,

ich habe da ein Problem bei der mir bisher noch keiner helfen konnte...

Und zwar injiziere ich eine DLL in ein anderes Programm (in diesem Beispiel zu Testzwecken in Notepad). Aus dieser DLL heraus soll dann in Notepad mittels CreateWindow ein Static Control angezeigt werden. Das funktioniert auch super... Das Problem ist nur, dass das Control sofort wieder verschwindet, es wird nur den Bruchteil einer Sekunde angezeigt.

Getestet habe ich das ganze auch mit einem Fenster welches anstatt des Static Controls angezeigt wird, aber auch da verschwindet das Fenster sofort wieder...

Wenn ich das ganze in einem normalen Programm versuche klappt es so wie gewünscht... Das Fenster bzw. Control wird so angezeigt wie es sein soll. Nur eben aus der DLL nicht. :wall:

Weiß einer Rat?

Liebe Grüße,
Kati

Code der DLL (Static):
Delphi-Quellcode:
uses
  SysUtils, Classes, Windows, Messages, ShareMem;

{$R *.res}


Procedure Init(); stdcall;
var hMain: HWND;
  WndDC: HDC;
  MyFont: HWND;
begin
  hMain := FindWindow('notepad',nil);
  if (hMain <> 0) then
  begin
    MyFont := CreateFont( -11, 0, 0, 0, 0, 0, 0, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, 'MS Sans Serif');
    WndDC := CreateWindow('Static', 'lbltest', WS_VISIBLE or WS_CHILD, 10, 10, 250, 14, hMain, 0, 0, nil);
    SendMessage(WndDC, WM_SETFONT, Integer(MyFont), Integer(true));
  end;
end;


Procedure EntryPoint(dwReason: Integer); stdcall;
begin
case dwReason of
    DLL_PROCESS_DETACH: {};
    DLL_PROCESS_ATTACH: Init();
    DLL_THREAD_ATTACH: {};
    DLL_THREAD_DETACH: {};
   end;
end;


begin
 DisableThreadLibraryCalls(hInstance);
 DLLProc := @EntryPoint;
 EntryPoint(DLL_PROCESS_ATTACH);
end.
Code der DLL (Fenster):
Delphi-Quellcode:
library InjectDLL1;


uses
  SysUtils, Classes, Windows, Messages, ShareMem;

{$R *.res}


function RegisterClass: Boolean;
var
  WindowClass: TWndClass;
begin
  WindowClass.Style := CS_HREDRAW or CS_VREDRAW;
  WindowClass.lpfnWndProc := @DefWindowProc;
  WindowClass.cbClsExtra := 0;
  WindowClass.cbWndExtra := 0;
  WindowClass.hInstance := hInstance;
  WindowClass.hIcon := 0;
  WindowClass.hCursor := 0;
  WindowClass.hbrBackground := COLOR_WINDOW;
  WindowClass.lpszMenuName := nil;
  WindowClass.lpszClassName := 'MyWindowClass';
  Result := Windows.RegisterClass(WindowClass) <> 0;
end;


Procedure Init(); stdcall;
var
  hMain: HWND;
  hWindow: HWND;
begin
  hMain := FindWindow('notepad',nil);
  if (hMain <> 0) then
  begin
    if not RegisterClass then
      begin
        MessageBox(0, 'RegisterClass failed...', 'Notepad', MB_OK);
        Exit;
      end;
      hWindow := CreateWindowEx(0, 'MyWindowClass', 'Do you see me?', WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, hInstance, nil);
      if hWindow <> 0 then
      begin
        ShowWindow(hWindow, SW_SHOWNORMAL);
        UpdateWindow(hWindow);
      end else
      begin
        MessageBox(0, 'CreateWindow failed...', 'Notepad', MB_OK);
        Exit;
      end;
  end;
end;


Procedure EntryPoint(dwReason: Integer); stdcall;
begin
case dwReason of
    DLL_PROCESS_DETACH: {};
    DLL_PROCESS_ATTACH: Init();
    DLL_THREAD_ATTACH: {};
    DLL_THREAD_DETACH: {};
   end;
end;


begin
 DisableThreadLibraryCalls(hInstance);
 DLLProc := @EntryPoint;
 EntryPoint(DLL_PROCESS_ATTACH);
end.

Zacherl 30. Okt 2007 16:19

Re: CreateWindow('Static'... aus injizierter DLL
 
Klapt es, wenn du die DllMain aus einem anderen Programm aufrufst, aber nicht injizierst? Und wie injizierst du? CreateRemoteThread?

Kati2608 31. Okt 2007 18:35

Re: CreateWindow('Static'... aus injizierter DLL
 
Zitat:

Zitat von Zacherl
Klapt es, wenn du die DllMain aus einem anderen Programm aufrufst, aber nicht injizierst?

ääähmmm.... Wenn ich das mache passiert garnix... :gruebel: Ohne jegliche Fehlermeldung...
Oder hab ich was falsch gemacht?
Delphi-Quellcode:
implementation
procedure Init(); stdcall;
external 'dll.dll';
procedure EntryPoint(dwReason: Integer); stdcall;
external 'dll.dll';

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  EntryPoint(1);
  //Init();
end;
Der DLL habe ich noch
Delphi-Quellcode:
exports
  EntryPoint, Init;
hinzugefügt.

Zitat:

Zitat von Zacherl
Und wie injizierst du? CreateRemoteThread?

Das mache ich über die madCHook.dll von madCodeHook

Liebe Grüße,
Kati

MartinA 2. Nov 2007 12:29

Re: CreateWindow('Static'... aus injizierter DLL
 
Hallo,

das injizieren scheint ja nicht das Problem zu sein.
Wenn Du das Control bzw. das Form in einen eigenen Thread legst sollte es permanent angezeigt werden.

etwas pseudocode

Delphi-Quellcode:
//zum Erzeugen:
wthreathandle := CreateThread(nil, 0, TFNThreadStartRoutine(@frmmsgThread), nil, 0, ThreadID);

//Zum zerstören:
PostThreadMessage(RTFCont.tid,WM_USER+$FFFF,0,0);

function frmmsgThread(): LongInt; stdcall;
var
  wmsg  : tmsg;
  X,i   : integer;
  twhwnd : thandle;
begin
try
  twhwnd        := getcurrentwindo; // oder einfach übergeben
  RTFCont       := tForm1.createparented(twhwnd);
  RTFCont.tid   := getcurrentthreadid;
  setparent (RTFCont.Handle,twhwnd);
  RTFCont.show;
  while wMSG.message <> WM_USER+$FFFF do
    begin
      GetMessage(wMsg,0,0,0);
      TranslateMessage(wMsg);
      DispatchMessage(wMsg);
    end;
  RTFCont.free;
except
end;

end;
RTFCont ist ein Form auf dem des Control liegt, in dem Beispiel ein RTF-Control.

Im Prinzip kann man mit diesem, nicht wirklich sauberen, Konstrukt nahezu jedes Delphi-Control in jeder Windwos-Anwendung (Konsolen ausgenommen) platzieren.

Gruß
Martin

[edit=SirThornberry]Code-Tags durch Delphi-Tags ersetzt - Mfg, SirThornberry[/edit]

SirThornberry 2. Nov 2007 12:37

Re: CreateWindow('Static'... aus injizierter DLL
 
für mich klingt das ganze auch danach das zwar das control erzeugt wird aber eben keine Nachrichtenschleife dazu abgearbeitet wird und somit gibt es keine PaintMessages etc. die verarbeitet werden.
Und wenn dann noch der Thread, aus dem es heraus erzeugt wird beendet wird gibt es das Control auch nicht mehr.

MartinA 2. Nov 2007 12:45

Re: CreateWindow('Static'... aus injizierter DLL
 
Zitat:

Zitat von SirThornberry
für mich klingt das ganze auch danach das zwar das control erzeugt wird aber eben keine Nachrichtenschleife dazu abgearbeitet wird und somit gibt es keine PaintMessages etc. die verarbeitet werden.
Und wenn dann noch der Thread, aus dem es heraus erzeugt wird beendet wird gibt es das Control auch nicht mehr.

Vollkommen richtig, Deine Annahme :)
Deswegen obiges Bsp.

Gruß
Martin

Kati2608 2. Nov 2007 14:31

Re: CreateWindow('Static'... aus injizierter DLL
 
Warum bin ich da nicht gleich drauf gekommen? :wall: :wall: :wall:
Mit GetMessage etc in einer Schleife hatte ich das gestern schon hinbekommen das das Fenster angezeigt wird, allerdings is das Notepad Fenster dann quasi eingefroren, natürlich weil das Threading gefehlt hatte... Manchmal sieht man einfach den Wald vor lauter Bäumen nicht...

Ich werde das später mal testen, und da es funktionieren wird markiere ich den Thread mal als gelöst...

Vielen Dank an euch!!

Liebe Grüße
die glückliche Kati :o)


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:23 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz