→ PlaidCTF 2012 - Mess [300]

| No TrackBacks
It was real "structured programming" task. Code contains lots of function, but there no direct xrefs. Control is passed from function to function via pointers in structs.

Typical struct has the following format:
    +0: function pointer
    +4: function arguments
Each structure has a helper procedure that allow to "execute" struct, i.e. call function with specified parameters. For example,
int exec_struct6_runtime_if_2(struc_6 *pStruct)
    return pStruct->proc(pStruct->bWhatChar,
There was 6 different structs that are correspond to input sequence, brainfuck sequence, and control flow management.

File has simple anti-debug (ptrace) trick, and two brainfuck-like sequences (for debug and non-debug sessions). A program interprets brainfuck sequence and modifies only one memory cell: + increments it, > multiplies it by 2, < divides it by 2. Each non-control (+<>) symbol forces interpreter to check user input sequence: current symbol from user input is XOR'ed with values from memory cell. If the result is equal to 'a', then loop is continued and memory cell is cleared. Else, interpreter stops and reports error.

The following code snapshot decodes the flag:
int result = 0;
int counter = 0;

for (int i = 1; i < bf_len; i++)
    char c = bf[i];
    if ((c & 0x80) != 0)
        c = ~c;

    if (c == '+')
    else if (c == '>')
        result >>= 1;
    else if (c == '<')
        result *= 2;
        pass[counter] = 'a' ^ result;
        result = 0;
Without a debugger we get the following: ar3n't_funct10n_p01nt3rs_fun?

Under debugger output is different: d3bugg3rs_ar3_just_t00_us3ful

No TrackBacks

TrackBack URL: http://smokedchicken.org/m/mt-tb.cgi/79

About this Entry

This page contains a single entry by Павел Збицкий published on May 2, 2012 9:45 PM.

PlaidCTF 2012 - Override [300] was the previous entry in this blog.

IDA: rename locals from a script is the next entry in this blog.

Find recent content on the main index or look in the archives to find all content.