Autor Beitrag
Tobi482
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 135



BeitragVerfasst: Mo 04.09.06 09:39 
Hi Leute,

meine Assemblerkenntnisse sind sehr begrenzt und daher wende ich mich an euch. Zu nächst wüsste ich gern etwa grundlegendes. Dieser Code ist eine CALL mit einer dahinter angehängten Adresse.
ausblenden Quelltext
1:
2:
         
00XXXXXX E86346FCFF              call 004F9EB0

Schaue ich mir weitere CALL's an, sehe ich, dass "E8" vermutlich der OpCode für Call ist und der Rest dahinter die Addresse ist "63 46 FC FF".

1 Frage:
Wie wird "63 46 FC FF" in 004F9EB0 umgerechnet?

Dies aber nur am Rande. Der Call und seine Parameter sind mir bekannt und die darunter stehende Zeile zeigt, dass es sich vermutlich um ein Parameter handelt.
ausblenden Quelltext
1:
00XXXXXX 83C404                  add esp, 00000004					

2. Frage
Ich habe einen fertig deklariert den Header für diese Subroutine und würde gerne eine Trampolin-Funktion einbauen, so dass der Aufruf des Calls unweigerlich mit dem Aufruf meiner Trampoling-Funktion verbunden ist, im grunde eine Art Hook.

Gibts es für soetwas fertige Codeschnipsel, Units, Dll's etc?

Wie nennt man soetwas? Patching? Call redirecting?

Hoffe ihr könnte mir weiter helfen.
Schon mal herzlichen Dank im Voraus.

Mit freundlichen Grüßen Tobi
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 04.09.06 13:39 
user profile iconTobi482 hat folgendes geschrieben:
Hi Leute,

meine Assemblerkenntnisse sind sehr begrenzt und daher wende ich mich an euch. Zu nächst wüsste ich gern etwa grundlegendes. Dieser Code ist eine CALL mit einer dahinter angehängten Adresse.
ausblenden Quelltext
1:
2:
         
00XXXXXX E86346FCFF              call 004F9EB0

Schaue ich mir weitere CALL's an, sehe ich, dass "E8" vermutlich der OpCode für Call ist und der Rest dahinter die Addresse ist "63 46 FC FF".

1 Frage:
Wie wird "63 46 FC FF" in 004F9EB0 umgerechnet?

Adresse hinter dem CALL-Befehl + Wert hinter dem CALL. Beispiel ...
Ausgehend von deinem Code stand dieser CALL an Offset $00535818. Da ein CALL mit relativer Adressangabe (Opcode E8) 5 Bytes lang ist, ist EIP nach der Ausführung $0053581D, was die Ausgangsadresse des Aufrufs ist. Da Du immer LSB-First speicherst, steht hinter dem CALL nicht "63 46 FC FF" sondern die Zahl $FFFC4663, die Du einfach zu der Ausgangsposition hinzuaddierst $0053581D + $FFFC4663 = $004F9EB0 ;-)

user profile iconTobi482 hat folgendes geschrieben:
Dies aber nur am Rande. Der Call und seine Parameter sind mir bekannt und die darunter stehende Zeile zeigt, dass es sich vermutlich um ein Parameter handelt.
ausblenden Quelltext
1:
00XXXXXX 83C404                  add esp, 00000004					

Nope ;-) Voraussichtlich eine lokale Variable ;-) Wobei dieser Source dazu nicht ganz ausreicht, da man sowohl die Zeilen VOR dem Aufruf, als auch die ersten 5-7 Zeilen der aufgerufnen Funktion benötigt um das ganz genau zu sagen (weil sich daraus auch die Aufrufkonvention ergibt).

user profile iconTobi482 hat folgendes geschrieben:
2. Frage
Ich habe einen fertig deklariert den Header für diese Subroutine und würde gerne eine Trampolin-Funktion einbauen, so dass der Aufruf des Calls unweigerlich mit dem Aufruf meiner Trampoling-Funktion verbunden ist, im grunde eine Art Hook.

