https://imoracle.tistory.com/49
들어가며
메모리해킹은 특히 게임분야에 사용되며, 유저들에게 피해를 입히는 기술로 사용됩니다.
이러한 해킹프로그램을 통칭 치트 또는 핵이라 부릅니다.
월핵, 맵핵, 스피드핵, 에임봇, 워프 등이 포함됩니다.
주로 사용되는 언어는 C/C++, C#, Delphi 가 있고, 매크로의 경우 AutoHotKey가 있습니다.
선행지식으로는
Assembly : 분석할 때 어셈블리어로 보여지므로 해당 지식이 필요합니다.
C/C++ : 강력하고 빠릅니다. 물론 C#과 C#이상의 GUI 컴포넌트 지원도 가능하며, C++과 속도또한 비슷한 Delphi도 있지만 필자는 Delphi7을 옛날에 잠시 가지고 논게 마지막이므로 c++을 사용하겠습니다.
Win32 API : MS에서 개발자에게 쉽게 프로그램을 만들때 가져다쓰라고 만든 함수들입니다.
Reversing : 말해 뭐해 !
게임분석
우선 탄약을 찾아 보겠습니다, 20을 스캔하면 무수히 많은 값들이 나옵니다만 총을 쏴 줄어든 탄약수를 넣어서 스캔해가며
값들을 줄여봅시다.
두개의 값이 나왔고 둘 중 하나가 진짜겠군요. 변조해서 알아보면 됩니다.
첫째 값인 009708F0이 진짜 값이었습니다.
값을 찾았으나 이렇게 찾은 값은 사용할 수 없습니다.
프로그램이 재시작 될 때마다 바뀌는 주소이기에, 위 주소를 사용해 핵을 만든다 한들 재시작하면 아무의미가 없어지고
또 값을 찾아서 사용해야하는 불상사가 생깁니다. 그래서, 정적주소를 찾을 필요가 있습니다.
찾아둔 탄약값에 접근하는 코드를 알아봅시다.
총을 발사해 총알갯수가 줄어들때 카운트가 늘어나며 FF 08 - dec [eax] 가 실행되는게 보여집니다.
자세히 보게되면 mov eax, [esi+14] 를 해주고 dec [eax]를 해주는군요.
esi는 베이스이고 +14 오프셋의 위치에 탄약값이 들어있는걸로 유추되지만 이부분은 나중에 다루겠습니다.
우선 지금에 집중하면, eax는 총알갯수로 보여지고 발사할 때마다 dec 인스트럭션을 이용해 1씩 값을 줄이고 있습니다.
포인터스캔을 이용해 주소를 찾아주도록 합시다.
포인터를 찾는 이유는 프로세스의 변수의 메모리주소를 오프셋과 함께 가리키고 있게 되므로, 재시작을 해도
포인터+오프셋을 이용해 바뀌어버린 주소의 위치를 알 수 있게 됩니다.
포인터찾기
84297개의 값이 검색됩니다. 여기서 동작하는 주소를 찾아야합니다.
총알갯수인 998을 넣어주고 재검색 해줍니다.
115개로 줄어든 모습을 볼 수 있습니다. 확실히 줄여보기위해 게임을 껐다 켜주겠습니다.
그럼에도 주소가 살아있다면 그 값일겁니다. 계속 재시작을 하는걸 추천합니다.
12개의 값이 살아남았습니다. 모두 제대로 동작중입니다.
하나씩 테스트 해보면 되긴 하지만, 아마도 12개의 주소들은 전부 제대로 된 주소일 겁니다.
오프셋이 다를뿐, 포인터는 같기 때문이죠.
제대로 작동합니다.
이제 체력을 찾아보겠습니다.
다르게 접근해보겠습니다.
mov [edx+000000EC], eax 를 보게되면 eax를 edx+000000EC 주소에 넣어주고 있습니다.
eax 에는 4E가 들어있고 Decimal 로 78이 되며 체력을 나타냅니다.
그렇다면, 포인터에서 0xEC 오프셋만큼 떨어진 곳이 체력이 저장되는 곳이란 말이 됩니다.
확인해봅시다.
총알값을 찾을때는 0을 넣어주었으나 지금은 EC를 넣어주고 검색해줍니다.
그렇게해서 찾은 포인터를 보게되면
플레이어 구조체 찾기
네 맞습니다, 위에서 edx에는 0090E160 이 들어있었습니다,
플레이어 구조체의 포인터의 주소는 0090E160이고 0xEC만큼 떨어진 곳에 체력이 존재한다는 말이됩니다.
0090E160이라는 주소는 역시 재시작시 바뀔것이며 정적주소를 보게되면
ac_client.exe + 0017E0A8 로 보여집니다. 해당 주소는 바뀌지 않는 주소입니다.
즉 플레이어구조체포인터는 ac_client.exe + 0017E0A8 란 말이됩니다.
ac_client.exe + 0017E0A8 + 0xEC 에는 체력이 저장되겠네요
이게 무슨 말이냐면
예를들어 이러한 플레이어 구조체가 있다고 가정하고
player 의 주소가 1000이라 가정한다면
hp값은 0x1000 + 0x04 에
ammo는 0x1000 + 0x08 에
delay는 0x1000 + 0x12 에 저장이 되어있다는 말입니다.
이제 구조체를 보겠습니다.
이곳에 플레이어의 좌표, 이름, 총기, 총알 등등이 저장되어 있겠네요
구분하기 쉽게 표시해줍시다.
체력을 456으로 바꿔 놓아서 맞는 값이 들어가있는게 맞습니다.
HexView로 보겠습니다.
Display Type이 기본은 hex로 설정되어 있을텐데 Decimal로 바꿔주었습니다.
드래그한 부분에 현재 체력값인 456이 들어가 있고 주변을 살펴보면 장전된 탄약수, 남은탄약수도 보입니다.
float 형식으로 보면 x, y, z 좌표도 알 수 있겠습니다.
우선 탄약값은 0090E2A0에 저장되어 있기에 0090E2A0 - 0090E160(플레이어구조체포인터) = 0x140이 되고
플레이어 구조체에서 0x140만큼 떨어져 있다는 말이됩니다.
이미 포인터와 오프셋을 찾았는데 왜 해주냐구요?
5중오프셋은 번거롭기도하고 잘 쓰이지 않습니다.
c언어에서도 N중 포인터까지 쓰려면 쓰지만서도, 2중 포인터까지만 보통 사용하는 느낌과 비슷합니다.
제대로 들어가 있습니다.
좌표를 찾아봅시다.
hex view 디스플레이타입을 float 으로 변경하고 캐릭터를 좌 우 점프 하며 움직이면 계속해서 변하는 값이 있습니다.
플레이어의 y좌표로 보이는 곳을 30.00으로 수정해주니 맵을 뚫고 하늘로 치솟았습니다, 이렇게 x,y,z 좌표를 구하면되고
바라보는 방향을 마우스로 돌려가며 앵글도 구할 수 있겠네요
좌표의 경우 월핵, 에임봇, 워프에 쓰이는게 일반적입니다.
잠깐! 높이를 왜 y좌표로 표현했나요? 라고 의문점을 가진다면
개발자들은 오른쪽이 맞다고 얘기하고, 보통의 경우는 왼쪽이 맞다고 말합니다.
게임쪽에서는 오른쪽의 개념을 압도적으로 많이 사용합니다. 뭐, 쓰기 나름이긴 합니다
수학에서는 왼쪽을 사용하는거 같긴합니다
2D게임에서 x를 횡 y를 높이로 사용하다 3D로 오며 z좌표가 종이 되지 않았을까 합니다.
수학에서는.. 글쓴이는 수학을 잘 못합니다.. 그러니 패스하겠습니다.
x, z, y도 찾아 주었습니다.
참, 상용게임에서도 이렇게 쉽게 분석이 될 거라 생각하시면 안됩니다.난독화와 암호화가 반겨줄거니까요
다음 2편에서는 게임핵을 개발 해보겠습니다.
https://imoracle.tistory.com/49
'Reverse Engineering > GAMEHACK' 카테고리의 다른 글
[Anti - Reversing] 보안솔루션 직접 제작하기 - 2 - (0) | 2024.07.05 |
---|---|
[Anti - Reversing] 보안솔루션 직접 제작하기 - 1 - (0) | 2024.07.04 |
[Game] 지뢰찾기 월핵 제작 - 2 - (1) | 2024.07.04 |
[Game] 지뢰찾기 월핵 제작 - 1 - (0) | 2024.07.04 |
[Assaultcube] FPS게임 분석 및 핵 제작 - 2 - (0) | 2024.07.04 |