A method of preventing return-oriented programming (ROP) attacks
By generating and adding Pointer Authentication Codes (PACs) to the return address in a pipelined mode, the high development cost and compatibility issues in the implementation of PAC functionality in existing technologies are resolved. This achieves improved software security and prevents ROP attacks without recompiling the program.
Patent Information
- Application Number
- CN202511001263.9
- Authority / Receiving Office
- CN · China
- Patent Type
- Patents(China)
- Current Assignee / Owner
- Filing Date
- 2025-07-21
- Publication Date
- 2025-12-16
- Estimated Expiration
- 2045-07-21
AI Technical Summary
The Pointer Authentication Code (PAC) feature introduced in the existing ARMv8.3 version has problems such as high development costs, compatibility issues, difficulty in hardware adaptation, and difficulty in coordination during implementation, which limits its progress in preventing Return-Oriented Programming (ROP) attacks.
By identifying specific instructions in function calls in pipelined mode, a Pointer Authentication Code (PAC) is generated and added to the return address. The return address, stack pointer, and key are obtained using the instruction bypass unit to generate a return address carrying the PAC, thus preventing ROP attacks.
Without requiring recompiling existing programs, PAC protects existing programs through instruction bypass, improving software security and preventing ROP attacks.
Smart Images

Figure CN120509013B_ABST
Abstract
Description
TECHNICAL FIELD
[0001] The present application relates to the technical field of computer instruction processing, and in particular to a method for preventing return-oriented programming (ROP) attack. BACKGROUND
[0002] With the rapid development of computer technology, software security problems are increasingly serious, especially malicious attacks on pointers, such as return-oriented programming (ROP) attacks, which pose a serious threat to system security.
[0003] At present, ARM Company introduces the function of pointer authentication code (PAC) in the ARMv8.3 version, which utilizes the characteristics that 64-bit architecture does not need to use the complete 64-bit address space, embeds authentication code in the unused bits to authenticate a pointer, and effectively prevents malicious attacks through the signature and signature verification mechanism.
[0004] However, in the process of introducing the PAC function, many problems are faced, such as the existing software written in high-level programming language needs to be recompiled to adapt to the new PAC instruction set, which not only increases the development cost, but also may cause compatibility problems; secondly, for assembly language, the developer needs to manually add PAC related instructions, which increases the development difficulty and workload; thirdly, only the newer hardware implements the PAC function, and the existing hardware does not implement the PAC function, so it cannot benefit from it; in addition, the comprehensive implementation of the PAC function requires close cooperation of numerous manufacturers, from hardware manufacturers to software developers, each link needs to be updated and adapted accordingly, the coordination difficulty is large, and the promotion speed is limited. SUMMARY
[0005] The present application provides a method for preventing return-oriented programming (ROP) attack, which is used to generate PAC, add PAC to the return address, and then prevent ROP attack.
[0006] In a first aspect, the embodiments of the present application provide a method for preventing ROP attack, the method comprising: when processing instructions in a pipeline mode, if a first target instruction in a function call is identified, pausing the pipeline; the first target instruction is a first set instruction for which a stack pointer points to a caller stack frame before and / or after execution; or the first target instruction is a second set instruction for which the stack pointer points to a callee stack frame before and / or after execution; the before and / or after execution are before and / or after execution; obtaining, by an instruction bypass unit, a return address of the function call, the stack pointer, and a key, and generating a PAC based on the return address, a context corresponding to the stack pointer, and the key; adding the PAC to reserved bits of the return address to obtain a return address carrying the PAC; the return address carrying the PAC is used to prevent ROP attack on the return address; and resuming the pipeline according to a target address indicated by the instruction bypass unit after the instruction bypass unit is executed.
[0007] In the above method, when the preset first target instruction is identified, the return address, the context corresponding to the stack pointer, and the key are obtained, the PAC is generated, the PAC is added to the reserved bits to obtain the return address carrying the PAC. The return address cannot be normally used because it carries the PAC. Therefore, only after the PAC is stripped from the return address and the signature verification is successful, the return address is a valid address that can be normally used. In this way, by using the complete bypass mode of the instruction, the existing program can be protected by the PAC without recompiling the existing program, ROP attack is prevented, and the security of the software is improved.
[0008] In a possible implementation, the obtaining, by the instruction bypass unit, of the return address of the function call comprises: reading the return address of the function call from a top of a stack or reading the return address of the function call from a return address register; and after the return address carrying the PAC is obtained, the method further comprises: writing, by the instruction bypass unit, the return address carrying the PAC into the top of the stack or the return address register.
[0009] In a possible implementation, before the pipeline is resumed according to the target address indicated by the instruction bypass unit, the method further comprises: executing, by the instruction bypass unit, the first target instruction; and the target address is an address of a next instruction corresponding to the first target instruction or an address of a jump target of the first target instruction.
[0010] In a possible implementation, the resuming of the pipeline according to the target address indicated by the instruction bypass unit comprises: after the pipeline is resumed, skipping instruction identification and directly executing the first target instruction; and the target address indicated by the instruction bypass unit is an address of the first target instruction.
[0011] In a possible implementation, the instruction is identified as the first target instruction in the following manner: (1) if a stack grows from top to bottom, the instruction is determined as the first target instruction if it satisfies any one of the following two conditions: (a) the operation code in the instruction is an immediate number addition operation code, the source register is a stack pointer register, the destination register is the stack pointer register, and the immediate number is negative; (b) the operation code in the instruction is an immediate number subtraction operation code, the source register is the stack pointer register, the destination register is the stack pointer register, and the immediate number is positive; (2) if a stack grows from bottom to top, the instruction is determined as the first target instruction if it satisfies any one of the following two conditions: (a) the operation code in the instruction is an immediate number addition operation code, the source register is the stack pointer register, the destination register is the stack pointer register, and the immediate number is positive; (b) the operation code in the instruction is an immediate number subtraction operation code, the source register is the stack pointer register, the destination register is the stack pointer register, and the immediate number is negative; the stack growing from top to bottom is a stack with a stack bottom at a high address and a stack top at a low address; the stack growing from bottom to top is a stack with a stack bottom at a low address and a stack top at a high address; the high address is a memory address with a larger address value; and the low address is a memory address with a smaller address value.
[0012] In a possible implementation, the first setting instruction is an instruction in which a stack pointer before execution points to a caller stack frame and a stack pointer after execution points to a callee stack frame; and the stack pointer is obtained by the instruction bypass unit in the following manner: before execution of the first setting instruction, the stack pointer stored in a stack pointer register is read by the instruction bypass unit; and the context corresponding to the stack pointer is the stack pointer.
[0013] In a possible implementation, the first setting instruction is a jump instruction used for function calling; and the stack pointer is obtained by the instruction bypass unit in the following manner: the stack pointer stored in a stack pointer register is read by the instruction bypass unit, and the context corresponding to the stack pointer is the stack pointer.
[0014] In a possible implementation, the second setting instruction is an instruction in which a stack pointer before execution points to a caller stack frame and a stack pointer after execution points to a callee stack frame; and the stack pointer is obtained by the instruction bypass unit in the following manner: before execution of the first setting instruction, the stack pointer stored in a stack pointer register is read by the instruction bypass unit; and the context corresponding to the stack pointer is a stack pointer updated after execution of the second setting instruction, which is calculated according to the stack pointer and the size of the stack frame.
[0015] In a possible implementation, the second setting instruction is an instruction for backing up a return address stored in a return address register to a stack; and the stack pointer is obtained by the instruction bypass unit by reading the stack pointer stored in a stack pointer register, the context corresponding to the stack pointer being the stack pointer.
[0016] In a possible implementation, the instruction is identified as the first target instruction by: (1) if a stack grows from top to bottom, determining that the instruction is the first target instruction if the operation code in the instruction is a memory storage operation code, the source register is a return address register, the memory base address register is a stack pointer register, and the offset is a positive value; or (2) if a stack grows from bottom to top, determining that the instruction is the first target instruction if the operation code in the instruction is a memory storage operation code, the source register is a return address register, the memory base address register is a stack pointer register, and the offset is a negative value.
[0017] The stack growing from top to bottom is a stack with a bottom at a high address and a top at a low address; the stack growing from bottom to top is a stack with a bottom at a low address and a top at a high address; the high address is a memory address with a larger address value; and the low address is a memory address with a smaller address value.
[0018] In a second aspect, the present application provides a method for preventing a return-oriented programming (ROP) attack, the method comprising: when processing instructions in a pipeline mode, if a second target instruction in a function call is identified, pausing the pipeline, the second target instruction being a third setting instruction for which a stack pointer before and after execution points to a caller stack frame, or the second target instruction being a fourth setting instruction for which a stack pointer before and after execution points to a callee stack frame; the before and / or after execution being before execution and / or after execution; obtaining, by an instruction bypass unit, a return address carrying a PAC, the stack pointer, and a key, and generating a PAC to be verified based on the return address stripped of the PAC, a context corresponding to the stack pointer, and the key; if the PAC is the same as the PAC to be verified, resuming the pipeline at a target address indicated by the instruction bypass unit; and if the PAC is different from the PAC to be verified, triggering an exception, the exception indicating an ROP attack on a return address.
[0019] With the above method, when a preset second target instruction is identified, a return address carrying a PAC, a stack pointer, and a key are obtained, a PAC to be verified is generated, and if the PAC to be verified is the same as the PAC carried, it can be determined that the return address carrying the PAC has not been attacked. In this way, by means of complete bypassing of instructions, an existing program can be protected by a PAC without recompiling the existing program, ROP attacks can be stopped, and the security of software is improved.
[0020] In a possible implementation, the instruction bypass unit acquires the return address carrying the PAC, including: reading the return address carrying the PAC from a stack top or a return address register; the method further includes: if the PAC is the same as the PAC to be verified, writing the return address stripped of the PAC into the stack top or the return address register.
[0021] In a possible implementation, before the pipeline is resumed at the target address indicated by the instruction bypass unit, the method further includes: executing the target instruction by the instruction bypass unit; the target address is an address of a next instruction corresponding to the second target instruction, or an address of a jump target corresponding to the second target instruction.
[0022] In a possible implementation, resuming the pipeline at the target address indicated by the instruction bypass unit includes: after the pipeline is resumed, skipping instruction identification and directly executing the second target instruction, the target address indicated by the instruction bypass unit being an address of the second target instruction.
[0023] In a possible implementation, the method of identifying the instruction as the second target instruction includes: (1) if a stack grows from top to bottom, determining that an instruction that meets any one of the following two conditions is the second target instruction: (a) the operation code in the instruction is an immediate number addition operation code, the source register is a stack pointer register, the destination register is the stack pointer register, and the immediate number is positive; (b) the operation code in the instruction is an immediate number subtraction operation code, the source register is the stack pointer register, the destination register is the stack pointer register, and the immediate number is negative; (2) if a stack grows from bottom to top, determining that an instruction that meets any one of the following two conditions is the first target instruction: (a) the operation code in the instruction is an immediate number addition operation code, the source register is a stack pointer register, the destination register is the stack pointer register, and the immediate number is negative; (b) the operation code in the instruction is an immediate number subtraction operation code, the source register is the stack pointer register, the destination register is the stack pointer register, and the immediate number is positive; the stack growing from top to bottom is a stack with a stack bottom at a high address and a stack top at a low address; the stack growing from bottom to top is a stack with a stack bottom at a low address and a stack top at a high address; the high address is a memory address with a larger address value; and the low address is a memory address with a smaller address value.
[0024] In a possible implementation, the third setting instruction is an instruction in which a stack pointer before execution points to a caller stack frame and a stack pointer after execution points to a callee stack frame; and the stack pointer is obtained by the instruction bypass unit before execution of the third setting instruction, by reading the stack pointer stored in a stack pointer register.
[0025] In a possible implementation, the third setting instruction is a jump instruction used for function return; and the stack pointer is obtained by the instruction bypass unit, by reading the stack pointer stored in a stack pointer register.
[0026] In a possible implementation, the fourth setting instruction is an instruction in which a stack pointer before execution points to a caller stack frame and a stack pointer after execution points to a callee stack frame; and the stack pointer is obtained by the instruction bypass unit before execution of the fourth setting instruction, by reading the stack pointer stored in a stack pointer register.
[0027] In a possible implementation, the fourth setting instruction is an instruction used for restoring a return address stored on a stack into a return address register; and the stack pointer is obtained by the instruction bypass unit before execution of the third setting instruction, by reading the stack pointer stored in a stack pointer register.
[0028] In a possible implementation, the instruction is identified as the second target instruction in the following manner: (1) if a stack grows from top to bottom, an instruction is determined as the second target instruction if the instruction satisfies the following conditions: an operation code in the instruction is a memory load operation code, a target register is a return address register, a memory base address register is a stack pointer register, and an offset is a positive value; (2) if a stack grows from bottom to top, an instruction is determined as the second target instruction if the instruction satisfies the following conditions: an operation code in the instruction is a memory load operation code, a target register is a return address register, a memory base address register is a stack pointer register, and an offset is a negative value; the stack growing from top to bottom is a stack in which a stack bottom is located at a high address and a stack top is located at a low address; the stack growing from bottom to top is a stack in which a stack bottom is located at a low address and a stack top is located at a high address; the high address is a memory address with a larger address value; and the low address is a memory address with a smaller address value.
[0029] In a third aspect, the present application provides a device for preventing a return-oriented programming (ROP) attack, the device comprising a memory for storing a computer program or instructions; and a processor for invoking the computer program or instructions stored in the memory to execute the method in any possible implementation of the first aspect or the second aspect. BRIEF DESCRIPTION OF DRAWINGS
[0030] In order to more clearly illustrate the technical solutions in the embodiments of the present application, the drawings needed in the embodiment description will be briefly introduced. Obviously, the drawings in the following description are only some embodiments of the present application, and other drawings can be obtained by those skilled in the art without creative labor.
[0031] Figure 1 A flowchart of a method for preventing a ROP attack provided by an embodiment of the present application;
[0032] Figure 2 A flowchart of a method for preventing a ROP attack provided by an embodiment of the present application;
[0033] Figure 3 A flowchart of a PAC signature and verification process provided by an embodiment of the present application;
[0034] Figure 4 A flowchart of another PAC signature and verification process provided by an embodiment of the present application;
[0035] Figure 5 A flowchart of another PAC signature and verification process provided by an embodiment of the present application;
[0036] Figure 6 A structural diagram of a device for preventing a ROP attack provided by an embodiment of the present application. DETAILED DESCRIPTION
[0037] In order to make the purposes, technical solutions and advantages of the present application more clear, the present application will be further described in detail below with reference to the drawings. Obviously, the described embodiments are only some embodiments of the present application, but not all embodiments. Based on the embodiments in the present application, all other embodiments obtained by those skilled in the art without creative labor are within the scope of protection of the present application.
[0038] The present application provides a method for preventing a ROP attack, which is used to prevent a ROP attack by generating a PAC and adding the PAC into a return address, and improves the security of software.
[0039] In order to facilitate understanding, some terms involved in the present application will be explained first.
[0040] Stack: a region in virtual memory, during the process of function call, used to store the state of the function and local variables or temporary variables inside the function, the stack is last in first out, the address of the top of the stack is called stack pointer. Generally speaking, the stack grows from top to bottom, in other words, the address of the bottom of the stack is larger than the address of the top of the stack (i.e. the stack pointer), in the case of the stack growing from top to bottom, the address of the bottom of the stack is the starting address of the stack, the address of the top of the frame is the stack pointer, and each time a new element needs to be pushed into the stack, it is always pushed into the top of the stack and the stack pointer points to a lower address. The stack in the present application can also grow from bottom to top, and the present application does not limit the growth mode of the stack.
[0041] Stack frame: during the process of function call, a new stack frame is generated each time the function is called, and the current stack frame is released each time the function returns. As can be seen, the stack frame is a block of stack area associated with a certain call of a function, and the size of the stack frame required by a given function is determined. For the same function, when it is called multiple times, the stack frame occupied may not be located at the same address. If a function appears multiple times on the call chain at a certain moment, the function must occupy different stack frames when it is called several times. For example: there are functions A, B and C, and the following call chain is generated: A -> B -> C -> B -> B -> C, assuming that the stack grows from top to bottom, from top to bottom there are: the stack frame of function A, the stack frame of the first call of function B, the stack frame of the first call of function C, the stack frame of the second call of function B, the stack frame of the third call of function B, and the stack frame of the second call of function C. At a certain place in the stack frame, the address to be returned after the current function is executed is stored.
[0042] Stack pointer and stack pointer register: the stack pointer represents the address of the top of the stack, which is equivalent to the address of the top of the current stack frame. The stack pointer register is a register that stores the stack pointer. By reading the stack pointer register, you can know where the current stack top is; by writing the stack pointer register, you can update the address of the stack top after pushing data into the stack or popping data out of the stack. In particular, with the occurrence of function calls, the value of the stack pointer also changes due to the establishment and release of the stack frame during function calls. The stack pointer register of some instruction set architectures such as Instruction Set Architecture (ISA) is automatically managed, in other words, special instructions are provided to move the stack pointer at the same time as pushing data into the stack or popping data out of the stack; the stack pointer register of some other instruction set architectures is manually managed, in other words, the value of the stack pointer register needs to be updated after or before pushing data into the stack or popping data out of the stack by using another instruction, in this case, the usual method is to update the value of the stack pointer register after or before pushing or popping a batch of data, rather than updating it every time a data is pushed or popped.
[0043] ROP: a very important attack technique in the field of computer security, which uses existing code fragments in the program to achieve the function that the attacker wants by skillfully combining these code fragments. Attackers can construct ROP chains to execute arbitrary code, such as opening backdoors, stealing data, etc. ROP can bypass some security protection mechanisms, such as writable XOR executable, stack non-executable, etc.
[0044] PAC: takes advantage of the feature that the full 64-bit address space does not need to be used under 64-bit architecture, and embeds authentication code in the unused bits to authenticate a pointer and verify its authentication before using the pointer later to prevent the use of some malicious attack techniques and achieve the effect of improving software security. The calculation of PAC uses a specific algorithm that takes three parameters as input: the pointer, which refers to the original pointer that has not yet embedded PAC, the context, and the key, and produces an output: PAC, which is the pointer authentication code.
[0045] The PAC is calculated by the above algorithm and embedded into the corresponding pointer. A pointer containing PAC cannot be used directly, so there are new instructions to verify the PAC and restore the pointer. Since the above algorithm is reproducible, it only needs to peel off the PAC from the pointer containing PAC first, and then calculate the PAC based on the peeled-off pointer, context and key using the above algorithm. If the two calculated PACs are equal, the PAC verification passes, and the pointer is modified to the form of peeled-off PAC, so that the pointer can be used directly in the future and becomes a legal pointer. If they are not equal, the PAC verification fails, and the pointer will remain illegal, or if it was not originally in the illegal form, such as a pointer without PAC, this step will convert it to an illegal form, and subsequent use of it will cause an exception.
[0046] Figure 1 A flowchart of a method for preventing ROP attacks provided by an embodiment of the present application, which can be executed by a CPU that processes instructions in a pipeline mode. The method is used to add a PAC to the reserved bits of a return address to obtain a return address carrying a PAC, as shown in Figure 1 The flowchart includes the following steps:
[0047] Step 101: When the CPU processes instructions in a pipeline mode, if a first target instruction in a function call is identified, the pipeline is paused.
[0048] Step 102: The CPU obtains the return address, stack pointer and key of the function call through the instruction bypass unit, and generates a PAC based on the context corresponding to the return address and stack pointer and the key. The PAC is added to the reserved bits of the return address to obtain a return address carrying a PAC.
[0049] Step 103: After the instruction bypass unit is executed, the pipeline is restored according to the target address indicated by the instruction bypass unit.
[0050] Specifically, the first target instruction is the first set of instructions before and after which the stack pointer points to the caller stack frame, or the second set of instructions before and after which the stack pointer points to the callee stack frame. After the first target instruction is identified, the instruction bypass unit obtains the return address, stack pointer and key of the function call, generates a PAC based on the context corresponding to the return address and stack pointer and the key, and embeds the PAC in the reserved bits of the return address to obtain a return address carrying a PAC. The return address carrying a PAC is used to prevent ROP attacks on the return address. After the instruction bypass unit is executed, the pipeline is restored according to the target address indicated by the instruction bypass unit.
[0051] In the embodiments of the present application, the return address of the function call is the pointer in the PAC algorithm. For the A-type instruction set architecture, generally, the A-type instruction set architecture belongs to the complex instruction set computer (CISC) architecture. The jump instruction for the function call inserts the return address into the top of the stack. At this time, the data stored in the top of the stack is the return address. There is also a jump instruction for the function return which directly reads the return address from the top of the stack and jumps to the address, that is, the function return. In the A-type instruction set architecture, there is no return address register as mentioned below. The jump instruction for the function call is also the instruction for updating the stack pointer register (that is, the instruction for pointing to the caller stack frame before execution and pointing to the callee stack frame after execution). It is also the instruction for loading the return address stored in the stack. The jump instruction for the function return is also the instruction for updating the stack pointer register (that is, the instruction for pointing to the callee stack frame before execution and pointing to the caller stack frame after execution). It is also the instruction for loading the return address stored in the stack. In the following, these instructions are described separately. However, in the A-type instruction set architecture, the instruction bypass behaviors of the jump instruction for the function call, the instruction for updating the stack pointer register (that is, the instruction for pointing to the caller stack frame before execution and pointing to the callee stack frame after execution; or the instruction for pointing to the callee stack frame before execution and pointing to the caller stack frame after execution), and the instruction for loading the return address stored in the stack (or the instruction for loading the return address stored in the stack) should be understood together. Similarly, the instruction bypass behaviors of the jump instruction for the function return and the instruction for updating the stack pointer register should be understood together.
[0052] In the B-type instruction set architecture, generally, the B-type instruction set architecture belongs to the reduced instruction set computer (RISC) architecture. The instruction for the function call writes the return address into a specific register, which is called the return address register. At this time, the data stored in the specific register is the return address. The prologue of the non-leaf function will have an instruction to back up the data in the specific register to the top of the stack. At this time, the data stored in the top of the stack is the return address. The epilogue of the non-leaf function will have an instruction to restore the return address stored in the top of the stack to a register. At this time, the data stored in the register is the return address. Then, there is an instruction to use the address in the register for jumping, which is the function return. Although it is also possible to restore the return address to another register, generally, according to the calling convention, the function epilogue will restore the return address to the return address register. The jump instruction for the function call in the B-type instruction set architecture is not the instruction for updating the stack pointer register. Similarly, the jump instruction for the function return in the B-type instruction set architecture is not the instruction for updating the stack pointer register.
[0053] In the embodiments of the present application, different types of pointers are allowed to use different keys to enhance security. For the same type of pointer, there are also multiple different keys to choose from. At the same time, the user state cannot access the value of the key to ensure security. Only the kernel state and higher privileged states can access the current effective key through special instructions. The current effective key can be defined in a control register, which makes the key accessible and modifiable by the kernel space. Generally, the kernel randomly generates a new key when starting a new program, and backs up / restores them when context switching. Randomly generating a key can prevent replay attacks.
[0054] Different keys are generated in the instruction bypass unit for different address space identifiers (ASIDs). Generally, when the kernel performs process switching, it will simultaneously operate the control register of the CPU to modify the current ASID. Therefore, generating different keys for different ASIDs can achieve key isolation between processes. However, the value range of ASID is limited. In typical practice, the maximum is only 1024 or several thousand. In many use cases, the number of running processes does not exceed the value range of ASID, and the key isolation between processes is sufficient at this time. However, when the number of running processes exceeds the value range of ASID, some processes will be forced to share ASIDs, resulting in insufficient key isolation between processes. Therefore, in order to enhance security in this case and implement sufficient key isolation, the next implementation is implemented.
[0055] A pair of instructions is designed and added to the match. Both of the instructions were originally undefined or reserved. Since they were originally undefined or reserved, there will be no such instructions in existing programs. Executing such instructions will cause the bypass to be entered, and then the instruction bypass unit first verifies the privileged state of the CPU. If it is in the user state, an exception is raised and it does not continue; if it is in the kernel state or higher privileged state, it continues. Then the instructions are parsed. One of the instructions is used to read the currently configured key and write it to the register or memory address specified by the instruction; the other instruction is used to read the key from the register or memory address specified by the instruction and configure it as the current key. Thus, the kernel can backup the key of the previous process when performing process switching using the former instruction, and then configure the key of the next process to be executed using the latter instruction. If a process is started for the first time, the kernel generates a unique key in some way and configures it using the latter instruction.
[0056] For PAC, optionally, the following restriction can be enforced, that is, all binary bits cannot be all 1 or all 0. In other words, it is also a restriction that PAC algorithm will not output all 1 or all 0. This can ensure that a pointer with PAC, if not PAC signed, will always be illegal address in the view of Memory Management Unit (MMU), thus cannot be used directly, or will cause exception when used.
[0057] It is also necessary to mention that in many programming languages, there is the concept of function call. Each time of function call, it involves caller and callee, and the function call involves the passing of parameters and return value, thus a common convention is needed to specify how to pass them, which is calling convention. Calling convention creates function prolog and function epilog, function prolog is a sequence of instructions at the beginning of a function, and function epilog is a sequence of instructions at the end of a function. According to the above explanations of terms, it can be determined that the value of stack pointer changes in the process of function call, but as long as the program is executing normally, it is guaranteed that the value of stack pointer is the same at the time of entering a function because of function call, i.e. function prolog, and at the time of completing the function call and returning from the function, i.e. function epilog.
[0058] Taking MIPS64 as an example, MIPS is one of the B-class instruction sets, and taking MIPS64 as an example and the stack growing from top to bottom as an example, the typical function prolog and function epilog are described in assembly language as follows, wherein the line starting with / / is the explanation of the instruction:
[0059] / / prolog 31 register stores the return address, which is written by the caller of the function when calling the function.
[0060] / / prolog
[0061] / / update stack pointer register (sp), subtract the stack frame size (FRAME_SIZE) from the value, that is, push the stack top down. sp), subtract the stack frame size (FRAME_SIZE) from the value, that is, push the stack top down.
[0062] / / wherein the stack frame size is sufficient to accommodate the registers to be backed up, and is also sufficient to accommodate the local variables used by the function, which is not described in detail.
[0063] daddiu sp, sp,-FRAME_SIZE
[0064] / / push the return address stored in the 31 register to the bottom of the current stack frame 31 register stores the return address, which is written by the caller of the function when calling the function.
[0065] sd 31,FRAME_SIZE-8( sp)
[0066] / / There can be other instructions to save other registers, which are omitted here.
[0067] <... function body...>
[0068] / / epilog
[0069] / / Pop the return address off the bottom of the current stack frame into 31 register.
[0070] / / ld rt,offset( base) will load the values from the address range offset( base) inclusive to offset+8( base) exclusive into register rt.
[0071] ld 31,FRAME_SIZE-8( sp)
[0072] / / Update the stack pointer register ( sp) with the value of the stack frame size (FRAME_SIZE), i.e. push the stack top back to its original position,
[0073] / / which is actually the value of the stack pointer register.
[0074] daddiu sp, sp,FRAME_SIZE
[0075] / / Jump to the address stored in 31 register to continue execution.
[0076] jr 31
[0077] nop
[0078] According to the above code, there are the following occasions where the value of the stack pointer register is the same, before the first daddiu instruction, that is, before the function prologue, and after the second daddiu instruction, at this time, the value of the stack pointer register is the old value, that is, it points to the top of the stack frame of the caller. Between the first daddiu instruction and the second daddiu instruction, that is, between the two instructions. At this time, the value of the stack pointer register is the new value, that is, it points to the top of the stack frame of the function, that is, the callee.
[0079] Therefore, there are two cases of determining the context corresponding to the stack pointer according to the old value of the stack pointer register and determining the context corresponding to the stack pointer according to the new value of the stack pointer register when signing the PAC.
[0080] (I) Determining the context corresponding to the stack pointer according to the old value of the stack pointer register
[0081] There are two suitable occasions for determining the context corresponding to the stack pointer using the old value of the stack pointer register. The first suitable occasion is the first daddiu instruction in the above code, which is used to update the stack pointer register by subtracting the size of the stack frame of the callee from the value of the stack pointer register. Before the execution of this instruction, the stack pointer points to the top of the stack frame of the caller (equivalent to the value in the stack pointer register being the old value), and after the execution of this instruction, the stack pointer points to the top of the stack frame of the callee (equivalent to the value in the stack pointer register being the new value). The second suitable occasion is not embodied in the above assembly code. Since MIPS has a series of instructions jal / jalr / bal etc. dedicated to function calls, these instructions all write the return address into 31 register when jumping, so the jal / jalr / bal etc. instructions are the second suitable occasion. These two instructions are the first target instructions.
[0082] For the first suitable occasion, the first setting instruction is the instruction whose execution before the stack pointer points to the caller stack frame (equivalent to the value in the stack pointer register being the old value) and after the execution of the stack pointer points to the callee stack frame (equivalent to the value in the stack pointer register being the new value). The stack pointer is obtained through the instruction bypass unit, including reading the stack pointer stored in the stack pointer register through the instruction bypass unit before the execution of the first setting instruction, and the context corresponding to the stack pointer is the stack pointer.
[0083] Specifically, the first setting instruction is the first daddiu instruction in the above code. When the first setting instruction is identified, the instruction bypass unit has two possible full bypass modes.
[0084] (1) The first full bypass mode under the first suitable occasion
[0085] One approach is to complete the PAC signature in the instruction bypass unit and simulate the execution of the instruction; that is, the instruction bypass unit performs the PAC signature. The PAC signature of the return address on register 31, and the... The modification of the sp register can be understood as occurring before the daddiu instruction has been fully rewritten. The sp register, therefore its value remains the old value, and it can be used for signing. The modification of the sp register is the behavior of the daddiu instruction itself, which is to obtain... The sp register value is decremented and then updated to the new value. Of course, these two steps don't necessarily have to be executed sequentially; they can be performed simultaneously, as long as the PAC signature uses... The old value of the sp register is sufficient. At this point, the daddiu instruction itself has been completely simulated by the instruction bypass unit, so the target address indicated after the instruction bypass unit has finished executing should be set to the address of the next instruction.
[0086] Specifically, the value of the stack pointer register is read as the context, i.e., the value of the stack pointer register before the execution of the first daddiu instruction. For Class A instruction set architectures, the return address is read from the top of the stack; for Class B instruction set architectures, the return address is read from the return address register. Combined with the current key, a PAC signature is generated according to the PAC algorithm. The PAC is embedded in the reserved bits of the return address. Then, for Class A instruction set architectures, the return address with the PAC is written to the top of the stack; for Class B instruction set architectures, the return address with the PAC is written to the return address register. The instruction is then simulated to execute according to its original behavior. The pipeline resumes at the target address indicated by the instruction bypass unit, which is the address of the next instruction corresponding to the first set instruction (i.e., the first daddiu instruction in this example).
[0087] (2) The second complete bypass method under the first appropriate timing
[0088] Another approach is to only perform the task in the instruction bypass unit. The PAC signature of the return address on register 31 is obtained at this time. The value of the sp register is still the old value; use it and then rewrite it. Register 31: Since this daddiu instruction was not simulated by the instruction bypass unit, the target address indicated by the instruction bypass unit after execution should be set to the address of this daddiu instruction. This causes the daddiu instruction to temporarily skip one instruction match, allowing the instruction to be executed normally, ultimately enabling the instruction to complete the task through normal execution. Rewriting the sp register.
[0089] Specifically, the value of the stack pointer register is read as the context, i.e., the value of the stack pointer register before the execution of the first daddiu instruction. For Class A instruction set architectures, the return address is read from the top of the stack; for Class B instruction set architectures, the return address is read from the return address register. Combined with the current key, a PAC signature is generated according to the PAC algorithm. The PAC is embedded in the reserved bits of the return address. Then, for Class A instruction set architectures, the return address with the PAC is written to the top of the stack; for Class B instruction set architectures, the return address with the PAC is written to the return address register. The pipeline resumes at the target address indicated by the instruction bypass unit. The target address is the address of the first set instruction (i.e., the first daddiu instruction in this example), which is equivalent to skipping instruction identification and directly executing the first set instruction.
[0090] In one possible implementation, if a top-to-bottom growing stack is used, the instruction is identified as the first target instruction in the following ways: if the opcode of the instruction is an immediate addition opcode, the source register is the stack pointer register, the destination register is the stack pointer register, and the immediate value is negative, then the instruction is the first target instruction; or if the opcode of the instruction is an immediate subtraction opcode, the source register is the stack pointer register, the destination register is the stack pointer register, and the immediate value is positive, then the instruction is the first target instruction. The top-to-bottom growing stack has its bottom at a high address and its top at a low address, where the high address is a memory address with a larger memory value, and the low address is a memory address with a smaller memory value.
[0091] Since instructions with the same purpose may have different names in different instruction set architectures, this application does not limit the specific name of the opcode. This application uses the MIPS64 instruction set architecture, and takes an example where the stack grows from top to bottom and the opcode is an immediate addition opcode. Therefore, in the MIPS64 instruction set architecture, the opcode in the instruction is DADDIU (an immediate addition opcode), and the immediate value is negative.
[0092] Specifically, since the daddiu command itself can also be used for ordinary arithmetic purposes, this is not the purpose we want to match; we only want to match its effects on... This refers to the decrementing of the sp register (i.e., the stack pointer register). Therefore, when using mask matching, it is necessary to match the opcode DADDIU and the matching source register field. sp, matching destination register field is sp. However, immediate values cannot be matched because the value entered there is the stack frame size, which varies for different functions. Examples of matches are shown in Table 1:
[0093] Table 1
[0094]
[0095] where 1 means that the binary bit is 1, 0 means that the binary bit is 0, and x means that the binary bit can be any value. As can be seen from Table 1, the binary bits with mask 1 participate in the matching, while the binary bits with mask 0 do not participate in the matching. This also applies to the subsequent tables, and will not be repeated.
[0096] Since in the prolog of the function, either no stack frame is allocated, or once the stack frame is allocated, the stack top is always pushed down (since the stack in this example grows from top to bottom), when further subdivision of the matching is needed, we want to match only the case that the stack top is pushed down, that is, the case that sp is decremented. In this case, the above immediate number must be filled in as a negative number. It is noted that according to the instruction definition of daddiu, the above filled-in immediate number is actually a signed number, that is, the most significant bit can be used to determine the sign of the immediate number, and when it is 1, the immediate number must be negative, otherwise it must be non-negative. An example of the matching item is shown in Table 2:
[0097] Table 2
[0098]
[0099] In one possible implementation, if the AArch64 (also called ARM64 or Arm A64) instruction set architecture is used, and the stack grows from top to bottom, and the operation code is an immediate number subtraction operation code, then the operation code in the instruction is SUB (and is an immediate number subtraction operation code), and the immediate number is a positive value. Exemplarily, if the matching item in this example is described in the assembly language of AArch64, it is SUB SP, SP, # 0x0000000000000004. ; where SUB indicates that the matching operation code is an immediate number subtraction operation code, SP is the stack pointer register of AArch64, the first SP indicates that the matching destination register is the stack pointer register, the second SP indicates that the matching source register is the stack pointer register, and # 0x0000000000000004 indicates that the matching positive immediate number.
[0100] In one possible implementation, if a bottom-growing stack is used, the instruction that satisfies either of the following two conditions is identified as the first target instruction: (a) the opcode in the instruction is an immediate addition opcode, the source register is the stack pointer register, the destination register is the stack pointer register, and the immediate value is positive; (b) the opcode in the instruction is an immediate subtraction opcode, the source register is the stack pointer register, the destination register is the stack pointer register, and the immediate value is negative. The bottom-growing stack has its bottom at a low address and its top at a high address, where the high address is a memory address with a larger memory value, and the low address is a memory address with a smaller memory value. The specific matching method will not be elaborated upon here.
[0101] For the second suitable timing, the first setting instruction is a jump instruction for function calls, which obtains the stack pointer through the instruction bypass unit, including reading the stack pointer stored in the stack pointer register through the instruction bypass unit, and the context corresponding to the stack pointer is the stack pointer.
[0102] The jump instruction used for function calls can be described as follows: write the return address to the top of the stack (for Class A instruction set architectures) or to the return address register (for Class B instruction set architectures), and then jump to the target address.
[0103] Specifically, the first setting instruction can be an instruction such as jal / jalr / bal. When the first setting instruction is detected, the instruction bypass unit has a complete bypass mode.
[0104] (3) The second appropriate time for a complete bypass method
[0105] Because instructions like jal / jalr / bal, which are specifically used for function calls, themselves rewrite... 31 (i.e., the return address register in the MIPS architecture) therefore cannot be executed as is, but must be simulated to some extent by the instruction bypass unit. And during this process, when... Before writing the return address to register 31, the PAC signature is completed first, and the data obtained at this time... The value of the sp register remains the old value; use it and write it back using the signed return address. Register 31 behaves the same as the original instruction.
[0106] In particular, the instruction is emulated to obtain the return address (including: partially emulating the instruction so that the return address is written to the top of the stack for the A-type instruction set architecture or to the return address register for the B-type instruction set architecture, then reading the return address from the top of the stack for the A-type instruction set architecture or from the return address register for the B-type instruction set architecture, but not performing the jump; or, partially emulating the instruction to directly obtain the return address, but not writing the return address to the top of the stack or the return address register, and not performing the jump), the value of the stack pointer register is read as the context, and the PAC signature is completed using the current key to generate the PAC. The PAC is embedded in the reserved bits of the return address, and then for the A-type instruction set architecture, the return address with the PAC is written to the top of the stack; for the B-type instruction set architecture, the return address with the PAC is written to the return address register. Since the return address (with the PAC) has been written to the expected target location (for the A-type instruction set architecture: the top of the stack; for the B-type instruction set architecture: the return address register) by the above operation, the remaining behavior of the instruction that is not emulated is only the jump to the jump target (i.e., the function to be called). Therefore, the pipeline is resumed at the target address indicated by the instruction bypass unit, which is the address of the jump target of the first specified instruction (i.e., the jal / jalr / bal instruction in this example).
[0107] When using mask matching for such instructions, only the operation code needs to be matched, because such instructions will definitely write the return address to the top of the stack (for the A-type instruction set architecture) or to the return address register (for the B-type instruction set architecture), regardless of the values filled in other fields. The operation codes of such instructions are not the same, some use one-level operation codes, and some use multi-level operation codes. Therefore, a sufficient number of operation code levels should be matched until the instruction type can be determined; this is also common to other aforementioned and hereinafter described other occasions and methods, and details are not repeated.
[0108] (2) Determining the context corresponding to the stack pointer according to the new value of the stack pointer register
[0109] There are two suitable occasions for determining the context corresponding to the stack pointer using the new value of the stack pointer register. The first suitable occasion is the first daddiu instruction in the above code, which is used to update the stack pointer register by subtracting the stack frame size of the callee from the value of the stack pointer register. Before the execution of this instruction, the stack pointer points to the top of the stack frame of the caller (equivalent to the value in the stack pointer register being the old value), and after the execution of this instruction, the stack pointer points to the top of the stack frame of the callee (equivalent to the value in the stack pointer register being the new value). The second suitable occasion is the sd instruction in the above assembly code, which is used to backup the value of the 31 register to the stack. Both of these instructions are the first target instructions. 31 register to the stack. Both of these instructions are the first target instructions.
[0110] For the first suitable timing, the second setting instruction is an instruction for pointing the stack pointer to the caller stack frame (equivalent to the value in the stack pointer register being the old value) before execution and pointing the stack pointer to the callee stack frame (equivalent to the value in the stack pointer register being the new value) after execution, the stack pointer is obtained by the instruction bypass unit, including, before execution of the second setting instruction, the stack pointer stored in the stack pointer register is read by the instruction bypass unit, and the context corresponding to the stack pointer is the stack pointer updated after the second setting instruction is executed, which is calculated according to the stack pointer and the size of the stack frame.
[0111] Specifically, the second setting instruction is the first daddiu instruction in the above code, and when the second setting instruction is identified, the instruction bypass unit has two possible complete bypass modes.
[0112] (1) The first complete bypass mode under the first suitable timing
[0113] One way is to simulate the execution of this instruction by the instruction bypass unit and complete the PAC signature, that is, the rewriting of the sp register by the instruction bypass unit is completed, that is, the behavior of the daddiu instruction itself, that is, the sp register value is decremented to become the new value, and the PAC signature of the return address on the 31 register, because the sp register has been changed to the new value at this time, so it can be used for signature. Of course, in fact, it is not necessary to execute the two steps in sequence, the two steps can be performed at the same time, as long as the PAC signature uses the new value of the sp register, at this time the daddiu instruction itself has been completely simulated by the instruction bypass unit, so the target address indicated after the execution of the instruction bypass unit should be set to the address of the next instruction. sp register. Of course, in fact, it is not necessary to execute the two steps in sequence, the two steps can be performed at the same time, as long as the PAC signature uses the new value of the sp register, at this time the daddiu instruction itself has been completely simulated by the instruction bypass unit, so the target address indicated after the execution of the instruction bypass unit should be set to the address of the next instruction. sp register. Of course, in fact, it is not necessary to execute the two steps in sequence, the two steps can be performed at the same time, as long as the PAC signature uses the new value of the sp register, at this time the daddiu instruction itself has been completely simulated by the instruction bypass unit, so the target address indicated after the execution of the instruction bypass unit should be set to the address of the next instruction.
[0114] Specifically, the execution is simulated according to the behavior that the instruction should have originally performed. The stack pointer register value is read as context, or the updated stack pointer register value is calculated as context, i.e., the value of the stack pointer register after the execution of the first daddiu instruction. For Class A instruction set architectures, the return address is read from the top of the stack; for Class B instruction set architectures, the return address is read from the return address register. Combined with the current key, a PAC signature is generated based on the PAC algorithm. The PAC is embedded in the reserved bits of the return address. Then, for Class A instruction set architectures, the return address with the PAC is written to the top of the stack; for Class B instruction set architectures, the return address with the PAC is written to the return address register. The pipeline resumes at the target address indicated by the instruction bypass unit. The target address is the address of the next instruction corresponding to the second set instruction (i.e., the first daddiu instruction in this example), which is equivalent to resuming normal execution from the next instruction.
[0115] (2) The second complete bypass method under the first appropriate timing
[0116] Another approach is for the instruction bypass unit to only perform the task on... The PAC signature of the return address on register 31 is obtained at this time. The value of the sp register is actually the old value; therefore, it is necessary to parse this daddiu instruction, obtain the stack frame size, and then, during signing, first... The value of sp is subtracted from the stack frame size before being fed into the algorithm for calculation and rewriting. Register 31, the recovery address after bypassing should be set to the address of this daddiu instruction, so that this daddiu instruction temporarily skips one instruction match, thus allowing the instruction to complete the operation normally. Rewriting the sp register.
[0117] Specifically, the updated stack pointer register value is calculated as the context (but the stack pointer register is not actually updated). That is, the value of the stack pointer register after the execution of the first daddiu instruction is calculated. For Class A instruction set architectures, the return address is read from the top of the stack; for Class B instruction set architectures, the return address is read from the return address register. Combined with the current key, a PAC signature is generated according to the PAC algorithm. The PAC is embedded in the reserved bits of the return address. Then, for Class A instruction set architectures, the return address with the PAC is written to the top of the stack; for Class B instruction set architectures, the return address with the PAC is written to the return address register. The pipeline resumes at the target address indicated by the instruction bypass unit. The target address is the address of the second set instruction (i.e., the first daddiu instruction in this example), which is equivalent to skipping instruction identification and directly executing the second target instruction.
[0118] As to how to match the first daddiu instruction, the foregoing has been described and will not be repeated here.
[0119] For the second suitable opportunity, the second setting instruction is an instruction for backing up the return address stored in the return address register to the stack, and the stack pointer is obtained by the instruction bypass unit, including reading the stack pointer stored in the stack pointer register by the instruction bypass unit, and the context corresponding to the stack pointer is the stack pointer.
[0120] Specifically, the second setting instruction can be the sd instruction in the above-mentioned assembly code, and when the second setting instruction is identified, the instruction bypass unit has two complete bypass modes.
[0121] (3) The first complete bypass mode under the second suitable opportunity
[0122] One way is to complete the PAC signature in the instruction bypass unit and simulate the execution of this instruction, because the above-mentioned sd instruction is used to back up the value of the 31 register to the stack, so the PAC signature of the return address on the 31 register (i.e. the return address register of the MIPS architecture) is completed by the instruction bypass unit, and the return address (carrying the PAC) is backed up to the stack. In this process, the PAC signature is completed before the return address stored in the 31 register is written to the specified location on the stack, at which time the value of the sp register obtained is already a new value, which is used, and the signed return address is written to the specified location on the stack.
[0123] Specifically, the value of the stack pointer register is read as the context, the return address is read from the return address register, and the PAC is generated by combining the use of the current key to complete the PAC signature. The PAC is embedded in the reserved bit of the return address, and then the return address with the PAC is written to the memory address specified by the instruction, which is generally the top of the stack. Since the behavior that the instruction should originally perform (writing the return address to the memory address specified by the instruction) has been completely completed in the instruction bypass unit, the recovery pipeline at the target address indicated by the instruction bypass unit, and the target address is the address of the next instruction corresponding to the second setting instruction (i.e. the sd instruction in this example).
[0124] (4) The second complete bypass mode under the second suitable opportunity
[0125] Another way is to only complete the PAC signature of the return address on the 31 register in the instruction bypass unit, at which time the The value of the sp register is already the new value, is used, and is overwritten 31 register, since this sd instruction is not emulated by the instruction bypass unit, the target address indicated by the instruction bypass unit after it is executed should be set to the address of this sd instruction. This makes this sd instruction temporarily skip one instruction match, so that it is executed normally, and finally makes this instruction complete the writing of the return address to the stack through normal execution. The return address (already carrying the PAC) on the 31 register (i.e., the return address register of the MIPS architecture) is written to the specified location on the stack.
[0126] Specifically, the value of the stack pointer register is read as the context, the return address is read from the return address register, the PAC signature is completed using the current key, and the PAC is generated. The PAC is embedded in the reserved bit of the return address, and then the return address with the PAC is written to the return address register. The pipeline is resumed at the target address indicated by the instruction bypass unit, which is the address of the second specified instruction (i.e., the sd instruction in this example), which is equivalent to skipping instruction recognition and directly executing the second specified instruction.
[0127] If a stack that grows from top to bottom is used, the instruction is identified as the first target instruction in the following manner: the opcode in the instruction is a memory storage opcode, the source register is the return address register, the memory base register is the stack pointer register, and the offset is positive. The instruction is the first target instruction. A stack that grows from top to bottom is a stack with the stack bottom at a high address and the stack top at a low address, where the high address is a memory address with a larger address value, and the low address is a memory address with a smaller address value.
[0128] Specifically, since instructions with the same purpose have different names in different instruction set architectures, the specific name of the opcode is not limited in this application. In this embodiment of the application, the MIPS64 instruction set architecture is used, and the stack is taken as an example of growing from top to bottom. Therefore, in the MIPS64 instruction set architecture, the opcode in the instruction is SD (which belongs to the memory storage opcode), and the offset is positive.
[0129] Specifically, when using a mask to match such an instruction, the sd instruction is a memory access instruction that uses a base register plus an immediate offset to address, reads the data stored in the source register, and writes it to the memory address determined by the addressing method. If the data is to be written to the stack, the base register should be sp, and if the data to be written is the return address, the source register should be 31. In this case, the matching item not only matches that the instruction is sd, but also matches that the source register used by the instruction is 31, and also matches that the base register used by the instruction is sp. Examples of matching terms are shown in Table 3:
[0130] Table 3
[0131]
[0132] Furthermore, considering that when accessing data in the stack, the data should reside in the stack rather than outside the stack, and that the memory address range occupied by the stack can be represented from the bottom of the stack to the top of the stack, and also considering... The address stored in the sp register points to the top of the stack. Therefore, since this example uses a stack that grows from top to bottom, the target address for a valid memory access to the stack must be higher than the address of the top of the stack. Thus, when using... When sp is used as a base address register, the offset must be a positive integer to ensure the target memory access address is located on the stack rather than off-stack. Furthermore, since the offset in the above instruction is a signed integer, for this offset to be a positive integer, its highest bit must be 0. Therefore, a preferred matching option is shown in Table 4:
[0133] Table 4
[0134]
[0135] In one possible implementation, if a bottom-up stack is used, the instruction is identified as the first target instruction as follows: the opcode in the instruction is a memory-stored opcode, the source register is the return address register, the memory base address register is the stack pointer register, and the offset is negative. A bottom-up stack has its bottom at a low address and its top at a high address; high addresses are memory addresses with larger numerical values, and low addresses are memory addresses with smaller numerical values. Specifically, taking the MIPS64 instruction set architecture and assuming a bottom-up stack, the opcode in the instruction in the MIPS64 architecture is SD (a memory-stored opcode), and the offset is negative. The matching example is similar to Table 4, except that the binary number representing the sign of the immediate value in the 15th bit is 0.
[0136] Figure 2 This is a flowchart illustrating a method for preventing ROP attacks provided in an embodiment of this application. This flowchart can be executed by a CPU that processes instructions in a pipelined manner. The method is used to determine whether the PAC to be verified is the same as the PAC carried at the return address. Figure 2 As shown, the process includes the following steps:
[0137] Step 201: When the CPU is processing instructions in pipelined mode, if it recognizes a second target instruction in a function call, it will pause the pipeline.
[0138] At step 202, the CPU acquires the return address, the stack pointer and the key carrying the PAC through the instruction bypass unit, and generates the PAC to be verified based on the context corresponding to the return address and the stack pointer stripped of the PAC and the key.
[0139] At step 203, if the PAC is the same as the PAC to be verified, the CPU resumes the pipeline at the target address indicated by the instruction bypass unit; if the PAC is different from the PAC to be verified, an exception is triggered.
[0140] Specifically, the second target instruction is a third setting instruction whose stack pointer points to the caller stack frame before and after execution, or the second target instruction is a fourth setting instruction whose stack pointer points to the callee stack frame before and after execution. After the second target instruction is identified, the instruction bypass unit acquires the return address, the stack pointer and the key carrying the PAC, and generates the PAC to be verified based on the context corresponding to the return address and the stack pointer stripped of the PAC. If the PAC is the same as the PAC to be verified, the pipeline is resumed at the target address indicated by the instruction bypass unit; if the PAC is different from the PAC to be verified, an exception is triggered, and the exception indicates a ROP attack on the return address. There are two cases when verifying the PAC: determining the context corresponding to the stack pointer according to the old value of the stack pointer register, and determining the context corresponding to the stack pointer according to the new value of the stack pointer register.
[0141] (1) Determining the context corresponding to the stack pointer according to the old value of the stack pointer register
[0142] There are two suitable opportunities to determine the context corresponding to the stack pointer using the old value of the stack pointer register. The first suitable opportunity is the second daddiu instruction in the above code, that is, the instruction for restoring the stack pointer register. Only the value of the restored stack pointer register needs to be used as the context in the bypass to perform verification and modify the target address of the jump accordingly. The second suitable opportunity is the above-mentioned jr instruction, that is, the instruction that actually uses the 31 register. At this time, only the value of the restored stack pointer register needs to be used as the context in the bypass to perform verification and modify the target address of the jump accordingly.
[0143] For the first suitable opportunity, the third setting instruction is an instruction whose stack pointer points to the callee stack frame before execution (equivalent to the value in the stack pointer register being a new value) and points to the caller stack frame after execution (equivalent to the value in the stack pointer register being an old value). The stack pointer is acquired through the instruction bypass unit, including, before the execution of the third setting instruction, the stack pointer stored in the stack pointer register is read through the instruction bypass unit, and the context corresponding to the stack pointer is calculated based on the stack pointer and the size of the stack frame to obtain the stack pointer updated after the execution of the third setting instruction.
[0144] Specifically, the third setting instruction is the second daddiu instruction in the above code, and when the third setting instruction is identified, the instruction bypass unit has two possible complete bypass manners.
[0145] (1) The first complete bypass manner under the first suitable opportunity
[0146] One way is that the instruction bypass unit simulates the execution of this instruction and completes the PAC verification, that is, the instruction bypass unit completes the rewriting of the sp register, that is, the behavior of the daddiu instruction itself, that is, the sp register value is increased and then restored to the old value, and the PAC verification of the return address on the 31 register, because at this time the sp register has been restored to the old value, so it can be used for verification; of course, in fact, it is not necessary to execute the two steps in sequence, the two steps can be performed at the same time, as long as the PAC verification uses the old value of the sp register; at this time the daddiu instruction itself has been completely simulated by the instruction bypass unit, so the target address indicated by the instruction bypass unit after execution should be set to the address of the next instruction.
[0147] Specifically, according to the behavior that the instruction should originally execute, simulate the execution (which will cause the stack pointer register to be updated, so that the value in the stack pointer register has been restored to the old value after simulation). For the A-type instruction set architecture, read the return address with PAC from the top of the stack, and for the B-type instruction set architecture, read the return address with PAC from the return address register. Strip the PAC in the return address to obtain the original return address. Read the value of the stack pointer register as the context or calculate the updated stack pointer register value of the instruction as the context, combine the current key, and use the original return address to generate a PAC again. Compare with the PAC obtained by stripping before, if they are consistent, for the A-type instruction set architecture, write the original return address to the top of the stack, and for the B-type instruction set architecture, write the original return address to the return address register. Otherwise, maintain the return address with PAC or write an illegal address. Optionally, an exception can be directly triggered when the comparison is inconsistent, without entering the next step. The instruction bypass unit indicates the target address to resume the pipeline, and the target address is the address of the next instruction corresponding to the third setting instruction (that is, the second daddiu instruction in this example).
[0148] (2) The second complete bypass manner under the first suitable opportunity
[0149] Another way is that the instruction bypass unit only completes the PAC verification of the return address on the 31 register, and the value of the sp register obtained at this time is actually a new value. Therefore, it is necessary to parse the daddiu instruction to obtain the stack frame size, and then add the stack frame size to the value of the sp register (which is equivalent to calculating the old value of the stack pointer register) before performing the PAC verification, and rewrite the 31 register according to the verification result. The restoration address after bypass completion should be set as the address of the daddiu instruction. This makes the daddiu instruction temporarily skip the instruction matching once, so that the instruction is normally executed, and finally the instruction completes the rewriting of the sp register through normal execution.
[0150] Specifically, for the A-type instruction set architecture, the return address with the PAC is read from the top of the stack, and for the B-type instruction set architecture, the return address with the PAC is read from the return address register.
[0151] The PAC in the return address is stripped to obtain the original return address. The updated stack pointer register value is calculated as the context, and the original return address is used to generate the PAC again using the current key. If the comparison is consistent, for the A-type instruction set architecture, the original return address is written to the top of the stack, and for the B-type instruction set architecture, the original return address is written to the return address register; otherwise, the return address with the PAC is maintained or a non-legal address is written. Alternatively, an exception can be directly triggered when the comparison is inconsistent, without entering the next step. The target address of the instruction bypass unit is the address of the third set instruction (i.e., the second daddiu instruction in this example), which is equivalent to skipping the instruction recognition and directly executing the third set instruction.
[0152] In a possible implementation, if a stack that grows from top to bottom is used, the second target instruction is identified by the following method: if the operation code in the instruction is an immediate number addition operation code, the source register is the stack pointer register, the destination register is the stack pointer register, and the immediate number is positive, then the instruction is the second target instruction; or if the operation code in the instruction is an immediate number subtraction operation code, the source register is the stack pointer register, the destination register is the stack pointer register, and the immediate number is negative, then the instruction is the second target instruction. The stack that grows from top to bottom is a stack with the stack bottom at a high address and the stack top at a low address. The high address is a memory address with a larger address value, and the low address is a memory address with a smaller address value.
[0153] This application uses the MIPS64 instruction set architecture, and takes the stack as growing from top to bottom and the opcode as an immediate addition opcode as an example. Therefore, in the MIPS64 instruction set architecture, the opcode in the instruction is DADDIU (which is an immediate addition opcode), and the immediate value is positive.
[0154] Specifically, since at the end of a function, either the stack frame is not released, or if it is released, the top of the stack is always pushed up (because this example uses a stack that grows from top to bottom), we want to only match the case where the top of the stack is pushed up, that is, for... When sp increments, the immediate value mentioned above must be filled with a positive number. According to the instruction definition of daddiu, its highest bit can be used to determine the sign of the immediate value, and the highest bit of the immediate value must be 0. Examples of matching items are shown in Table 5:
[0155] Table 5
[0156]
[0157] In one possible implementation, if a bottom-growing stack is used, the instruction that satisfies either of the following two conditions is identified as the second target instruction: (a) the opcode in the instruction is an immediate addition opcode, the source register is the stack pointer register, the destination register is the stack pointer register, and the immediate value is negative; (b) the opcode in the instruction is an immediate subtraction opcode, the source register is the stack pointer register, the destination register is the stack pointer register, and the immediate value is positive. A bottom-growing stack has its bottom at a low address and its top at a high address; the high address is a memory address with a larger memory value, and the low address is a memory address with a smaller memory value. The specific matching method will not be elaborated upon here.
[0158] For the second suitable timing, the third setting instruction is a jump instruction used for function return, which obtains the stack pointer through the instruction bypass unit, including reading the stack pointer stored in the stack pointer register through the instruction bypass unit, and the context corresponding to the stack pointer is the stack pointer.
[0159] Specifically, the third setting instruction can be a jr instruction. When the third setting instruction is detected, the instruction bypass unit has a complete bypass mode.
[0160] (3) The second appropriate time for a complete bypass method
[0161] Because the jr command itself uses... 31 (i.e. the return address register of MIPS architecture), but before the PAC verification is completed, because the reserved bit is occupied by the PAC, its value is still an illegal address, so it cannot be executed as it is, but must be simulated by the instruction bypass unit more or less. In this process, before the jump, the PAC verification is completed, at this time the value of the sp register has been restored to the old value by the previous daddiu instruction, and the return address stripped of the PAC is used for the jump after the verification passes, if the verification does not pass, an exception is raised, and the rest of the behavior is consistent with the original instruction behavior.
[0162] Specifically, for the A-type instruction set architecture, the return address with the PAC is read from the top of the stack, and for the B-type instruction set architecture, the return address with the PAC is read from the return address register; the PAC in the return address is stripped to obtain the original return address. The value of the stack pointer register is read as the context, and the original return address is regenerated again using the current key. Compared with the PAC stripped before, if the comparison is consistent, the original return address is taken as the jump target address, otherwise, the return address with the PAC is maintained as the jump target address or an illegal address is used as the jump target address. Alternatively, an exception can also be directly raised when the comparison is inconsistent, without entering the next step. In addition, in addition to the jump, the behavior that the instruction should originally execute is simulated, and the above two steps can be performed in sequence or simultaneously. Since the behavior that the instruction should originally execute has been completely completed in the instruction bypass unit, the target address indicated by the instruction bypass unit is restored to the pipeline, and the target address is the address of the jump target of the third set instruction (i.e. the jr instruction in this example).
[0163] The jr instruction is an instruction that reads the address stored in the source register and jumps to the address. If the jump is to the return address, the source register should be the return address register (for the MIPS instruction set architecture, it is 31). In this case, the matching item not only matches that the instruction is jr, but also matches that the source register used by the instruction is 31, so as to determine that the instruction is the jump instruction for function return (it is worth noting that the jump instruction for function return of some instruction set architectures does not need to specify the register in the instruction, for such instruction set architectures, only the operation code needs to be matched, and details are not described). In addition, it is noted that the jr instruction uses two levels of operation codes, so two levels of operation codes must be matched to determine that the instruction is jr. The matching item is shown in Table 6:
[0164] Table 6
[0165]
[0166] (ii) determining the context corresponding to the stack pointer according to the new value of the stack pointer register
[0167] There are two suitable opportunities to determine the context corresponding to the stack pointer using the new value of the stack pointer register. The first suitable opportunity is the second daddiu instruction described above, that is, the instruction for restoring the stack pointer register, and only the current value (the value before the instruction is executed) of the stack pointer register needs to be used in the bypass as the context to perform the signature verification and the corresponding modification 31 register. The second suitable opportunity is the ld instruction in the above code, that is, the instruction for popping the return address from the bottom of the current stack frame to the 31 register, and at this time, only the current value of the stack pointer register needs to be used in the bypass as the context to perform the signature verification and the corresponding use of the signature-verified return address written into 31.
[0168] For the first suitable opportunity, the fourth setting instruction is an instruction whose stack pointer points to the caller stack frame before execution (equivalent to the value in the stack pointer register being the new value) and whose stack pointer points to the caller stack frame after execution (equivalent to the value in the stack pointer register being the old value), and the stack pointer is obtained by the instruction bypass unit, including, before the execution of the fourth setting instruction, the stack pointer stored in the stack pointer register is read by the instruction bypass unit, and the context corresponding to the stack pointer is the stack pointer.
[0169] Specifically, the fourth setting instruction is the second daddiu instruction in the above code, and when the second setting instruction is identified, the instruction bypass unit has two possible complete bypass modes.
[0170] (1) The first complete bypass mode under the first suitable opportunity
[0171] One way is to complete the PAC signature verification by the instruction bypass unit and simulate the execution of this instruction, that is, the PAC signature verification of the return address on the 31 register is completed by the instruction bypass unit, and at this time, the sp register has not been overwritten, so its value is still the new value, which can be used for signature verification. And the overwriting of the sp register is the behavior of this daddiu instruction itself, that is, the sp register value is incremented and then restored to the old value. Of course, in practice, it is not necessary to execute these two steps in sequence, and these two steps can be performed simultaneously, as long as the PAC signature verification uses the new value of the sp register. At this time, this daddiu instruction itself has been completely simulated by the instruction bypass unit, so the restore address should be set to the address of the next instruction.
[0172] Specifically, for the A-type instruction set architecture, the return address with PAC is read from the top of the stack, and for the B-type instruction set architecture, the return address with PAC is read from the return address register. The PAC in the return address is stripped, thus obtaining the original return address. The value of the stack pointer register before the update is read as the context, and the original return address is used to generate the PAC again using the current key. If the comparison is consistent with the PAC stripped before, for the A-type instruction set architecture, the original return address is written to the top of the stack, and for the B-type instruction set architecture, the original return address is written to the return address register. Otherwise, the return address with PAC is maintained or an illegal address is written. Alternatively, an exception can be directly triggered when the comparison is inconsistent, without entering the next step. In addition, the execution is simulated according to the behavior that the instruction should originally perform. The pipeline is resumed at the target address indicated by the instruction bypass unit, which is the address of the next instruction corresponding to the fourth specified instruction (i.e., the second daddiu instruction in this example), which is equivalent to resuming normal execution from the next instruction.
[0173] (2) The second complete bypass mode under the first suitable opportunity
[0174] Another way is that the instruction bypass unit only completes the PAC verification of the return address on the 31 register, and at this time, the value of the sp register obtained is still a new value, which can be used for PAC verification, and the 31 register is rewritten according to the verification result. The recovery address after bypassing should be set to the address of the daddiu instruction, so that the daddiu instruction temporarily skips the instruction matching once, so that the instruction completes the rewriting of the sp register through normal execution. 31 register. The recovery address after bypassing should be set to the address of the daddiu instruction, so that the daddiu instruction temporarily skips the instruction matching once, so that the instruction completes the rewriting of the sp register through normal execution.
[0175] Specifically, for the A-type instruction set architecture, the return address with PAC is read from the top of the stack, and for the B-type instruction set architecture, the return address with PAC is read from the return address register. The PAC in the return address is stripped, thus obtaining the original return address. The value of the stack pointer register is read as the context, and the PAC is regenerated again using the original return address in combination with the current key. If the comparison is consistent, the original return address is written into the top of the stack for the A-type instruction set architecture, and the original return address is written into the return address register for the B-type instruction set architecture. Otherwise, the return address with PAC is maintained or an illegal address is written, and optionally, an exception can be directly triggered when the comparison is inconsistent, without entering the next step. The pipeline is restored at the target address indicated by the instruction bypass unit, and the target address is the address of the fourth setting instruction (i.e., the second daddiu instruction in this example), which is equivalent to skipping the instruction recognition and directly executing the fourth setting instruction.
[0176] As to how to match the second daddiu instruction, the foregoing has been described, and will not be repeated here.
[0177] For the second suitable opportunity, the fourth setting instruction is an instruction for restoring the return address stored on the stack into the return address register, and the stack pointer is obtained through the instruction bypass unit, including, before the execution of the third setting instruction, the stack pointer stored in the stack pointer register is read through the instruction bypass unit, and the context corresponding to the stack pointer is the stack pointer.
[0178] Specifically, the fourth setting instruction can be the ld instruction in the above-mentioned assembly code, and when the fourth setting instruction is recognized, the instruction bypass unit has two complete bypass modes.
[0179] (3) The first complete bypass mode under the second suitable opportunity
[0180] One way is to complete the PAC verification in the instruction bypass unit and simulate the execution of this instruction, because the above-mentioned ld instruction is used to pop the return address from the current stack to the 31 register, so the PAC verification of the return address in the stack is completed by the instruction bypass unit, and the return address (the original return address, which has been stripped of the PAC) is written into the return address register (i.e., the 31 of MIPS). In this process, the PAC verification is completed before the return address is written into the 31 register, at which time the value of the sp register is still a new value, which is used, and according to the verification result, the return address is written into the 31 register, and the remaining behaviors are consistent with the behaviors of the original instruction.
[0181] Specifically, except for the restoring behavior of the return address, the behavior that the instruction is supposed to perform is emulated. The return address with PAC is read from the memory address specified by the instruction (usually the top of the stack). The PAC in the return address is stripped, thus obtaining the original return address. The value of the stack pointer register is read as the context, and the original return address is used to generate a PAC again using the current key. If the comparison with the PAC stripped from the original return address is consistent, the original return address is written to the return address register. Otherwise, the return address with PAC is maintained or an illegal address is written, and optionally, an exception can be triggered directly without entering the next step. Since the behavior that the instruction is supposed to perform (writing the return address to the return address register) has been completed completely in the instruction bypass unit, the target address of the pipeline is restored to the address of the next instruction corresponding to the fourth setting instruction (i.e., the ld instruction in this example) indicated by the instruction bypass unit.
[0182] (4) The second complete bypass mode under the second suitable timing
[0183] Another way is to only complete the PAC verification of the return address in the stack in the instruction bypass unit, and the PAC obtained at this time is The value of the sp register is still the new value, which is used, and the return address in the stack is rewritten according to the verification result. Since the ld instruction is not emulated by the instruction bypass unit, the target address indicated by the instruction bypass unit after the execution of the instruction bypass unit should be set to the address of the ld instruction. This makes the ld instruction temporarily skip the instruction matching once, so that the instruction is normally executed, and finally the instruction completes the writing of the return address in the stack to the 31 register (i.e., the return address register of the MIPS architecture).
[0184] Specifically, the return address with PAC is read from the memory address specified by the instruction (usually the top of the stack). The PAC in the return address is stripped, thus obtaining the original return address. The value of the stack pointer register is read as the context, and the original return address is used to generate a PAC again using the current key. If the comparison with the PAC stripped from the original return address is consistent, the original return address is written to the memory address specified by the instruction (usually the top of the stack). Otherwise, the return address with PAC is maintained or an illegal address is written, and optionally, an exception can be triggered directly without entering the next step. The target address of the pipeline is restored to the address of the fourth setting instruction (i.e., the ld instruction in this example) indicated by the instruction bypass unit, which is equivalent to skipping the instruction recognition and directly executing the fourth setting instruction.
[0185] If the stack grows from top to bottom, the instruction is identified as the second target instruction if the opcode in the instruction is a memory load opcode, the target register is the return address register, the memory base register is the stack pointer register, and the offset is positive.
[0186] The embodiment of the present application is based on the MIPS64 instruction set architecture, and takes the stack growing from top to bottom as an example. Therefore, in the MIPS64 instruction set architecture, the opcode in the instruction is LD (a memory load opcode), and the offset is positive.
[0187] Specifically, when using mask matching to match such instructions, the ld instruction is a memory access instruction using a base register plus an immediate offset to address, which reads data from a determined memory address and writes the data into a target register. If the data is to be read from the stack, the base register should be sp. In this case, the matching item should match that the instruction is ld, that the target register used by the instruction is 31, and that the base register used by the instruction is sp. An example of the matching item is shown in Table 7:
[0188] Table 7
[0189]
[0190] Further, considering that when accessing data in the stack, the data should be in the stack rather than outside the stack, and the memory address range occupied by the stack can be represented from the bottom of the stack to the top of the stack, and considering that the address stored in the sp register points to the top of the stack, since the stack in this example grows from top to bottom, the target address of a legal memory access to the stack must be higher than the address of the top of the stack. Therefore, when using sp as the base register, the offset must be a positive integer, so that the target memory access address is in the stack rather than outside the stack. Since the offset of the above instruction is a signed integer, to make the offset a positive integer, the highest bit of the offset must be 0. Therefore, an example of the matching item is shown in Table 8:
[0191] Table 8
[0192]
[0193] In a possible implementation, if a stack grows from bottom to top, the instruction satisfying the following condition is determined as the second target instruction: the operation code in the instruction is a memory loading operation code, the target register is a return address register, the memory base register is a stack pointer register, and the offset is a negative value. The stack growing from bottom to top is a stack with the bottom at a low address and the top at a high address; the high address is a memory address with a larger address value; and the low address is a memory address with a smaller address value. Specifically, taking the MIPS64 instruction set architecture and the stack growing from bottom to top as examples, in the MIPS64 instruction set architecture, the operation code in the instruction is LD (belonging to the memory loading operation code), and the offset is a negative value. The matching example is similar to Table 8, except that the binary number representing the sign of the immediate number on the 15th bit is 1.
[0194] Therefore, as described above, the PAC signature can be signed in the reserved bit of the pointer, Figure 3 A flowchart of a PAC signature and verification process provided by an embodiment of the present application. In order to implement the PAC, we must define which bit field of the pointer is to be used to embed the PAC, and also need to pay attention to not causing additional information loss in this process, that is, in this process, the valid bits of the pointer cannot be used, and the high / low address identification cannot be lost, or at least the lost information can be recovered.
[0195] The existing pointer actually integrates the reserved bit and the high / low address identification, because there are usually the following two applicable regulations at the same time: the highest bit is 1, which is a high address (kernel space address), and the lowest bit is 0, which is a low address (user space address). Each bit between the highest bit and the most significant bit is a reserved bit. All reserved bits must be synchronized with the highest bit to be the same binary value, otherwise it is an illegal pointer, that is, an illegal memory address or an unstandard memory address. In other words, the highest bit and the reserved bit must be all 1 or all 0, otherwise it is not a legal address.
[0196] Therefore, as long as a pointer is legal, any reserved bit of the pointer is related to the high / low address identification. Therefore, the highest bit and the reserved bit can be collectively referred to as the reserved bit and the high / low address identification.
[0197] Based on this, an embodiment of the present application provides a redefinition manner of a pointer bit field, which can embed the PAC without losing any original valid information. That is, the purpose of the original valid bit is not changed, and the reserved bit and the high / low address identification are re-allocated.
[0198] In a possible implementation, at least one bit is used as the high / low address identification, which can not be limited in position and length, and the remaining bits are used to embed the PAC. Figure 4This is another schematic diagram of the PAC signature and verification process provided in this application embodiment. Figure 4 As can be seen, the highest bit can be used as the high / low address identifier, and the remaining reserved bits are all used to embed the PAC.
[0199] Figure 5 This is a schematic diagram illustrating another PAC signature and verification process provided in an embodiment of this application. In one possible implementation, all bits of the pointer are used to embed the PAC. During PAC verification, since the original pointer needs to be restored first, the possible values of the reserved bits and the high / low address identifiers can be exhaustively enumerated during the restoration process. In reality, there are only two possible values: either all 1s or all 0s. If one of these values allows the PAC verification to pass, the original high / low address identifier values are restored, thus confirming the correct value of the original pointer.
[0200] Figure 6 This is a schematic diagram of a device 6000 for preventing ROP attacks, provided as an embodiment of this application. Figure 6 As shown, it includes at least one processor 601 and a memory 602 connected to at least one processor 601. In this embodiment, the specific connection medium between the processor 601 and the memory 602 is not limited. Figure 6 Taking the connection between the processor 601 and the memory 602 via a bus as an example, the bus can be divided into address bus, data bus, control bus, etc.
[0201] In this embodiment of the application, the memory 602 stores instructions that can be executed by at least one processor 601. By executing the instructions stored in the memory 602, the at least one processor 601 can implement the steps of the above-described method for preventing ROP attacks.
[0202] The processor 601 is the control center of the computer device, capable of connecting various parts of the computer device via various interfaces and lines. It performs resource configuration by running or executing instructions stored in the memory 602 and accessing data stored in the memory 602. Optionally, the processor 601 may include one or more processing units. The processor 601 may integrate an application processor and a modem processor. The application processor primarily handles the operating system, user interface, and applications, while the modem processor primarily handles wireless communication. It is understood that the modem processor may not be integrated into the processor 601. In some embodiments, the processor 601 and the memory 602 may be implemented on the same chip; in other embodiments, they may be implemented on separate chips.
[0203] The processor 601 can be a general processor, such as a central processing unit (CPU), a digital signal processor, an application specific integrated circuit (ASIC), a field programmable gate array or other programmable logic device, a discrete gate or transistor logic component, a discrete hardware component, and can implement or execute the methods, steps and logical block diagrams disclosed in the embodiments of the present application. The general processor can be a microprocessor or any conventional processor. The steps of the methods disclosed in the embodiments of the present application can be directly embodied as being executed by a hardware processor, or executed by a combination of hardware and software modules in the processor.
[0204] The memory 602 is a non-volatile computer readable storage medium, and can be used to store non-volatile software programs, non-volatile computer executable programs and modules. The memory 602 can include at least one type of storage medium, such as flash memory, hard disk, multimedia card, card type memory, random access memory (RAM), static random access memory (SRAM), programmable read only memory (PROM), read only memory (ROM), electrically erasable programmable read only memory (EEPROM), magnetic storage, magnetic disk, optical disk, etc. The memory 602 is any other medium capable of carrying or storing desired program codes in the form of instructions or data structures and capable of being accessed by a computer, but is not limited thereto. The memory 602 in the embodiments of the present application can also be a circuit or any other device capable of realizing a storage function, used to store program instructions and / or data.
[0205] Those skilled in the art should understand that the embodiments of the present application can be provided as a method, a system or a computer program product. Therefore, the present application can take the form of a complete hardware embodiment, a complete software embodiment or an embodiment combining software and hardware aspects. Moreover, the present application can take the form of a computer program product implemented on one or more computer usable storage media (including but not limited to disk storage, CD-ROM, optical storage, etc.) containing computer usable program codes.
[0206] The computer program instructions can also be loaded onto a computer or other programmable data processing apparatus to cause a series of operational steps to be performed on the computer or other programmable apparatus to produce a computer-implemented process such that the instructions which execute on the computer or other programmable apparatus provide steps for implementing the functions specified in the flowchart block or blocks. Figure 1 one or more flow or blocks Figure 1 one or more flow or blocks
[0207] These computer program instructions can also be stored in a computer readable memory that can direct a computer or other programmable data processing apparatus to function in a particular manner, such that the instructions stored in the computer readable memory produce an article of manufacture including instructions which implement the function specified in the flowchart block or blocks. Figure 1 one or more flow or blocks Figure 1 one or more flow or blocks
[0208] The computer program instructions can also be loaded onto a computer or other programmable data processing apparatus to cause a series of operational steps to be performed on the computer or other programmable apparatus to produce a computer-implemented process such that the instructions which execute on the computer or other programmable apparatus provide steps for implementing the functions specified in the flowchart block or blocks. Figure 1 one or more flow or blocks Figure 1 one or more flow or blocks
[0209] Obviously, numerous modifications and variations of the present application are possible in light of the above teachings. It is therefore to be understood that within the scope of the appended claims and their equivalents, the application can be practiced otherwise than as specifically described.
Claims
1. A method of preventing a return-oriented programming (ROP) attack, the method comprising: The method comprises: When processing instructions in a pipeline mode, if a first target instruction in a function call is identified, the pipeline is paused; the first target instruction is a first set instruction whose stack pointer points to a caller stack frame before and / or after execution; or, the first target instruction is a second set instruction whose stack pointer points to a callee stack frame before and / or after execution; A return address, the stack pointer and a key of the function call are acquired by an instruction bypass unit, and a pointer authentication code (PAC) is generated based on the return address, a context corresponding to the stack pointer and the key; the PAC is added to reserved bits of the return address to obtain a return address carrying the PAC; the return address carrying the PAC is used to prevent a return address ROP attack; After the instruction bypass unit is executed, the pipeline is resumed according to a target address indicated by the instruction bypass unit.
2. The method of claim 1, wherein, The first set instruction is an instruction whose stack pointer points to a caller stack frame before execution and a callee stack frame after execution; The stack pointer is acquired by the instruction bypass unit, comprising: Before the first set instruction is executed, the stack pointer stored in a stack pointer register is read by the instruction bypass unit; The context corresponding to the stack pointer is the stack pointer.
3. The method of claim 1, wherein, The first set instruction is a jump instruction used for the function call; The stack pointer is acquired by the instruction bypass unit, comprising: The stack pointer stored in a stack pointer register is read by the instruction bypass unit, and the context corresponding to the stack pointer is the stack pointer.
4. The method of claim 1, wherein, The second set instruction is an instruction whose stack pointer points to a caller stack frame before execution and a callee stack frame after execution; The stack pointer is acquired by the instruction bypass unit, comprising: Before the second set instruction is executed, the stack pointer stored in a stack pointer register is read by the instruction bypass unit; The context corresponding to the stack pointer is a stack pointer updated after the second set instruction is executed, which is calculated according to the stack pointer and a size of a stack frame.
5. The method of claim 1, wherein, The second set instruction is an instruction used for backing up a return address stored in a return address register to a stack; The stack pointer is acquired by the instruction bypass unit, comprising: The stack pointer stored in a stack pointer register is read by the instruction bypass unit, and the context corresponding to the stack pointer is the stack pointer.
6. A method of preventing a return-oriented programming (ROP) attack, the method comprising: The method comprises: When processing instructions in a pipeline mode, if a second target instruction in a function call is identified, the pipeline is paused; the second target instruction is a third set instruction whose stack pointer points to a caller stack frame before and / or after execution, or the second target instruction is a fourth set instruction whose stack pointer points to a callee stack frame before and / or after execution; the before and / or after execution is before execution and / or after execution; A return address carrying a pointer authentication code (PAC), the stack pointer and a key are acquired by an instruction bypass unit, and a PAC to be verified is generated based on a return address stripped of the PAC, a context corresponding to the stack pointer and the key; If the PAC is the same as the PAC to be verified, the pipeline is resumed at the target address indicated by the instruction bypass unit; if the PAC is different from the PAC to be verified, an exception is triggered, and the exception represents a ROP attack on a return address.
7. The method of claim 6, wherein, The third setting instruction is an instruction in which a stack pointer points to a caller stack frame before execution and points to a callee stack frame after execution; The stack pointer is obtained by an instruction bypass unit, including: Before execution of the third setting instruction, the stack pointer stored in a stack pointer register is read by the instruction bypass unit; The context corresponding to the stack pointer is a stack pointer updated after execution of the third setting instruction, which is calculated according to the stack pointer and a size of a stack frame.
8. The method of claim 6, wherein, The third setting instruction is a jump instruction for function return. The stack pointer is obtained by an instruction bypass unit, including: The stack pointer stored in a stack pointer register is read by the instruction bypass unit; The context corresponding to the stack pointer is the stack pointer.
9. The method of claim 6, wherein, The fourth setting instruction is an instruction in which a stack pointer points to a caller stack frame before execution and points to a callee stack frame after execution; The stack pointer is obtained by an instruction bypass unit, including: Before execution of the fourth setting instruction, the stack pointer stored in a stack pointer register is read by the instruction bypass unit; The context corresponding to the stack pointer is the stack pointer.
10. The method of claim 6, wherein, The fourth setting instruction is an instruction for restoring a return address stored on a stack into a return address register; The stack pointer is obtained by an instruction bypass unit, including: Before execution of the third setting instruction, the stack pointer stored in a stack pointer register is read by the instruction bypass unit; The context corresponding to the stack pointer is the stack pointer.
Citation Information
Patent Citations
Call path dependent authentication
CN111052115A
Consistent Speculation of Pointer Authentication
US20250094567A1