Autor Beitrag
Don Krawallo
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 45

Windows 10 x64
Delphi 10.4.1
BeitragVerfasst: Fr 24.09.10 07:44 
Schönen guten Morgen...

Ich habe mal eine recht kniffligge Frage meinerseits...

Folgender Fall...
Eine Dll wird ja dynamisch geladen, aber per CreateToolhelp32Snapshot etc. kann ma ja z.b. die BaseAddress oder Modulgröße
rausfinden.

Auf neueren Betriebssystemen gibts die Möglichkeit das eine EXE Datei ebenfalls dynamisch geladen wird.
"Dynamic Image Randomization" oder "Address Space Load Randomization" ist das Zauberwort.

Mich würde nun interessieren wie man dennoch bei einer solch geladenen EXE Datei an die BaseSize oder BaseAdress rankommt?

Danke schonmal im vorraus
Don Krawallo
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Fr 24.09.10 12:14 
Du hast in der System.pas ein HMODULE bzw. HINSTANCE (Name müsst ich nachgucken), der die Instanz-Handles für die Anwendung enthält. Historisch (Win 3.11) ist das gleichzeitig auch das Modulhandle der EXE = Basisadresse der EXE im Speicher.

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.


Zuletzt bearbeitet von BenBE am Sa 25.09.10 03:29, insgesamt 1-mal bearbeitet
Don Krawallo Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 45

Windows 10 x64
Delphi 10.4.1
BeitragVerfasst: Fr 24.09.10 17:17 
user profile iconBenBE hat folgendes geschrieben Zum zitierten Posting springen:
Du hast in der Windows.pas ein HMODULE bzw. HINSTANCE (Name müsst ich nachgucken), der die Handles für die Anwendung enthält. Historisch (Win 3.11) ist das gleichzeitig auch das Modulhandle der EXE = Basisadresse der EXE im Speicher.


Ganz ehrlich muss ich eingestehen das dass für mich chinesisches Neuland ist.

Um an die Module Base Addresse ranzukommen kommt ja der Befehl
ModuleEntry:= ModuleEntry.modBaseAddr
in Frage.

Allerdings funktioniert das so nur bei DLL oder anderen Dynamisch geladenen Dateien.
Könntest Du mir das an einem konkreten Codebeispiel zeigen?

MFG Don Krawallo
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Sa 25.09.10 03:26 
ausblenden Delphi-Quelltext
1:
2:
3:
4:
procedure TForm1.FormCreate(Sender: TObject);
begin
  Caption := IntToStr(System.MainInstance);
end;

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
Don Krawallo Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 45

Windows 10 x64
Delphi 10.4.1
BeitragVerfasst: Sa 25.09.10 21:33 
OK... Ich denke da komm ich mit...

Mein Problem ist aber, das ich von einem Fremden Prozess diese Informationen benötige.

Sieht im folgenden so aus:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
    ProcSnap:= CreateToolHelp32Snapshot(TH32CS_SnapProcess, 0);
    ProcessEntry.dwSize:= SizeOf(ProcessEntry);
    FindProcess:= Process32First(ProcSnap, ProcessEntry);
      ProcID:= -1;
    while FindProcess do begin
      if (CompareText(ProcessEntry.szExeFile, ProcessName) =0then
        ProcID := ProcessEntry.th32ProcessID;
        FindProcess := Process32Next(ProcSnap, ProcessEntry);
      end;
      CloseHandle(ProcSnap);
    if ProcID >= 0 then begin
      ProcOpen := OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcID);


Da komm ich also mit dem auslesen des eigenen(MainInstance) Prozesses nicht weiter.
Im übrigen bedanke mich ganz herzlich für Deine Geduld mir zu helfen.

Don Krawallo

EDIT:// Ich sehe grade... Du hast als Wohnort Jahnsdorf angegeben... Gehe ich richtig in der Annahme
das damit Jahnsdorf in Sachsen gemeint ist?
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Sa 25.09.10 22:06 
user profile iconDon Krawallo hat folgendes geschrieben Zum zitierten Posting springen:
OK... Ich denke da komm ich mit...

Mein Problem ist aber, das ich von einem Fremden Prozess diese Informationen benötige.

