Hook note (1)

Source: Internet
Author: User
There are many forms of hook. Here we analyze the inline HOOK API
This type of hook only targets the process to be hooked, and does not affect other processes.
For example, a process uses the MessageBox API, Program If you want to change the behavior of the original MessageBox function, you can perform this hook.

There are several methods for inline hook
1. First execute the hook function and then execute the original API.
2. First execute the original API and then execute the hook function.

Knowledge points to be learned:
1. If you do an experiment in debug, You need to disable the link increase function.

2. Jump command JMP xxxx; jump to an address
Corresponding to machine code E9 relative_add where E9 is a byte relative_add is four bytes, that is, this command contains five bytes in total. The redirected address should be add_start + 5 + relative_add.
Here, add_start is the address starting with E9, and relative_add is the relative address.
Instead, relative_add = XXXX-5-add_start.

3. Analyze the Hook's original function and analyze the first few bytes. For example, MessageBox
77d8050b 8B FF mov EDI, EDI
77d8050d 55 push EBP
77d8050e 8B EC mov EBP, ESP
77d80510 83 3D 1C 04 da 77 00 cmp dword ptr ds: [77da041ch], 0
......
It can be seen that the first five commands can be replaced, but the first six bytes will certainly fail.

Principle:
During inline Hook, you need to prepare a prehook function and a posthook function.

1. Calculate the address of the original API function.
2. Back up the first five bytes of the original API function.
3. Use JMP prehook to replace the first five bytes of orginapi.

// One is a byte. The first five bytes are the first five bytes of the original API backup, and the last five bytes are JMP originapi.
_ Declspec (naked) int posthook ()
{
_ ASM
{
_ Emit 0x90
_ Emit 0x90
_ Emit 0x90
_ Emit 0x90
_ Emit 0x90
_ Emit 0x90
_ Emit 0x90
_ Emit 0x90
_ Emit 0x90
_ Emit 0x90
}
}

Prehook ()
{
Call hook;
Goto posthook;
}

TestCode:
# Include <windows. h>
# Include <stdio. h>

DWORD upperfunctionreturnadd; // Save the API return address
Int nret;
Byte orig_code [5] = {0x90, 0x90, 0x90, 0x90, 0x90}; // store the original command
Byte hook_code [5] = {0xe9, 0, 0, 0, 0}; // stores the command to jump to mymessageboxa
Byte jmp_org_code [5] = {0xe9, 0, 0, 0, 0}; // stores the command that jumps to the last 5 bytes of the original starting address.

Int mymessageboxa ();
Int mymessageboxaa (
Hwnd, // handle to owner window
Lptstr lptext, // text in message box
Maid, // message box title
Uint utype // message box style
);
Int myfunc ();
Void hook ();
Int jmp_back ();

Ulong oldfuncaddr;
Ulong myfuncaddr;
Ulong jmp_backaddr;

// When modifying the first few bytes, note that the obtained command is complete.

Int main ()
{

Hook ();

Int RT = messageboxa (null, "Hello World", "title", mb_ OK );

Return 0;
}

Void hook ()
{
DWORD dwoldprotect;
Oldfuncaddr = (ulong) messageboxa;

// Myfuncaddr = actual address of mymessageboxa
Myfuncaddr = (ulong) mymessageboxaa;

// Actual address of jmp_backaddr = jmp_back
Jmp_backaddr = (ulong) jmp_back;
// Modify the memory to page_execute_readwrite.
Virtualprotect (lpvoid) jmp_backaddr, 10, page_execute_readwrite, & dwoldprotect );

Virtualprotect (lpvoid) oldfuncaddr, 5, page_execute_readwrite, & dwoldprotect );

// Calculate the jump address, which is redirected from oldfuncaddr to myfuncaddr
* (Ulong *) (hook_code + 1) = (ulong) myfuncaddr-(ulong) oldfuncaddr-5;

Memcpy (orig_code, (byte *) oldfuncaddr, 5 );

Memcpy (byte *) oldfuncaddr, hook_code, 5 );

// Calculate the return address, jump from jmp_backaddr to oldfuncaddr
* (Ulong *) (jmp_org_code + 1) = (ulong) oldfuncaddr-(ulong) jmp_backaddr-5;

Memcpy (byte *) jmp_backaddr, orig_code, 5 );

Memcpy (byte *) jmp_backaddr + 5, jmp_org_code, 5 );
}

_ Declspec (naked) int jmp_back ()
{
_ ASM
{
_ Emit 0x90
_ Emit 0x90
_ Emit 0x90
_ Emit 0x90
_ Emit 0x90
_ Emit 0x90
_ Emit 0x90
_ Emit 0x90
_ Emit 0x90
_ Emit 0x90
}
}

// Mymessageboxa: Perform the processing before the function is executed.
_ Declspec (naked) int mymessageboxa ()
{
Printf ("mymessageboxa is called \ r \ n ");

Myfunc (); // can be added to the function process.
_ ASM
{
// Jump back to the messageboxa entry point
JMP jmp_back;
}
}

// Mymessageboxa: perform processing after the function is executed.
_ Declspec (naked) int mymessageboxaa (
Hwnd, // handle to owner window
Lptstr lptext, // text in message box
Maid, // message box title
Uint utype // message box style
)
{
Printf ("mymessageboxaa is called \ r \ n ");
_ ASM
{
Pop upperfunctionreturnadd
Push offset S1; // The return address is S1:

// Jump back to the messageboxa entry point
JMP jmp_back;
S1: NOP
}

Myfunc ();

_ ASM
{
; // Press the original return address to the stack
MoV eax, 0; // Demo: Change the returned result to 0, which can also be returned by myfunc.
Push upperfunctionreturnadd
RET;
}
}

Int myfunc ()
{
Printf ("Hello world \ r \ n ");
Return 1;
}

Refer:
1. http://bbs.pediy.com/showthread.php? T = 69666

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.