35C3 0pack (idapython)

Reversing/리버싱 문제풀이

2019. 1. 9. 12:40

이 문제는 가장 쉬운문제이기도 하고 실제로 많이 풀리기도 했다.

다양한 문제풀이 방법이 있지만, 그냥 idapython을 이용해 풀어보았다.

[ https://www.hex-rays.com/products/ida/support/idapython_docs/ ]


[메인함수 부분]


해당 바이너리는 문제이름답게 packing이 되어있는 상태이다. 따라서 ida에서 동적디버깅을 통해 unpack된 상태에서 idapython을 이용해 간단하게 풀 수 있다.


[한글자씩 비교하는 루틴]


한글자씩 비교하는 루틴이 15번 반복되고, 특정 주소 + offset에 있는 글자와 비교하는 방식이다.


[unpack된 시점에서의 memory map]


특정 주소는 메모리맵을 보았을 때, offset 0번째를 기준으로 한다.

unpack과정에서 해당 영역에 실행가능한 코드들을 write하고 execute하는 전형적인 방식인 것 같다.


[ida에서 해당 python script 실행결과]


따라서 어셈에서 오프셋부분만 들고와서 해당하는 글자들을 가져오면 된다.



# env : IDA PRO 7.1
start = MinEA()
end = get_next_module(SegStart(MinEA()))

curr = start
out = []
while(curr <= end):
    disasm = idc.GetDisasm(curr)
    if ('add' in disasm) and ('rax' in disasm):
        oper0 = idc.get_operand_value(curr, 0)
        if oper0 == 0:  # rax
            oper1 = idc.get_operand_value(curr, 1)
            out.append(Byte(start+oper1))
            add_bpt(curr)
            print hex(curr), idc.GetDisasm(curr)
    curr = idc.NextHead(curr, end)

print ''.join(map(chr, out))

# delete breakpoint
start = MinEA()
end = get_next_module(SegStart(MinEA()))

curr = start
while(curr <= end):
    if ida_dbg.check_bpt(curr) != -1:
        print hex(curr)
        del_bpt(curr)
    curr = idc.NextHead(curr, end)