1. Unconditional Jump Instruction JMP#
The EIP (Instruction Pointer)
points to the next instruction to be executed. After execution, the EIP points to the next instruction. The value in the EIP is automatically updated after each instruction execution, pointing to the address of the next instruction to be executed. Some jump instructions in assembly language (such as JMP, JE, JNE, etc.) can modify the value in EIP to jump to a specified address for execution.
In the JMP A instruction, A is the memory address to which the program author wants to unconditionally jump.
jmp short instruction
The JMP SHORT instruction is a two-byte short jump instruction that can only jump forward or backward. The first byte EB is the jump operation code (OPCODE). The direction of the jump is determined by the value of the second byte. This type of jump has a distance limit.
Machine code of jmp short instruction
In the above figure, EB is the opcode of jmp, and this instruction jumps forward 5 bytes after the instruction ends. The target address can be calculated using the following method: starting address of the instruction + length of the instruction itself (2 bytes) + distance of the second byte of the jump (5 bytes).
Calculating the jump position
The jump distance of short: The maximum forward jump distance is 0x7f.
Note: IDA displays machine code
Set the value of Number of opcode bytes (graph) to 12 (10) in the Options-General menu, the default is 0.
Note: Database snapshot function
During reverse engineering, some modifications will be made to the program, which will interrupt the recognized functions. Using the database snapshot can return to the state at a certain point in the past. When encountering problems and not knowing how to fix them, this function can be used.
Name the snapshot
Load the snapshot, View-Database snapshot manager
You can see all the snapshot lists and the dates they were created.
Experiment 2: Change the second byte of the jump from 05 to 7f
Use the IDA patch byte function to change 05 to 7f
Experiment 2: Change 05 to 7f
Experiment 2: Modified assembly view
From the above figure, you can see the arrow on the left side, and the program jumps forward to 0x4013a5 at this point.
Next, change 0x7f to 0x80.
After changing to 0x80, the program jumps backward. The previous 0x7f is the farthest forward jump, so 0x80 is the farthest backward jump.
Since Python does not determine whether to jump forward or backward based on the value, a dword representing -0x80 must be entered, which is 0xffffff80
, and the result is bitwise AND with 0xffffffff
. The bit exceeding 32 bits will be cleared, so the result is 0x4012a6
.
If 0xff is used as the jump distance of the second byte, this is the minimum jump distance -1. As shown in the figure above, it will finally jump to 0x401325, which means it jumps 1 byte.
If you jump back one more byte, change the second byte of the instruction to fe, and it will finally jump back to the starting position, forming an infinite loop.
If the second byte is changed to fd, it will jump back 3 bytes from the end of the instruction, and finally jump to 0x401323.
Using short jumps can only jump around the current address and cannot jump to all addresses. Therefore, the program will use long jumps.
The figure above shows some long jumps, and the loc in the figure indicates that the instruction is a general instruction.
The figure above is a long jump, and the distance from 0x4026ae to 0x4029b3 exceeds the range of short jumps.
The jump range calculation formula is: End instruction start address - Start instruction start address - 5
5 is the length of the jump instruction, and the result is 0x300, which is the dword after the opcode E9 of the long jump instruction.
2. Conditional Jump Instructions#
CMP A, B # Compare A and B and perform different operations based on the comparison result
Conditional jump instructions
In the above figure, CMP compares eax and ebx (subtracting the registers). If they are equal, the result is 0, triggering the Z flag or zero flag in the flag register (EFLAGS). The JZ instruction detects this flag and then jumps. If the Z flag is triggered, the green
arrow path in the figure will be executed. If not triggered, the cyan
arrow path will be executed.
Hexadecimal | ASM | Description |
---|---|---|
74 or 0F84 | JE | Jump if equal |
75 or 0F85 | JNE | Jump if not equal |
77 or 0F87 | JA | Jump if above |
7C | JL | Jump if less |
7D | JGE | Jump if greater than or equal |
7E | JLE | Jump if less than or equal |
7F | JG | Jump if greater than |
80 | JO | Jump if overflow |
81 | JNO | Jump if not overflow |
82 | JB/JNAE | Jump if below |
83 | JNB/JAE | Jump if not below |
86 | JNA/JBE | Jump if not above or equal |
88 | JS | Jump if sign |
89 | JNS | Jump if not sign |
8C | JL/JNGE | Jump if less than |
8D | JGE/JNL | Jump if greater than or equal |
8E | JLE/JNG | Jump if less than or equal |
8F | JG/JNLE | Jump if greater than or equal |
Except for JMP and NOP, the remaining instructions are conditional jump instructions executed based on the comparison result.
3. CALL and RET Instructions#
- The CALL instruction is used to call a function.
- The RET instruction is used to return to the instruction below the instruction that called this function.
In the figure above, there is a CALL instruction, and the program will jump to 0x4013d8
to execute this function. (The sub_
before 0x4013d8
indicates that this is a function) The CALL instruction will save the return address 0x40123d
on the stack.
Example of call instruction
Double-click on this function to jump to the following location, and the specific content of the function is as follows:
Specific content of the function at 0x4013d8
As shown in the above figure, after the function is executed, the ret instruction is executed, and it jumps to the return address saved on the stack, which is 0x4012d, which is the next instruction after the call to this function.
Return address