들어가기에 앞서...
본 포스팅은 학술적 연구 및 리버싱 학습을 목적으로 작성되었습니다. 모든 테스트는 오프라인(Local Bot Match) 환경에서 진행되었으며, 실제 멀티플레이 서버나 타인의 게임 경험을 저해하는 행위에는 사용되지 않았습니다.
본인은 게임의 공정성을 해치는 어떠한 바이너리(DLL, EXE)도 배포하지 않으며, 이 글은 DirectX API의 동작 원리와 시스템 후킹 기법을 이해하고자 하는 분들을 위한 기술적 공유임을 밝힙니다.
https://imoracle.tistory.com/66
[게임핵의 원리] 월핵은 어떻게 만들어지는가 -DirectX 후킹 원리 분석- 1
들어가기에 앞서..본 포스팅은 학술적 연구 및 리버싱 학습을 목적으로 작성되었습니다. 모든 테스트는 오프라인(Local Bot Match) 환경에서 진행되었으며, 실제 멀티플레이 서버나 타인의 게임 경
imoracle.tistory.com
들어가며
이전 포스팅에서 DIP 후킹 까지 완료 하였습니다. 이번 포스팅에서는 Stride 분석으로 캐릭터 메시를 찾고 찾은 메시에
색을 입혀 최종적으로 월핵을 구현하는 과정을 담도록 하겠습니다. 플레이어 포인터를 이용하면 정확하겠지만 나중에 다루도록하고...
Stride 분석으로 캐릭터 메시 찾기
DrawIndexedPrimitive는 게임의 모든 3D 오브젝트를 그릴 때 호출됩니다.
캐릭터만 골라내기 위해선 파라미터 분석이 필요합니다.
주요 파라미터
| 파라미터 | 의미 |
| Stride | 버텍스 하나의 데이터 크기(바이트). 메시 포맷에 따라 고정값 |
| NumVertices | 버텍스 총 갯수. LOD에 따라 변함 |
| primCount | 삼각형 갯수 |
| startIndex | 인덱스 버퍼 시작 위치 |
게임을 실행해 봇들을 생성해둔 후 이리저리 움직이며 값을 수집하겠습니다.

Stride 값은 32, 48, 64, 80 으로만 찍혀서 나왔습니다. 더 있을 수 있겠으나 봇들이 시야에 들어오는 환경에서 이리저리 움직여서
우선은 이렇습니다.
Stride:48 | NumV:648 | prim:128 | Start:1536
Stride:48 | NumV:648 | prim:128 | Start:2304
Stride:48 | NumV:648 | prim:128 | Start:1920
Stride:48 | NumV:648 | prim:128 | Start:2688
똑같은 NumV 와 prim 인데 Start만 다릅니다. 캐릭터 파츠를 여러번 그리는 패턴이 아닐까 의심되는 모습입니다.
Stride:64 | NumV:598 | prim:426
Stride:64 | NumV:507 | prim:280
도 계속 교대로 반복되어 나오는 모습을 보니 상체/하체 또는 몸통/머리 이런 식일까 의심됩니다.
이제 시각적으로 확인해 보겠습니다.
찾는게 힘들었네요 처음엔 Stride 32로 시도를 했습니다만 그림자 였습니다. 그림자도 오브젝트로 관리가 되는건가?
Stride 48은 길 바닥의 모래로 보였습니다. 뭐 그 외에도 제가 캐치하지 못한 오브젝트들이 있겠죠
Stride 64는 캐릭터 및 나무, 손수레, 박스, 차량 등등 이었습니다.
문제는 소스엔진은 LOD 시스템을 사용한다는 것이었습니다.
LOD 시스템이란?
LOD(Level Of Deteil) 시스템은 거리에 따라 다른 해상도의 메시를 사용하는 것을 뜻합니다. 즉,
| 가까이 있을 때 | NumV 높음 (고해상도) |
| 중간 거리 | NumV 중간 |
| 멀리 있을 때 | NumV 낮음 (저해상도) |
버튼 별로 값을 다르게 넣어 정확히 캐릭터 모델을 골라내기 위한 작업을 시작합니다.

return S_OK;를 이용해 해당 값들에 해당된다면 렌더링을 멈춰 보이지 않게 할 수 있습니다.