Gibts es für soetwas fertige Codeschnipsel, Units, Dll's etc?

Gibt's massig ... U.a. z.B. die uallCollection, madHook, ...

user profile iconTobi482 hat folgendes geschrieben:
Wie nennt man soetwas? Patching? Call redirecting?

Allgemein Hook, und je nach dem, wie Du umleitest unterscheidet man zwischen IAT, Code Overwriteing, Code Injection und noch diversen anderen Hooks ...

user profile iconTobi482 hat folgendes geschrieben:
Hoffe ihr könnte mir weiter helfen.
Schon mal herzlichen Dank im Voraus.

Mit freundlichen Grüßen Tobi

MfG,
BenBE.

_________________
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.
Tobi482 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 135



BeitragVerfasst: Mo 04.09.06 14:26 
Supi,

Danke für deine Anwort :-D

So, nun haben sich doch noch ein paar Fragen aufgetan. Der Code sieht wie folgt aus.
ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
:00535816 8B45E0                  mov eax, dword ptr [ebp-20]
:00535819 8B88485F0000            mov ecx, dword ptr [eax+00005F48]
:0053581F 034DFC                  add ecx, dword ptr [ebp-04]
:00535822 8B55E0                  mov edx, dword ptr [ebp-20]
:00535825 898A485F0000            mov dword ptr [edx+00005F48], ecx
:0053582B 8B45E0                  mov eax, dword ptr [ebp-20]
:0053582E 8B4DE0                  mov ecx, dword ptr [ebp-20]
:00535831 8B90485F0000            mov edx, dword ptr [eax+00005F48]
:00535837 3B91505F0000            cmp edx, dword ptr [ecx+00005F50]
:0053583D 7526                    jne 00535865
:0053583F 8B45E0                  mov eax, dword ptr [ebp-20]
:00535842 0508400000              add eax, 00004008
:00535847 50                      push eax

:00535848 E86346FCFF              call 004F9EB0    <--- der erwähnte Call

:0053584D 83C404                  add esp, 00000004
:00535850 85C0                    test eax, eax
:00535852 7504                    jne 00535858
:00535854 33C0                    xor eax, eax
:00535856 EB12                    jmp 0053586A


Ich dachte bisher, das hier ein Parameter, vermutlich ein Pointer zu einem Bytearray, in den Stack geschoben wird.
ausblenden Quelltext
1:
:00535847 50                      push eax					

Und, dass hier der Stack erhöht wird, um den Rückgabewert(4 Byte) des Call's im Stack zu sichern.
ausblenden Quelltext
1:
:0053584D 83C404                  add esp, 00000004					

Daher hatte ich eine Function wie hier erwartet.
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
var
       Hook_Next : function(a:Pointer):integer;stdcall;

function Hook_Callback(a:Pointer):integer;stdcall;
begin
      Result := Hook_Next(a);
end;


1 Frage:
Bist du dir ganz sicher, dass es sich dabei wirklich um Variabeln handelt?


Ich habe mir die von dir empfohlenen Units, speziell die uallCollectiont, angesehen.
Die Funktion die dabei für mich interessant ist, ist vermutlich die "uallhook.HookCodeNt"

Die Funktion möchte ein orgFunc:Pointer einen CallbackFunc:Pointer und einen NewFunc:Pointer haben
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:
var
       Hook_Next : function(a:Pointer):integer;stdcall;

...

function Hook_Callback(a:Pointer):integer;stdcall;
begin
      //mach ekligen Krach wenn's klappt!
      Beep(3000,1000);
      Result := Hook_Next(a);
end;

...

procedure Patch_Func;
var
     p : Integer;
begin
     p := $00535848;
     if uallhook.HookCodeNt(Ptr(p), @Hook_Callback, @Hook_Next) then
     begin
           //mach Krach wenn's geklappt hat !
           Beep(1000,1000);
     end;