Okay, dann sieht die Sache etwas anders aus.

user profile iconDon Krawallo hat folgendes geschrieben Zum zitierten Posting springen:
Sieht im folgenden so aus:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
    ProcSnap:= CreateToolHelp32Snapshot(TH32CS_SnapProcess, 0);
    ProcessEntry.dwSize:= SizeOf(ProcessEntry);
    FindProcess:= Process32First(ProcSnap, ProcessEntry);
      ProcID:= -1;
    while FindProcess do begin
      if (CompareText(ProcessEntry.szExeFile, ProcessName) =0then
        ProcID := ProcessEntry.th32ProcessID;
        FindProcess := Process32Next(ProcSnap, ProcessEntry);
      end;
      CloseHandle(ProcSnap);
    if ProcID >= 0 then begin
      ProcOpen := OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcID);


Da komm ich also mit dem auslesen des eigenen(MainInstance) Prozesses nicht weiter.
Im übrigen bedanke mich ganz herzlich für Deine Geduld mir zu helfen.

Don Krawallo

Schau dich mal um bzgl. Abfragen der Modul-Liste in fremden Prozessen (müsste da auch erst suchen, könnt ggf. in der uallCollection drin sein). Und dort schauen, wohin der mit szExeName erhaltene Codeblock gemappt ist.

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
Don Krawallo Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 45

Windows 10 x64
Delphi 10.4.1
BeitragVerfasst: So 26.09.10 05:33 
user profile iconBenBE hat folgendes geschrieben Zum zitierten Posting springen:

Schau dich mal um bzgl. Abfragen der Modul-Liste in fremden Prozessen (müsste da auch erst suchen, könnt ggf. in der uallCollection drin sein). Und dort schauen, wohin der mit szExeName erhaltene Codeblock gemappt ist.


Das wird ja immer verwirrender... :?: :?: :?:
Gemäß der Tatsache das ich kein Delphi Genie bin und die UAllCollection schwierig zu kriegen ist, glaube ich sagen zu können das sich in dieser nichts dergleichen befindet was mir weiterhelfen könnte.
Oder ich habs ganz einfach nicht gefunden bzw. was übersehen.

Sieht aus als wäre mir das doch eine Nummer zu hoch... :(
SAiBOT
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 323
Erhaltene Danke: 6

XP SP2; 7
D7; D2009
BeitragVerfasst: Mo 27.09.10 21:32 
Ich habe dir mal eine Funktion geschrieben:
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:
function GetProcessBaseAddress(PID: Cardinal;
  var BaseAddress: Cardinal):Boolean;
var
  proc,fool,th: Cardinal;
  adr: Pointer;
begin
  proc := OpenProcess(PROCESS_ALL_ACCESS, False, PID);
  if proc = 0 then
    Exit(False);
  try
    adr := GetProcAddress(GetModuleHandle('kernel32.dll'), 'GetModuleHandleA');
    if not assigned(adr) then
      Exit(False);
    th := CreateRemoteThread(proc, nil0, adr, nil0, fool);
    if th = 0 then
      Exit(False);
    try
      WaitForSingleObject(th,INFINITE);
      Result := GetExitCodeThread(th,BaseAddress);
    finally
      CloseHandle(th);
    end;
  finally
    CloseHandle(proc);
  end;
end;


Sollte so funktionieren, wenn mich nicht alles täuscht!

_________________
Debuggers don't remove bugs, they only show them in slow-motion.
Don Krawallo Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 45

Windows 10 x64
Delphi 10.4.1
BeitragVerfasst: Mo 27.09.10 22:57 
Hallöchen @SAiBOT...

Danke auch für Deinen Beitrag.
Aber bei der Funktion versteh ich nur Bahnhof...

Die Funktion erwartet doch als Übergabeparameter eine Prozess ID und eine Base Address :?: :?: :?:

Aber genau diese Base Address suche bzw. benötige ich ja... D.h. das diese Base Address zu diesem Zeitpunkt eine Unbekannte ist.
Oder ich habe einfach ein Problem beim Aufrufen der Funktion...

grEEtZ Don Krawallo
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Mo 27.09.10 23:23 
Beachte das var in der Parameterliste. Sollte aber eigentlich eher ein out sein IMHO.

Und bzgl. Prozess-ID: Ist halt die Prozess-ID, für die du das wissen möcht. Über den Rückgabewert erhälst Du, ob die Basisadresse ermittelt werden konnte.

@user profile iconSAiBOT: Netter Hack ;-)

