Explore new implementation methods of NDIS Hook (2)

Source: Internet
Author: User

--- Inline hook implements NDIS Hook
The previous section describes how to implement the NDIS Hook by obtaining ndis_protocol_block. The second method is the inline Hook method. Inline hook is nothing new. It is nothing more than embedding a JMP machine command in the first part of a function. Before the function executes valid code, it jumps to our proxy function, after necessary processing is done in our proxy function, we will jump back to the original function and then execute the command of the original function.
Since tcpip. sys is a standard NDIS protocol driver, so the package receiving function should obviously be in tcpip. as implemented internally by sys, we can find the two package receiving functions directly, and then can we just hook them to the inline? After reverse analysis, I found these two functions. I installed two XP systems, one of which exported the two functions, but the other was not exported, therefore, we still need to use the signature to search for these two functions. The declaration of these two functions is as follows:
Ndis_status
Arprcv (ndis_handle bindcontext,
Ndis_handle maccontext,
Uchar * headbuffer,
Ulong headsize,
Uchar * buffer,
Ulong buffersize,
Ulong packetsize );
Int
Arprcvpacket (ndis_handle bindcontext,
Pndis_packet packet );
The code for searching these two function addresses is as follows:
// Address of the following global variables to save the two functions
Void * arprcv = NULL;
Void * arprcvpacket = NULL;
Void searchprotocolroutine ()
{
// The following are the signatures of the two functions.
Uchar arprcvbytes [] = {0x8b, 0xff, 0x55, 0x8b, 0xec, 0x56, 0x8b, 0x75, 0x08,0x33 };
Uchar arprcvpacketbytes [] = {0x8b, 0xff, 0x55, 0x8b, 0xec, 0x51,0x53,0x56,0x57, 0x8b };
// Obtain the base address of the tcpip. SYS module. This function is provided in the previous section.
Char * base = findmodule ("tcpip. sys ");
While (arprcv = NULL | arprcvpacket = NULL)
{
If (arprcv = NULL &&
Rtlcomparememory (arprcvbytes, base, 10) = 10)
{
Arprcv = base;
}
Else if (arprcvpacket = NULL &&
Rtlcomparememory (arprcvpacketbytes, base, 10) = 10)
{
Arprcvpacket = base;
}
Base ++;
}
}
The first few commands of the functions compiled by various compilers are almost the same and used to create stack frames. These commands are called the function's preface.
Three bytes in Win2000
Push EBP
MoV EBP, ESP
In WINXP and later systems, it is changed to five bytes.
MoV EDI, EDI
Push EBP
MoV EBP, ESP
However, a near-jump command is exactly five bytes, And it just overwrites the function's preface on XP, so it is easier to hook up on XP. Here we will explain how to hook arprcv, we insert a JMP Command inside arprcv, which will jump to the arprcvprox function. This function is a bare function and is implemented as follows:
_ Declspec (naked) arprcvprox () // springboard Function
{
_ ASM
{
MoV EDI, EDI
Push EBP
MoV EBP, ESP
// Seven parameters start to press the stack
Push [EBP + 20 H]
Push [EBP + 1ch]
Push [EBP + 18 h]
Push [EBP + 14 H]
Push [EBP + 10 h]
Push [EBP + 0ch]
Push [EBP + 8]
Call newarprcv // call the newarprcv Function
CMP eax, 0x10003 // determine whether the function return value is ndis_status_not_accepted
JZ end // if it is ndis_status_not_accepted, directly end this function
// Returns the arprcv function without skipping.
MoV eax, arprcv // If ndis_status_not_accepted is not returned
// Execute this command to load the address of the arprcv function into eax
Add eax, 5 // Add the arprcv address value to 5 and save it to eax, indicating the address to be redirected
JMP eax // start to jump back to arprcv
End:
Pop EBP
Retn 1ch
}
}
Inside the function, the newarprcv function is called. The prototype is consistent with that of arprcv and must be implemented by ourselves:
Ndis_status
Newarprcv (
In ndis_handle protocolbindingcontext,
In ndis_handle macreceivecontext,
In pvoid headerbuffer,
In uint headerbuffersize,
In pvoid lookaheadbuffer,
In uint lookaheadbuffersize,
In uint packetsize
)
{
/*
Add your judgment logic code here to determine whether to intercept the data
If interception is required, ndis_status_not_accepted is returned.
Otherwise, ndis_status_success is returned and the data is handed over to arprcv for processing.
*/
Return ndis_status_success;
}
In the same principle, we insert the JMP command in arprcvpacket to jump to the arprcvpacketprox bare function, which is implemented as follows:
_ Declspec (naked) arprcvpacketprox ()
{
_ ASM
{
MoV EDI, EDI
Push EBP
MoV EBP, ESP
// Two parameters start to press the stack
Push [EBP + 0ch]
Push [EBP + 8]
Call newarprcvpacket // call newarprcvpacket
CMP eax, 0 // If 0 is returned, this packet is rejected
JZ end // return this function directly
MoV eax, arprcvpacket
Add eax, 5
JMP eax // The sixth byte of the arprcvpacket function.
End: Pop EBP
Retn 8
}
}
Inside the function, newarprcvpacket is called. The function implementation is as follows:
Int
Newarprcvpacket (ndis_handle bindcontext,
Pndis_packet ndispacket)
{
/*
Add your judgment logic here to determine whether to intercept the data. If you want to intercept the data, 0 is returned,
Otherwise, a non-0 value is returned.
*/
Dbuplint ("rcvpacket ");
Return 1;
}
Please read the comments of the above Code carefully. Next, we must provide a function to install and uninstall the hook.
Void patcharprcv (Boolean ispatch) // If ispatch is set to true, the hook is installed. If it is set to false, the hook is uninstalled.
{
/* The following five bytes will be used to overwrite the first five bytes of the arprcv function.
These five bytes are the machine code of the jmp xxxx command.
Further computation, so temporarily use zero fill
*/
Uchar patchbytes [5] = {0xe9, 0x00,0x00,0x00,0x00 };
// Cover the first five bytes of the arprcvpacket function with the following five Bytes:
Uchar patchbytes2 [5] = {0xe9, 0x00,0x00,0x00,0x00 };
// Save the first five bytes of the original function to facilitate future hook recovery
Uchar restorebytes [5] = {0x8b, 0xff, 0x55, 0x8b, 0xec };
/*
The following two lines of code calculate the jump offset
*/
Int offset = (char *) arprcvprox-(char *) ARPRcv-5;
Int offset2 = (char *) arprcvpacketprox-(char *) ARPRcvPacket-5;
// Modify the relative address in patchbytes and patchbytes2
Memcpy (patchbytes + 1, & offset, 4 );
Memcpy (patchbytes2 + 1, & offset2, 4 );
If (ispatch)
{
Disablewriteprotect (); // disable write Protection
Memcpy (arprcv, patchbytes, 5 );
Memcpy (arprcvpacket, patchbytes2, 5 );
Enablewriteprotect (); // Enable write Protection
}
Else
{
Disablewriteprotect ();
Memcpy (arprcv, restorebytes, 5 );
Memcpy (arprcvpacket, restorebytes, 5 );
Enablewriteprotect ();
}
}
Because the arprcv and arprcvpacket functions are on a read-only page, you must disable write protection before you can insert code into it. Disable write protection and enable write Protection Code as follows:
Void
Disablewriteprotect ()
{
_ ASM {
CLI
MoV eax, Cr0
And eax, 0 fffeffffh
MoV Cr0, eax
}
}
Void
Enablewriteprotect ()
{
_ ASM {
MoV eax, Cr0
Or eax, not 0 fffeffffh
MoV Cr0, eax
STI
}
}
Note that these codes are only applicable to the XP system for the time being. A few changes are required on win2000 and win2003.

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.