반응형

치트 엔진으로 게임에서 수정하고 싶은 값의 주소를 찾아도 게임을 다시 실행시키면 그 주소가 변경되어 처음부터 다시 진행해야만 하는 경우가 있다.(포인터 등으로 해결 불가) 예를 들어 도스박스로 고전 게임을 실행시키는 경우 값의 주소가 변경될 뿐만 아니라 그 값을 기록하는 명령이 다른 여러 주소에 접근하기 때문에 쉽게 에디터를 만들 수가 없다.

 

※ 참고:

2023.01.01 - [Reverse Engineering] - Cheat Engine AOB Injection with DosBox - 치트 엔진 코드 인젝션 도스박스

 

Rick Dangerous 2 게임을 실행하고 번개를 사용해 수치를 변화 시킨다.

 

번개 수치가 저장된 주소를 파악한다.

 

어떤 명령이 번개 수치를 변화 시키는지 확인한다.

 

번개 수치를 변경하는 명령이 접근하는 다른 주소들을 확인한다. 도스박스에서는 굉장히 많은 주소에 접근한다. 그래서 그 명령을 함부로 수정할 수 없다.

 

 

번개 수치 변경 명령을 메모리 뷰어에서 확인하고 AOB Injection을 준비한다.

 

어셈블리 코드를 작성하고 주소 리스트 창에 저장한다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
[ENABLE]
 
aobscanmodule(INJECT,DOSBox.exe,66 89 34 18 8B 5C 24 14) // should be unique
alloc(newmem,$1000)
globalalloc(editor, 4) // Thunder 주소 저장을 위한 4 바이트 메모리 할당
 
label(code)
label(return)
 
newmem:
  cmp [eax+ebx+61], 'JOHN' // [Thunder 주소+61]에 'JOHN' 문자열이 있다
  jne code          // Thunder 값이 저장된 장소가 아니면 원래 코드 실행
  push edx          // eax+ebx 값을 저장하기 위해 edx 사용
  xor edx, edx      // edx 초기화
  mov edx, eax
  add edx, ebx
  mov [editor], edx // editor 심볼에 Thunder 주소 저장
  mov [eax+ebx], si // 원래 코드 실행
  mov ebx, [esp+14]
  pop edx           // 원래 edx 값 복구
  jmp return
 
code: // 원래 코드
  mov [eax+ebx],si
  mov ebx,[esp+14]
  jmp return
 
INJECT:
  jmp newmem
  nop 3
return:
registersymbol(INJECT)
 
[DISABLE]
 
INJECT:
  db 66 89 34 18 8B 5C 24 14
 
unregistersymbol(INJECT)
dealloc(newmem)
dealloc(editor)         // 6바이트 메모리 해제
 

 

 

번개 수치 주소를 생성한다.

주소 리스트 창에서 위와 같이 번개 수치가 저장된 주소를 스크립트의 [심볼(editor)+offset] 방식으로 생성한다. 아래 폭탄과 생명도 동일한 방법으로 진행한다.

 

 

폭탄 수치 주소를 생성한다.

 

생명 수치 주소를 생성한다.

 

위에서 작업한 내용이 주소 리스트 창에 저장되었다. 스크립트를 실행하고 번개를 한 번 사용하면 각각의 수치들이 정확히 반영된다.

 

도스박스와 게임을 다시 실행하면 모든 주소가 변경되어 엉뚱한 값이 대입 된다.

 

 

다시 스크립트를 실행하고 번개를 한 번 사용하면 모든 값들이 제대로 반영된다.

 

치트 테이블을 저장하면 언제든 다시 스크립트와 모든 수치를 간단히 수정할 수 있다.

 

반응형
Posted by J-sean
:
반응형

도스박스에서 실행한 고전 게임을 치트해 보자. 코드 인젝션으로 번개와 폭탄을 무한대로 사용할 수 있게 한다.

 

도스박스를 실행한다.

 

Rick Dangerous 2를 실행한다.

 

Rick Dangerous II.zip
0.19MB

 

게임이 시작되면 번개를 사용한다.

 

번개 숫자가 변하면 번개가 저장된 메모리를 찾을 수 있다. (Value Type은 2Bytes로 설정해야 한다)

 

 

번개 메모리 주소에서 Find out what writes to this address를 실행한다.

 

다시 번개를 한 번 쏘면 어떤 코드가 번개 메모리 주소를 사용하는지 찾을 수 있다. Show disassembler 버튼을 클릭한다.

 

Memory Viewer에 어셈블리 코드가 표시된다.

 

Tools - Auto Assemble을 클릭한다.

 

 

Auto Assemble 창이 뜨면 Template - AOB Injection을 클릭한다.

 

번개 메모리에 6(번개 최대치)을 저장하는 코드를 newmem영역에 작성한다.

 

File - Assign to current cheat table을 클릭한다.

 

Cheat Table Address List에 스크립트가 추가되었다. Active 체크박스를 클릭해 활성화 한다.

 

 

게임에 오류가 발생한다. 왜 그럴까?

 

다시 Memory Viewer를 확인해 보자. 새로운 코드가 생성된 곳으로 점프하는 명령어가 잘 들어가 있다.

 

새로운 코드도 잘 들어가 있다. 이유를 알 수가 없다.

 

처음부터 다시 해 보자. 게임을 시작하고 번개가 저장된 메모리 주소를 찾는다.

 

 

어떤 코드가 번개가 저장된 메모리 주소를 사용하는지 찾은 후 이번엔 Find out what addresses this code accesses를 실행한다. 이 코드가 어떤 메모리 주소에 접근하는지 찾아준다. 예상대로라면 번개 메모리 주소만을 접근해야 한다.

 

게임에 오류가 발생한 이유를 찾았다. 우리가 찾은 코드는 번개 저장 메모리뿐만 아니라 다른 메모리에도 엄청나게 많은 접근을 하고 있었던 것이다. 이 모든 메모리에 6을 덮어 썼으니 오류가 나지 않을 수 없었다. 어떻게 해야 번개 메모리에만 6을 저장할 수 있을까?

 

다시 Memory Viewer로 돌아와서 메모리 덤프창에서 우클릭 - Goto address를 클릭한다.

 

번개가 저장된 메모리 주소를 입력하고 OK를 클릭한다.

 

 

번개가 저장된 메모리(04 00)가 표시된다. (그 옆의 06 00은 폭탄이 저장된 메모리이고 다시 그 옆의 06 00은 생명이 저장된 메모리이다) 주변을 살펴보자. 00, 09, FF등 별 특이한 값은 보이지 않지만 0A590B31~0A590B34에 JOHN이라는 이름이 기록되있다. 우리가 찾은 코드가 접근하는 다른 메모리 근처엔 없을거 같은 특이한 값이다. (JOHN 이외의 다른 이름들은 높은 점수를 기록한 사람들의 이름이 저장된 HALL OF FAME에 나오는 이름들이다. JOHN은.. 모르겠다)

 

이번엔 JOHN이라는 값을 이용해 번개 저장 메모리 주소를 구분하고 번개와 폭탄을 모두 6으로 덮어쓰는 코드를 작성한다. JOHN은 번개 메모리 주소에서 offset이 0x61이다. 또 번개 메모리 주소 바로 옆, offset 0x02에 폭탄 갯수가 저장되어 있다.

 

코드를 실행하면 번개를 사용할때마다 폭탄과 번개가 6으로 세팅된다.

 

반응형
Posted by J-sean
: