이론 공부만 하니까 문제 풀어보고 싶어서 해봤다. 드림핵이랑 rev.kr 중 뭐할까 고민하다가 그래도 "근본은 rev.kr이지!"하고 풀었다.

Decompiling한 코드를 분석해보자. InputName을 입력받고 반복문을 돌려 Serial_Key로 바꾼 다음, 비교하여 맞으면 'Correct!' 아니면 'Wrong!'을 출력한다.
우리가 구하고자 하는 Serial_Key는 for문을 중심으로 어떻게 돌아가는지를 파악해야 하는데, 일단은 어디에 어떻게 저장되는지를 먼저 확인했다.
main 함수의 EP는 00401000이고, 쭉 읽다보면 for문과 관련된 코드가 나오는데 이는 아래와 같다.

Buffer에 Serial_Key가 저장되는 것을 알고 있기에 Buffer쪽에 Break를 걸고 실행시켜보았다. 실행값은 "aaaaaa"으로 넣었다.

sprintf 함수에 4가지 파라미터가 들어가는데 스택에 역순으로 저장되는 것을 알고 있으니, 중요한 부분의 값만 읽으면 되겠다고 생각할 수 있다. 그곳이 "v8[v3++] ^ v7[i-1]"이고 이는 4번째 파라미터이므로 첫번째로 push되었을 것이다. 이부분의 stack register를 보면 다음과 같다.

ESP는 19FDEC를 가리키고 있으므로 첫번째 원소의 값을 71이 나왔다. for문이니 모든 문자에 대해서 진행할 것으로 예상되므로 일단 모든 문자에 대해 진행한 게 Buffer에 저장되므로 다 돌리고 난 뒤의 Buffer 값을 보면 그게 답일 것이다.
다 돌리고 난 뒤의 Buffer의 주소에 값을 확인해 보았는데 이는 아래와 같다.

71 41 51 71 41 51로 3번마다 한번씩 반복됨을 알 수 있다.
이 값을 Serial_Key값에 넣어보니 성공한다.

여기서 끝이면 좋겠지만... 여기서 끝이 아니라 이제 알고리즘을 파악해야 한다.
우리가 구하고자 하는 값은 Serial_Key 값이 "5B134977135E7D13"이 되는 Name을 찾는 것이다.
그러면 우선 for문을 좀 더 자세히 보자

v7에 대한 값을 잘 읽어보아야 할 것 같은데 v7의 값은 어셈블리 코드에 이렇게 나와있다.

이걸 보면 아까 3개마다 한번씩 값이 왜 반복되었는지를 알 수 있다.
1. 1번째 문자와 0x10을 XOR 하여 값 생성
2. 2번째 문자와 0x20을 XOR 하여 값 생성
3. 3번째 문자와 0x30을 XOR 하여 값 생성
4. 이걸 문자열이 끝날때까지 반복
XOR의 특성 상 XOR을 같은 값으로 두번 반복하면 원래 값으로 돌아간다. 따라서 "5B134977135E7D13"을 각 규칙에 맞게 XOR 하면 Name값은 쉽게 나온다.
따라서 진행한 후 답을 넣으면 성공한다.