F1은 박스들, 나무들, 캐릭터들, 캐릭터들의 그림자에 해당했고 너무 가까이가면 사라지지 않았습니다.
F2는 작은 나무들, 캐릭터들 그림자, 봇들과 어느정도 거리가 멀어져야 사라지고 아니면 사라지지 않았습니다.
F3은 내가 플레이하는 캐릭터의 무기는 보이고 손만 사라졌으며 봇들과 가까이있으면 봇들은 보이고 떨어지면 다시 사라졌다가 더멀어지면 없어졌습니다.
F4는 봇들하고 작은나무들이 F3때 보다 더 멀리 중간 거리정도 떨어지면 사라지기 시작했습니다.
사실 이러한 과정들을 반복하다 보면 찾을 수 있겠으나 지금은 어디까지나 학습목적이기에 정확한 값을 찾을 필요가 없을뿐더러
보통 월핵들도 보면 제대로 구분이 안되어 일부 오브젝트들도 색이 칠해지거나 하는 현상이 있을때가 있죠
귀찮을 뿐더러 대충 구분만 해서 사용하자 이런 마인드 인거 같긴합니다.
픽셀 셰이더로 색상 입히기
처음엔 D3D9 고정 파이프라인 방식으로 색상을 입혀주려 했습니다.


처음 코드로 진행했을때 아래와 같이 실패하여 우측의 코드로 머티리얼을 강제해주어 진행해보았으나 여전히 실패했습니다.
월핵의 순기능은 동작합니다만, 왜냐면 벽을 뚫고 봇플레이어가 보이니까요. 하지만 Chams처럼 색을 입혀 구분하기 쉽게 만드는 것이 목표이기에 다른 방법을 생각해 보아야합니다.

Counter-Strike : Source 는 HLSL 셰이더를 사용하기 때문에 고정 파이프라인 색상 설정이 전부 무시됩니다.
픽셀 셰이더 때문인가 의심되어 셰이더를 강제로 해제한 후 색상을 강제하도록 변경하였습니다만

사실 버텍스 셰이더는 꺼서는 안됩니다.. 버텍스 셰이더를 끄게되면 뼈대의 버텍스 계산이 되지않아 캐릭터가 T포즈로 깨지고 찌그러지고 난리도 아닙니다. 아래를 보시면 바로 이해가 될겁니다.

바로 수정에 들어갑니다. 이 과정에서 d3dx9.h 헤더를 추가로 include 했습니다.
괜히 d3dx9.h를 같이 쓰는게 아니었네요..버텍스 셰이더는 유지하도록 합니다

최종결과

이제 오브젝트 뒤에 위치할때만 빨간색으로 칠해지게 됩니다.


벽 너머의 캐릭터가 빨간색으로 표시되며, 캐릭터 외 일부 오브젝트(나무, 자동차, 지붕?)도 포함되나 대충 이정도는 허용하겠습니다, Stride값을 더 세밀하게 분석하면 캐릭터만 정확히 격리가 가능하겠죠
마치며
이번 작업을 통해 D3D9 후킹의 전체 흐름을 익혀 보았습니다.
VTable 구조 이해
더미 디바이스로 함수 주소 추출
Detours로 후킹
DIP 파라미터 분석으로 메시 식별
픽셀 셰이더 교체로 색상 강제 적용
에 대해서 알아 보았고, 부족한 글이고 실력이지만 끝까지 봐주셔 감사드립니다.
현대 게임들은 안티치트와 셰이더 보호가 훨씬 강력해서 이 방법은 통하지 않습니다.
어디까지나 D3D9 렌더링 파이프라인과 후킹 메커니즘 학습을 위한 공부 목적 임을 밝힙니다. 감사합니다.
이전포스팅은
https://imoracle.tistory.com/66
[게임핵의 원리] 월핵은 어떻게 만들어지는가 -DirectX 후킹 원리 분석- 1
들어가기에 앞서..본 포스팅은 학술적 연구 및 리버싱 학습을 목적으로 작성되었습니다. 모든 테스트는 오프라인(Local Bot Match) 환경에서 진행되었으며, 실제 멀티플레이 서버나 타인의 게임 경
imoracle.tistory.com
'Reverse Engineering > GAMEHACK' 카테고리의 다른 글
| [게임핵의 역사] 안티치트를 우회해온 기술들의 역사 -왜 게임핵은 사라지지 않는가- (0) | 2026.04.03 |
|---|---|
| [AI 게임핵의 원리] YOLOv8로 CS:S 에임봇 구현하기 (0) | 2026.03.30 |
| [게임핵의 원리] 월핵 제작기 및 월핵에 관해서 (D3D 월핵, OpenGL) -1- (0) | 2026.03.27 |
| [게임핵의 원리] 월핵 제작기 및 월핵에 관해서 -0- (4) | 2025.07.18 |
| [Anti - Reversing] 보안솔루션 직접 제작하기 - 4 - (0) | 2024.07.06 |