Common Logic Structures

When analyzing code, it’s important to recognize basic flow control structures.

  • Remember that the decompiler may be unreliable.

Basic structures:

  • If else

  • Switch case

  • For

Conditional Branches (if else)

Basic control-flow instructions: move execution to a defined address if a condition is true.

  • Usually, one condition is tested at a time. Complex If/else must be broken.

Assembly code is structured as a graph with tests and execution statements (the body of the condition).

x86 and most architectures have inherent support for many types of comparisons.

  • In x86 this is the jXX family of instructions.

  • Signed comparison: l < , le <=, g >, ge >=

  • Unsigned comparison: b <, be <=, a >=, ae >=

    • Below and Above.

  • Equality e

  • Every condition can be negated with n

  • z, s, c, o, and p for ZF, SF, CF OF, and PF

    • ZF: Zero Flag, 1 if the last operation was 0.

    • CF: Carry Flag. The last operation required an additional bit (e.g. 255 + 1, which has 9 bits).

    • OF: Overflow Flag. The last operation had an arithmetic overflow (127 + 127 in a signed variable results in overflow).

    • PF: Parity Flag. 1 if the last operation resulted in a value with an even number of 1.

    • SF: Sign Flag. 1 if the last operation resulted in a signed value (MSB bit = 1)

  • s means negative, ns non-negative.

    • Signal or not signal.

  • p and np are also pe “parity even” and po “parity odd”.

  • and, or, and xor clear OF and CF, and set ZF, SF, and PF based on the result.

  • test is like and but only sets the flags discarding the result.

  • Checking nz after test is like if (x & mask) in C

  • test a register against itself is the fastest way to check for zero or negative.

Direct jump: target(s) specified in code (harcoded).

Indirect jump: target selected from runtime data like register or memory contents.

Conditional jump: target differs based on a condition.

Structure can be recognized by one or more conditional branches, without loops.

je: jump equal.

js: jump is sign.

Switch case

A structure can be recognized by several comparisons and jumps or jump tables.

Observe the difference between what a programmer writes and what is produced.

  • A switch is written as an atomic instruction, but it isn’t.

  • Also, it is dangerous because of missing breaks.

Test: compare two registers. Set 3 flags:

  • PF: Even the number of bits

  • ZF: Zero

  • SF: Signed value

loops

For, while and do while are generally the same.

Identified by:

  • an index.

  • an increment.

  • a comparison.

  • two jumps.

Last updated