[ASM/C] Hook

Pagina: 1
Acties:

  • MLM
  • Registratie: Juli 2004
  • Laatst online: 12-03-2023

MLM

aka Zolo

Topicstarter
Ik wil graag in een niet-door-mij-geschreven executable een beetje "debuggen", ik wil namelijk 2 functie-calls hooken:

code:
1
2
functie 1: obj *func1(void)    -> allocate 1 en ander
functie 2: void func2(obj *)   -> deallocate geheel

door de executable de de-assemblen vindt ik een 2tal adressen die ik nodig heb, de functie zelf en (het unieke) aanroepende adres.
Voorbeeldje:
GAS:
1
2
3
4
5
6
7
8
9
10
11
12
13
...
0x10 call 0x20     <- aanroepende adres functie 1
...
0x15 call 0x40     <- aanroepende adres functie 2
...
0x20               <- functie 1
... (functie)
0x30 ret
...
0x40               <- functie 2
... (functie)
0x50 ret
...


nu inject ik mijn eigen code, aangepast aan voorbeeld hierboven:
C:
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
typedef obj * __cdecl f1proto(void);
typedef void __cdecl f2proto(obj *);

f1proto *f1original = (f1proto *)0x20;
f2proto *f2original = (f2proto *)0x40;

obj *adres;

extern "C"
{
  obj *f1_hooked(void) {
    adres = f1original();
    return adres;
  }
  void f2_hooked(obj *p) {
    f2original(p);
  }
}

void hook()
{
  /* schrijf naar 0x10 instructie call <f1_hooked>
     schrijf naar 0x15 instructie call <f2_hooked>
  */
}

Probleem is, functie 1 werkt naar behoren (wordt aangeroepen, en returnt de juiste waarde), maar zodra ik f2original aanroep (regel 16) krijg ik een mooie access violation.

Nu denk ik dat het probleem met f2_hooked is dat het iets niet goed opruimt, of dat p niet goed doorkomt, maar ik zou niet weten hoe ik dit zou kunnen verbeteren...
Alle hints/tips/ervaringen zijn zeer welkom!

[ Voor 3% gewijzigd door MLM op 20-06-2005 14:25 . Reden: layout ]

-niks-


  • igmar
  • Registratie: April 2000
  • Laatst online: 20-04 22:06

igmar

ISO20022

Zet je wel de juiste parameters op de stack voordat je functie 2 aanroept ? Een functie met parameters verwacht namelijk een bepaalde stacklayout, en ik vermoed dat die in jouw geval niet (helemaal) klopt.

  • Radiant
  • Registratie: Juli 2003
  • Niet online

Radiant

Certified MS Bob Administrator

Denk er ook aan dat als het programma dat je probeert te debuggen in C++ geschreven is en die functie een member functie is dat je een extra parameter moet pushen (aan het begin) voor de "this" pointer.

  • igmar
  • Registratie: April 2000
  • Laatst online: 20-04 22:06

igmar

ISO20022

Radiant schreef op dinsdag 21 juni 2005 @ 14:10:
Denk er ook aan dat als het programma dat je probeert te debuggen in C++ geschreven is en die functie een member functie is dat je een extra parameter moet pushen (aan het begin) voor de "this" pointer.
De C++ ABI verschilt per compiler.. Erg fijn :P. C is denk ik hier een betere start, angezien dat kwa stacklayout bij een x86 niet zo heel erg ingewikkeld is.

[ Voor 4% gewijzigd door igmar op 22-06-2005 09:03 ]


  • Radiant
  • Registratie: Juli 2003
  • Niet online

Radiant

Certified MS Bob Administrator

Je moet gewoon goed kijken naar hoeveel pushes er worden gedaan voor een function call, dat zijn het aantal arguments wat je nodig hebt. Als je ziet dat er alleen registers ipv vaste waardes gepushed worden kan je eens proberen je function __fastcall te maken, dat scheelt soms ook.

  • Dricus
  • Registratie: Februari 2002
  • Laatst online: 15:26

Dricus

ils sont fous, ces tweakers

Volgens mij moeten de typedefs van de te-hooken functies ook als extern "C" gedeclareerd worden. Dus:
C:
1
2
3
4
5
extern "C"
{
  typedef obj * __cdecl f1proto(void); 
  typedef void __cdecl f2proto(obj *); 
}


Kijk ook goed naar de calling convention die je gebruikt. Hebben de te-hooken functies echt de __cdecl calling convention of toch __stdcall of __fastcall? Dit maakt nogal uit als het gaat om hoe de parameters op stack gezet worden en hoe het resultaat wordt teruggegeven.

Zorg er ook expliciet voor dat de hook-functies (f1_hooked en f2_hooked) dezelfde calling convention hebben als de originele functies. Als je de calling convention voor een functie declaratie weglaat, dan wordt de default van de door jou gebruikte compiler gebruikt en dat verschilt per compiler.
Dus beter zou zijn (in het door jou genoemde voorbeeld):
C:
1
2
3
4
5
6
7
8
9
10
extern "C"
{
  obj * __cdecl f1_hooked(void) {
    adres = f1original();
    return adres;
  }
  void __cdecl f2_hooked(obj *p) {
    f2original(p);
  }
}

[ Voor 67% gewijzigd door Dricus op 22-06-2005 13:11 . Reden: Extra tips ]

Stel niet uit tot morgen wat je vandaag nog tot morgen kunt uitstellen...


  • Dricus
  • Registratie: Februari 2002
  • Laatst online: 15:26

Dricus

ils sont fous, ces tweakers

*schop*

Ik ben benieuwd of het gelukt is en zo ja, wat er fout was :).

Stel niet uit tot morgen wat je vandaag nog tot morgen kunt uitstellen...

Pagina: 1