Autor Beitrag
Cypher2000
Hält's aus hier
Beiträge: 15

Win XP
Delphi 7
BeitragVerfasst: Fr 07.08.09 19:18 
Hallo Delphi-freunde!

Derzeit schlage ich mich mit DLL injections und anderen Dingen rum.


Den folgenden Code habe ich auf irgendeinem Delphi board gefunden (Danke an den Autor! :D ) und an sich funktioniert er auch einwandfrei:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
function TForm1.InjectIntoProcess(lpProcessID: Cardinal; lpDllname: String):Boolean;
var
  hProc: Cardinal;
  oAlloc: Pointer;
  cWPM: Cardinal;
  hRemThread: Cardinal;
begin
  result := false;
  SetLastError(ERROR_SUCCESS);
  hProc := OpenProcess(PROCESS_ALL_ACCESS, false, lpProcessID);
  if hProc <> 0 then
  begin
    oAlloc := VirtualAllocEx(hProc, nil, length(lpDllname), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    if oAlloc <> nil then
    begin
      if WriteProcessMemory(hProc, oAlloc, PChar(lpDllName), length(lpDllName), cWPM) = true then
      begin
        CreateRemoteThread(hProc, nil0, GetProcAddress(GetModuleHandle('kernel32.dll'), 'LoadLibraryA'), oAlloc, 0, hRemThread);
        if GetLastError = ERROR_SUCCESS then
        begin
          result := true;
        end;
      end;
    end;
  end;
  CloseHandle(hProc);
end;


Mein Problem ist, dass ich gerne den Rückgabewert der "LoadLibraryA" irgendwie abrufen möchte die in "CreateRemoteThread" aufgerufen wurde. Jedoch habe ich keine Ahnung wie. Zuerst dachte ich das es möglich ist einfach den Rückgabewert von CreateRemoteThread zu übernehmen aber diese Funktion liefert mir ja nur den thread handle zurück, soweit ich das richtig gelesen und verstanden habe.

Kann mir da jemand helfen?

Vielen Dank! :D
AHT
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 207



BeitragVerfasst: Fr 07.08.09 19:33 
An EAX kommst du über GetThreadContext. Ich schau morgen mal nach, ob das geht oder der Wert zu flüchtig ist.
uall@ogc
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1826
Erhaltene Danke: 11

Win 2000 & VMware
Delphi 3 Prof, Delphi 7 Prof
BeitragVerfasst: Sa 08.08.09 15:02 
Also wenn die dllmain keine endlosschleife beinhaltet und der Thread beendet ist kannst du mittels WaitForSingleObject auf das Threadende warten. Anschließend mit GetExitCodeThread bekommst du den ExitCode -> der sollte EAX zurückliefern, welches dem DLLHandle entspricht. Ansonsten shcau die mal die ToolHelp-API an (tlhelp32)

_________________
wer andern eine grube gräbt hat ein grubengrabgerät
- oder einfach zu viel zeit
Cypher2000 Threadstarter
Hält's aus hier
Beiträge: 15

Win XP
Delphi 7
BeitragVerfasst: Di 11.08.09 14:10 
Hallo!

Vielen Dank AHT und uall@ogc für eure Hilfe. :)
Leider kann ich mit diesem "EAX" nicht viel anfangen und war auch nicht erfolgreich damit. Aber mit tlhelp32 hab ich dann alles hinbekommen. :) (Hätte ich nur geahnt dass das so einfach geht... ;) )

Falls später jemand danach suchen sollte, hier der Code den ich in ähnlicher Form nach dem Injecten der DLL (siehe oben für Inject code) ausführe:
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
procedure TForm1.Button2Click(Sender: TObject);
var
  psnap,msnap: THandle;
  pe32: TProcessEntry32;
  me32: TModuleEntry32;

  buffer: Array [0..255of Byte;
  readbytes: Cardinal;

  foundp: Boolean;
begin
  psnap:=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
  pe32.dwSize := SizeOf(pe32);

  foundp:=false;

  if Process32First(psnap,pe32)=true then begin
    while Process32Next(psnap,pe32) do
      if LowerCase(pe32.szExeFile)='programmname.exe' then begin
        foundp:=true;
        break;
      end;
    CloseHandle(psnap);

    if foundp=true then begin
      me32.dwSize:=sizeof(me32);
      msnap:=CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,pe32.th32ProcessID);
      if Module32First(msnap,me32)=true then begin
        while Module32Next(msnap,me32)=true do begin
          if lowercase(me32.szModule)='dllname.dll' then begin

