[Post] talking about Hook APIS is a very basic thing (of course, you can ignore the direct pass !)

Source: Internet
Author: User

Hook api is an eternal topic. Without hook, many technologies will be hard to implement and may not be implemented at all.
The API mentioned here is a generalized API, which includes dos interruptions, Windows APIs, interrupt services, ifs and
NDIS filtering. For example, the real-time translation software that everyone is familiar with relies on hook textout () or exttextout ().
Function implementation, before the operating system uses these two functions to output the text, it replaces the corresponding English with Chinese to achieve
The same is true for ifs and NDIS filtering. Before Reading and Writing disks and sending and receiving data, the system calls
The callback function is used to determine whether an operation can be opened. Unlike normal hooks, the callback function is permitted by the operating system.
Provides interfaces to install callback functions.
Even if there is no hook, there will be no virus, because no matter it is a DOS virus or a Windows virus,
All functions are implemented by hook system services: DOS viruses are infected by hook int 21 (File virus ), hook INT 13 is used to infect the Boot Sector (BOOT virus). In Windows, viruses are infected by hook system APIs (including ring0 and ring3) Or ifs. Therefore, we can say that "without hook, there will be no colorful Software world today ".

Because it involves patents, intellectual property rights, or trade secrets, Microsoft has never advocated hook up its system APIs,
Other filtering interfaces such as IFs and NDIS are provided to meet the needs of anti-virus software and firewall. Therefore
In most cases, the hook api depends on its own strength.

The hook api has a principle that the original functions of the hooked API cannot be affected. Just like
The doctor saves lives. If the virus in the patient's body is killed and the patient is dead, it makes no sense to "save lives.
If you hook the API, your goal is achieved, but the original function of the API is invalid, this is not the hook, but the replace, the normal function of the operating system will be affected, even crashes.

Hook api technology is not complicated to say, that is, changeProgramProcess Technology. There are several CPU commands
Commands can change the process of a program: JMP, call, Int, RET, retf, iret, and other commands. Theoretically, you only need to change the API
Any machine code at the entry and exit can be hooked, but the actual implementation is much more complicated because the following problems must be handled:
1. CPU instruction length problem. In 32-bit systems, the length of a JMP/call instruction is 5 bytes, so you only have to replace the API
Machine code that exceeds the length of 5 bytes (or replace several commands that add up to 5 bytes). Otherwise
Several commands after a machine code smaller than five bytes are modified, and even program processes are disrupted, causing unpredictable consequences;
2. parameter problems. To access the parameters of the original API, you must reference the parameters through EBP or ESP. Therefore, you must be very clear about your hookCodeIn this case, what is the value of EBP/ESP;
3. Timing: some hooks must start with the API, and some must end with the API, such as hook createfilaa (),
If you hook the API at the end of the API, you cannot write or even access the file. Hook Recv (),
If you have not received the data in the API header hook, you can view the Recv () receiving buffer. Of course there is no
The data you want must be hooked at the end of Recv () after Recv () is executed normally. Check the Recv () Buffer,
Only the desired data is available;
4. context problems. Some hook codes cannot perform certain operations. Otherwise, the context of the original API is damaged and the original API becomes invalid;
5. For synchronization problems, use local variables instead of global variables in the hook code, which is also required by modular programs;
6. Note that the original functions of the replaced CPU commands must be simulated somewhere in the hook code.

The following uses send () in ws2_32.dll as an example to illustrate how to hook this function:

