banner
lca

lca

真正的不自由,是在自己的心中设下牢笼。

"Learning Notes on IDA Reverse Engineering from Scratch - 7 (Flow Control)"

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.

HexadecimalASMDescription
74 or 0F84JEJump if equal
75 or 0F85JNEJump if not equal
77 or 0F87JAJump if above
7CJLJump if less
7DJGEJump if not less
7EJLEJump if less or equal
7FJGJump if greater
80JOJump if overflow
81JNOJump if not overflow
82JB/JNAEJump if below
83JNB/JAEJump if not below
86JNA/JBEJump if not above or equal
88JSJump if sign is negative
89JNSJump if sign is positive
8CJL/JNGEJump if less
8DJGE/JNLJump if not less
8EJLE/JNGJump if less or equal
8FJG/JNLEJump 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

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.