문제는 다음과 같다.

DIE로 열어봤을때 패킹은 되어있지 않았다.

Serial에 아무 값이나 입력하니 숫자를 넣으라고 나온다.

숫자를 입력하면 위와 같이 나온다.
이제 디버거에 올려서 디버깅을 시작해보자.
Try Again이라는 문자열로 탐색을 해보았다.

아마 44496C라는 함수가 메시지 박스를 만드는 함수 인것 같다.
그리고 위에 성공 메시지도 보이는데 이 둘의 분기점은 cmp eax. [45B844]문 이후 jne .. 이다.
해당 부분이 BP를 걸고 레지스터 및 덤프창을 확인해보았다.


eax값을 보면 4d2, 즉 사용자가 입력한 1234를 숫자로 변환해서 가져왔다.
45b844위치에는 0x6160이 있다.
6160은 10진수로 24928이므로 시리얼은 24928이다.

하지만 여기서 바로 끝내기 보다는 저 6160이라는 숫자가 어떻게 만들어진건지 암호화 과정을 살펴보는게 좋겠다.
우선 45B844 위치에 암호화 된 코드가 저장되므로 해당 위치에 하드웨어 BP를 걸고 진행했다.

해당 위치에서 멈추었다. 덤프를 보니 45b844는 0으로 초기화 되어있었다.

403A64함수를 실행하니 문자열의 길이가 eax에 저장되었다.
403A64는 문자열 길이를 측정하는 함수인것 같다.
이후 test eax, eax를 통해 길이가 0보다 큰지를 확인후 진행한다.

위 내용을 해석하면 다음과 같다.
문자열에서 앞자리부터 하나씩 1바이트 단위로 읽어 온다.
그값에 shl 3을 하여 8배곱을 해준후 그값을 45b844에 더한다.
이것을 문자열이 끝날때까지 반복한다.
그후 문자열의 길이를 8배곱한것을 45b844에 더한다.
그후 45b844에 저장된 값을 4배곱 해준다.
이것을 간단히 C++로 작성해보았다.
#include <iostream>
int main()
{
char name[0x100] = { 0, };
std::cin.getline(name, 0x100);
int cnt = strnlen_s(name, 0x100);
int result = 0;
for (int i = 0; i < cnt; ++i) {
result += (name[i] << 3);
}
result += (cnt << 3);
result = (result << 2);
std::cout << std::hex << result << std::endl;
return 0;
}

정상적으로 작동한다.
이로써 문자열을 암호화하는 코드까지 분석해보았다.