Exported FN (): Send-ord: 0013 H
Assembly Code of address machine code
: 71a21af4 55 push EBP // machine code to be hooked (1st methods)
: 71a21af5 8bec mov EBP, esp // machine code to be hooked (2nd methods)
: 71a21af7 83ec10 sub ESP, 00000010
: 71a21afa 56 push ESI
: 71a21afb 57 push EDI
: 71a21afc 33ff xor edi, EDI
: 71a21afe 813d1c20a371931ca271 cmp dword ptr [71a3201c], 71a21c93 // machine code to be hooked (4th methods)
: 71a21b08 0f84853d0000 je 71a25893
: 71a21b0e 8d45f8 Lea eax, dword ptr [ebp-08]
: 71a21b11 50 push eax
: 71a21b12 e869f7ffff call 71a21280
: 71a21b17 3bc7 CMP eax, EDI
: 71a21b19 8945fc mov dword ptr [ebp-04], eax
: 71a21b1c 0f85c4940000 JNE 71a2afe6
: 71a21b22 ff7508 push [EBP + 08]
: 71a21b25 e826f7ffff call 71a21250
: 71a21b2a 8bf0 mov ESI, eax
: 71a21b2c 3bf7 cmp esi, EDI
: 71a21b2e 0f84ab940000 je 71a2afdf
: 71a21b34 8b4510 mov eax, dword ptr [EBP + 10]
: 71a21b37 53 push EBX
: 71a21b38 8d4dfc Lea ECx, dword ptr [ebp-04]
: 71a21b3b 51 push ECx
: 71a21b3c ff75f8 push [ebp-08]
: 71a21b3f 8d4d08 Lea ECx, dword ptr [EBP + 08]
: 71a21b42 57 push EDI
: 71a21b43 57 push EDI
: 71a21b44 ff7514 push [EBP + 14]
: 71a21b47 8945f0 mov dword ptr [ebp-10], eax
: 71a21b4a 8b450c mov eax, dword ptr [EBP + 0C]
: 71a21b4d 51 push ECx
: 71a21b4e 6a01 push 00000001
: 71a21b50 8d4df0 Lea ECx, dword ptr [ebp-10]
: 71a21b53 51 push ECx
: 71a21b54 ff7508 push [EBP + 08]
: 71a21b57 8945f4 mov dword ptr [ebp-0C], eax
: 71a21b5a 8b460c mov eax, dword ptr [ESI + 0C]
: 71a21b5d ff5064 call [eax + 64]
: 71a21b60 8bce mov ECx, ESI
: 71a21b62 8bd8 mov EBX, eax
: 71a21b64 e8c7f6ffff call 71a21230 // machine code to be hooked (3rd methods)
: 71a21b69 3bdf cmp ebx, EDI
: 71a21b6b 5B pop EBX
: 71a21b6c 0f855f940000 JNE 71a2afd1
: 71a21b72 8bda-8 mov eax, dword ptr [EBP + 08]
: 71a21b75 5f pop EDI
: 71a21b76 5E pop ESI
: 71a21b77 C9 leave
: 71a21b78 c21000 RET 0010

Here are four methods to hook this API:

1. Replace push EBP (machine code 0x55) with INT 3 (machine code 0xcc ),
Then, use the debugging functions provided by windows to execute your own code. This method is widely used by debuger such as soft ice,
It sets a breakpoint through an int 3 command in the corresponding place through BPX. However, this method is not recommended because it
Conflicts with windows or debugging tools, while assembly code must be debugged;

2. Replace the second mov EBP and ESP command (machine code 8bec, 2 bytes) with int F0 command (machine code cdf0 ),
Set an interrupt gate in IDT to point to our code. Here is a hook code:

Lea EBP, [esp + 12] // simulate the functions of the original command mov EBP and ESP
Pushfd // Save the site
Pushad // Save the site

// Do what you want to do here

Popad // restore the site
Popfd // restore the site
Iretd // return the next command of the original command to continue executing the original function (71a21af7 address)

This method is good, but the disadvantage is to set an interrupt gate in IDT, that is, to enter ring0.

3. Change the relative address of the Call Command (call is in 71a21b12, 71a21b25, and 71a21b64 respectively, but there is a condition before the first two calls
The jump command may not be executed, so we need to hook the call command at 71a21b64 ). Why do I need to get started with the call command?
Because they are both 5-byte commands and call commands, as long as the operation code 0xe8 remains unchanged, you can change the following relative address
After the hook code is executed, the hook code is transferred to the target address for execution.

Suppose our hook code is at 71a20400, then we change the call command at 71a21b64 to call 71a20400 (the original command is like this: Call 71a21230)
The hook code at 71a20400 is as follows:

71a20400:
Pushad

// Do what you want to do here

Popad
JMP 71a21230 // jump to the target address of the original call command. The original command is as follows: Call 71a21230

This method is well concealed, but it is difficult to find this 5-byte call command, and the calculation of the relative address is also complicated.

4. Replace the cmp dword ptr [71a3201c] And 71a21c93 commands (machine code: 813d1c20a371931ca271, 10 bytes) on the 71a21afe address
Call 71a20400
NOP
NOP
NOP
NOP
NOP
(Machine code: E8 xx 90 90 90, 10 bytes)

