Funktionspointer help

07/16/2008 19:15 wadimwadim#1
Hallo,
habe ein Problem. Nehmen wir an diese Adresse ist ein Funktionspointer (00A12345) in einem fremden Prozess. Nun möchte ich diese Funktion aufrufen. Dazu habe ich folgendes versucht... Ich habe eine dll erstellt, die diese Funktion aufrufen soll.
Die struct stimmt!

DELPHI 6
Code:
library MoveFunction;

uses
  Windows,
  Messages,
  SysUtils,
  Variants,
  Classes,
  Graphics,
  Controls,
  Forms,
  Dialogs;

function MoveToPos (PosX: Single; PosY: Single; PosZ:Integer):Single;stdcall;
begin
  asm
    push PosX
    push PosY
    push PosZ
    call [$00A12345] // bsp.
  end;
end;

exports
  MoveToPos;
begin
end.
Müsste doch eigentlich gehen...
Oder wie würdet ihr so eine Funktion aufrufen?
07/17/2008 11:26 verT!c4L#2
Na mit C,sry aber von Delphi hab ich kein Plan, und bin auch stolz darüber :P
07/17/2008 13:33 mr.rattlz#3
Ich bin mir über die Assemblersyntax in Delphi nicht ganz sicher, also ob die [] um die Adresse gehören oder nicht, was ich allerdings weiß ist dass, damit der Aufruf funktioniert, die DLL von dem von dir genannten Programm geladen sein muss. Jedes Programm im Speicher hat ja seinen privaten Adressbereich, und dein Aufruf findet natürlich innerhalb des Programms statt, das die DLL geladen hat.
[Only registered and activated users can see links. Click Here To Register...] ist dein Freund.

Um den Assemblerteil zu verstehen muss man übrigens gar keine Ahnung von Delphi haben, die Aussage von verT!c4L war also absoluter Müll :p
07/17/2008 14:28 wadimwadim#4
OK... thx erstmal an die schnellen Antworten von euch. Die Syntax sollte so stimmen; Meine eigentliche Frage war ja, ob das überhaupt die Func aufrufen würde. Hat sich somit alles geklärt.


Gruß

wadimwadim
07/17/2008 19:30 Term!nX#5
Um eine DLL in einen anderen Prozess zu injecten - denn das lese ich des öfteren, konnte mir nur nie was darunter vorstellen - erstelle ich einen Thread mit CreateRemoteThread und lasse diesen Thread auf die DLL zugreifen?
Hat dieser Thread eigentlich volle Zugriffsrechte auf den Adressbereich des anderen Prozesses (zB ein Spiel)?

Im Endeffekt erstelle ich den Prozess in dem Adressbereich des anderen Prozesses und kann dann die Funktionen des anderen Prozesses benutzen?
07/17/2008 20:37 mondesser#6
Du musst den Prozess irgendwie dazu bringen, deine Dll zu laden. Dann führt der andere Prozess deine DllMain in seinem Speicher aus. Und damit hat deine Dll vollen Zugriff auf seinen Speicher.
Dazu gibt es viele Möglichkeiten, eine währe, den Prozess von deinem Prozess aus zu starten, und deine Dll gleich mit zu übergeben.
Eine andere währe, per WriteProcessMemory einen LoadLibraryA(deine dll) befehl in eine Code Cave in den Zielprozess zu schmuggeln und ein jmp irgendwo im code so umbiegen, dass es auf die Code Cave zeigt.

Du kannst auch ein malloc einschmuggeln, das dann genug platz alloziert für deine Funktion, in diesen neuen Platz kopierst du dann per WriteProcessMemory deine ganze Funktion.

Alternativ kannst du auch Speicher im Fremden Prozess reservieren mit VirtualAllocEx und da deinen coden reinschreiben...gibt endlos viele möglichkeiten.

Im großen und ganzen geht es immer darum, irgendwie 1-2 Zeilen code in den Speicher des Prozesses zu schmuggeln, und den Prozess dazu zu bringen sie auszuführen.
Die 1-2 Zeilen laden dann deine Dll, und die tut alles weitere.