end;


2 Frage:
Wo startet die Originalfunktion? Bei p := $00535848; ??? Davor? Dahinter? Die anderen Parameter kann ich über den @-Operator bestimmen.


Mit freundlichen Grüßen
Tobi
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: Mo 04.09.06 14:45 
Hi Tobi,
wenn du die uallCollection dafür verwendest (uallHook.HookCode) [das NT wird nur intern verwendet] dann solltest du immer die Adresse angeben wo die Funktion anfängt.
D.h. in deinem Fall ist es nicht 00535848 sondern 004F9EB0.

Für einen E8 hook kannst du das natürlich selbst berechnen.
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
  myFunctiob := Addr;
  origFunction := Addr; //bla e8 call

  nextFunction := Pointer(PInteger(Integer(origFunction)+1)^+Integer(origFunction)+5);
  PPointer(Integer(origFunction)+1)^ := Pointer(Integer(myFunction)-Integer(orgFunction)-5);


Bauchst natürlich noch Schreibrechte die du mit VirtualProtect bekommst.

_________________
wer andern eine grube gräbt hat ein grubengrabgerät
- oder einfach zu viel zeit
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 04.09.06 15:10 
user profile iconTobi482 hat folgendes geschrieben:
Supi,

Danke für deine Anwort :-D

NP.
user profile iconTobi482 hat folgendes geschrieben:
So, nun haben sich doch noch ein paar Fragen aufgetan. Der Code sieht wie folgt aus.

k, kommentieren wir erstmal den Source ein wenig ;-)

user profile iconTobi482 hat folgendes geschrieben:
ausblenden 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:
:00535816 8B45E0                  mov eax, dword ptr [ebp-20]           //Lokale Variable lesen (wahrscheinlich Objekt)
:00535819 8B88485F0000            mov ecx, dword ptr [eax+00005F48]     //Feld dieses Objekts lesen
:0053581F 034DFC                  add ecx, dword ptr [ebp-04]           //Zu diesem Wert eine lokale Var addieren
:00535822 8B55E0                  mov edx, dword ptr [ebp-20]           //Objekt wieder lesen
:00535825 898A485F0000            mov dword ptr [edx+00005F48], ecx     //Und geänderten Wert schreiben ...

:0053582B 8B45E0                  mov eax, dword ptr [ebp-20]           //Man ist Delphi ineffizient!!!
:0053582E 8B4DE0                  mov ecx, dword ptr [ebp-20]           //mov ecx, eax wär schneller gewesen ...
:00535831 8B90485F0000            mov edx, dword ptr [eax+00005F48]     //Man hätte auch gleich sich ECX von oben merken können
:00535837 3B91505F0000            cmp edx, dword ptr [ecx+00005F50]     //Wert mit dem von oben vergleichen
:0053583D 7526                    jne 00535865                          //wenn die sich unterschieden nach unten springen ...

//Hier kommt jetzt der CALL (incl. Vorbereitungen)
:0053583F 8B45E0                  mov eax, dword ptr [ebp-20]           //Objekt lesen
:00535842 0508400000              add eax, 00004008                     //Adresse auf das zu bearbeitende Feld berechnen
:00535847 50                      push eax                              //Als Parameter für STDCALL speichern
:00535848 E86346FCFF              call 004F9EB0                         //Aufruf ausführen, EAX enthält ergebnis

//Prüfung des Ergebnisses
:0053584D 83C404                  add esp, 00000004                     //Weiß nicht, welchen Müll Delphi hier coded ...*
:00535850 85C0                    test eax, eax                         //Ergebnis auf <> 0 prüfen
:00535852 7504                    jne 00535858                          //Bei ungleich 0 springen ...
:00535854 33C0                    xor eax, eax                          //EAX := 0, ZF setzen
:00535856 EB12                    jmp 0053586A


