Self-implemented function hooks

Source: Internet
Author: User

After reading the principle of detour, I thought about whether I could simulate one.

Some details were found during the comparison. Detour replaces the first few bytes of the function (five bytes when reading the document) with jmp __

. But does machine code truncation take effect? You can see the machine code of each Assembly instruction in the Disassembly window of vs. The length of the machine code of each instruction is not fixed, I think detour is not as simple as a fixed copy of five bytes (the source code of detour has not been studied yet ). Therefore, the second step (this is a learning experiment) is to change the design.

I chose to change the modified Code back to the original function after the defined function is executed. It looks like this:

In addition, the user-defined function does not know that it returns traceBack.

That is, the original function is always executed. This becomes a hook and can only be hooked once, because I restored the modified area.

However, I will not care about this for the moment (this is a learning experiment ).

Some interesting details are discovered only when it is actually implemented by itself. For example, the jmp should have multiple machine codes. Which one should be selected? The code page is not allowed to be written and must be modified by the VirtualProtect function, traceBack cannot return but jmp. To ensure stack balance, it must be written as _ declspec (naked.

I also modified 15 bytes and three sentences:

Push __

Push __

Jmp __

The first push information is provided to traceBack so that he can find the code before modification and copy it back.

The second push is pushed to the traceBack address, so that the jump to traceBack is transparent to the User-Defined Function (hook.

The last hop is a recent hop, so the relative displacement must be calculated.

Effect:

   1: #include "detour.h"

   2: #include <stdio.h>

   3: #include <windows.h>

   4:  

   5: #pragma optimize("",off)

   6:  

   7: void hook()

   8: {

   9:     printf("detoured\n");

  10: }

  11:  

  12: int main()

  13: {

  14:     detourInit();

  15: //---------------------------------------------------------

  16:  

  17:     detour( Sleep,hook );

  18:  

  19:     Sleep(1);

  20:  

  21:     system("pause");

  22:     return 0;

  23: }

PS: detour. h is my own source code. (The code is below)

Result:

Sleep is hooked up. However, it is normal to call Sleep again.

 

Code:

Detour. h (actually, it should be named hook)

   1: #ifndef __DETOUR_H__

   2: #define __DETOUR_H__

   3:  

   4: #pragma once

   5:  

   6: #include <windows.h>

   7: #include <assert.h>

   8: #include <stdlib.h>

   9:  

  10: typedef unsigned char u8;

  11:  

12: // push (subscript) + push (traceBack address) + jmp (hook) cover 15 bytes

  13: #define TBSIZE 15

  14: #define INFOSIZE 5

  15: #define REPSIZE 15

  16:  

  17: //machine code

  18: #define MC_FARJMP    0xE9

  19: #define MC_PUSH        0x68

  20:  

  21: struct s_detour

  22: {

  23:     void *oldFunc;

  24:     void *hook;

  25:     u8 backUp[TBSIZE];

  26: };

  27:  

  28: s_detour gInfo[INFOSIZE];

  29:  

  30: void detourInit()

  31: {

  32:     assert( sizeof(gInfo) > sizeof(s_detour) );

  33:     memset( gInfo,0,sizeof(gInfo) );

  34: }

  35:  

  36: LPDWORD ftb_old = new DWORD;

  37: BOOL ftb_res;

  38: void* ftb_addr;

  39: __declspec(naked) void traceBack( int tn )

  40: {

  41:     //restore

42: // ps: Only jmp can return

  43:     __asm

  44:     {

45: push 0x1 // pretend to fill the address so that tn can be accessed correctly

  46:         push ebp

  47:         mov ebp,esp

  48:     }

  49:  

  50:     assert( tn >= 1 && tn < INFOSIZE );

  51:  

  52:     //#the return would work?

  53:     ftb_res = VirtualProtect( gInfo[tn].oldFunc,REPSIZE,PAGE_EXECUTE_READWRITE,ftb_old );

  54:     assert( ftb_res );

  55:  

  56:     memcpy( gInfo[tn].oldFunc,gInfo[tn].backUp,REPSIZE );

  57:  

  58:     ftb_res = VirtualProtect( gInfo[tn].oldFunc,REPSIZE,*ftb_old,ftb_old );

  59:     assert( ftb_res );

  60:  

  61:     //ready to back

  62:     ftb_addr = (void*)gInfo[tn].oldFunc;

  63:     gInfo[tn].oldFunc = NULL;

  64:     __asm

  65:     {

  66:         mov esp,ebp

  67:         pop ebp

  68:         pop eax        //pop 0x1

  69:         pop eax        //balance stack  pop tn

  70:  

  71:         mov eax,ftb_addr

  72:         jmp eax

  73:     }

  74: }

  75:  

  76: //register

  77: bool detour( void *oldFunc,void *hook )

  78: {

  79:     if( oldFunc == NULL || hook == NULL )

  80:         return false;

  81:  

  82:     int tn;

  83:     for( tn = 1;tn < INFOSIZE;++tn )

  84:     {

  85:         if( gInfo[tn].oldFunc == NULL )        //could be used

  86:             break;

  87:     }

  88:     if( tn == INFOSIZE )

  89:         return false;

  90:  

  91:     gInfo[tn].oldFunc = oldFunc;

  92:     gInfo[tn].hook = hook;

  93:  

  94:     LPDWORD lpOld = new DWORD;

  95:     BOOL res = VirtualProtect( oldFunc,REPSIZE,PAGE_EXECUTE_READWRITE,lpOld );

  96:     assert( res );

  97:  

  98:     memcpy( gInfo[tn].backUp,oldFunc,REPSIZE );    //back up

  99:  

 100:     //replace

 101:     u8 *pf = (u8*)oldFunc;

 102:     pf[0] = MC_PUSH;

103: * (int *) (int) pf + 1) = tn; // press the tag

 104:  

 105:     pf = (u8*)( (int)pf + 5 );

 106:     pf[0] = MC_PUSH;

107: * (int *) (int) pf + 1) = (int) traceBack; // press the traceBack address

 108:  

 109:     pf = (u8*)( (int)pf + 5 );

 110:     pf[0] = MC_FARJMP;

111: * (int *) (int) pf + 1) = (int) hook-(int) pf)-5 ); // relative address of near jmp

 112:  

 113:     res = VirtualProtect( oldFunc,REPSIZE,*lpOld,lpOld );

 114:     assert( res );

 115:     free( lpOld );

 116:  

 117:     return true;

 118: }

 119:  

 120: #endif

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.