KINGx - Das inoffizielle PlayStation Forum & News Portal

Normale Version: Hooking Problem/Trace Funktionsaufrufe
Sie sehen gerade eine vereinfachte Darstellung unserer Inhalte. Normale Ansicht mit richtiger Formatierung.
Hi zusammen,

ich arbeite gerade an einem Plugin bei dem ich diverse Funktionen Hooke und eigene Logik ausführe. Dabei werden die Funktionen die ich in meinem PlugIn ge"hooked" habe von der PSP der Reihe nach aufgerufen:
hook_func1, hook_func2, hook_func3...also muss ja im "normalen" coding die Aufrufreihenfolge die selbe sein.

Interessanterweise stimmt dies nur für Homebrews...wenn ich das Plugin für offizielle Spiele starte scheint die Funktion 2 nicht aufgerufen zu werden...

Wenn ich das hooking richtig verstehe gibt es eine "system tabelle" in der die Aufrufe (nid's) und zugehöhrige adressen des Aufrufes drin stehen...Gibt es nun eine möglichkeit eine art trace zu machen, welche funktion bei richtigen Spielen zwischen 1 und 3 aufgerufen wird ?

Bin dankbar für jeden tipp ;o)

anmabagima :
Hi zusammen,

ich arbeite gerade an einem Plugin bei dem ich diverse Funktionen Hooke und eigene Logik ausführe. Dabei werden die Funktionen die ich in meinem PlugIn ge"hooked" habe von der PSP der Reihe nach aufgerufen:
hook_func1, hook_func2, hook_func3...also muss ja im "normalen" coding die Aufrufreihenfolge die selbe sein.

Interessanterweise stimmt dies nur für Homebrews...wenn ich das Plugin für offizielle Spiele starte scheint die Funktion 2 nicht aufgerufen zu werden...

Wenn ich das hooking richtig verstehe gibt es eine "system tabelle" in der die Aufrufe (nid's) und zugehöhrige adressen des Aufrufes drin stehen...Gibt es nun eine möglichkeit eine art trace zu machen, welche funktion bei richtigen Spielen zwischen 1 und 3 aufgerufen wird ?

Bin dankbar für jeden tipp ;o)


Ich versteh ehrlicherweiße nicht genau was du meinst... Sad

Ich glaub du hast dass mit den NIDs falsch verstanden, dass sind keine Aufrufe oder so was, sonder einfach Idendifizierer für eine Funktion (eine Zahl an der man weiß welche Funktion gemeint ist).
Um du die Funktionen hookst bevor dass Spiel gestartet, kannst du entweder (aber wirklich BEVOR dass Spiel geladen/gestartet wird!) die Exports von Librarys hooken, um für die gesuchten NIDs andere Adressen auszugeben (zeiger auf deine eigenen Funktionen). Wenn dass Spiel geladen ist, musst du die Stubs pachten. Die Stubs sind eine Sektion im ELF-Modul, die Platzhalter für richtige Funktionsaufrufe sind. Vor dem ausführen sehen die Stubs so aus:

Code:
jr $ra
nop


springen also nur auf den Caller zurück. Die NIDs zu jedem Stub stehen in .lib.ent. Nachdem der Firmware-linker durchgelaufen ist sehen die Stubs entwder so aus (wenn es um eine user funktion geht):

Code:
j 0xDEADBEEF
nop


oder wenn es um eine kernel Funktion geht:

Code:
jr $ra
syscall 0xDEADBEEF


Wenn die Funktion vom Modul aufgerufen wird, springt dass Modul einfach auf den Stub. Du kannst also die Adresse die beim jump angegeben ist ändern (dafür gibts dass MAKE_JUMP macro), oder wenn du ein kernel modul hast die syscall Nummer ändern.
Vllt hilft dass dir einwenig weiter, aber ich versteh ehrlicherweiße nicht was das genaue Problem ist Wink

mfg

Hi Hackman,

erstmal danke für die erklärung...das bringt etwas licht in's dunkel ;o)

Ich versuche das mal zu erklären Wink

Also:
ich will ein paar Grafik-Routinen der GE hooken.
Das klappt auch super Wink ich bekomme keinen fehler...

so weit so gut...
Die erwartete Funtkionsweise (ohne mein Hook) ist, dass 3 Funktionen nach einander aufgerufen werden.
Das ist die sceGeListEnqueue, dann die sceGeListUpdateStall und dann die sceGeDrawSync...

nun habe ich alle 3 ge"hooked"...in meinem eigenen Homebrew werden alle 3 wie erwartet aufgerufen...jedoch wird bei einem original spiel (als ISO - aber egal) der Aufruf sceGeListUpdateStall nicht durchlaufen und ich hab' keine Ahnung wieso und dachte es gibt eine Art "trace" mit dem man rausfinden kann ob das original spiel hier irgendeine andere Funktion aufruft die ich noch hooken muss ;o)

ich weiß nicht, ob dies nun verständlicher erklärt ist ;o)
Hast du noch eine Idee ?

Parallel hab ich mal das original EBoot.bin des spiels und das einer Homebrew versucht zu reversen und hab' da eine unstimmigkeit gefunden...

Laut Import-Liste des Homebrews ist die sceGeListUpdateStall dort:

Code:
0xE0D68148 [0x0008A4DC] - sceGeListUpdateStallAddr

Im Reverse-Code sieht der Aufruf dann so wie du es schreibst aus:

Code:
; ======================================================
; Subroutine sceGe_user_E0D68148 - Address 0x0008A4DC
; Imported from sceGe_user
sceGe_user_E0D68148:        ; Refs: 0x00055968 0x000565D4
    0x0008A4DC: 0x03E00008 '....' - jr         $ra
    0x0008A4E0: 0x00000000 '....' - nop


