CodeEngn Reversing Basic_Level15


실행 시 위와 같은 창을 띄운다.

CodeEngn과 12345를 입력했을 때의 반응이다.

패킹은 없는 것 같다. 올리디버거로 돌려보자.

referenced text에서 찾은 문자열이다. 주요 문자열을 참조하는 코드에 bp를 걸고 실행해보자.

Try Again문장에서 bp가 걸렸다. 빨간 화살표를 보니 위에서 JNZ로 분기함을 알 수 있다. 그 위에서 CMP로 EAX와 45B844 주소의 값(DWORD)을 비교한다. 메모리 덤프와 레지스터 값을 확인해 보았다.

EAX의 값은 시리얼 입력값인 12345의 16진수, 0x3039이다.

45B844의 주소에 저장된 값은 00006160이다.
0x6160의 10진수 값이 시리얼일까? 계산하여 넣어보았다. 10진수 값은 24928이다.

맞았다. 따라서 flag의 값은 24928이다.
시리얼을 만드는 루틴을 분적해보자. 메모리의 45BB44 위치에 하드웨어 bp를 걸고 실행했다. 이 메모리를 참조할 때 bp가 걸릴 것이다.

커서가 있는 바로 위의 코드인 MOV DWORD PTR [EBX], EAX 로 bp가 걸렸다.
EBX에는 45B844가 있다. 이 주소를 메모리 덤프로 보면 0으로 차있다.
바로 위에서 EAX를 0으로 초기화하는 것을 볼 수 있다. 따라서 bp가 걸린 코드는 45BB44를 0으로 초기화하는 코드이다.
이후 입력한 name값의 주소를 가져온다. call을 실행하면 EAX에 8이 들어온다. name의 길이인 것 같다.
test eax, eax 로 eax가 0인지 판한하고, 0일 시 JLE로 점프한다.

0이 아닐 시 EAX를 반복문의 인덱스삼아 반복한다. 즉, name의 길이만큼 반복문을 돈다.

이후 코드에 주석을 달았다. name에 입력한 문자열의 각 문자에 접근해 shift연산을 하고 더한다. 이후 name의 길이를 shift 한 것을 45B844 버퍼에 더한다. 그 뒤 45B844버퍼에 저장된 값을 불러와 shift 한 뒤 저장한다.