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 erster Versuch mit CreateRemoteThread schlägt fehl :( (https://www.delphipraxis.net/62700-erster-versuch-mit-createremotethread-schlaegt-fehl.html)

MCQ 8. Feb 2006 12:02


erster Versuch mit CreateRemoteThread schlägt fehl :(
 
Hi, Ich wollte mich mal näher mit der API CreateRemoteThread auseinandersetzen, allersings stürzt die zielanwendung immer ab sobald icch diese funktion aufrufe. Woran kann das liegen?

Hier mal der aktuelle Code:

Delphi-Quellcode:
procedure Thread;
var s:string;
begin
//MessageBox(0,'test','',0);
s:='test';
end;

procedure TForm1.Button1Click(Sender: TObject);
var hProcess,hRemote:THandle;
    ThreadID:DWORD;
    Flags:Pointer;
begin
hProcess:=OpenProcess(PROCESS_ALL_ACCESS,false,4072);
hRemote:=CreateRemoteThread(hProcess,nil,0,@Thread,nil,0,ThreadID);
if hRemote=0 then showmessage('Error');
end;

Gruß MCQ

MCQ 8. Feb 2006 16:49

Re: erster Versuch mit CreateRemoteThread schlägt fehl :(
 
Update:
Ich hab noch etwas gegooglet und herausgefunden, das ich die Thread-Prozedur erst zusammen mit den Daten in den Remote-Prozess kopieren muss. Das hab ich getan und eine kleine ASM-Prozedur entwickelt die die daten ausliest. Funktioniert auch alles wundeerbar, solange ich es in den eigenen Prozess injeziere. Das macht aber leider wenig sinn. Wenn ich es in einen anderen Prozess injeziere funktioniert der kopiervorgang auch wunderbar allerdings stürzt die Remote-Anwendung nochimmer bei dem Aufruf CreateRemoteThread ab :(

Hier der bisherige Code:
Delphi-Quellcode:
unit Unit2;

interface

uses
  Windows, Sysutils;

//  {$DEFINE Set_BreakPoint}

implementation

function GetProcSize(proc : Pointer) : Cardinal;
begin
  result := 1;
  while(true)do
  begin
    if(Byte((pointer(Cardinal(proc) + result - 1))^) = $C3)then
      Break;
    Inc(result);
  end;
end;

function ExpandFileName(const FileName: string): string;
var
  FName: PChar;
  Buffer: array[0..MAX_PATH - 1] of Char;
begin
  SetString(Result, Buffer, GetFullPathName(PChar(FileName), SizeOf(Buffer),
    Buffer, FName));
end;


procedure Thread(param:Pointer);stdcall;
var
  (* API-Pointer *)
  pLoadLibrary,pGetProcAddress:pointer;
  (* inkludierte API-Funktionen *)
  LoadLibrary    : function(libname:PChar):THandle;stdcall;
  GetProcAddress : function(hModule:THandle;ProcName:PChar):Pointer;stdcall;
  MsgBox         : function (h:THandle;Text,Caption:PChar;typ:integer):integer;stdcall;
  (* Zeichenketten *)
  user32          : PChar;
  kernel32        : PChar;
  msg_api        : PChar;
  (* normale Variablen *)
  h:THandle;
begin
 asm
{$IFDEF Set_BreakPoint}
  int 3
{$ENDIF}
  mov eax,[ebp+8]          // Parameter
  xor ebx,ebx
  mov bl, [eax]           // Parameter - Anzahl d. Zeichenketten
  add eax, ebx
  inc eax                  // Springe hinter die Längenangaben der Zeichenketten
  (* LoadLibrary und GetProcAddress werden ermittelt *)
  mov ebx, [eax]           // Parameter - LoadLibrary
  mov pLoadLibrary,ebx
  add eax, 4
  mov ebx, [eax]           // Parameter - GetProcAddess
  mov pGetProcAddress,ebx
  (* Zeichenketten *)
  xor ecx, ecx
  xor edx, edx
  mov al,[ebp+8]          // eax = Länge der Zeichenketten
  mov ebx, eax             // ebx = Pointer auf Zeichenkette
  mov cl, [eax]           // ecx = Anzahl d. Zeichenketten
  add ebx, ecx
  add ebx, 9
  inc eax
  mov user32, ebx          // Zeichenkette 1 - user32.dll
  inc ebx
  mov dl,[eax]
  add ebx,edx
  inc eax
  mov kernel32, ebx        // Zeichenkette 2 - kernel32.dll
  inc ebx
  mov dl,[eax]
  add ebx,edx
  inc eax
  mov msg_api, ebx         // Zeichenkette 3 - MessageBoxA
 end;
 @LoadLibrary:=pLoadLibrary;
 @GetProcAddress:=pGetProcAddress;
 h:=LoadLibrary('user32.dll');
 @MsgBox:=GetProcAddress(h,msg_api);
 MsgBox(0,user32,kernel32,0);
end;


var param    : pByteArray;
    p        : Pointer;
    pAPI     : Pointer;
    tmp      : DWORD;
    s        : PChar;
    len      : byte;
    num      : byte;
    hProcess : THandle;
    ThreadSize: DWORD;
    procedure AddPtr(var p:Pointer;i:integer);
     begin
      p:=ptr(DWORD(p)+i);
     end;
begin
ThreadSize:=GetProcSize(@Thread);
num:=0;
hProcess:=OpenProcess(PROCESS_ALL_ACCESS,false,GetCurrentProcessID());
param:=VirtualAllocEx(hProcess, nil, 30 + threadsize, MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(hProcess,param,@num,SizeOf(num),tmp);
p:=param;
(* Die Länge des Strings "user32.dll" wird ermittelt und gespeichert *)
AddPtr(p,1);
len:=length('user32.dll');
inc(num);
WriteProcessMemory(hProcess,p,@len,SizeOf(len),tmp);
(* Die Länge des Strings "kernel32.dll" wird ermittelt und gespeichert *)
AddPtr(p,1);
len:=length('kernel32.dll');
inc(num);
WriteProcessMemory(hProcess,p,@len,SizeOf(len),tmp);
(* Die Länge des Strings "MessageBoxA" wird ermittelt und gespeichert *)
AddPtr(p,1);
len:=length('MessageBoxA');
inc(num);
WriteProcessMemory(hProcess,p,@len,SizeOf(len),tmp);
(* Die Anzahl der Zeichenketten wird aktuallisiert *)
WriteProcessMemory(hProcess,param,@num,SizeOf(num),tmp);
(* Die API-Adressen werden gespeichert *)
AddPtr(p,1);
pAPI:=GetProcAddress(GetModuleHandle('kernel32.dll'), 'LoadLibraryA');
WriteProcessMemory(hProcess,p,@pAPI,SizeOf(pAPI),tmp);

AddPtr(p,SizeOf(pAPI));
pAPI:=GetProcAddress(GetModuleHandle('kernel32.dll'), 'GetProcAddress');
WriteProcessMemory(hProcess,p,@pAPI,SizeOf(pAPI),tmp);
(* Zeichenketten werden geschrieben *)
(* user32.dll *)
AddPtr(p,SizeOf(pAPI));
s:='user32.dll';
pAPI:=@s;
pAPI:=Pointer(DWORD(pAPI^));
WriteProcessMemory(hProcess,p,pAPI,length(s),tmp);
AddPtr(p,length(s)+1);
(* kernel32.dll *)
s:='kernel32.dll';
pAPI:=@s;
pAPI:=Pointer(DWORD(pAPI^));
WriteProcessMemory(hProcess,p,pAPI,length(s),tmp);
AddPtr(p,length(s)+1);
(* MessageBoxA *)
s:='MessageBoxA';
pAPI:=@s;
pAPI:=Pointer(DWORD(pAPI^));
WriteProcessMemory(hProcess,p,pAPI,length(s),tmp);
AddPtr(p,length(s)+1);
writeProcessMemory(hProcess,p,@Thread,1024,tmp);
CreateRemoteThread(hProcess,nil,0,p,param,0,tmp);
end.

brechi 5. Mär 2006 18:32

Re: erster Versuch mit CreateRemoteThread schlägt fehl :(
 
Lad lieber eine DLL in den Speicher die den Code enthält. Dann musst du dich nicht um die Relocations / Imports usw. kümmern.

ichbins 5. Mär 2006 19:28

Re: erster Versuch mit CreateRemoteThread schlägt fehl :(
 
hi, es wäre interresant zu wissen WIE das Proggie abstürtzt (AV, Einfach weg, Bleibt hängen etc.) wird die messagebox angezeigt wenn du die Kommentarstriche wegtust?

MCQ 5. Mär 2006 19:31

Re: erster Versuch mit CreateRemoteThread schlägt fehl :(
 
Zitat:

Zitat von brechi
Lad lieber eine DLL in den Speicher die den Code enthält. Dann musst du dich nicht um die Relocations / Imports usw. kümmern.

Genau so hab ich es dann auch gelöst

Zitat:

Zitat von ichbins
hi, es wäre interresant zu wissen WIE das Proggie abstürtzt (AV, Einfach weg, Bleibt hängen etc.) wird die messagebox angezeigt wenn du die Kommentarstriche wegtust?

Da gib ne nette Meldung von XP in der Sinngemäß steht "Das Programm wurde aus Sicherheitsgründen beendet"


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:14 Uhr.

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