@user profile iconDon Krawallo: Zur Erklärung: Der Code ruft über einen Remote-Thread die Funktion kernel32.GetModuleHandle auf. Und was die für den Fall eines Null-Pointers für den Modul-Namen zurückliefert, steht in der MS-Doku.

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
Don Krawallo Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 45

Windows 10 x64
Delphi 10.4.1
BeitragVerfasst: Di 28.09.10 23:56 
Moderiert von user profile iconNarses: Komplett-Zitat des letzten Beitrags entfernt.

Ok, nach langem studieren der MSDN Database denk ich hab ich das soweit verstanden.

Und wie ich im letzten Posting schon schrieb
user profile iconDon Krawallo hat folgendes geschrieben Zum zitierten Posting springen:
...Oder ich habe einfach ein Problem beim Aufrufen der Funktion...

Genau da liegt jetzt das Problem.
Im Folgenden sieht das so aus...
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
procedure TForm1.Button1Click(Sender: TObject);
begin
    ProcSnap:= CreateToolHelp32Snapshot(TH32CS_SnapProcess, 0);
    ProcessEntry.dwSize:= SizeOf(ProcessEntry);
    FindProcess:= Process32First(ProcSnap, ProcessEntry);
      ProcID:= 0;
    while FindProcess do begin
      if (CompareText(ProcessEntry.szExeFile, ProcessName) =0then
        ProcID := ProcessEntry.th32ProcessID;
        FindProcess := Process32Next(ProcSnap, ProcessEntry);
      end;
    CloseHandle(ProcSnap);
      if ProcID > 0 then begin
         ProcBaseAddy:= GetProcessBaseAddress(ProcID, ?????);        // Hier raff ich nich was da anstelle der Fragezeichen hingehört

      end;
end;


Den Kopf der Funktion hab ich dahingehend abgeändert var ---> out.

grEEtZ Don Krawallo
Sinspin
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1335
Erhaltene Danke: 118

Win 10
RIO, CE, Lazarus
BeitragVerfasst: Mi 29.09.10 10:42 
Nachdem user profile iconBenBE das so schön erklärt hat ist doch alles ganz einfach. Du musst lediglich user profile iconSAiBOTs Funktion in deinen Quelltext kopieren und verwenden. Was ist daran denn nun zu schwehr!? Du must nix ändern oder dir irgend einem Kopf um irgendwelche Parameter machen.
Du übergibst die PID = Process Id und bekommst die BaseAddress als zweiten Parameter zurück.
Weißt du überhaupt was Ausgabeparameter (alt : var; jetzt : out) überhaupt sind? Du übergibst eine Variable bei der es im Normalfall total egal ist was bei der Übergabe an die Funktion drinne steht. Aber nach der Funktion ist der Inhalt der Variablen interessant. Hoffentlich habe ich dich damit jetzt nicht wieder überfordert.

Was ich aber gerne noch wissen möchte, wofür brauchst du das? Du willst bei einem laufenden Process den BP wissen, was sollte es dafür für eine sinnvolle Verwendung geben? Mir fallen mur illegale ein.
Du bist ziemlich neu hier, da muss ich diese Frage einfach stellen. Wir haben einfach keine Lust "irgendjemandem" dabei zu helfen seinen ersten Hack :lol: zu machen.

_________________
Wir zerstören die Natur und Wälder der Erde. Wir töten wilde Tiere für Trophäen. Wir produzieren Lebewesen als Massenware um sie nach wenigen Monaten zu töten. Warum sollte unser aller Mutter, die Natur, nicht die gleichen Rechte haben?
Don Krawallo Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 45

Windows 10 x64
Delphi 10.4.1
BeitragVerfasst: Mi 29.09.10 16:05 
user profile iconSinspin hat folgendes geschrieben Zum zitierten Posting springen:
Was ich aber gerne noch wissen möchte, wofür brauchst du das? Du willst bei einem laufenden Process den BP wissen, was sollte es dafür für eine sinnvolle Verwendung geben? Mir fallen mur illegale ein.
Du bist ziemlich neu hier, da muss ich diese Frage einfach stellen. Wir haben einfach keine Lust "irgendjemandem" dabei zu helfen seinen ersten Hack :lol: zu machen.


Diese Frage ist natürlich berechtigt und ich will sie gern beantworten um dieses Misstrauen aus dem Weg zu räumen.
Und zwar dreht sich das ganze um ein PC Spiel. Um genau zu sein "Halo 2". Und um das Thema Trainer Creation. Im Normalfall hat so ein Spiel eine feste BaseAddress. Bei diesem Spiel ist das allerdings nicht so. Die EXE bzw. Startdatei verhält sich in diesem Sinne wie eine DLL. Das Problem ist das diese EXE auch nicht von einem anderen Process geladen wird so dass man per SnapModule und letztenendes per th32ModBaseAddr an die BaseAddress rankommmen könnte.

Ich muss natürlich eingestehen das ich auch grade erst dabei bin mich in die Thematik "Funktionen" einzulesen. Allerdings hab ich nur Beispiele gesehen die folgendermaßen aussehen:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
Function SummeAusDrei (zahl1, zahl2, zahl3: integer): integer;
begin
result:= zahl1 + zahl2 + zahl3;
end;

Um genau zu sein bezieht sich das auf die Seite:
www.delphi-treff.de/...uren-und-funktionen/

Aber um Deine Frage bezüglich was daran so schwer ist zu beantworten...
Egal wie oder mit/ohne welchen Parametern ich diese Funktion aufrufe bekomm ich nen Compilerfehler...
Wird nur "ProcID" übergeben --> Nicht genügend wirkliche Parameter.
Ansonsten --> [DCC Fehler] Unit1.pas(170): E2033 Die Typen der tatsächlichen und formalen Var-Parameter müssen übereinstimmen

grEEtZ Don Krawallo

Moderiert von user profile iconNarses: Überflüssige Zeilenumbrüche/Leerzeilen entfernt.
Sinspin
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1335
Erhaltene Danke: 118

Win 10
RIO, CE, Lazarus
BeitragVerfasst: Mi 29.09.10 16:30 
Es ist eigentlich ganz einfach:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
Procedure DoIt; // deine Procedure die die ProcessId ermittelt und nun die BaseAddress haben will.
var
  OutBaseAddress: Cardinal; // der Rückgabeparameter den du mit übergeben muss, "Out" habe ich nur der Lesbarkeit halber davor gesetzt
  PID: Cardinal;

begin
  PID := GibMirNenPID;
  if GetProcessBaseAddress(PID, OutBaseAddress) then
  begin
    // mache was mit der erhaltenen BaseAddress (OutBaseAddress)
  end;
end;


Wenn man mit Out(var)-Parametern arbeitet muss man beachten das die Typen des Parameters und der Variablen die man verwendet 100% identisch sein müssen.

_________________
Wir zerstören die Natur und Wälder der Erde. Wir töten wilde Tiere für Trophäen. Wir produzieren Lebewesen als Massenware um sie nach wenigen Monaten zu töten. Warum sollte unser aller Mutter, die Natur, nicht die gleichen Rechte haben?
Don Krawallo Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 45

Windows 10 x64
Delphi 10.4.1
BeitragVerfasst: Mi 29.09.10 17:52 
Moderiert von user profile iconNarses: Komplett-Zitat des letzten Beitrags entfernt.

Also irgendwie komm ich mir verarscht vor. Nein nicht von Dir, BenBE oder Saibot... Nein vielmehr von Delphi.
Ich habe mal das ganze so übernommen. Das die Variablendeklarationen übereinstimmen da hab ich schon aufgepasst.
Also soweit kenn ich mich mit Delphi schon aus.
Aber... Es funktioniert nachwievor nicht. :?:

Ganz einfach mal ein anderes Beispiel... Habe das ganze mal ganz neu aufgesetzt. Habe ne neue Formularanwendung mit einem Button1 sowie ein Editfeld kreiert. Als Beispiel habe ich Firefox genommen weils auch relativ bekannt ist.
Im folgenden mal der Sourcecode inkl. Funktion etc. etc.
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:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    procedure Button1Click(Sender: TObject);
    function GetProcessBaseAddress(PID: Cardinal; var BaseAddress: Cardinal):Boolean;   // Hier wird die Funktion implementiert
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;                           // Hier sind sämtliche Deklarationen meiner Prozedur Button1Click
  hSnapshot: Thandle;
  ProcessEntry: ProcessEntry32;
  Schleife: Boolean;
  pD: Cardinal;                            // Uhrsprünglich war in der Variable pID die ProcessID abgelegt
                                           // umbenannt zu pD der Deutlichkeit halber
  Const ProcessName = 'Firefox.exe';

implementation

{$R *.dfm}

function GetProcessBaseAddress(PID: Cardinal; var BaseAddress: Cardinal):Boolean;   // Das ist die Funktion, nicht abgeändert
var                                                                                 // völlig "Original"
  proc,fool,th: Cardinal;
  adr: Pointer;
begin
  proc := OpenProcess(PROCESS_ALL_ACCESS, False, PID);
  if proc = 0 then
    Exit(False);
  try
    adr := GetProcAddress(GetModuleHandle('kernel32.dll'), 'GetModuleHandleA');
    if not assigned(adr) then
      Exit(False);
    th := CreateRemoteThread(proc, nil0, adr, nil0, fool);
    if th = 0 then
      Exit(False);
    try
      WaitForSingleObject(th,INFINITE);
      Result := GetExitCodeThread(th,BaseAddress);
    finally
      CloseHandle(th);
    end;
  finally
    CloseHandle(proc);
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  OutBaseAddress: Cardinal; // der Rückgabeparameter den du mit übergeben muss, "Out" habe ich nur der Lesbarkeit halber davor gesetzt
  PID: Cardinal;

begin                                                                 // Ab hier werden die Prozesse nach "Firefox.exe" gefiltert
  hSnapshot := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  ProcessEntry.dwSize := Sizeof(ProcessEntry);
  Schleife := Process32First(hSnapshot, ProcessEntry);
  pD := 0;                                                            // pD vorher auf 0 (NULL) setzen
    while Schleife do begin
      if (CompareText(ProcessEntry.szExeFile, ProcessName) = 0then  // Wenn der Prozess "Firefox.exe" gefunden wurde
      pD := ProcessEntry.th32ProcessID;                               // dann wird in pD die ProcessID abgelegt
      Schleife := Process32Next(hSnapshot, ProcessEntry);             // ansonsten von vorn beginnen
    end;
  CloseHandle(hSnapshot);                                             // Schließen des Snapshots
    if pD > 0 then begin                                              // Wenn pD größer 0 (NULL) dann übergabe an Funktion "GetProcessBaseAddress
       PID := pD;                                                     // Der Verdeutlichung halber wird die ProcessID
                                                                      //   die ja in pD abgelegt ist, nach PID verschoben
       if GetProcessBaseAddress(PID, OutBaseAddress) then
        NewAddy:= OutBaseAddress;                                     // Hier wird/sollte die ermittelte Basis Addresse in die
       end;                                                           //   Variable NewAddy geschoben werden
    end;
end;

end.


Entweder kann mich Delphi net leiden oder Funktionen sind mir doch noch eine Nummer zu hoch.
Wenn ihr natürlich ein gutes Tutorial habt oder eine Internetseite wisst die die Problematik Funktionen
ausführlich behandelt... Immer her damit.
Habe mich auch schon nach Büchern umgeguckt, aber der Büchermarkt ist recht spärlich besäht was Delphi Bücher anbelangt.

Viele Grüße
Don Krawallo
SAiBOT
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 323
Erhaltene Danke: 6

XP SP2; 7
D7; D2009
BeitragVerfasst: Mi 29.09.10 18:46 
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:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  hSnapshot: Thandle;
  ProcessEntry: ProcessEntry32;
  Schleife: Boolean;
  pD: Cardinal;                            // Uhrsprünglich war in der Variable pID die ProcessID abgelegt
                                           // umbenannt zu pD der Deutlichkeit halber
  Const ProcessName = 'Firefox.exe';

implementation

{$R *.dfm}

function GetProcessBaseAddress(PID: Cardinal; var BaseAddress: Cardinal):Boolean;   // Das ist die Funktion, nicht abgeändert
var                                                                                 // völlig "Original"
  proc,fool,th: Cardinal;
  adr: Pointer;
begin
  proc := OpenProcess(PROCESS_ALL_ACCESS, False, PID);
  if proc = 0 then
    Exit(False);
  try
    adr := GetProcAddress(GetModuleHandle('kernel32.dll'), 'GetModuleHandleA');
    if not assigned(adr) then
      Exit(False);
    th := CreateRemoteThread(proc, nil0, adr, nil0, fool);
    if th = 0 then
      Exit(False);
    try
      WaitForSingleObject(th,INFINITE);
      Result := GetExitCodeThread(th,BaseAddress);
    finally
      CloseHandle(th);
    end;
  finally
    CloseHandle(proc);
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  OutBaseAddress: Cardinal; // der Rückgabeparameter den du mit übergeben muss, "Out" habe ich nur der Lesbarkeit halber davor gesetzt
  PID: Cardinal;

begin                                                                 // Ab hier werden die Prozesse nach "Firefox.exe" gefiltert
  hSnapshot := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  ProcessEntry.dwSize := Sizeof(ProcessEntry);
  Schleife := Process32First(hSnapshot, ProcessEntry);
  pD := 0;                                                            // pD vorher auf 0 (NULL) setzen
  while Schleife do
  begin
    if (CompareText(ProcessEntry.szExeFile, ProcessName) = 0then  // Wenn der Prozess "Firefox.exe" gefunden wurde
      pD := ProcessEntry.th32ProcessID;                               // dann wird in pD die ProcessID abgelegt
    Schleife := Process32Next(hSnapshot, ProcessEntry);             // ansonsten von vorn beginnen
  end;
  CloseHandle(hSnapshot);                                             // Schließen des Snapshots
  if pD > 0 then
  begin                                              // Wenn pD größer 0 (NULL) dann übergabe an Funktion "GetProcessBaseAddress
    PID := pD;                                                     // Der Verdeutlichung halber wird die ProcessID                                                                //   die ja in pD abgelegt ist, nach PID verschoben
    if GetProcessBaseAddress(PID, OutBaseAddress) then
      Edit1.Text := IntToStr(OutBaseAddress);                                     // Hier wird/sollte die ermittelte Basis Addresse in die
  end;                                                           //   Variable NewAddy geschoben werden
end;
//end;
end.


So sollte es gehen... und jetzt beschäftige dich bitte erstmal mit den Grundlagen.

_________________
Debuggers don't remove bugs, they only show them in slow-motion.
Don Krawallo Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 45

Windows 10 x64
Delphi 10.4.1
BeitragVerfasst: Mi 29.09.10 23:53 
Mit den Grundlagen beschäftigen ist ja schön und gut... Ich habe auch nichts dagegen selbst etwas zu "er"lernen.

Mit der Editbox komm ich klar bzw. mit der Stringverarbeitung. Das stellt für mich kein Problem dar. Ich hatte dieses Beispiel:
ausblenden Delphi-Quelltext
1:
NewAddy:= OutBaseAddress;					

deswegen gewählt um zu sehen ob sich überhaupt was tut, bzw. ob wieder eine Compilerwarung bzw. ein Fehler kommt. Ok zugegeben, war vielleicht auch ein schlechtes Beispiel.

Der Schlüssel liegt eher darin:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
type
  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    procedure Button1Click(Sender: TObject);
    // Bei mir war hier noch die Funktion eingebunden

Jetzt und dafür wäre ich Dir/Euch sehr dankbar, erklär mir doch bitte mal einer warum diese Funktion nicht eingebunden werden muss?
Im nachhinein betrachtet kann ich auch behaupten: "Das ist doch recht einfach."
Ihr könnt es, ich möchte - nein, WILL - es lernen.

Also, warum wird diese nicht unter "Type" eingebunden?

Ansonsten... Bedanke ich mich ganz aufrichtig für eure Geduld und Mühe und wünsche noch eine Gute Nacht.
Don Krawallo

Moderiert von user profile iconNarses: Überflüssige Zeilenumbrüche/Leerzeilen entfernt.
Sinspin
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1335
Erhaltene Danke: 118

Win 10
RIO, CE, Lazarus
BeitragVerfasst: Do 30.09.10 10:34 
Ich kann wirklich nicht verstehen warum du lieber hier fragst und auf eine Antwort wartest anstatt einfach mal deinen Quelltext anzusehen den du vor der Nase hast :gruebel:
Da ist ganz deutlich drinne zu erkennen das du unter "type" eine Klassendeklaration hast. Bisher ist in dieser eine Methode, die Procedure "Button1Click", deklariert. Willst du diese Methode implementieren, was für dich ja teilweise von der IDE erledigt wurde, damm musst du ja schreiben:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
...
implementation

procedure TForm1.Button1Click(Sender: TObject);
begin
end;
...

Fügst du eine weitere Methode (function oder procedure) hinzu musst du natürlich auf die gleiche Weise vorgehen.
Allerdings ist der obere Abschnitt der Klassendeklaration, also alles oberhalb von "private" der IDE vorbehalten. Du solltest die function unter "private" einfügen (deklarieren)
Oder, du lässt es wie es bisher ist, dann gehört die function nicht zu deiner Klasse, du kannst sie aber trotzdem nutzen. Und auch in jeder anderen Klasse die du in der gleichen Datei deklarierst und implementierst.

PS: Delphi hasst dich nicht, du wehrst dich nur immernoch dagegen das es dich lieb hat :wink:

_________________
Wir zerstören die Natur und Wälder der Erde. Wir töten wilde Tiere für Trophäen. Wir produzieren Lebewesen als Massenware um sie nach wenigen Monaten zu töten. Warum sollte unser aller Mutter, die Natur, nicht die gleichen Rechte haben?

Für diesen Beitrag haben gedankt: BenBE
Don Krawallo Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 45

Windows 10 x64
Delphi 10.4.1
BeitragVerfasst: Do 30.09.10 12:13 
Aaahhhhhh, jetz wird mir das schon klarer... Was für ne Blamage.

ausblenden Delphi-Quelltext
1:
function GetProcessBaseAddress(PID: Cardinal; var BaseAddress: Cardinal):Boolean; forward;					

Dazu habe ich dann erfahren/gelesen das eine Funktion ab Beginn der Definition gültig bzw. bekannt ist. Soll diese schon vorher bekannt sein dann muss diese wie oben angezeigt mit dem Parameter "forward" eingebunden sein.
Wird also die Funktion schon am Anfang der Form geschrieben kann von allen nachfolgenden Prozeduren drauf zugegriffen werden.

grEEtZ Don Krawallo
Don Krawallo Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 45

Windows 10 x64
Delphi 10.4.1
BeitragVerfasst: So 21.08.11 19:35 
Guten Tag...

Nach langer Zeit hab ich mich mal wieder dran gesetzt. Hab jetz ne knappe Stunde programmiert, probiert und die hier geschriebenen Beiträge gelesen und im einfachsten Sinne nachprogrammiert. Mittlerweile funktioniert das Ganze auch ohne Probleme. Hab nämlich grade selbst das Problem gehabt das, und das kann ma ja sagen, dass Spiel Two Worlds 2 oder besser gesagt die EXE Datei selbst dynamisch geladen wird.
Zum besseren Verständnis...
Einmal war die Basisadresse 0xC00000, ein anderes mal 0xD20000. Und da kommt man ja mit dem herkömmlichen schreiben in fremden Prozessen nicht weiter. Eben genau der Fall wie ich ihn im ersten Beitrag beschrieben hate.

An dieser Stelle möchte ich mich ganz einfach nochmal herzlich bei allen Beitragschreibern bedanken für ihre Geduld und Hilfestellungen. Insbesondere aber auch @SAiBOT für seine zur Verfügung gestellte Funktion - Danke SAiBOT!!!

MFG
Don Krawallo