CodeEngn Reversing Advance_Level03

프로그램 실행 모습이다. 키젠 문제이다. 아무 문자나 입력하고 check를 눌렀는데, 눌리지 않는다. 탭을 이용하여 누르니 된다.

위와 같은 에러 메시지를 출력한다.

about을 누르면 다음과 같은 설명이 뜬다. 시리얼 생성 로직을 풀어보라 요구한다.

PEiD에 넣어보았다. 패킹은 없다.

에러 때문에 올리디버거에서 string 검색이 안 되길래 직접 메모리에서 찾았다. 상수 찾기로 해당 문자열을 이용하는 코드를 찾아보았다.

성공 메시지로 보이는 것도 찾았다. 하지만 아무리 찾아봐도 성공문으로 가는 점프문이 없다.

call stack을 추적하기 위해 스택을 보게 되었는데, SEH 핸들러가 보인다.

그래서 SEH chain을 열어보았다.

따라가보면 성공 메시지를 출력하는 코드가 핸들러로 등록되었음을 볼 수 있다. 분기문을 이용하는 대신, 성공 시 예외를 일으켜 SEH를 호출하도록 했다.

핵심 코드를 분석했다. 문자열을 비교한 결과가 0이면(입력값과 시리얼이 같다면) 0으로 나누기 예외를 일으킨다. 그러면 등록해둔 SEH가 호출된다. SEH에서 성공 메시지를 출력한다.

올리디버거 주석으로 시리얼이 전부 보인다.

3265754874를 입력해 보았다.

정답이다. 따라서 flag는 3265754874이다.

시리얼 생성 로직 분석 (작업중)

시리얼 생성 로직을 살펴보자. 시리얼 생성 함수는 주요 코드의 중간에서 호출된다.

이름이 저장된 주소를 403258에 저장해두고, 함수를 호출한다.

다음은 함수 내부이다. 간단히 요약하자면, 이후에 불릴 함수의 코드를 수정한다. 매 상황에 따라 다른 알고리즘(동적으로 생성된 코드)을 이용한다

이어서 분석하자. 함수의 마지막에서 EBP를 변경하는 것을 볼 수 있다. 변경한 EBP에 있는 리턴 주소를 이용하여 RETN에서 점프한다. 

가장 아래에 주석이 달린 함수는 입력한 이름을 가공한 값을 받아 시리얼을 생성한다.

이 함수이고, 이 함수는 스스로 재귀적으로 호출한다. 다음 재귀 호출을 하기 전 시리얼을 생성하는 함수가 불린다.

다음은 시리얼을 생성하는 함수이다. 빨간 부분이 동적으로 수정된 코드이다. 재귀호출로 인해 이 함수는 여러번 호출된다.

재귀호출로 다시 같은 함수(시리얼을 생성하는 함수)에 들어오면 코드가 변경되어 있다.

(어쩐지 하다가 관뒀다… 지금 보니 메모리 참조 bp를 걸어 코드를 동적으로 변경하는 로직을 찾고 분석하면 될 것 같다.)


tags: writeup, reversing, pe file, windows, exception handling, windows seh, keygen, x86asm