Wesnoth라는 게임에서 케릭터가 꼭 성에 있어야지만 병력 소집이 가능하다.
이번 포스트에서는 모든 지형에서 병력 소집이 가능하도록 해킹해보겠다.
3편에서 병력 소집 시 골드가 감소하는 코드를 찾았고 중단점을 설정하였다.
자, 처음으로 돌아가보자.
플레이어가 병력 소집을 하기 위한 interaction은 다음과 같다.
1. 성에서 우클릭.
2. 옵션창이 뜬다.(Recruit, Recall, Terrain Description... 등)
3. Recruit.
function handle_options() {
switch() {
case A:
recruit();
case B:
recall();
case C:
terrain_description();
}
}
function recruit() {
reduce_gold();
}
코드는 옵션창을 handle하는 함수에서 recruit하는 함수를 호출하도록 짜여있을 것이라고 의심해볼 수 있다.
우리는 3편에서 recruit 시 골드가 깎이는 코드를 찾았다.
이를 이용해서 옵션창을 handle하는 함수를 찾을 수 있을 것이다.
이를 위해 Execute until return과 Step over 테크닉을 사용할 것이다.
Execute Until Return & Step over
add ... --- EIP
sub ...
mov ...
ret
위 assembly 코드를 보자.
EIP는 add ...에 있다고 가정하자.
Execute Until Return은 return문을 만날 때까지 실행하도록 한다.
즉, 위 코드에서 Execute Until Return을 실행하면 ret에서 멈춘다.
call some_function --- EIP
mov ...
some_function:
어쩌고저쩌고...
ret
위 assembly 코드를 보자.
EIP는 add ...에 있다고 가정하자.
Step over를 실행하면은 call 함수를 통채로 실행해버리고 다음줄로 넘어간다.
즉, 위 코드에서 Step Over를 실행하면 mov에서 멈춘다.
우리가 3편에서 찾은 골드가 감소하는 코드에서 Execute Until Return과 Step Over를 계속 반복하면 결국 함수를 호출한 부모함수를 찾아갈 것이다.
결국 handle_options() 함수에 해당하는 코드를 찾을 수 있을 것이다.
그리고 handle_options()는 분명 switch case문이나 if else문으로 짜여져 있을 것이다.
Assembly어로 유추해보면 대충 다음과 같은 형식일 것이다.
call some_function
jmp to_end
call some_function
jmp to_end
call some_function
jmp to_end
...
백문이 불여일견. 바로 해보자.
3편에서 골드를 감소시키는 코드에 중단점을 설정하였다.
우선 병력을 소집하여 해당 코드로 이동하자.
sub dword ptr ds:[edx+4], eax
저 부분이 골드를 감소시키는 코드였다.
이 상태에서 Execute Until End와 Step Over를 반복해보자.
8번을 반복하면 아래와 같은 코드에 도착한다.
call, jmp구문이 반복되는 곳에 도착한다.
이 형태로 보았을 때 옵션을 handling하는 함수로 의심해볼 수 있다.
사진에서 0x00CAF20번지에 있는 아래 코드가 바로 recruit과 관련된 함수일까?
call dword ptr ds:[eax+54]
확인해보자.
우선 해당 코드를 nop로 대체해본다.
그리고 실행하고 게임으로 돌아가보자.
아무리 Recruit을 눌러도 이전처럼 recruit창이 뜨지 않는다.
call dword ptr ds:[eax+54] // recruit units
이로 보았을 때 위 코드가 정말 recruit함수였다는 것을 확신할 수 있다.
이제 nop코드를 원래대로 복원하자.
그리고 위 사진과 같이 주석을 남겨놓자. 주석을 남겨놓는 습관은 특히 reverse engineering을 하면서 필수적이다.
다른 call 코드도 살펴보자.
call dword ptr ds:[eax+50]
이번엔 위 코드를 nop로 대체하고 게임으로 돌아가보자.
이번엔 recall이 작동하지 않는다. 따라서 위 코드는 recall과 관련된 함수임에 틀림없다.
마찬가지로 주석을 남겨놓자.
call dword ptr ds:[eax+28]
이번엔 위 코드를 nop로 대체해보자.
이번엔 terrain description이 동작하지 않는다. 마찬가지로 주석을 남겨놓자.
자. 이제 우리의 목표인 성이 아닌 지형에서도 병력 소집이 가능하게 코드를 바꿔보자.
성이 아닌 지형을 눌렀을 때 terrain description옵션이 뜨는 것을 확인할 수 있다.
따라서 [eax + 28]을 [eax + 54]로 대체한다면, 성이 아닌 일반지형에서도 recruit이 가능할 것이다!
call dword ptr ds:[eax+28] // terrain description
call dword ptr ds:[eax+54] // recruit units
code를 바꾸는 방법은 다음과 같다.
바꾸고 싶은 코드를 우클릭 후 바이너리 - 편집을 클릭한다.
Hex 부분에서 위와 같이 28을 54로 편집한다.
완성. 드디어 일반 지형에서도 병력 소집이 가능하게 되었다.
'Cheating' 카테고리의 다른 글
Wesnoth 해킹하기 (6) DMA 파훼하기 (0) | 2024.02.28 |
---|---|
Wesnoth 해킹하기 (5) Code Cave (0) | 2024.02.28 |
Wesnoth 해킹하기 (3) Assembly 변경 (1) | 2024.02.27 |
Wesnoth 해킹하기 (2) Memory Scan (1) | 2024.02.27 |
Wesnoth 해킹하기 (1) 기본세팅 (0) | 2024.02.27 |