Sry fals der Text etwas verwirrend ist, hab das ganze schon seit zwei Jahren nichtmehr gemacht und schreibe das so ausm kopf runter, hoffe das stimmt so einigermaßen alles. Einfach mal googlen, gibt viele gute Tutorials.
Und wenn du das nur zu legalen zwecken nutzt, gibt es sogar von M$ eine Bibliothek die das ganze enorm vereinfacht : [Only registered and activated users can see links. Click Here To Register...]

Mr. rattlz kann das sicherlich alles viel besser und richtiger erklären, aber so ganz grob die Richtung müsste ich getroffen haben :P
07/17/2008 20:53 wadimwadim#7
so würde es dann aussehen, wenn du eine dll in ein process injezieren möchtest. (nicht der ganze code)



Code:
function GetProcessID(Exename: string): DWORD;
var
  hProcSnap         : THandle;
  pe32              : TProcessEntry32;
begin
  result := 0;
  hProcSnap := CreateToolHelp32SnapShot(TH32CS_SNAPPROCESS, 0);
  if hProcSnap <> INVALID_HANDLE_VALUE then
  begin
    pe32.dwSize := SizeOf(ProcessEntry32);
    if Process32First(hProcSnap, pe32) = true then
    begin
      while Process32Next(hProcSnap, pe32) = true do
      begin
        if pos(Exename, pe32.szExeFile) <> 0 then
          result := pe32.th32ProcessID;
      end;
    end;
    CloseHandle(hProcSnap);
  end;
end;

function GetProcessHandleFromID(ID: DWORD): THandle;
begin
  result := OpenProcess(PROCESS_CREATE_THREAD or PROCESS_QUERY_INFORMATION or PROCESS_VM_OPERATION or PROCESS_VM_WRITE
    or PROCESS_VM_READ, False, ID);
end;


var
  ProcessID         : Integer;
  hProcess          : THandle;
  DLLPath           : string;
  pDLLPath          : Pointer;
  BytesWritten      : Cardinal;
  ThreadID          : Cardinal;
  DLLFILENAME       : string;
begin
  DLLFILENAME:= 'XM.dll';  // DLL NAME
  ProcessID := GetProcessID('Gw.exe');
  Writeln ('DLL Injector');
  DLLPath := ExtractFilePath(ParamStr(0)) + '\' + DLLFILENAME;
  if ProcessID <> 0 then
  begin
    hProcess := GetProcessHandleFromID(ProcessID);
    if hProcess <> 0 then
    begin
      pDLLPath := VirtualAllocEx(hProcess, nil, Length(DLLPath), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
      if Assigned(pDLLPath) then
      begin
        if WriteProcessMemory(hProcess, pDLLPath, PChar(DLLPath), Length(DLLPath), BytesWritten) then
        begin
          if CreateRemoteThread(hProcess, nil, 0, GetProcAddress(GetModuleHandle('kernel32.dll'), 'LoadLibraryA'),
            pDLLPath, 0, ThreadID) <> 0 then
          begin
            CloseHandle(hProcess);
            Writeln('DLL injected... ' + DLLFILENAME);
          end
          else
          Writeln('CreateRemoteThread error');
        end
        else
        Writeln('WriteProcessMemory error');
      end
      else
      Writeln('VirtualAllocEx error');
    end
    else
    Writeln('hProcess error');
  end
  else
  Writeln('ProcessID error');
  Readln;
end.
07/17/2008 22:42 Atheuz#8
Quote:
Originally Posted by mondesser View Post
Sry fals der Text etwas verwirrend ist, hab das ganze schon seit zwei Jahren nichtmehr gemacht und schreibe das so ausm kopf runter, hoffe das stimmt so einigermaßen alles. Einfach mal googlen, gibt viele gute Tutorials.
Und wenn du das nur zu legalen zwecken nutzt, gibt es sogar von M$ eine Bibliothek die das ganze enorm vereinfacht : [Only registered and activated users can see links. Click Here To Register...]
Wurden nicht aus der Detours Library einige Befehle gelöscht die man eigentlich dazu braucht?