sweetchip's blog


어제 시큐인사이드 문제를 푸는데 갑자기 이 문제가 생각나서 다시한번 풀어보게 되었습니다.


시큐인사이드의 game 문제와 비슷하네요~


Reversing.kr FPS [바이너리는 reversing.kr 에 있습니다.]




문제는 3D 게임 서든@택의 텍스트를 본 따서 만든것 같습니다.


일반 fps게임과 같으며 걸어다니는 고구마들을 모두 제거해야 합니다.


옛날에 풀면서 삽질을좀 했는데 이상한 문자열이 존재 했었습니다.



이 문자열을 보면서 상관이 있나 없나 계속 고민을 하고 고구마들을 모두 쏘고나니 아래와 같이 바뀌었습니다.



축하합니다 답은 Thr3EDPr... 인데 답이 깨진것 같습니다.


다시 상황을 살펴보면 몬스터를 한마리 잡을때마다 1바이트씩 변화가 생기기 시작했습니다.


그렇다면 모든 고구마를 없애버리면 해결되지 않을까 생각을 했고 그 생각 대로라면 의문의 50바이트 문자열을 모두 복호화 시키려면


50마리[?]의 고구마를 모두 없애야 했습니다.



하지만 위 사진에는 2개가 바뀌지 않았고 실제로 세보니 48마리 였습니다.


그래서 생각해 낸것이 흔하게 말하는 벽을 뚫는 '월핵' 이나 복호화 루틴을 알아내서 복호화 시키는 것이었습니다.


저는 복호화 루틴을 알아 내기로 했습니다.


위 의문의 50바이트에 메모리 브레이크 포인트를 설정하고 몬스터를 잡자 아래와 같은 함수에서 멈췄습니다.



위가 바로 복호화 시키는 부분입니다.


BP를 기준으로 몬스터를 죽이면 아래 JG문 바로 아래로 내려가 xor 연산을 시행합니다.


하지만 어느 것과 연산을 하는지는 아직 잘 모르기 때문에 00403427에 BP를 설정하고 CL을 받아오는 메모리 주소를 복사하고


프로그램을 다시 로딩시킨뒤 방금 메모해둔 메모리 주소에 하드웨어 브레이크를 설정했습니다.



그랬더니 아래와 같은 루프에서 멈췄습니다.



이 부분이 의문의 50바이트와 함께 xor 연산을할 배열을 생성하는 부분입니다.


잡다한것 빼고 필요한것만 분석해보면 배열을 생성하는데 0x00~0xc4 까지 0x04 간격으로 배열을 생성합니다 [0, 4, 8, c, ... , c4]



총 정리를 해보면


1. 몬스터를 잡을때마다 한글자씩 복호화가 되는것을 확인

2. 의문의 50바이트와 숫자배열[0x00 ~ 0xc4]과 xor 연산

3. 복호화는 배열순서에 따라서 진행 [ex 의문의50바이트[1]^숫자배열[1]]


이므로 스크립트를 만들어서 따로 복호화 할 것입니다.


의문의 50바이트 - en_data


import array


f = open("en_data","rb")

encrypted = bytearray(f.read())

f.close()


a=array.array('i',(i*4 for i in range(0,0xc4/4 1)))


for i in range(len(a)):

encrypted[i] = encrypted[i] ^ a[i]


print "Flag : " encrypted





Flag : [삭제]

신고

Comment 8

  • 2013.06.30 11:59 신고 수정 답글

    풀이 과정은 상관없는데 정답 공개하지 말아주세요 ㅠㅠ

  • BlogIcon ff
    2014.12.30 04:11 신고 수정 답글

    리버싱kr에들어갓는데 문제이름이뭔가요?;;

    • 2014.12.31 17:44 신고 수정

      Challenge 탭에 들어가시면 문제를 볼 수 있습니다.
      감사합니다.

    • Favicon of http://wqe BlogIcon ff
      2015.01.02 02:39 신고 수정

      아니...그러니까요...
      문제이름이뭔가요?ㅠㅠ

    • 2015.01.02 13:23 신고 수정

      아아.. 게시글을 착각했네요...
      Direct3D FPS 입니다. 감사합니다

  • 2015.07.31 00:56 수정 답글

    비밀댓글입니다

    • 2015.08.02 17:15 신고 수정

      하드웨어 브레이크 포인트를 사용하는 이유는 만약 저 곳에 하드웨어 브포를 설정한다면 그 메모리를 참조 / 쓰기 / 읽기를 하는 순간 그 명령어에서 정지하기 때문에 리버싱에 도움이 될 것 같아 사용했던걸로 기억합니다.
      그리고 메모리 브레이크 포인트도 사용이 가능할 것입니다.