문제확인


이번문제는 CodeEngn Basic에서도 유사한 문제가 존재한다. 하지만 Advance인 만큼 그때와는 다르게 열정적으로 풀었다. 정말 시간이 참 빨리가는 삽질을 한 것 같다. 우선 문제를 확인해보면 참 말은 쉽다. Key 값이 주어지고 그에 맞는 값을 찾아라. 여기서 힌트는 2자리라는 것이다.


하지만 정작 2자리를 입력하면 위와 같이 더 입력해야한다고 출력이 된다. 그러므로 우리는 CMP len(name),3을 비교하는 부분을 찾을 것이다. 그 부분은 밑에 사진에서와 같이       CMP EAX,3 의 형태로 있으며 숫자 3을 2로 수정하여 2자리로도 입력이 가능하게끔 패치를 해주자. 나는 저렇게 수정을 한 후에 OllyDump를 통해서 저장을 하였다.


이렇게 패치를 한 파일을 가지고 분석을 시작할 것이다. 일단 Name 값은 AA로 시작을 하였다.

진행을 하다보면 위와 같이 성공으로 가는 분기문이 나타나며 레지스터 부분을 보면 내가 입력한 값과 해당 name에 따른 key 값이 나타나 비교될려 하는 것을 확인 할 수가 있다. 따라서 우리는 이처럼 쉽게 key 값을 확인 할 수가 있다. 문제는 key 값이 주어져 있고 우리는 name을 찾아야 한다는 것이다. 

그러므로 우리가 해야할 것은 바로 알고리즘 분석이다. 참고로 이 알고리즘 분석에서 애를 꽤 많이 먹었다. 결국 5개의 알고리즘에서 한개는 끝까지 풀지 못하였다. 하지만 그렇다 해도 문제를 푸는데에 있어서는 지장이 없다.



알고리즘 분석



첫번째 알고리즘이다. 위의 주석과 같이 name[i]를 통한 연산이 진행된 후에 레지스터를 보는 것과 같이 ESI에 저장되어있는 값의 앞자리 4자리가 첫번째부분의 키 값으로 사용이 된다. 이처럼 첫번째 알고리즘은 쉽게 분석을 하여 끝낼 수가 있다.


두번째 알고리즘이다. 이번에도 위와 같이 쉬운 연산으로 진행이 되지만 가령 Name이 'AB'일 경우 뒷자리인 'B'에서부터 연산을 시작한다. 뿐만 아니라 여기서는 Local.4가 있는 것을 확인 할 수가 있는데, 연산을 통한 값이 바로 이 Local.4에 저장이 되어 나중에 최종 키 완성에 전달이 된다. 이 값이 두번째 키 값이 된다.


세번째 알고리즘이다. 이 부분도 주석과 같이 쉽게 설명이 되어 있고 레지스터에서 보는 것과 같이 EDI의 앞자리 4자리가 키값의 4번째 값에 쓰인다.


네번째 알고리즘이다. 이 부분은 괜히 쓸때 없이 길다. EBX의 값이 마지막 키 값으로 사용이 된다. 



삽질 - 실패


위에서 확인 한 것과 같이 4개의 알고리즘을 통해 Key1 - Key2 - 빈부분 - Key3 - Key4 로 진행이 되어 있는 것을 확인 할 수가 있다. 그렇다 바로 저 빈부분이 내가 정말 삽질을 해도 나의 실력으로는 더이상 하지 못할 그것이였다. 분석하면서도 너무 복잡하여 결국 포기하여 버렸다.

위와 같이 FILD 부분과 RETN의 두칸 위에인 FISTP Cases 9,A,B....이 부분을 통해서 FILD에서 읽을 부분을 FISTP에서는 저장할 공간을 나타내어 값을 옮기는 형식으로 진행이 되는 것 같다. 이를 통해서 덤프창에서와 같이 가운데 키 값의 값이 형성이 된다. 이 키 값은 결국 밑의 연산을 통해서 나타난다.


위와 같이 ADD 연산을 통해서 덤프창에 있는 PTR:EAX의 값에 EDX를 더하므로 인하여 밑에와 같이 키 값이 형성이 된다. 이 키 값을 통하여 위의 사진처럼 FILD를 통하여 키 값이 형성이 된다. ...내가 말했지만 참 모르겠다. 정말 이 부분은 내 멘탈이 찢겨진 곳이라 할 수 있다.




프로그래밍


위의 알고리즘들을 통하여 우리는 프로그램을 만들 수가 있다. 브루트포스와 같이 모든 값을 출력하는 형식으로 프로그래밍을 해보았다. 여기서 내가 잊지 않기 위한 필기로서 파이썬에선 배열을 선언하고자 할 때 tmp=[0]*n 을 통하여 해당 크기 만큼의 값을 선언을 해 놓아야 한다. 그리고 아래의 5~7번줄과 같이 값을 선언해주면 된다.

위와 같이 코드를 짜준 다음에 실행을 하면 아래와 같이 텍스트파일이 생성이 되어있다. 이를 통하여 우리는 모든 경우의 값을 확인 할 수가 있으며, 주어진 문제의 키값을 통하여 Ctrl+F를 통하여 찾으면 문제를 풀 수가 있다. 


텍스트파일에서 찾은 값을 통하여 입력을 해주어 답이 맞는지를 확인하는 과정이다. 솔직히 쉽게 풀 수 있었는데, 모든 알고리즘을 분석하려다 보니 시간이 오래걸려 버렸다. 그리고 아래의 코드는 위와 같이 할 수 있는 알고리즘을 모두 출력하는 것이 아니라 입력한 키 값에 해당하는 부분을 출력해주는 프로그램을 별도로 만들어 보았다. 

아무래도 위의 프로그램보단 아래의 프로그램이 문제를 푸는데에는 시간이 훨씬 절약이 된다. 이렇게 코드를 짜 놓으면 주어진 문제의 Name 값이 길어지더라도 쉽게 문제를 풀 수가 있을 것이다. 

아래의 사진은 위의 프로그램을 통하여 답을 찾은 결과이다. 새삼스럽지만 답은 블럭처리하였다. 글을 읽는 여러분도 쉽게 문제를 풀 수가 있을 것이다. 나처럼 저 늪에 빠지지 않는다면..

by Kali-KM


'Reversing > CodeEngn' 카테고리의 다른 글

CodeEngn Advance 10  (0) 2015.07.13
CodeEngn Advance 09  (0) 2015.07.12
CodeEngn Advance 06  (0) 2015.06.28
CodeEngn Advance 05  (0) 2015.06.28
CodeEngn Advance 04  (0) 2015.06.28