BuringStraw

BuringStraw

ホワイトハットコンテスト11 RE2

私(reverse 問題で)最も嫌いな言語は、go です。

ida で見かける奇妙な構造体には驚かされます。

main 関数は cutter では runtime.text と表示されますが(ただし、sym.runtime.main で呼び出されます)。

まず、プログラム全体が大きな無限ループで囲まれており、続けて scanf % d を行います。EOF が読み込まれると停止し、13 個の数字(見かけ上は 12 個)かどうかを判断します。

現在の数字が EOF でない場合、配列に追加されます(インデックスは 1 から始まり、0 番目は 0 です)。また、数字の出現回数をカウントするための配列もあり、一度しか出現できません。

チェックのプロセスは次のようになります。配列が範囲外になるかどうかを判断するための多くの条件文があるため(削除済み)、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);

Python に変換すると(アセンブリを参考に修正しました)

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

その後の解法はおそらく数学の問題です。https://dakutenpura.hatenablog.com/entry/2016/06/28/030236

しかし、私は分かりませんので、全探索を行い、permutations(range(0,13))を検索しましたが、途中で詰まりました。

しかし、観察した結果、s が 1 から始まり、毎回 1 ずつ増えることに気付きました。したがって、次のようになります:

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
読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。