banner
lca

lca

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

"Learning Notes on Starting from Zero with IDA Reverse Engineering - 10 (IDA Debugger)"

image

Choose IDA Debugger#

IDA supports multiple debuggers.

image

Supported debuggers in IDA

Select the Local Windows debugger.

Open the menu bar Debugger - Debugger Options to set some debugger features.

image

IDA debugger options

Debugger Interface Features#

Check Pause at process entry point, select event conditions, and click OK.

image

Rename and change the color of the previous key code jinx.

image

After modification, press the X key to see where this function is referenced:

image

Color the reference points.

image

Set a breakpoint at 0x00401243, hover the mouse over this line, right-click - Add Breakpoint, and it will change to a red background after adding the breakpoint.

image

Start debugging through the menu bar Debugger - Start Process (F9). If debugging an executable locally, the following warning window will pop up.

image

Note:

When analyzing the loader program, the program will not execute locally, but debugging is different. If the program is a virus or other dangerous malware, extra caution is needed. In this case, a remote debugger should be used to execute the program in a virtual machine.

Click Yes to continue debugging.

Since the debugger is set to pause at the entry point, as shown in the figure below, IDA pauses at the entry point (0x00401000).

image

Adjust the general register and flag register windows in the upper right corner for viewing.

image

In the above figure, the values of these registers can be seen. After adjusting normally, open the menu bar Window - Save Desktop and check the default option to save as the debugger's default window settings. Then, when running the debugger, the program will run according to the default settings, which can also be modified if needed.

A stack view can be placed below the general registers.

image

The left side and the bottom are the disassembly and hexadecimal windows.

image

Below the disassembly view is the current memory address and file offset, which refers to the executable file offset.

image

In IDA, the default G key is a shortcut to jump to a memory address. Press G and input 0x401389 to jump to the previously set breakpoint.

image

All static analysis, renaming, and other changes will be saved.

image

Open the menu bar View - Open Subview - Segments, and find that the loader has loaded 3 segments.

image

Loaded the code field at 0x401000, as well as the data and .idata fields below. Modifications to these segments will be saved, while modifications to other segments will not be saved because they are segments loaded by the debugger and will not be saved to the IDA database.

The L flag in the above figure indicates that this program is loaded by both the loader and the debugger, allowing for static analysis while not losing static analysis information during dynamic debugging.

Below are some small toolbars.

  1. Menu bar View - Toolbars - Jump, and then use the save desktop feature to set it as default enabled.

image

Press the back key to return to the previous program entry point.

image

In the menu bar Debugger - Breakpoints - Breakpoint List, you can view all program breakpoints.

image

Clicking anywhere will jump to the corresponding breakpoint.

Conditional Jump Instructions and Flag Registers#

The debugger is currently at the program entry point and has set two breakpoints. Press F9 to continue running.

image

At this point, the crackme.exe program is running, and the target program Help - Register menu bar prompts for a username and password.

image

Click OK.

image

In the above figure, the flashing red arrow on the left indicates the path the program continues to execute. At this time, the value of eax is 0x6c.

image

0x6c converted to a string is l.

image

image

In the above figure, the al register is compared with 0x41 to determine if it is less than 0x41 (A). The green code block below also compares the al register with 0x5a.

asmconditionoperation
JAz=0 and c=0jump if above
JAEc=0jump if above or equal
JBc=1jump if below
JBEz=1 or c=1jump if below or equal
JCc=1jump if carry
JECXZecx=0jump if ecx is 0
JEz=1jump if equal
JZz=1jump if zero
JNEz=0jump if not equal
JNZz=0jump if not zero
JOoverflowjump if overflow
JPeven parityjump if parity
JPEeven parity checkjump if parity even
JNPnot even parityjump if not parity
JPOodd parityjump if parity odd
JSsign bit is 1jump if sign
JNSsign bit is 0jump if not sign
JL/JNGEsign bit same as overflow bitjump if less or not greater/equal
JLE/JNGz=1 or sign bit same as overflow bitjump if less or equal/not greater
JG/JNLEz=0 and sign bit same as overflow bitjump if greater/not less or equal

Conditional jump instructions and jump conditions

Next, switch to the IDA flag register view, as shown below.

image

According to the table, if CF=0, the program will not jump and will execute towards the green code block. So what mathematical condition triggers this C flag?

The C flag indicates that there was an error in unsigned integer operations. If we consider the cmp instruction as a subtraction that does not save the result, then 0x6c - 0x41 = 0x2b, the result is positive. If al is 0x30, then 0x30 - 0x41 = -0x11.