*Dieser ESP-Befehl ist kein Stack-Cleanup de Aufrufs, sondern gehört zu einem anderen Stack-Frame, dass von Delphi im Laufe des Codes angelegt wurde ... Bei STDCALL müssen sich die aufgerufenen Funktionen nämlich selbstständig um das Aufräumen kümmern (durch ein RET(F) 04 in diesem Fall)

user profile iconTobi482 hat folgendes geschrieben:
Ich dachte bisher, das hier ein Parameter, vermutlich ein Pointer zu einem Bytearray, in den Stack geschoben wird.
ausblenden Quelltext
1:
:00535847 50                      push eax					

Jup, wird er auch ...

user profile iconTobi482 hat folgendes geschrieben:
Und, dass hier der Stack erhöht wird, um den Rückgabewert(4 Byte) des Call's im Stack zu sichern.
ausblenden Quelltext
1:
:0053584D 83C404                  add esp, 00000004					

Kurz zum Merken: Wenn ESP kleiner wird, wird auf den Stack gespeichert, wird ESP vergrößert, wird gelöscht ;-)

user profile iconTobi482 hat folgendes geschrieben:
Daher hatte ich eine Function wie hier erwartet.
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
var
       Hook_Next : function(a:Pointer):integer;stdcall;

function Hook_Callback(a:Pointer):integer;stdcall;
begin
      Result := Hook_Next(a);
end;

Jup, korrekt.
Wobei der Result sogar nur Boolean zu sein scheint (bestenfalls LONGBOOL).

user profile iconTobi482 hat folgendes geschrieben:
1 Frage:
Bist du dir ganz sicher, dass es sich dabei wirklich um Variabeln handelt?

Siehe meine Kommentare im Source *g*

user profile iconTobi482 hat folgendes geschrieben:
Ich habe mir die von dir empfohlenen Units, speziell die uallCollectiont, angesehen.
Die Funktion die dabei für mich interessant ist, ist vermutlich die "uallhook.HookCodeNt"

Allgemein HookCode, da uall automatisch die richtige für das Betriebssystem unterscheided ...

user profile iconTobi482 hat folgendes geschrieben:
Die Funktion möchte ein orgFunc:Pointer einen CallbackFunc:Pointer und einen NewFunc:Pointer haben
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:
var
       Hook_Next : function(a:Pointer):integer;stdcall;

...

function Hook_Callback(a:Pointer):integer;stdcall;
begin
      //mach ekligen Krach wenn's klappt!
      Beep(3000,1000);
      Result := Hook_Next(a);
end;

...

procedure Patch_Func;
var
     p : Integer;
begin
     p := $00535848;
     if uallhook.HookCodeNt(Ptr(p), @Hook_Callback, @Hook_Next) then
     begin
           //mach Krach wenn's geklappt hat !
           Beep(1000,1000);
     end;
end;

Jain ... Die Funktion möchte den Pointer auf das Ziel des CALLs ...

user profile iconTobi482 hat folgendes geschrieben:
2 Frage:
Wo startet die Originalfunktion? Bei p := $00535848; ??? Davor? Dahinter? Die anderen Parameter kann ich über den @-Operator bestimmen.

ausblenden Delphi-Quelltext
1:
p := PInteger($00535849)^;					


user profile iconTobi482 hat folgendes geschrieben:
Mit freundlichen Grüßen
Tobi

HTH.

_________________
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.
Tobi482 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 135



BeitragVerfasst: Mo 04.09.06 20:38 
Oh Mann, Jungs ihr seid Klasse :-D

da bin ich ja direkt an zwei Spezialisten geraten.

VIELEN VIELEN DANK an euch beiden ihr habt mir sehr
geholfen. Der Hook Funktioniert jetzt :)

Also programmieren ist eine Sache für sich, aber
ASM verstehen ist noch viel schwieriger, also meinen
größten Respekt an euch beide.

Mit freundlichen Grüßen
Tobi