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 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.

HexadecimalASMDescription
74 or 0F84JEJump if equal
75 or 0F85JNEJump if not equal
77 or 0F87JAJump if above
7CJLJump if less
7DJGEJump if greater than or equal
7EJLEJump if less than or equal
7FJGJump if greater than
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
89JNSJump if not sign
8CJL/JNGEJump if less than
8DJGE/JNLJump if greater than or equal
8EJLE/JNGJump if less than or equal
8FJG/JNLEJump 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

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