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 of 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.
Display of jmp short instruction machine code
In the above figure, EB is the opcode of jmp. This instruction jumps forward 5 bytes after the instruction is completed. The target address can be calculated using the method shown in the figure, which is the starting address of the instruction plus the length of the instruction itself (2 bytes) plus the distance of the second byte jump (5 bytes).
Calculating the jump position
The distance of the short jump: The maximum forward jump distance is 0x7f.
Note: IDA displays the machine code.
Set the value of Number of opcode bytes (graph) to 12 (10) in the Options-General settings of the menu bar, which is the default value of 0.
Note: Database snapshot function
During reverse engineering, some modifications may 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: Modify 05 to 7f
From the above figure, it can be seen that 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 judge whether to jump forward or backward based on the numerical value, a dword representing -0x80 must be entered, which is 0xffffff80
, and the result is bitwise AND with 0xffffffff
. The bit beyond 32 bits will be cleared, so the value obtained is 0x4012a6
.
If 0xff is used as the jump distance of the second byte, this is the minimum jump distance -1. From the above figure, it can be seen that it finally jumps to 0x401325, which is a jump of 1 byte.
If it jumps back one more byte, and the second byte of the instruction is changed to fe, it will eventually jump back to the starting position, forming an infinite loop.
If the second byte is changed to fd, it jumps back 3 bytes from the end of the instruction and finally jumps to 0x401323.
Short jumps can only jump around the current address and cannot jump to all addresses. Therefore, the program will use long jumps.
The above figure shows some long jumps, and the loc in the figure indicates that the instruction is a general instruction.
The above figure 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 starting address - Start instruction starting address - 5
5 is the length of the jump instruction, and the result is 0x300, which is the dword after the long jump instruction opcode E9.
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 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 not less | |
7E | JLE | Jump if less or equal | |
7F | JG | Jump if greater | |
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 is negative | |
89 | JNS | Jump if sign is positive | |
8C | JL/JNGE | Jump if less | |
8D | JGE/JNL | Jump if not less | |
8E | JLE/JNG | Jump if less or equal | |
8F | JG/JNLE | Jump if greater or equal |
Except for JMP and NOP, the rest are conditional jump instructions that are 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 above figure, 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:
The function ends with the ret instruction, which jumps to the return address saved on the stack, which is the next instruction after the call to this function.
Return address