//an dieser stelle ist oder sollte in me32.modBaseAddr die basis adresse der "dllname.dll" sein die im prozess "programmname.exe" läuft

            break;
          end;
        end;
        CloseHandle(msnap);
      end;
    end;
  end;
end;


Leider weiß ich bis jetzt noch nicht zu 100% ob das alles korrekt läuft, da ich es mit ReadProcessMemory nicht testen kann.
Hier der neue Thread mit dem neuen Problem: www.delphi-forum.de/viewtopic.php?p=574073

Also wie gesagt: Vielen Dank für eure Hilfe! :)
uall@ogc
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1826
Erhaltene Danke: 11

Win 2000 & VMware
Delphi 3 Prof, Delphi 7 Prof
BeitragVerfasst: Mi 12.08.09 19:08 
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
program test;

uses
  Windows, Sysutils;

{$APPTYPE CONSOLE}

function InjectIntoProcess(lpProcessID: Cardinal; lpDllname: String): DWord;
var
  pWriteProcessMemory: function(hProcess: THandle; const lpBaseAddress: Pointer; lpBuffer: Pointer;
    nSize: DWORD; var lpNumberOfBytesWritten: DWORD): BOOL; stdcall;

  pCreateRemoteThread: function(hProcess: THandle; lpThreadAttributes: Pointer;
    dwStackSize: DWORD; lpStartAddress: TFNThreadStartRoutine; lpParameter: Pointer;
    dwCreationFlags: DWORD; var lpThreadId: DWORD): THandle; stdcall;

  pLoadLibraryA: function(lpLibFileName: PAnsiChar): HMODULE; stdcall;

  hProc: Cardinal;
  oAlloc: Pointer;
  cWPM: Cardinal;
  hRemThread: Cardinal;
  hThreadHandle: Cardinal;
  Modulhandle: Cardinal;

  hKernelhandle: Cardinal;
begin
  Result := 0;
  hKernelHandle := GetModuleHandle('kernel32.dll');
  if hKernelHandle <> 0 then
  begin
    pWriteProcessMemory := GetProcAddress(hKernelHandle, 'WriteProcessMemory');
    pCreateRemoteThread := GetProcAddress(hKernelHandle, 'CreateRemoteThread');
    pLoadLibraryA := GetProcAddress(hKernelHandle, 'LoadLibraryA');
    if (@pWriteProcessMemory <> niland (@pCreateRemoteThread <> niland (@pLoadLibraryA <> nilthen
    begin
      hProc := OpenProcess(PROCESS_ALL_ACCESS, false, lpProcessID);
      if hProc <> 0 then
      begin
        oAlloc := VirtualAllocEx(hProc, nil, length(lpDllname)+1, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
        if oAlloc <> nil then
        begin
          if pWriteProcessMemory(hProc, oAlloc, PChar(lpDllName), length(lpDllName), cWPM) then
          begin
            hThreadHandle := pCreateRemoteThread(hProc, nil0, @pLoadLibraryA, oAlloc, 0, hRemThread);
            if hThreadhandle <> 0 then
            begin
              WaitForSingleObject(hThreadhandle, INFINITE);
              VirtualFreeEx(hProc, oAlloc, 0, MEM_RELEASE);
              if GetExitCodeThread(hThreadHandle, ModulHandle) then
                Result := ModulHandle;
              CloseHandle(hThreadHandle);
            end;
          end;
        end;
        CloseHandle(hProc);
      end;
    end;
  end;
end;

begin
  Writeln(IntToHex(InjectIntoProcess(GetCurrentProcessID, 'opengl32.dll'),8));
  Writeln(IntToHex(GetModuleHandle('opengl32.dll'), 8));
  readLn;
end.


Update:
wichtige Funktionen werden dynamisch geladen, da bei WriteProcessMemory + CreateRemoteThread bei AntiVir ein Virus vermutet wird (da in der Import-Tabelle geladen), dynamisch wird dann nicht mehr gemeckert :)

_________________
wer andern eine grube gräbt hat ein grubengrabgerät
- oder einfach zu viel zeit