CodeEngn Reversing Basic_Level14

입력값을 이용하여 시리얼을 만드는 프로그램인 것 같다.

프로그램 화면이다. 입력값은 내가 쓴 것이다.

위의 상태로 프로그램을 실행하면 에러 메시지가 뜬다.

PEiD로 확인한 결과 UPX 패킹이 되어있다는 것을 알 수 있다. 패킹을 해제해 준다.

패킹 해제 후 다시 확인했더니 더이상 패킹이 없는 것 같다. 올리디버거로 돌려보자.

referenced text를 찾아보려 했는데 또 이런 경고창이 뜨고 실행되지 않는다. 그래서 이번에는 all intermodular calls를 검색하여 bp를 걸어보았다.


GetDlgItemTextA 함수는 입력 값을 얻어오는 함수이다. 입력 값으로 시리얼을 만드는 것으로 의심되므로 여기에 bp를 걸고 실행해 보았다.

핵심 로직으로 보이는 코드에 도달했다. 성공/실패 string에 bp를 걸고 cmp와 점프문을 중심으로 분석해보자.


GetDlgItemTextA 함수는 받아온 string의 길이를 반환한다. GetDlgItemTextA로 반환된 값(EAX)과 0을 비교한 뒤 같으면 에러 메시지를 띄우는 루틴이 있다.
버퍼에 입력값을 가져오면 올리디버거의 주석 부분에서 내용을 확인할 수 있다. 위의 스크린샷에서는 CodeEngn, 아래 스크린샷에는 12345를 입력한 것이 보인다. CodeEngn은 입력한 이름이고 12345는 입력한 시리얼이다.
따라서 이 조건문을 통과하기 위해서는 두 입력 값 모두 길이가 1 이상이어야 함을 알 수 있다.

성공 메시지 출력 분기를 찾았다. EAX와 ESI를 비교하고, 같지 않을 시 오류메시지를 낸다. 비교하는 값이 무엇인지 추적해보았다.

cmp하는 순간의 레지스터이다. EAX에는 12345을 16진수 변환한 값이 들어있다.
이와 비교하는 ESI는 129A1이다. 그렇다면 시리얼은 ESI의 10진수 값인 76193일까?

맞았다. 문제의 조건에도 맞는 5자리 수이다. 따라서 flag는 76193이다.
사실 처음에는 알고리즘을 분석하여 키를 찾아내는 프로그램을 만들었다. 문제의 힌트처럼 brute force 방식으로 찾아냈다.

이게 그 프로그램이다.

tags: writeup, reversing, pe file, windows, packing, upx packer, keygen, x86asm