# 문제 상황
- 데이브와 에릭은 제 편이고, 컴퓨터편인 홀과 키트가 있습니다.
두 팀이 대결을 하는데 에릭과 데이브는 체력이 100이고 홀과 키트는 500이라서 항상 질 수 밖에 없는 게임을 이기게 해줘야 합니다.
# 접근 방식
- 다른 방법이 존재하지만 체력을 깎는 곳 어셈블리어를 수정했습니다.
- 원래 어셈블리어 코드는 esi,eax이지만, eax를 체력을 500을 한번에 깎을 수 있는 500값을 주었습니다.
- 아래 이미지는 수정한 어셈블리어 코드 입니다.
- LINE : Tutorial-i386.exe+2653B
- 레지스터 기준으로 오프셋을 잡아, esi,[eax+20] 형식으로 500값을 포인터로 주고 싶었지만, 게임을 다시시작 하게 되면 주소가 바뀌기 때문에 쓸 수 없었습니다.
- 플레이어 네명 모두 체력이 깎일 때 하나의 함수로 분기하기 때문에 체력이 깎이는 값만 수정해서는 데이브와 에릭을 살릴 수 없습니다. 그래서 데이브의 체력이 내려갈 때 홀의 체력이 내려가게, 에릭의 체력이 내려갈 때 키트의 체력이 내려가게 했습니다.
#문제 풀이
- 먼저 데이브와 에릭, 홀, 키트의 체력을 스캔해 데이터 구조체를 뽑아봅니다.
- 체력으로 향하는 오프셋 4만큼을 빼주면 전부 같은 곳을 가리키는 포인터임을 알 수 있습니다.
- 메모리 뷰어 창에서 브레이크 포인트를 F5를 통해서 잡습니다.
- 동그라미 친 부분에 맨위 스택을 더블 클릭하면 브레이크잡은 함수 종료후 ret되는 eip 위치로 이동합니다. 그렇게되면 현재 체력값을 계산하는 함수의 시작위치로 이동할 수 있고, 어느 부분에서 체력값을 1만큼 빼는지 레지스터 상태를 브레이크 걸어가면서 step over 할 수 있게 됩니다.
- 두세번 돌려보면 esi가 1값을 가지고 그 값을 뺀 값이 ebp-04에 저장되고 다시 저장된(체력에서 -1 뺀 값)값을 ebx+04 옮기기만 하는 것을 확인 할 수 있습니다. 그렇다면 제가 수정할 수 있는 부분은 1값만큼 빼는 부분이고 그 값을 500으로 변경해주면 한방에 즉사하게 됩니다.
- 마지막으로 똑같은 저희 팀이 죽는 것도 해결하고 이부분을 해결하려면 팀을 구분하는 코드를 찾아내야합니다. 이 코드는 함수 콜전 파라미터를 저장하는 레지스터에서 볼 수 있습니다. 플레이어 홀과 키트의 오프셋은 각각 4d4, 4d8로 데이브와 에릭의 오프셋을 이 오프셋으로 바꿔주고 팀을 구분짓는 [eax+02]를 컴퓨터 팀에 해당하는 [eax+01] 값으로 바꾸어 줍니다. 마지막으로, Tutorial-i386.exe+26530을 콜하기 전 함수인 Tutorial+i386.exe+e700의 파라미터도 이 함수가 리턴될 때 레지스터가 이 후 레지스터 상태에 영향을 주기 때문에, 컴퓨터 팀과 동일하게 1로 바꾸어줍니다.
- 게임 다시하기 버튼을 눌렀을 때와 게임을 다시시작하고 자동 실행하기 버튼을 눌렀을 떄 함수 콜이 다르기 때문에 데이브와 에릭이 파라미터를 수정해 주었음에도 죽습니다. 게임 다시하기 버튼을 눌렀을 때 동일하게 무조건적으로 분기하는 mov [ebx+04],eax 에 브레이크 포인트를 걸고, 다시 한번 더 함수 파라미터를 수정해야합니다.
# 문제 해결
'Memory Hacking' 카테고리의 다른 글
Cheat Engine/hero siege (10) | 2018.01.27 |
---|---|
치트엔진 - tutorial step 8 Multilevel pointer (2) | 2016.12.20 |
치트엔진 - tutorial step 7 - code injection (0) | 2016.12.20 |
치트엔진 - tutorial step 6 포인터! (0) | 2016.12.20 |
치트엔진 - 값의 주소가 변경 될 때. (2) | 2016.12.20 |