An Inline Hook Method and Apparatus for Compiled Languages
By determining the difference between the size of the target function and the address of the hook function, a jumper function with consistent execution logic is constructed, solving the problem that existing inline hook methods cannot be applied to compiled languages, and realizing inline hooking for compiled languages.
Patent Information
- Authority / Receiving Office
- CN · China
- Patent Type
- Applications(China)
- Current Assignee / Owner
- ZHEJIANG DAHUA TECH CO LTD
- Filing Date
- 2026-05-20
- Publication Date
- 2026-06-19
AI Technical Summary
Existing inline hook methods are not applicable to compiled languages such as C, C++, and Rust because these languages generate machine code directly after compilation, lacking metadata, and therefore cannot be used to dynamically modify and monitor functions using existing methods.
By determining the size of the target function and the address difference of the hook function, it is determined whether inline hooking is possible. A target jump instruction is written at the beginning of the target function to redirect the call to the hook function, thus constructing a jump function with the same execution logic as when it is not hooked, thereby realizing inline hooking for compiled languages.
It implements inline hooking for compiled languages, solving the problem that existing methods are not applicable and ensuring the consistency and safety of the execution logic of the target function.
Smart Images

Figure CN122240079A_ABST
Abstract
Description
Technical Field
[0001] This application relates to the field of computer technology, and in particular to an inline hook method and apparatus for compiled languages. Background Technology
[0002] With the development of computer technology, in scenarios such as hot patching, reverse engineering, and software customization, it is often necessary to monitor, modify, or replace the behavior of specific functions in a running program without modifying the original program source code and binary files. Inline hook technology, as a technique that can directly modify the machine instructions of the target function at runtime, forcing its execution flow to jump to a user-defined hook function, is receiving increasing attention.
[0003] Existing inline hook methods primarily employ hook technology based on managed runtime environments, utilizing metadata reflection and just-in-time compilation capabilities provided by the runtime environments of languages such as Java and C# to dynamically obtain and modify function information. This approach is only applicable to languages like Java and C# that retain complete metadata, and cannot be used with compiled languages such as C, C++, and Rust that directly generate machine code after compilation.
[0004] There is currently no effective solution to the problem that existing inline hook methods cannot be applied to compiled languages. Summary of the Invention
[0005] Therefore, it is necessary to provide an Inline Hook method and apparatus for compiled languages to address the aforementioned technical problems.
[0006] Firstly, this application provides an Inline Hook method suitable for compiled languages. The method includes:
[0007] In response to a received Inline Hook request, the size of the target function to be inline hooked is determined; based on the size of the target function and the difference between the address of the hook function and the address of the target function, it is determined whether the target function can be inline hooked; the hook function is a function used to execute the functionality of the target function by calling a jump function;
[0008] When it is determined that the target function can be inline hooked, the instruction code of the target function is copied to a preset memory area, and the contents of the copied instruction code are revised to obtain the jumper function of the target function;
[0009] Write a target jump instruction at the beginning of the target function, and use the target jump instruction to redirect the call to the target function to the hook function.
[0010] In one embodiment, determining the size of the target function to be inline-hooked in response to a received inline hook request includes:
[0011] Based on the received Inline Hook request, determine the address of the target function;
[0012] The size of the objective function is determined based on its address.
[0013] In one embodiment, determining whether the target function can be inline hooked based on the size of the target function and the difference between the address of the hook function and the address of the target function includes:
[0014] The instruction length of the target jump instruction is determined based on the difference between the address of the hook function and the address of the target function.
[0015] When the size of the target function is greater than or equal to the instruction length of the target jump instruction, it is determined that the target function can be inline hooked;
[0016] When the size of the target function is less than the instruction length of the target jump instruction, it is determined that the target function cannot be inline hooked.
[0017] In one embodiment, determining the size of the objective function based on its address includes:
[0018] Based on the address of the target function, determine the ELF file corresponding to the target function;
[0019] Parse the ELF file corresponding to the objective function to obtain the virtual address of the Dynamic Section in the ELF file;
[0020] The actual address of the Dynamic Section is determined based on the virtual address of the Dynamic Section and the load address of the ELF file;
[0021] When the target function is not the last function, the difference between the address of the function adjacent to and following the address of the target function in the actual address of the Dynamic Section and the address of the target function is determined as the size of the target function.
[0022] In one embodiment, it further includes:
[0023] When the target function is the last function, create a CPU simulator;
[0024] Using the created CPU simulator, the target function is simulated and executed starting from its entry point at the address of the target function. The maximum access length among all branch paths of the target function is determined. The stopping condition for simulating the execution of the target function is that all branch paths encounter a RET instruction. The maximum access length among all branch paths of the target function is determined as the minimum value of the function space. When the minimum value of the function space is greater than the instruction length of the target jump instruction, the minimum value of the function space is determined as the size of the target function.
[0025] In one embodiment, before copying the instruction code of the target function to a preset memory region and revising the content of the copied instruction code to obtain the jumper function of the target function, the process includes:
[0026] The maximum value of the jump function is determined based on the size of the target function, the number of jump instructions and call instructions in the bytecode of the target function, and the number of instructions in the PC register;
[0027] Based on the maximum value of the jump function, construct the memory region corresponding to the jump function.
[0028] In one embodiment, revising the content of the copied instruction code to obtain the springboard function of the target function includes:
[0029] Identify the jump instruction to be revised in the copied instruction code; the jump instruction to be revised is a jump instruction whose original target address is not within the address range of the target function; the original target address is the target address determined by the program counter value and operands of the jump instruction to be revised in the target function;
[0030] Determine a first offset from the location of the jump instruction to be revised to the original target address;
[0031] When the first offset is within a preset offset range, based on a preset offset-operand correspondence table, the first target operand corresponding to the first offset is determined, and the operand of the jump instruction to be revised is replaced with the first target operand; the preset offset range is the range of offsets covered by the preset offset-operand correspondence table.
[0032] When the first offset is not within the preset offset range, a first absolute jump instruction is written at the beginning of the instruction revision buffer in the preset memory region to obtain an updated instruction revision buffer; the first absolute jump instruction is used to jump the call at the beginning of the instruction revision buffer to the original target address; the instruction revision buffer is an unoccupied area in the preset memory region;
[0033] Determine a second offset from the location of the jump instruction to be revised to the starting address of the first absolute jump instruction;
[0034] Based on the preset offset-operand correspondence table, the second target operand corresponding to the second offset is determined, and the operand of the jump instruction to be revised is replaced with the second target operand.
[0035] In one embodiment, revising the content of the copied instruction code to obtain the jumper function further includes:
[0036] Identify the calling instructions in the copied instruction code, and identify the instructions that are relative address calls as the calling instructions to be revised;
[0037] Determine a third offset from the location of the call instruction to be revised to the call target address; the call target address is the target address determined by the program counter value and operands of the call instruction to be revised in the target function;
[0038] Based on a preset offset-operand correspondence table, the third target operand corresponding to the third offset is determined, and when the third target operand is less than the operand of the call instruction to be revised, the operand of the call instruction to be revised is replaced with the third target operand.
[0039] When the third target operand is greater than the operand of the call instruction to be revised, a second absolute jump instruction is written at the beginning of the updated instruction revision buffer; the second absolute jump instruction is used to jump the call at the beginning of the updated instruction revision buffer to the call target address;
[0040] Determine the fourth offset from the location of the scheduling instruction to be revised to the starting address of the second absolute jump instruction;
[0041] Based on the preset offset-operand correspondence table, the fourth target operand corresponding to the fourth offset is determined, and when the fourth target operand is less than the operand of the call instruction to be revised, the operand of the scheduling instruction to be revised is replaced with the fourth target operand.
[0042] In one embodiment, writing the target jump instruction at the beginning of the target function includes:
[0043] Based on the instruction length of the target jump instruction and the preset jump instruction generation rules, the jump instruction bytecode is generated;
[0044] The generated jump instruction bytecode is then filled into the starting position of the target function.
[0045] Secondly, this application also provides an inline hook device suitable for compiled languages. The device includes:
[0046] The function size determination module is used to determine the size of the target function to be inline hooked in response to a received inline hook request;
[0047] The judgment module is used to determine whether the target function can be inline hooked based on the size of the target function and the difference between the address of the hook function and the address of the target function; the hook function is a function used to execute the function of the target function by calling the jump function;
[0048] The jump function determination module is used to copy the instruction code of the target function to a preset memory area when it is determined that the target function can be inline hooked, and to revise the content of the copied instruction code to obtain the jump function of the target function.
[0049] And a jump writing module, used to write a target jump instruction at the beginning of the target function, and use the target jump instruction to redirect the call to the target function to the hook function.
[0050] The aforementioned inline hooking method and apparatus for compiled languages, in response to a received inline hook request, determines the size of the target function to be inline hooked. Then, based on the size of the target function and the difference between the address of the hook function and the address of the target function, it determines whether the target function can be inline hooked. If the target function can be inline hooked, its instruction code is copied to a preset memory area, preserving the original execution environment of the target function. The copied instruction code is then revised to obtain a jump function whose execution logic is consistent with the unhooked target function. Finally, a target jump instruction is written at the beginning of the target function. When the target function is called externally, the target jump instruction redirects the call to the target function to the hook function. The hook function then executes the target function's functionality by calling the jump function. By constructing a jump function with execution logic consistent with the unhooked target function to execute the target function's functionality, it achieves inline hooking for compiled languages with inherent characteristics such as address dependence and code immobilization, solving the problem that existing inline hooking methods are not applicable to compiled languages.
[0051] Details of one or more embodiments of this application are set forth in the following drawings and description to make other features, objects and advantages of this application more readily apparent. Attached Figure Description
[0052] The accompanying drawings, which are included to provide a further understanding of this application and form part of this application, illustrate exemplary embodiments and are used to explain this application, but do not constitute an undue limitation of this application. In the drawings:
[0053] Figure 1 A hardware structure block diagram of a terminal for an inline Hook method applicable to a compiled language, provided as an embodiment of this application;
[0054] Figure 2 A flowchart of an Inline Hook method for a compiled language provided in an embodiment of this application;
[0055] Figure 3 A flowchart of an Inline Hook method for compiled languages provided in a preferred embodiment of this application;
[0056] Figure 4 This is a structural block diagram of an inline hook device for compiled languages provided in an embodiment of this application. Detailed Implementation
[0057] To better understand the purpose, technical solution, and advantages of this application, the application is described and explained below in conjunction with the accompanying drawings and embodiments.
[0058] Unless otherwise defined, the technical or scientific terms used in this application shall have the general meaning understood by one of ordinary skill in the art to which this application pertains. Words such as “a,” “an,” “an,” “the,” “the,” and “these” used in this application do not indicate quantitative limitation and may be singular or plural. The terms “comprising,” “including,” “having,” and any variations thereof used in this application are intended to cover non-exclusive inclusion; for example, a process, method, system, product, or device that comprises a series of steps or modules (units) is not limited to the listed steps or modules (units) but may include steps or modules (units) not listed, or may include other steps or modules (units) inherent to these processes, methods, products, or devices. Words such as “connected,” “linked,” and “coupled” used in this application are not limited to physical or mechanical connections but may include electrical connections, whether direct or indirect. “Multiple” used in this application refers to two or more. “And / or” describes the relationship between related objects, indicating that three relationships may exist; for example, “A and / or B” can represent: A alone, A and B simultaneously, and B alone. Normally, the character " / " indicates that the objects before and after it are in an "or" relationship. The terms "first," "second," "third," etc., used in this application are merely to distinguish similar objects and do not represent a specific order of objects.
[0059] The method embodiments provided in this example can be executed on a terminal, computer, or similar computing device. For example, it can run on a terminal. Figure 1 This is a hardware structure block diagram of the terminal for the Inline Hook method of a compiled language in this embodiment. For example... Figure 1 As shown, a terminal may include one or more ( Figure 1 Only one is shown in the diagram. A processor 102 and a memory 104 for storing data are also included. The processor 102 may be, but is not limited to, a microprocessor (MCU) or a programmable logic device (FPGA). The terminal may also include a transmission device 106 for communication functions and an input / output device 108. Those skilled in the art will understand that… Figure 1 The structure shown is for illustrative purposes only and does not limit the structure of the terminal described above. For example, the terminal may also include components that are larger than... Figure 1 The more or fewer components shown, or having the same Figure 1 The different configurations shown are illustrated.
[0060] Memory 104 can be used to store computer programs, such as application software programs and modules, like the computer program corresponding to the Inline Hook method for compiled languages in this embodiment. Processor 102 executes various functional applications and data processing by running the computer programs stored in memory 104, thus implementing the methods described above. Memory 104 may include high-speed random access memory and may also include non-volatile memory, such as one or more magnetic storage devices, flash memory, or other non-volatile solid-state memory. In some instances, memory 104 may further include memory remotely located relative to processor 102, and these remote memories can be connected to the terminal via a network. Examples of such networks include, but are not limited to, the Internet, corporate intranets, local area networks, mobile communication networks, and combinations thereof.
[0061] The transmission device 106 is used to receive or send data via a network. This network includes a wireless network provided by the terminal's communication provider. In one example, the transmission device 106 includes a Network Interface Controller (NIC), which can connect to other network devices via a base station to communicate with the Internet. In another example, the transmission device 106 can be a Radio Frequency (RF) module used for wireless communication with the Internet.
[0062] This embodiment provides an Inline Hook method suitable for compiled languages. Figure 2 This is a flowchart of the Inline Hook method for compiled languages in this embodiment, as shown below. Figure 2 As shown, the process includes the following steps:
[0063] Step S210: In response to the received Inline Hook request, determine the size of the target function to be Inline Hooked; based on the size of the target function and the difference between the address of the hook function and the address of the target function, determine whether the target function can be Inline Hooked; hook function is a function used to execute the function of the target function by calling the jump function.
[0064] The Inline Hook method provided in this embodiment is a reliable Inline Hook method applicable to compiled languages under x86_64 architecture or Linux systems. The compiled language can be a language that directly converts source code into machine code (or intermediate code) through a compilation process. The core feature of such compiled languages is that code conversion is completed before execution, generating binary files that can be directly run by computer hardware or virtual machines. The Inline Hook request can be a parameter package including the address of the target function, the address of the hook function, and control flags. The address of the target function can be the address of the first instruction of the target function in memory. The address of the hook function is the entry address of the hook function's code in memory. The control flags can include information such as whether to enable immediately, whether to allow multi-threaded concurrency safety, and whether to rollback on failure. The Inline Hook request is a request to redirect the call of the target function to the hook function. The target function can be a function whose behavior is monitored or modified (i.e., the function that needs to be hooked). The hook functions mentioned above can be functions used to replace the target function; that is, functions that execute the target function's functionality by calling a jumper function. The jumper functions mentioned above can be functions whose behavior is equivalent to the target function; that is, functions whose execution logic is consistent with the target function when it is not hooked.
[0065] The above response to the received Inline Hook request determines the size of the target function to be inline hooked. This can be done by determining the address of the target function based on the received Inline Hook request, and then determining the size of the target function based on the address of the target function.
[0066] Step S220: When it is determined that the target function can be inline hooked, the instruction code of the target function is copied to a preset memory area, and the contents of the copied instruction code are revised to obtain the jumper function of the target function.
[0067] Because functions in compiled languages on x86_64 architectures or Linux systems contain PC register-related operations (e.g., address-related instructions), directly copying the target function to a pre-defined memory region as a jump function can lead to errors in address location due to the lack of adjustment for address-related instructions. Therefore, the copied instruction code needs to be revised to ensure that the instructions in the revised jump function function work correctly in the new location, making the jump function completely equivalent to the target function, allowing hook functions to safely call the jump function. Copying the target function's instruction code to the pre-defined memory region can be done by copying the instruction code and then filling it from the beginning of the pre-defined memory region. The area within the pre-defined memory region not occupied by the copied data of the target function is used as an instruction revision buffer. This buffer stores revision instructions used to revise the copied instruction code. These revision instructions can include jump instructions and bridging code. The content of the jump function includes the revised instruction code obtained after revising the copied instruction code and the revision instructions.
[0068] Step S230: Write a target jump instruction at the beginning of the target function and use the target jump instruction to redirect the call to the target function to the hook function.
[0069] The aforementioned target jump instruction is an instruction that can redirect calls to the target function to the hook function.
[0070] Steps S210 to S230, in response to a received Inline Hook request, determine the size of the target function to be inline hooked. Then, based on the size of the target function and the difference between the address of the hook function and the address of the target function, determine whether the target function can be inline hooked. If the target function can be inline hooked, copy the target function's instruction code to a preset memory area to preserve the original execution environment of the target function. Revise the copied instruction code to obtain a jump function whose execution logic is consistent with the unhooked target function. Finally, write a target jump instruction at the beginning of the target function. When the target function is called externally, the target jump instruction redirects the call to the hook function. The hook function then executes the target function's functionality by calling the jump function. By constructing a jump function with execution logic consistent with the unhooked target function to execute the target function's functionality, this method achieves inline hooking for compiled languages with inherent characteristics such as address dependence and code fixation, solving the problem that existing inline hooking methods are not applicable to compiled languages.
[0071] In one embodiment, step S210, in response to a received Inline Hook request, determines the size of the target function to be inline hooked, including:
[0072] Step S211: Determine the address of the target function based on the received Inline Hook request.
[0073] The above method of determining the address of the target function based on the received Inline Hook request can be achieved by reading the address of the target function from the Inline Hook request.
[0074] Step S212: Determine the size of the objective function based on its address.
[0075] The above-mentioned determination of the size of the target function based on its address can be achieved by determining the ELF file corresponding to the target function based on its address, and then determining the actual address of the Dynamic Section based on the virtual address of the Dynamic Section and the load address of the ELF file. When the target function is not the last function, the difference between the address of the function adjacent to and following the target function in the actual address of the Dynamic Section and the address of the target function is used to determine the size of the target function. When the target function is the last function, a CPU simulator is created, and the maximum access length among all branch paths of the target function is determined using the created CPU simulator. The maximum access length among all branch paths of the target function is then determined as the minimum value of the function space. When the minimum value of the function space is greater than the instruction length of the target jump instruction, the minimum value of the function space is determined as the size of the target function.
[0076] Steps S211 to S212 above determine the address of the target function based on the received Inline Hook request, and then determine the size of the target function based on the address of the target function. Determining the size of the target function facilitates subsequent determination of whether the target function can be Inline Hooked based on the size of the target function and the difference between the address of the hook function and the address of the target function.
[0077] Specifically, in one embodiment, determining whether the target function can be inline hooked is based on the size of the target function and the difference between the address of the hook function and the address of the target function, including:
[0078] Step S213: Determine the instruction length of the target jump instruction based on the difference between the address of the hook function and the address of the target function.
[0079] The method described above, which determines the instruction length of the target jump instruction based on the difference between the address of the hook function and the address of the target function, can be achieved by first calculating the address difference between the hook function and the target function, obtaining the address difference, and then determining the instruction length corresponding to the address difference (represented by offsets in the table) according to a preset offset-operand correspondence table. The instruction length corresponding to the address difference is then determined as the instruction length of the target jump instruction. The preset offset-operand correspondence table can be a table showing the correspondence between the preset offset (address difference), operands, and instruction length. This preset offset-operand correspondence table can be specifically set based on specific application scenarios and requirements; this embodiment does not impose specific limitations on it. The preset offset-operand correspondence table is shown in Table 1.
[0080] Table 1
[0081]
[0082] Step S214: When the size of the target function is greater than or equal to the instruction length of the target jump instruction, it is determined that the target function can be inline hooked.
[0083] Since hooking requires writing a certain number of jump instructions to the header of the target function to overwrite the original instructions, if the space is too small, it will be unable to store these instructions. Therefore, it is necessary to determine whether the target function can be inline hooked based on its size and the length of the target jump instructions. When the size of the target function is greater than or equal to the length of the target jump instructions, the original space of the target function can store the length of the target jump instructions, and the target function can be inline hooked.
[0084] Step S215: When the size of the target function is less than the instruction length of the target jump instruction, it is determined that the target function cannot be inline hooked.
[0085] When the size of the target function is less than the instruction length of the target jump instruction, the original space of the target function is too small to store the instruction length of the target jump instruction, and the target function cannot be inline hooked.
[0086] Steps S213 to S215 above determine the instruction length of the target jump instruction based on the difference between the address of the hook function and the address of the target function. Then, based on the size of the target function and the instruction length of the target jump instruction, it is determined whether the target function can be inline hooked. By determining whether the target function can be inline hooked, sufficient space is ensured for inline hooking of the target function, preventing blind hooking from causing program crashes and data corruption.
[0087] In another embodiment, step S212, determining the size of the objective function based on its address, includes:
[0088] Step S2121: Determine the ELF file corresponding to the target function based on the address of the target function.
[0089] Each Linux process has its own independent virtual address space. The operating system loads files from the disk (such as ELF executables and shared libraries) into the process's address space through memory mapping. Linux displays runtime information about processes through the ` / proc` filesystem. ` / proc / self / maps` contains the memory mapping information for the current process. Therefore, the memory mapping information of the current process can be determined by reading the ` / proc / self / maps` file. The format of the memory mapping information for the current process can be: address range, permissions, offset, device number of the file, inode number of the file, and storage path of the file. The address range can be the range defined by the start and end addresses of the current process in the process's address space. The permissions can be one or more of the permissions of the current process, specifically including read (r), execute (x), private mapping (p), etc. The offset can be the offset of the current process within the file. The inode number of the file can be the inode number of the file. The inode is a core data structure in the Unix / Linux filesystem, used to store file metadata and data block pointers. The last column of the storage path of the file is the ELF file. The ELF file mentioned above can be an executable file format under Linux. For example, the memory mapping information of the current process can be represented as: 35b1800000-35b1820000 r-xp 00000000 08:02 135522 / usr / lib64 / ld-2.15.so. Here, 35b1800000-35b1820000 is the address range, r-xp is the permission, 00000000 is the offset, 08:02 is the device number where the file resides, 135522 is the inode number of the file, / usr / lib64 / ld-2.15.so is the storage path of the file, and ld-2.15.so is the ELF file. Generally, the memory mapping information of the current process consists of multiple entries.
[0090] After determining multiple memory mapping information of the current process by reading the / proc / self / maps file, the memory mapping information whose address range can include the address of the target function is determined according to the address of the target function. The ELF file in the memory mapping information whose address range can include the address of the target function is determined as the ELF file corresponding to the target function. At this time, the target function is located in this ELF file.
[0091] Step S2122: Parse the ELF file corresponding to the target function to obtain the virtual address of the Dynamic Section in the ELF file.
[0092] The aforementioned Dynamic Section can be considered a core data structure in an ELF file specifically designed for dynamic linking. Parsing the ELF file corresponding to the target function yields the virtual address of the Dynamic Section. This allows for opening and reading the ELF file, parsing its header, locating the section header table, traversing the header table, finding the .dynamic section, extracting the sh_addr field from the .dynamic section header, and ultimately obtaining the virtual address of the Dynamic Section.
[0093] Step S2123: Determine the actual address of the Dynamic Section based on the virtual address of the Dynamic Section and the loading address of the ELF file.
[0094] The load address of the ELF file mentioned above can be the starting virtual address where the operating system maps the ELF file to memory space during program execution. Because Linux uses a random load protection mechanism for ELF addresses, the load address of the ELF file is not fixed. Therefore, the load address of the ELF file can be obtained through the Linux interface dl_iterate_phdr.
[0095] Specifically, the process of determining the actual address of the Dynamic Section based on its virtual address and the load address of the ELF file can be as follows:
[0096] The actual address of the Dynamic Section = the virtual address of the Dynamic Section + the load address of the ELF file;
[0097] Step S2124: When the target function is not the last function, the difference between the address of the function adjacent to and following the address of the target function in the actual address of the Dynamic Section and the address of the target function is determined as the size of the target function.
[0098] After determining the actual addresses of each Dynamic Section, these addresses are sorted to obtain a sequence of sorted addresses. Then, based on the address of the objective function and the sequence of sorted addresses, it is determined whether the objective function is the last function. This determination can be made as follows: if there are no subsequent Dynamic Section addresses following the objective function, the objective function is considered the last function; otherwise, it is not considered the last function.
[0099] When the objective function is not the last function, the difference between the address of the function adjacent to and following the address of the objective function in the actual address of the Dynamic Section and the address of the objective function can be used to determine the size of the objective function.
[0100] Steps S2121 to S2124 above involve obtaining the size of the target function through the Inject scheme, determining the corresponding ELF file based on the target function's address, parsing the ELF file to obtain the virtual address of the Dynamic Section, determining the actual address of the Dynamic Section based on the virtual address of the Dynamic Section and the load address of the ELF file, and finally, when the target function is not the last function, determining the size of the target function by comparing the address of the function adjacent to and following the target function's address in the actual address of the Dynamic Section with the address of the target function. This determination of the target function's size facilitates subsequent determination of whether the target function can be inline hooked based on its size and the difference between the hook function's address and the target function's address.
[0101] In one embodiment, the above-described Inline Hook method for compiled languages further includes:
[0102] Step S2125: When the objective function is the last function, create a CPU simulator.
[0103] The CPU simulator mentioned above can be a simulator that estimates function boundaries by simulating the execution of a target function.
[0104] Step S2126: Using the created CPU simulator, simulate the execution of the target function starting from the entry point of the target function's address, and determine the maximum access length among all branch paths of the target function; wherein, the stopping condition for simulating the execution of the target function is that all branch paths encounter the RET instruction; the maximum access length among all branch paths of the target function is determined as the minimum value of the function space.
[0105] In this step, during the simulated execution of the target function, attention needs to be paid to return instructions and jump instructions (such as JB (Jump if Carry, jump if less than or equal to), JBE (Jump if Below or Equal, jump if less than or equal to), JCXZ (Jump if CX is Zero, jump if CX is zero), JECXZ (Jump if ECX is Zero, jump if ECX is zero), JL (Jump if Less, jump if less than), JLE (Jump if Less or Equal, jump if less than or equal to), JNB (Jump if Not Below, jump if no carry), JNBE (Jump if Not Below or Equal, jump if higher than), JNL (Jump if Not Less, jump if not less than), JNLE (Jump if Not Less or Equal, jump if greater than), JNO (Jump if Not Overflow, jump if no overflow), JNP (Jump if Not Parity, jump if parity is odd), JNS (Jump if Not...). The following instructions simulate the execution of the target function, recording the address of the furthest accessed instruction (maximum access length): `Sign` (jump if the sign is non-negative), `JNZ` (jump if Not Zero), `JO` (jump if Overflow), `JP` (jump if Parity), `JRCXZ` (jump if RCX is Zero), `JS` (jump if Sign is negative), `JZ` (jump if Zero), `JMP` (jump, unconditional jump), and branch instructions (`CMP` (Compare, comparison instruction)). Return instructions can be machine code instructions that load the program counter from the top of the stack and return the thread execution flow to the instruction after the call point. Jump instructions can be unconditional or conditional jump machine code instructions that only modify the program counter without saving the return address. Branch instructions can be arithmetic-logical comparison machine code instructions used in conjunction with subsequent conditional jump instructions to set status flags to influence the direction of the conditional jump.
[0106] The above method uses a created CPU simulator to simulate the execution of the target function starting from the entry point of the target function's address, and determines the maximum access length among all branch paths of the target function. This can be achieved by using the created CPU simulator to simulate the execution of the target function starting from the entry point of the target function's address, simulating each branch path, determining the access length of each branch path, and then determining the longest access length among all branch path access lengths as the maximum access length among all branch paths of the target function.
[0107] Steps S2125 to S2126 above involve creating a CPU simulator when the target function is the last function, simulating execution of the target function starting from its entry point, determining the maximum access length of all branch paths, and setting this maximum access length as the minimum value of the function space. When the minimum value of the function space is greater than the instruction length of the target jump instruction, the minimum value of the function space is set as the size of the target function. This simulation scheme determines the size of the target function using a CPU simulator when it is the last function. This determination of the target function's size facilitates subsequent determination of whether the target function can be inline hooked, based on its size and the difference between the hook function's address and the target function's address.
[0108] Additionally, in one embodiment, prior to step S220, the above-described Inline Hook method applicable to compiled languages includes:
[0109] Step S216: Determine the maximum value of the jump function based on the size of the target function, the number of jump instructions in the bytecode of the target function, the number of call instructions, and the number of instructions in the PC register.
[0110] The above method of determining the maximum value of the jump function based on the size of the target function, the number of jump instructions, the number of call instructions in the target function's bytecode, and the number of instructions in the PC register can be achieved by parsing the target function's bytecode to determine the number of jump instructions, the number of call instructions, and the number of instructions in the PC register, and then determining the maximum value of the jump function based on the size of the target function, the number of jump instructions, the number of call instructions, and the number of instructions in the PC register.
[0111] The calculation process for determining the maximum value of the jump function based on the size of the target function, the number of jump instructions in the target function's bytecode, the number of call instructions, and the number of instructions in the PC register is as follows:
[0112] The maximum value of the jump function = the size of the target function + the number of jump instructions × A + the number of CALL instructions × B + the number of instructions in the PC register × C;
[0113] Where A is the number of bytes reserved for each jump instruction, B is the number of bytes reserved for each call instruction, and C is the number of bytes reserved for each instruction in the PC register.
[0114] It should be noted that the number of reserved bytes for each jump instruction, each call instruction, and each instruction in the PC register are all specifically set based on specific needs and application scenarios, and this embodiment does not impose any specific limitations on them.
[0115] Step S217: Based on the maximum value of the jump function, construct the memory region corresponding to the jump function.
[0116] The above method of constructing the memory region corresponding to the jump function based on the maximum value of the jump function can be achieved by using a value greater than the maximum value of the jump function as the memory region corresponding to the jump function.
[0117] Steps S216 to S217 above determine the maximum value of the jump function, and then construct the memory region corresponding to the jump function based on the maximum value of the jump function. The construction of the memory region corresponding to the jump function facilitates the subsequent copying of the instruction code of the target function into the preset memory region, and when revising the content of the copied instruction code, the revision instructions are stored in the memory region.
[0118] Further, in one embodiment, step S220, revising the content of the copied instruction code to obtain the springboard function of the target function, includes:
[0119] Step S1: Determine the jump instruction to be revised in the copied instruction code; the jump instruction to be revised is a jump instruction whose original target address is not within the address range of the target function; the original target address is the target address determined by the program counter value and operands of the jump instruction to be revised in the target function.
[0120] Because the instruction code of the target function contains jump instructions, call instructions, and instructions for the PC register, the copied instruction code will also contain jump instructions, call instructions, and instructions for the PC register. Instructions for the PC register do not require revision. However, some jump instructions require revision. The process of determining which jump instructions in the copied instruction code need revision can be based on the program counter value and operands of each jump instruction in the target function (the target function before the move). This allows determining the jump target address of each jump instruction, and then judging whether the jump target address is within the address range of the target function (the address range of the target function before the move, i.e., the address range of the original function). Based on whether the jump target address is within the address range of the target function, it is determined whether each jump instruction needs revision. Jump instructions that need revision are those that require revision. It should be noted that regardless of whether the jump instruction is moved, whether the jump instruction needs to be revised will not change. Therefore, this embodiment can determine whether the jump instruction is a jump instruction to be revised by whether the original target address of the jump instruction before the move is within the address range of the target function.
[0121] The above method determines whether each jump instruction needs revision based on whether its target address is within the address range of the target function. For example, if the target address of a jump instruction is within the address range of the target function, the jump corresponding to this instruction only involves a short jump within the address range of the target function, and the jump will still function normally after relocation, requiring no revision. However, if the target address of a jump instruction is outside the address range of the target function, the operands of the jump instruction need to be updated or other operations need to be performed; otherwise, the jump will go to the wrong address after relocation, and this jump instruction is a jump instruction that needs revision.
[0122] The process of determining the jump target address of each jump instruction based on the program counter value and operands of each jump instruction in the target function is as follows:
[0123] The target address of a jump instruction = the program counter value of the jump instruction in the target function + operand;
[0124] Here, the original target address is the target address determined by the sum of the program counter value and operands of the jump instruction to be revised within the target function; it is the absolute address to which the jump instruction needs to jump. The operands can be the offset of the jump instruction relative to the entry point of the relocated target function. The jump instruction can be the offset of the jump instruction relative to the current PC register value, or an absolute jump address.
[0125] Step S2: Determine the first offset from the location of the jump instruction to be revised to the original target address.
[0126] The location of the jump instruction to be revised can be its address within a preset memory region, i.e., the address after relocation. The first offset can be the distance between the address of the jump instruction to be revised within the preset memory region and the original target address. The calculation of the first offset is used to determine whether the operands of the jump instruction can be directly adjusted using a preset offset-operand correspondence table to revise the jump instruction. For the jump instruction to be revised, if the jump range is small, the instruction can be revised by modifying the operands. If the jump range is too large, exceeding the offset range corresponding to the preset offset-operand correspondence table, an absolute jump instruction (long jump instruction or jump code) needs to be inserted at the beginning of the instruction revision buffer. This causes the jump instruction to be revised to first jump a short distance to the beginning of the instruction revision buffer, and then jump to the original target address via the absolute jump instruction.
[0127] Step S3: When the first offset is within a preset offset range, the first target operand corresponding to the first offset is determined based on the preset offset-operand correspondence table, and the operand of the jump instruction to be revised is replaced with the first target operand; the preset offset range is the range of offsets covered by the preset offset-operand correspondence table.
[0128] In this step, when the first offset is within the preset offset range, the operation instruction can be revised by adjusting the operands of the jump instruction to be revised, based on the preset offset-operand correspondence table.
[0129] The aforementioned determination of the first target operand corresponding to the first offset, based on a preset offset-operand correspondence table, can be achieved by determining the instruction length corresponding to the first offset in the preset offset-operand correspondence table, and using the difference between the first offset and the instruction length corresponding to the first offset as the first target operand. In this embodiment, the difference between the first offset and the instruction length corresponding to the first offset is used as the first target operand, and the operand of the jump instruction to be revised is replaced with the first target operand. By adjusting the operand to compensate for the length of the instruction itself, the target jump address pointed to by the modified jump instruction is consistent with the target jump address pointed to by this jump instruction in the target function.
[0130] Step S4: When the first offset is not within the preset offset range, write the first absolute jump instruction at the beginning of the instruction revision buffer in the preset memory region to obtain the updated instruction revision buffer; the first absolute jump instruction is used to jump the call at the beginning of the instruction revision buffer to the original target address; the instruction revision buffer is an unoccupied area in the preset memory region.
[0131] When the first offset is not within the preset offset range, it is not possible to directly modify the opcode of the jump instruction to be revised so that the target jump address pointed to by the modified jump instruction is consistent with the target jump address pointed to by this jump instruction in the target function before copying. It is necessary to introduce a first absolute jump instruction. With the help of the first absolute jump instruction, the call at the beginning of the instruction revision buffer is jumped to the original target address.
[0132] Step S5: Determine the second offset from the location of the jump instruction to be revised to the starting address of the first absolute jump instruction.
[0133] Step S6: Based on the preset offset-operand correspondence table, determine the second target operand corresponding to the second offset, and replace the operand of the jump instruction to be revised with the second target operand.
[0134] Before jumping from the start of the instruction revision buffer to the original target address using the first absolute jump instruction, the opcode of the jump instruction to be revised needs to be adjusted so that the call at the location of the jump instruction to be revised jumps to the start of the instruction revision buffer. Therefore, it is necessary to determine the second offset from the location of the jump instruction to be revised to the start address of the first absolute jump instruction, and based on the preset offset-operand correspondence table, determine the second target operand corresponding to the second offset, and replace the operand of the jump instruction to be revised with the second target operand.
[0135] The aforementioned determination of the second target operand corresponding to the second offset based on a preset offset-operand correspondence table can be achieved by determining the instruction length corresponding to the second offset in the preset offset-operand correspondence table, and using the difference between the second offset and the instruction length as the second target operand. In this embodiment, the difference between the second offset and the instruction length is used as the second target operand, and the operand of the jump instruction to be revised is replaced with the second target operand. By adjusting the operand to compensate for the instruction's length, the target jump address pointed to by the modified jump instruction is the starting position of the instruction revision buffer. Then, the first absolute jump instruction is used to jump from the starting position of the instruction revision buffer to the original target address.
[0136] Steps S1 to S6 above involve determining the jump instruction to be revised in the copied instruction code, determining the first offset from the position of the jump instruction to be revised to the original target address, and when the first offset is within a preset offset range, determining the first target operand corresponding to the first offset based on a preset offset-operand correspondence table, and replacing the operand of the jump instruction to be revised with the first target operand. This achieves the goal of adjusting the operand of the jump instruction to be revised so that the target jump address pointed to by the modified jump instruction is consistent with the target jump address pointed to by this jump instruction in the target function. When the first offset is not within the preset offset range, a first absolute jump instruction is written at the beginning of the instruction revision buffer in the preset memory region to obtain the updated instruction revision buffer. A second offset is determined to jump from the position of the jump instruction to be revised to the starting address of the first absolute jump instruction. Based on the preset offset-operand correspondence table, the second target operand corresponding to the second offset is determined, and the operand of the jump instruction to be revised is replaced with the second target operand. This ensures that the target jump address pointed to by the modified jump instruction is the starting position of the instruction revision buffer. The call at the starting position of the instruction revision buffer is then jumped to the original target address using the first absolute jump instruction. This ensures that the target jump address pointed to by the modified jump instruction after two jumps is consistent with the target jump address pointed to by this jump instruction in the target function.
[0137] In one embodiment, step S220, revising the content of the copied instruction code to obtain the jump function, further includes:
[0138] Step S7: Determine the calling instructions in the copied instruction code, and identify the instructions that are relative address calls as the calling instructions to be revised.
[0139] When the operand of the call instruction is an absolute address, the call instruction is an instruction that calls from an absolute address; when the operand of the call instruction is a relative address, the call instruction is an instruction that calls from a relative address.
[0140] When the copied instruction code contains a call instruction using an absolute address, since absolute addresses are independent of location, changing the location of the call instruction will not affect the call, and therefore no revision is needed. However, when the copied instruction code contains a call instruction using a relative address, revision is required.
[0141] Step S8: Determine the third offset from the location of the call instruction to be revised to the call target address; the call target address is the target address determined by the program counter value and operands of the call instruction to be revised in the target function.
[0142] The aforementioned target address can be the absolute address of the target function that the revised instruction needs to call. The aforementioned location of the revised instruction can be the address of the revised instruction within a predefined memory region, i.e., the address after relocation. The aforementioned third offset can be the distance between the address of the revised instruction within the predefined memory region and the target address.
[0143] The calculation process for the target address mentioned above is as follows:
[0144] The target address is equal to the program counter value of the calling instruction in the target function plus the operand.
[0145] Step S9: Based on the preset offset-operand correspondence table, determine the third target operand corresponding to the third offset, and when the third target operand is less than the operand of the call instruction to be revised, replace the operand of the call instruction to be revised with the third target operand.
[0146] The aforementioned determination of the third target operand corresponding to the third offset, based on a preset offset-operand correspondence table, can be achieved by determining the operand corresponding to the third offset in the preset offset-operand correspondence table and setting the operand corresponding to the third offset as the third target operand. In this embodiment, by determining the third target operand corresponding to the third offset, and when the third target operand is less than the operand of the call instruction to be revised, the operand of the call instruction to be revised is replaced with the third target operand. The purpose is that when the third target operand is less than the operand of the call instruction to be revised, the bytes occupied by the third target operand are less than the bytes originally occupied by the operand of the call instruction to be revised. This allows the operand of the call instruction to be revised to provide sufficient space for opcode revision, enabling the replacement of the operand of the call instruction to be revised with the third target operand, so that the call address corresponding to the adjusted call instruction is the call target address.
[0147] Step S10: When the third target operand is greater than the operand of the call instruction to be revised, a second absolute jump instruction is written at the beginning of the updated instruction revision buffer; the second absolute jump instruction is used to jump the call at the beginning of the updated instruction revision buffer to the call target address.
[0148] When the third target operand is greater than the operand of the call instruction to be revised, the byte space of the original operand of the call instruction to be revised is too small to replace the operand of the call instruction to be revised with the third target operand. Therefore, a second absolute jump instruction needs to be introduced. With the help of the second absolute jump instruction, the call at the beginning of the updated instruction revision buffer is jumped to the call target address.
[0149] Step S11: Determine the fourth offset from the location of the scheduling instruction to be revised to the starting address of the second absolute jump instruction.
[0150] Step S12: Based on the preset offset-operand correspondence table, determine the fourth target operand corresponding to the fourth offset, and when the fourth target operand is less than the operand of the call instruction to be revised, replace the operand of the scheduling instruction to be revised with the fourth target operand.
[0151] Before using the second absolute jump instruction to jump from the start of the updated instruction revision buffer to the target address, the opcode of the call instruction to be revised needs to be adjusted so that the call jump from the position of the call instruction to be revised is to the start of the instruction revision buffer. Therefore, it is necessary to determine the fourth offset from the position of the call instruction to be revised to the start address of the second absolute jump instruction, and based on the preset offset-operand correspondence table, determine the fourth target operand corresponding to the fourth offset. When the fourth target operand is less than the operand of the call instruction to be revised, the operand of the jump instruction to be revised is replaced with the fourth target operand.
[0152] The aforementioned determination of the fourth target operand corresponding to the fourth offset, based on a preset offset-operand correspondence table, can be achieved by determining the operand corresponding to the fourth offset in the preset offset-operand correspondence table and setting the operand corresponding to the fourth offset as the fourth target operand. In this embodiment, when the fourth target operand is less than the operand of the call instruction to be revised, the operand of the scheduling instruction to be revised is replaced with the fourth target operand. By adjusting the operand, the target call address invoked by the modified call instruction is made to be the starting position of the instruction revision buffer. Then, a second absolute jump instruction is used to jump the call from the starting position of the instruction revision buffer to the call target address.
[0153] In this step, the revision fails if the fourth target operand is greater than the operand of the call instruction to be revised.
[0154] Steps S7 to S12 above involve determining the call instruction to be revised and determining the third offset from the position of the call instruction to be revised to the target address. Based on a preset offset-operand correspondence table, the third target operand corresponding to the third offset is determined. When the third target operand is less than the operand of the call instruction to be revised, the operand of the call instruction to be revised is replaced with the third target operand. This is to achieve the goal of adjusting the operand of the call instruction to be revised so that the target address called by the modified call instruction is consistent with the target address called by the call instruction in the target function. Furthermore, when the third target operand is greater than the operand of the call instruction to be revised, a second absolute jump instruction is written at the beginning of the updated instruction revision buffer. By adjusting the operand, the target call address called by the modified call instruction is made to be the beginning of the instruction revision buffer. The second absolute jump instruction is used to jump the call from the beginning of the instruction revision buffer to the target address, so that the call address called by the modified call instruction after the jump is consistent with the target address called by the call instruction in the target function.
[0155] In one embodiment, step S230, writing a target jump instruction at the beginning of the target function, includes:
[0156] Step S232: Generate jump instruction bytecode based on the instruction length of the target jump instruction and the preset jump instruction generation rules.
[0157] The aforementioned preset jump instruction generation rules can be specifically set according to specific needs and application scenarios, and this embodiment does not impose specific limitations here. For example, the aforementioned preset jump instruction generation rules can be a correspondence table between instruction length and jump instruction bytecode, as shown in Table 2.
[0158] Table 2
[0159]
[0160] Step S234: Fill the generated jump instruction bytecode into the starting position of the target function.
[0161] The jump instruction bytecode can be bytecode used to redirect a call to a target function to a hook function.
[0162] Steps S232 to S234 above generate jump instruction bytecode based on the instruction length of the target jump instruction and the preset jump instruction generation rules, and fill the generated jump instruction bytecode into the starting position of the target function. By writing the target jump instruction, it is convenient to use the target jump instruction to redirect the call to the target function to the hook function.
[0163] This embodiment implements Inline Hook through two interfaces (INJECT interface and UNINJECT interface), specifically:
[0164]
[0165] The INJECT interface replaces the fn_target function (target function) with the fn_hook function (hook function), automatically redirecting subsequent calls to fn_target to fn_hook. fn_original (jump function) is an automatically generated equivalent implementation of fn_target; a call to fn_original is equivalent to the behavior of fn_target without injection. The UNINJECT interface restores the effects caused by the INJECT interface.
[0166] The present embodiment will now be described and illustrated through preferred embodiments.
[0167] Figure 3 This is a flowchart of an Inline Hook method for compiled languages provided in a preferred embodiment of this application. Figure 3 As shown, this Inline Hook method for compiled languages includes the following steps:
[0168] Step S301: Determine the address of the target function based on the received Inline Hook request;
[0169] Step S302: Determine the size of the objective function based on its address;
[0170] Step S303: Based on the size of the target function and the difference between the address of the hook function and the address of the target function, determine whether the target function can be inline hooked; Hook function is a function used to execute the function of the target function by calling the jump function; Jump function is a function whose execution logic is the same as that of the target function when it is not hooked;
[0171] Step S304: When it is determined that the target function can be inline hooked, the instruction code of the target function is copied to a preset memory area.
[0172] Step S305: Revise the contents of the copied instruction code to obtain the jumper function of the objective function;
[0173] Step S306: Write a target jump instruction at the beginning of the target function and use the target jump instruction to redirect the call to the target function to the hook function.
[0174] Steps S301 to S306 above, in response to a received Inline Hook request, determine the size of the target function to be inline hooked. Then, based on the size of the target function and the difference between the address of the hook function and the address of the target function, determine whether the target function can be inline hooked. If the target function can be inline hooked, copy the instruction code of the target function to a preset memory area to preserve the original execution environment of the target function. Revise the content of the copied instruction code to obtain a jump function for the target function whose execution logic is consistent with that of the unhooked target function. Finally, write a target jump instruction at the beginning of the target function. When the target function is called externally, the target jump instruction redirects the call to the target function to the hook function. The hook function then executes the function's functionality by calling the jump function. By constructing a jump function with execution logic consistent with that of the unhooked target function to execute the target function's functionality, this method achieves inline hooking for compiled languages with inherent characteristics such as address dependence and code fixation, solving the problem that existing inline hooking methods are not applicable to compiled languages.
[0175] It should be understood that although the steps in the flowcharts of the embodiments described above are shown sequentially according to the arrows, these steps are not necessarily executed in the order indicated by the arrows. Unless explicitly stated herein, there is no strict order restriction on the execution of these steps, and they can be executed in other orders. Moreover, at least some steps in the flowcharts of the embodiments described above may include multiple steps or multiple stages. These steps or stages are not necessarily completed at the same time, but can be executed at different times. The execution order of these steps or stages is not necessarily sequential, but can be performed alternately or in turn with other steps or at least some of the steps or stages of other steps.
[0176] Based on the same inventive concept, this embodiment also provides an InlineHook device suitable for compiled languages, which is used to implement the above embodiments and preferred embodiments, and will not be repeated as already described. The terms "module," "unit," "subunit," etc., used below can refer to combinations of software and / or hardware that implement a predetermined function. Although the device described in the following embodiments is preferably implemented in software, hardware implementation, or a combination of software and hardware, is also possible and contemplated.
[0177] In one embodiment, Figure 4 This is a structural block diagram of an inline hook device for compiled languages provided in an embodiment of this application, as shown below. Figure 4 As shown, this inline hook device for compiled languages includes:
[0178] Function size determination module 42 is used to determine the size of the target function to be inline hooked in response to the received inline hook request;
[0179] The judgment module 44 is used to determine whether the target function can be inline hooked based on the size of the target function and the difference between the address of the hook function and the address of the target function; the hook function is a function used to execute the function of the target function by calling the jump function;
[0180] The jump function determination module 46 is used to copy the instruction code of the target function to a preset memory area when it is determined that the target function can be inline hooked, and to revise the contents of the copied instruction code to obtain the jump function of the target function.
[0181] And a jump writing module 48, used to write a target jump instruction at the beginning of the target function and use the target jump instruction to redirect the call to the target function to the hook function.
[0182] The aforementioned inline hooking mechanism for compiled languages, in response to a received inline hook request, determines the size of the target function to be inline hooked. Then, based on the size of the target function and the difference between the address of the hook function and the address of the target function, it determines whether the target function can be inline hooked. If the target function can be inline hooked, its instruction code is copied to a preset memory area, preserving the original execution environment of the target function. The copied instruction code is then revised to create a jump function whose execution logic is identical to that of the unhooked target function. Finally, a target jump instruction is written at the beginning of the target function. When the target function is called externally, the call is redirected to the hook function using the target jump instruction. The hook function then executes the target function's functionality by calling the jump function. By constructing a jump function with execution logic identical to the unhooked target function to execute the target function's functionality, it achieves inline hooking for compiled languages with inherent characteristics such as address dependence and code immobilization, solving the problem that existing inline hooking methods are not applicable to compiled languages.
[0183] It should be noted that the above modules can be functional modules or program modules, and can be implemented through software or hardware. For modules implemented through hardware, the above modules can reside in the same processor; or the above modules can be located in different processors in any combination.
[0184] Those skilled in the art will understand that all or part of the processes in the above embodiments can be implemented by a computer program instructing related hardware. The computer program can be stored in a non-volatile computer-readable storage medium. When executed, the computer program can include the processes of the embodiments described above. Any references to memory, databases, or other media used in the embodiments provided in this application can include at least one of non-volatile and volatile memory. Non-volatile memory can include read-only memory (ROM), magnetic tape, floppy disk, flash memory, optical memory, high-density embedded non-volatile memory, resistive random access memory (ReRAM), magnetic random access memory (MRAM), ferroelectric random access memory (FRAM), phase change memory (PCM), graphene memory, etc. Volatile memory can include random access memory (RAM) or external cache memory, etc. By way of illustration and not limitation, RAM can take many forms, such as Static Random Access Memory (SRAM) or Dynamic Random Access Memory (DRAM). The databases involved in the embodiments provided in this application may include at least one type of relational database and non-relational database. Non-relational databases may include, but are not limited to, blockchain-based distributed databases. The processors involved in the embodiments provided in this application may be general-purpose processors, central processing units, graphics processing units, digital signal processors, programmable logic devices, quantum computing-based data processing logic devices, etc., and are not limited to these.
[0185] The technical features of the above embodiments can be combined in any way. For the sake of brevity, not all possible combinations of the technical features in the above embodiments are described. However, as long as there is no contradiction in the combination of these technical features, they should be considered to be within the scope of this specification.
[0186] The embodiments described above are merely illustrative of several implementation methods of this application, and while the descriptions are specific and detailed, they should not be construed as limiting the scope of this patent application. It should be noted that those skilled in the art can make various modifications and improvements without departing from the concept of this application, and these all fall within the protection scope of this application. Therefore, the protection scope of this application should be determined by the appended claims.
Claims
1. An Inline Hook method suitable for compiled languages, characterized in that, The method includes: In response to a received Inline Hook request, the size of the target function to be inline hooked is determined; based on the size of the target function and the difference between the address of the hook function and the address of the target function, it is determined whether the target function can be inline hooked; the hook function is a function used to execute the functionality of the target function by calling a jump function; When it is determined that the target function can be inline hooked, the instruction code of the target function is copied to a preset memory area, and the contents of the copied instruction code are revised to obtain the jumper function of the target function; Write a target jump instruction at the beginning of the target function, and use the target jump instruction to redirect the call to the target function to the hook function.
2. The Inline Hook method for compiled languages according to claim 1, characterized in that, The step of determining the size of the target function to be inline-hooked in response to a received inline hook request includes: Based on the received Inline Hook request, determine the address of the target function; The size of the objective function is determined based on its address.
3. The Inline Hook method for compiled languages according to claim 2, characterized in that, The step of determining whether the target function can be inline hooked based on the size of the target function and the difference between the address of the hook function and the address of the target function includes: The instruction length of the target jump instruction is determined based on the difference between the address of the hook function and the address of the target function. When the size of the target function is greater than or equal to the instruction length of the target jump instruction, it is determined that the target function can be inline hooked; When the size of the target function is less than the instruction length of the target jump instruction, it is determined that the target function cannot be inline hooked.
4. The Inline Hook method for compiled languages according to claim 3, characterized in that, Determining the size of the objective function based on its address includes: Based on the address of the target function, determine the ELF file corresponding to the target function; Parse the ELF file corresponding to the objective function to obtain the virtual address of the Dynamic Section in the ELF file; The actual address of the Dynamic Section is determined based on the virtual address of the Dynamic Section and the load address of the ELF file; When the target function is not the last function, the difference between the address of the function adjacent to and following the address of the target function in the actual address of the Dynamic Section and the address of the target function is determined as the size of the target function.
5. The Inline Hook method for compiled languages according to claim 4, characterized in that, Also includes: When the target function is the last function, create a CPU simulator; Using the created CPU simulator, the target function is simulated and executed starting from its entry point at the address of the target function. The maximum access length among all branch paths of the target function is determined. The stopping condition for simulating the execution of the target function is that all branch paths encounter a RET instruction. The maximum access length among all branch paths of the target function is determined as the minimum value of the function space. When the minimum value of the function space is greater than the instruction length of the target jump instruction, the minimum value of the function space is determined as the size of the target function.
6. The Inline Hook method for compiled languages according to claim 5, characterized in that, Before copying the instruction code of the target function to a preset memory area and revising the contents of the copied instruction code to obtain the jumper function of the target function, the process includes: The maximum value of the jump function is determined based on the size of the target function, the number of jump instructions and call instructions in the bytecode of the target function, and the number of instructions in the PC register; Based on the maximum value of the jump function, construct the memory region corresponding to the jump function.
7. The Inline Hook method for compiled languages according to claim 1, characterized in that, The step of revising the content of the copied instruction code to obtain the springboard function of the objective function includes: Identify the jump instruction to be revised in the copied instruction code; the jump instruction to be revised is a jump instruction whose original target address is not within the address range of the target function; the original target address is the target address determined by the program counter value and operands of the jump instruction to be revised in the target function; Determine a first offset from the location of the jump instruction to be revised to the original target address; When the first offset is within a preset offset range, based on a preset offset-operand correspondence table, the first target operand corresponding to the first offset is determined, and the operand of the jump instruction to be revised is replaced with the first target operand; the preset offset range is the range of offsets covered by the preset offset-operand correspondence table. When the first offset is not within the preset offset range, a first absolute jump instruction is written at the beginning of the instruction revision buffer in the preset memory region to obtain an updated instruction revision buffer; the first absolute jump instruction is used to jump the call at the beginning of the instruction revision buffer to the original target address; the instruction revision buffer is an unoccupied area in the preset memory region; Determine a second offset from the location of the jump instruction to be revised to the starting address of the first absolute jump instruction; Based on the preset offset-operand correspondence table, the second target operand corresponding to the second offset is determined, and the operand of the jump instruction to be revised is replaced with the second target operand.
8. The Inline Hook method for compiled languages according to claim 7, characterized in that, The step of revising the content of the copied instruction code to obtain the jumper function further includes: Identify the calling instructions in the copied instruction code, and determine the instructions that are relative address calls as the calling instructions to be revised; Determine a third offset from the location of the call instruction to be revised to the call target address; the call target address is the target address determined by the program counter value and operands of the call instruction to be revised in the target function; Based on a preset offset-operand correspondence table, the third target operand corresponding to the third offset is determined, and when the third target operand is less than the operand of the call instruction to be revised, the operand of the call instruction to be revised is replaced with the third target operand. When the third target operand is greater than the operand of the call instruction to be revised, a second absolute jump instruction is written at the beginning of the updated instruction revision buffer; the second absolute jump instruction is used to jump the call at the beginning of the updated instruction revision buffer to the call target address; Determine the fourth offset from the location of the scheduling instruction to be revised to the starting address of the second absolute jump instruction; Based on the preset offset-operand correspondence table, the fourth target operand corresponding to the fourth offset is determined, and when the fourth target operand is less than the operand of the call instruction to be revised, the operand of the scheduling instruction to be revised is replaced with the fourth target operand.
9. The Inline Hook method for compiled languages according to claim 3, characterized in that, Writing the target jump instruction at the beginning of the target function includes: Based on the instruction length of the target jump instruction and the preset jump instruction generation rules, the jump instruction bytecode is generated; The generated jump instruction bytecode is then filled into the starting position of the target function.
10. An inline Hook device suitable for compiled languages, characterized in that, The device includes: The function size determination module is used to determine the size of the target function to be inline hooked in response to a received inline hook request; The judgment module is used to determine whether the target function can be inline hooked based on the size of the target function and the difference between the address of the hook function and the address of the target function; the hook function is a function used to execute the function of the target function by calling the jump function; The jump function determination module is used to copy the instruction code of the target function to a preset memory area when it is determined that the target function can be inline hooked, and to revise the content of the copied instruction code to obtain the jump function of the target function. And a jump writing module, used to write a target jump instruction at the beginning of the target function, and use the target jump instruction to redirect the call to the target function to the hook function.