image

-0x11 is a negative number, and the program can only continue to run with its corresponding hexadecimal representation.

image

As shown in the figure, the hexadecimal of -0x11 is 0xffffffef, and in decimal, it is 4294967279, which is a large value, and 0x30-0x41 will not be positive.

So how do we know if the operation considers the sign? This depends on the type of jump used. JB is used for jumps after unsigned number comparisons, while the corresponding signed number instruction is JL.

When using the JB instruction, it is typically used to check if an unsigned integer is less than a certain value. If the operation results in a borrow, it indicates that the second operand (the number being compared) is larger than the first operand (the comparison number). At this point, the JB flag is set to 1, allowing the jump. Otherwise, if the operation does not produce a borrow, the JB flag is 0, meaning the condition is not met, and no jump occurs.

Example:

mov al, 150    ; Assign 150 to al
cmp al, 255    ; Compare al and 255
jb  smaller    ; If al is less than 255, jump to smaller label
   ; Execute other operations
   smaller:
   ; If al is less than or equal to 255, it will jump here

In this example, if the value in al is less than 255, the CF flag will be set to 1, and it will jump to the smaller label. Otherwise, if the value in al is greater than 255, the CF flag will be 0, and it will not jump, executing other operations. (In summary, if al is less than 255, then jump)

To determine if the comparison is signed, it needs to be confirmed by the subsequent conditional jump instruction.

Unsigned jumps

SymbolDescriptionFlag
JE/JZJumps if equal or zerozf
JNE/JNZJumps if not equal or zerozf
JA/JNBEJumps if above or not below or equalzf,cf
JB/JNAEJumps if below or not above or equalcf
JBE/JNAJumps if below or equal or not abovecf,af

Unsigned jumps

The instructions in the above figure do not consider the sign, and each jump has a corresponding signed jump.

SymbolDescriptionFlag
JE/JZJumps if equal or zerozf
JNE/JNZJumps if not equal or zerozf
JG/JNLEJumps if greater or not less or equalzf,sf,of
JGE/JNLJumps if greater or not equal or lesssf,of
JL/JNGEJumps if less or not greater or equalsf,of
JLE/JNGJumps if less or equal or not greaterzf,sf,of

Signed jumps

In the above two figures, JE (equal) appears in both figures because in this special case, the sign does not matter. If the two numbers are equal, zf=1, indicating that the flag is triggered. In signed jumps, JG = Jumps if greater, while in unsigned jumps, the corresponding instruction is JA, Jumps if above.

Continuing to debug the program, IDA will pause at each set breakpoint. A loop is executed, where each loop reads a character from the username input in the target program and compares it with 0x41. If any character is less than 0x41, an error will be reported. Since the input is lca, each value is greater than 0x41, so no error is displayed.

Try entering a number to see.

image

At this point, it jumps to the red block, which is where the jb jump occurs, because the first character being compared is 2 (0x32), which is definitely less than 0x41.

image

image

The C flag is also triggered, CF=1, because 0x32 - 0x41 is a negative result when subtracting unsigned numbers, which will trigger the C flag.

image

Right-click on the C flag and select Zero Value to clear the C flag to 0.

image

image

Press F9 to continue the process. The program reads the second character of 22lca, and the left red arrow starts flashing again. Continue to set the CF flag to 0, and the subsequent characters lca will all be greater than 0x41, not triggering the flag, and the program will follow the left red arrow.

After character detection is complete, the program reaches the last jump.

image

In the above figure, the cmp instruction compares eax and ebx, and jz checks if they are equal, which is unsigned. The program moves towards the red block because these two registers are not equal.

image

Since they are not equal, the zf flag is not triggered.

image

If the zf flag is manually triggered, changing the jump direction, the program will turn towards the green block, indicating successful registration.

image

image

SET IP#

Set IP is only available in debugger mode.

Sometimes you can also modify the jump indirectly by moving the mouse to the code block you want to execute, right-clicking, and selecting SET EIP.

At 0x40124c, set eip, and the program will start running from 0x40124c.

image

Note: In version 7.7, doing this multiple times results in the following error:

image

It prompts "Attempt to execute an illegal instruction."

image

image

The error message indicates that the memory is not writable, possibly because the read content exceeds the range.

Summary#

By using the IDA debugger, dynamic debugging and static analysis can be performed to gain an in-depth understanding of the program's structure and execution process. However, this chapter does not modify the source program; it only changes the values of the flag registers in the debugger.

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