The hook code in 71a20400 is:
Pushad
MoV edX, 71a3201ch // simulate the original command cmp dword ptr [71a3201c], 71a21c93
Cmp dword ptr [edX], 71a21c93h // simulate the original command cmp dword ptr [71a3201c], 71a21c93
Pushfd

// Do what you want to do here

Popfd
Popad
RET
This method is best concealed, but not every API has such commands. You need to perform specific operations according to the specific situation.

The above methods are commonly used. It is worth mentioning that many people change the first five bytes of the API, but now many anti-virus software use this method.
Check whether the API is hooked, or other viruses and Trojans change the first five bytes after you, so that they will overwrite each other. The last hook api operation is effective,
Therefore, 3rd and 4th methods are recommended.

Ssdt hook implementation:
Typedef struct servicedescriptortable {
Pvoid pvssdtbase;
Pvoid pvservicecountertable;
Ulong ulnumberofservices;
Pvoid pvparamtablebase;
} Ssdt, * pssdt;
The header file of DDK declares keservicedescriptortable,
Extern pssdt keservicedescriptortable;

// Modify the ssdt table to read-only
_ ASM
{
CLI
MoV eax, Cr0
And eax, not 10000 h
MoV Cr0, eax
}

Ulong address;
// In Windows XP, the index of the ntopenprocess item in the ssdt table is 7ah.
// Therefore, the address in the ssdt table is: base address + 7ah * 4
Address = (ulong) keservicedescriptortable-> servicetablebase + 0x7a * 4;

// Save the original ntopenprocess address
Realopserviceaddress = * (ulong *) address;
Realntopenprocess = (ntopenprocess) realopserviceaddress;

// Mount the ntopenprocess Hook Function
* (Ulong *) Address) = (ulong) myntopenprocess;

// Modify ssdt to read-only
_ ASM
{
MoV eax, Cr0
Or eax, 10000 h
MoV Cr0, eax
STI
}

Now, the ntopenprocess function is hook complete and will be executed when other processes are called.
Myntopenprocess. The process of canceling a hook is similar to that of canceling a hook, but it only saves the original
The actual service address of can be written back to the ssdt table.

Implementation of hook functions:
Ntstatus _ stdcall myntopenprocess (Out phandle processhandle,
In access_mask desiredaccess,
In pobject_attributes objectattributes,
In pclient_id clientid ){
,,
// Determine whether the process is being protected
If (clientid! = NULL )){
PID = (ulong) clientid-> uniqueprocess;
For (I = 0; I <max_antiopen_num; I ++)
// If yes, an error is returned.
If (antiopen_pids = PID ){
Processhandle = NULL;
Rc = STATUS_ACCESS_DENIED;
Return RC;
}
}
// The unprotected process calls the original OPEN function to open normally.
Rc = (ntstatus) (ntopenprocess) realntopenprocess (processhandle, desiredaccess,
Objectattributes, clientid );
Return RC;
}

// Getprocessinfo: obtains the process PID and process name from the specified process execution body.
Void getprocessinfo (in peprocess, out Pulong uprocessid, out puchar *
Szproccessname)
{
Puchar eprocess = (puchar) peprocess;
* Uprocessid = * (Pulong) (eprocess + 0x084 ));
* Szproccessname = eprocess + 0x0174;
}
Ntstatus _ stdcall myntterminateprocess (in handle processhandle,
In ntstatus exitstatus ){
,,
// Obtain the address of the memory block corresponding to the Process Handle
Rc = obreferenceobjectbyhandle (processhandle, file_read_data, 0, kernelmode
, & Peprocess, 0 );
If (RC! = STATUS_SUCCESS)
Return (ntstatus) (ntterminateprocess) realntterminateprocess (
Processhandle, exitstatus );
// Obtain the process PID from the data structure of the Process execution body
Getprocessinfo (peprocess, & uprocessid, & szproccessname );
// Determine whether the process is being protected
For (I = 0; I <max_antiterm_num; I ++)

If (antiterm_pids= Uprocessid) {// If yes, the end fails to be returned.
Rc = STATUS_ACCESS_DENIED;
Return RC;
}
// The unprotected process calls the original end function and ends.
Return (ntstatus) (ntterminateprocess) realntterminateprocess (processhandle,
Exitstatus );
}

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.