본문 바로가기
리버싱/CodeEngn 문제해결

Basic L15

by 멍청이 개발자 2026. 9. 18.
반응형

문제는 다음과 같다.

그림0. 문제 화면

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

그림1. 프로그램 화면

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

그림2. 숫자를 입력해봤다.

숫자를 입력하면 위와 같이 나온다.

 

이제 디버거에 올려서 디버깅을 시작해보자.

Try Again이라는 문자열로 탐색을 해보았다.

그림3. 도착

아마 44496C라는 함수가 메시지 박스를 만드는 함수 인것 같다.

그리고 위에 성공 메시지도 보이는데 이 둘의 분기점은 cmp eax. [45B844]문 이후 jne .. 이다.

해당 부분이 BP를 걸고 레지스터 및 덤프창을 확인해보았다.

그림4. eax
그림5. 45b844

eax값을 보면 4d2, 즉 사용자가 입력한 1234를 숫자로 변환해서 가져왔다.

45b844위치에는 0x6160이 있다.

6160은 10진수로 24928이므로 시리얼은 24928이다.

그림6. 성공메시지

 

하지만 여기서 바로 끝내기 보다는 저 6160이라는 숫자가 어떻게 만들어진건지 암호화 과정을 살펴보는게 좋겠다.

 


우선 45B844 위치에 암호화 된 코드가 저장되므로 해당 위치에 하드웨어 BP를 걸고 진행했다.

그림7. Hello를 입력후 진행

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

그림8. 403a64함수 실행

403A64함수를 실행하니 문자열의 길이가 eax에 저장되었다.

403A64는 문자열 길이를 측정하는 함수인것 같다.

이후 test eax, eax를 통해 길이가 0보다 큰지를 확인후 진행한다.

그림9. 어셈블리 코드 분석

위 내용을 해석하면 다음과 같다.

문자열에서 앞자리부터 하나씩 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;
}

그림10. 코드 실행

정상적으로 작동한다.

 

이로써 문자열을 암호화하는 코드까지 분석해보았다.

반응형

'리버싱 > CodeEngn 문제해결' 카테고리의 다른 글

Basic L17  (0) 2026.09.19
Basic L16  (0) 2026.09.19
Basic L14  (0) 2026.09.18
Basic L13  (0) 2026.09.18
Basic L12  (0) 2026.09.18