in dem originalen spiel ist das aber irgendwie komisch....

Code:
0xE0D68148 [0x0029ADA0] - sceGeListUpdateStallAddr


die adresse 0x0029ADA0 zeigt im reverse code aber irgendwie mitten rein (siehe markierung mit <---):

Code:
; ======================================================
; Subroutine sub_0029AD90 - Address 0x0029AD90
sub_0029AD90:        ; Refs: 0x00051814 0x00284190
    0x0029AD90: 0x03E00008 '....' - jr         $ra
    0x0029AD94: 0x00000000 '....' - nop        
    0x0029AD98: 0x03E00008 '....' - jr         $ra
    0x0029AD9C: 0x00000000 '....' - nop        
    0x0029ADA0: 0x03E00008 '....' - jr         $ra    "&lt;----- ????? macht das sinn????
    0x0029ADA4: 0x00000000 '....' - nop


irgendeine idee ????

Code:
; ======================================================
; Subroutine sub_0029AD90 - Address 0x0029AD90
sub_0029AD90:        ; Refs: 0x00051814 0x00284190
    0x0029AD90: 0x03E00008 '....' - jr         $ra
    0x0029AD94: 0x00000000 '....' - nop        
    0x0029AD98: 0x03E00008 '....' - jr         $ra
    0x0029AD9C: 0x00000000 '....' - nop        
    0x0029ADA0: 0x03E00008 '....' - jr         $ra    "&lt;----- ????? macht das sinn????
    0x0029ADA4: 0x00000000 '....' - nop

Ja, das ist schon richtig, das ist nur ein Fehler von PRXTool, welches die Funktionsnamen manchmal nicht resolved (aber solang die Addresse stimmt ist das egal).

Hi,

danke für den Hinweis...
dann stehe ich wieder ein wenig am Anfang, denn die Adresse 0x0029ADA0 wird nirgendwo per -jal oder so angesprungen... Sad

Was bedeutet, dass das Spiel nicht diese erwartete Funktion zu nutzen scheint, und es eine andere geben muss ... Dann versuche ich mal rauszufinden welche ;o)

PS: wenn ich die von Hackmann beschriebenen Platzhalter für die Funktionsaufrufe kenne, aber nicht die Signatur der Funktion - also ihre parameter - (und vermutlich auch nicht die nid) kenne, kann man die dann trotzdem "dynamisch" hooken um zu schauen, ob und wann diese angesprungen werden ?
Ich denke ja mal dass die Paramater in den Registern a0 bis a? stehen und könnte diese Inhalte beim Aufruf der original funktion (adresse) unverändert lassen...
Ginge das ?
Hm... zum ersten Problem, würde ich mal schauen ob überhaupt auf den sceGeListUpdateStallAddr Stub gesprungen wird. Ansonsten wird anscheinend eine andere Funktion verwendet.

anmabagima :
Hi,

danke für den Hinweis...
dann stehe ich wieder ein wenig am Anfang, denn die Adresse 0x0029ADA0 wird nirgendwo per -jal oder so angesprungen... Sad

Was bedeutet, dass das Spiel nicht diese erwartete Funktion zu nutzen scheint, und es eine andere geben muss ... Dann versuche ich mal rauszufinden welche ;o)

PS: wenn ich die von Hackmann beschriebenen Platzhalter für die Funktionsaufrufe kenne, aber nicht die Signatur der Funktion - also ihre parameter - (und vermutlich auch nicht die nid) kenne, kann man die dann trotzdem "dynamisch" hooken um zu schauen, ob und wann diese angesprungen werden ?
Ich denke ja mal dass die Paramater in den Registern a0 bis a? stehen und könnte diese Inhalte beim Aufruf der original funktion (adresse) unverändert lassen...
Ginge das ?


Also den NID heraufzufinden ist einfach... einfach in der Libdoc nachschauen. Ansonsten wird der Funktionsnamen normalerweiße in der Form libname_NID geschrieben. Du musst die Parameter nicht kennen, die sind egal. Du kannst ja als patch schreiben (natürlich mit anderen Funktionsnamen^^)


Code:
int (* originalFunktion) (int a0, int a1, int a2) = NULL;

int patch(int a0, int a1, int a2)
{
     return originalFunktion(a0, a1, a2); // die parameter kannste ja beliebig austauschen
};

int module_start(int args, void *argp)
{
     // hier irgendwo originalFunktion der richtigen addresse zuweißen, und patchen
     return 0;
};

Hi,

tja - es sieht so aus, alls wenn dieser Stub nicht angesprungen wird, da ich keinen Aufruf dieser Adresse finden kann (0x0029ADA0)....
in dem von PRXTOOL reversten (blödes eingedeutschtes wort Wink ) code stehen die Aufrufe leider nicht in der Form Library_NID....

es ist eher so:

Code:
0x00051814: 0x0C0A6B64 'dk..' - jal        sub_0029AD90

...
der Stub-Teil sieht dann so aus:

Code:
; Subroutine sub_0029AD90 - Address 0x0029AD90
sub_0029AD90:        ; Refs: 0x00051814 0x00284190


keine ahnung wie man da jetzt auf die Nid's bzw. die library beim aufruf kommt....hab dem Prxtool auf jedenfall eine psplibdoc.xml mitgegeben, aber troztdem sieht es so aus.....

Bei meiner eigenen Homebrew hat das prxtool richtig sauber die library und die NID ausgegeben bei dem call und wenn ich die libdoc eingebunden hab, hat er sogar die funktionsnamen richtig gezeigt Smile

was das "dynamische" hooken angeht, werde ich mal mein glück versuchen...vielleicht bringt mich das weiter....

Referenz-URLs