Écrire une fonction de trampoline

J’ai réussi à écraser les premiers octets d’une fonction en mémoire et à les détourner de ma propre fonction. J’ai maintenant des problèmes pour créer une fonction de trampoline pour redonner le contrôle à la fonction réelle.

Ceci est une deuxième partie de ma question ici .

BYTE *buf = (BYTE*)VirtualAlloc(buf, 12, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); void (*ptr)(void) = (void (*)(void))buf; vm_t* VM_Create( const char *module, intptr_t (*systemCalls)(intptr_t *), vmInterpret_t interpret ) { MessageBox(NULL, L"Oh Snap! VM_Create Hooked!", L"Success!", MB_OK); ptr(); return NULL;//control should never get this far } void Hook_VM_Create(void) { DWORD dwBackup; VirtualProtect((void*)0x00477C3E, 7, PAGE_EXECUTE_READWRITE, &dwBackup); //save the original bytes memset(buf, 0x90, sizeof(buf)); memcpy(buf, (void*)0x00477C3E, 7); //finish populating the buffer with the jump instructions to the original functions BYTE *jmp2 = (BYTE*)malloc(5); int32_t offset2 = ((int32_t)0x00477C3E+7) - ((int32_t)&buf+12); memset((void*)jmp2, 0xE9, 1); memcpy((void*)(jmp2+1), &offset2, sizeof(offset2)); memcpy((void*)(buf+7), jmp2, 5); VirtualProtect((void*)0x00477C3E, 7, PAGE_EXECUTE_READ, &dwBackup); } 

0x00477C3E est l’adresse de la fonction qui a été remplacée. Les asm de la fonction originale sont sauvegardés avant que je ne les écrive. Ensuite, mon instruction jmp de 5 octets est ajoutée à buf pour revenir au rest de la fonction d’origine.

Le problème se pose lorsque ptr () est appelé, le programme se bloque. Lors du débogage du site, il se bloque ptr() fonction ptr() ne ressemble pas, mais la vérification de mon calcul de décalage semble correcte.

REMARQUE: le code superflu est omis pour faciliter la lecture de tout.

EDIT: Voici à quoi ressemble la fonction ptr() dans ollydbg

 0FFB0000 55 PUSH EBP 0FFB0001 57 PUSH EDI 0FFB0002 56 PUSH ESI 0FFB0003 53 PUSH EBX 0FFB0004 83EC 0C SUB ESP,0C 0FFB0007 -E9 F1484EFD JMP 0D4948FD 

Il semblerait donc que mon calcul de compensation est erroné.

Donc, votre buf [] finit par contenir 2 choses:

  • 7 premiers octets de l’instruction d’origine
  • jmp

Ensuite, vous transférez le contrôle à buf. Est-il garanti que les 7 premiers octets ne contiennent que des instructions entières? Sinon, vous pouvez planter pendant ou après l’exécution de la dernière instruction incomplète commençant dans ces 7 octets.

Est-il garanti que les instructions de ces 7 octets ne font pas de calculs relatifs à EIP (cela inclut les instructions avec un adressage relatif à EIP, telles que les sauts et les appels principalement)? Sinon, la poursuite de la fonction d’origine ne fonctionnera pas correctement et finira probablement par faire planter le programme.

La fonction d’origine prend-elle des parameters? Si c’est le cas, faites simplement ptr(); fera en sorte que le code original fonctionne avec des ordures provenant des registres et / ou de la stack (dépend de la convention d’appel) et peut se bloquer.

EDIT : Une dernière chose. Utilisez buf+12 au lieu de &buf+12 . Dans votre code, buf est un pointeur, pas un tableau.