BuringStraw

BuringStraw

Whitehat Contest 11 RE2

The language I hate the most (in the reverse question) - go.

I was scared by the strange structures that appeared in ida.

Why is the main function called runtime.text in cutter (but it is called in sym.runtime.main)?

First of all, the entire program is wrapped in a big infinite loop, and then scanf %d is continuously used. When EOF is read, it stops and checks if it is 13 digits (on the surface, but actually 12 digits).

If the current digit is not EOF, it will be appended to the array (even starting from index 1, with the 0th position being 0). There is also an array used to count the occurrence of each digit, which can only occur once.

The check process is like this, because there are a lot of statements in the middle to check if the array is out of bounds (already deleted), it is easy to get confused and cannot see the initial value of var_1e8h.

var_1e8h = 1;
uVar5 = 1;
do {
    uVar2 = *(uint64_t *)(var_18h + uVar5 * 8);
    var_1e8h = ((&var_168h)[uVar2] + -1) * (&var_1d0h)[var_1e0h - uVar5] + var_1e8h;

    uVar2 = *(uint64_t *)(var_18h + uVar5 * 8);
    while (uVar2 = uVar2 + 1, (int64_t)uVar2 <= var_1e0h) {
        (&var_168h)[uVar2] = (&var_168h)[uVar2] + -1;
    }
    uVar4 = (uint32_t)uVar2;
    uVar5 = uVar5 + 1;
} while ((int64_t)uVar5 <= var_1e0h);

In Python, it becomes (I made a mistake in the array when writing, and modified it based on the assembly code)

def check(inpt):
    #inpt = [0,6,12,9,4,5,1,2,8,10,7,11,3]
    len_nums = 0xd
    v1d0h = [1,1,2,6,0x18,0x78,0x02d0,0x13b0,0x9d80,0x058980,0x375f00,0x02611500,0x1c8cfc00]

    v18h = []
    v168h = list(range(0xd))

    for i in inpt:
        v18h.append(i)

    i = 1
    s = 1
    while True:
        #print(v168h)
        r11 = v18h
        r8 = r11[i]
        rbx = v168h[r8]-1
        r8=len_nums-1-i
        rbp = v1d0h[r8]
        #print(hex(rbx), hex(rbp))
        s += (rbx*rbp)
        j = v18h[i]+1
        while j<=len_nums-1:
            v168h[j] -= 1
            j+=1
        i+=1
        if i > len_nums -1:
            break
    print(hex(s))
    return s == 0xe37f550

The final solution is probably a math problem. https://dakutenpura.hatenablog.com/entry/2016/06/28/030236

But I don't know, so I brute-forced it by searching permutations(range(0,13)), and it got stuck.

However, after observation, I found that s starts from 1 and increases by 1 each time. So it becomes:

j = 0
for i in permutations(range(0,13)):
    #sys.stdout.write("%s\n"%str(i))
    j += 1
    if j == 0xe37f550:
        print(check(i))
        print(i)
        break
Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.