최상단

컨텐츠

● 프로그래밍/다이렉트 후킹[D3D]

4

  1. 3. Direct3D Hooking (1)2014.05.14
  2. 2. Direct3D 2014.05.14
  3. 1. 개요 2014.05.14
  4. Direct3D Hooking 강의 에 앞서.. 2014.05.14

3. Direct3D Hooking

글 정보

Category
● 프로그래밍/다이렉트 후킹[D3D]
2014.05.14 00:35

본문

3. Direct3D Hooking


 3-1. What is Direct3D Hooking?


 말 그대로 D3D에 대해 Hooking 하는 것이다. 이 문서에서 다루는 D3D Hooking은 원래


프로세스에서 D3D 관련 함수를 호출할 때 D3D 함수 대신 내가 제작한 함수가 호출되게 만드는
것이다.


 이 강의에서 할 D3D Hooking의 원리를 설명해드리면 타겟 프로세스가 그려주는 함수를 호출


할 때 내가 만든 함수를 호출 한 후 그리고 싶은 것을 그리고 원래의 그려주는 함수를 호출하면


프로세스는 정상적으로 작동하면서 내가 원하는 부분이 추가된 것이다. 이 문서에서는 d3dx의


vTable을 참고하여 타겟 함수를 설정하여 Detours 방식의 Hooking을 시도할 것이다.


 D3D Hooking이 쓰이는 대표적인 것으로는 아직까지는 악용되는 것밖에 보질 못했다. FPS


게임에서 Wall Hack, RPG 게임에서 Map Hack 등등 그래픽을 가진 게임에서는 무궁무진하게


D3D Hooking 악용될 수 있다. 이 문서를 통해 FPS 게임이나 기타 프로그램에서 D3D에 대한


후킹을 연구하여 방어 방법에 대해 생각 할 수 있는 기회가 되었으면 좋겠다.


이 강의에서 D3D Hooking 하는데 사용될 방법은 Detours 라는 후킹 기법이다.


Detours에 대한 자세한 내용은 뒤에서 설명하겠다.


악용되는 예 - FPS Game Wall Hack

 


출처 : 네이버 이미지 ( 본 문서와 해당 그림은 상관없습니다.)

 

3-2. D3D Hooking 원리


 D3D Hooking 원리는 함수를 후킹 할 때 사용하는 방법인 "Detours Hook"와 후킹 할 함수의

 
주소를 찾고자 할 때 참고하는 “vTable”를 사용하여 D3D에서 사용하는 함수를 후킹 한다.


"Detours Hook" 와 "vTable“ 에 대한 설명을 간단하게 하고 넘어가겠다.

 


 3-2-1. Detours Hook 이란? (Detours hook 원리에 대해 알고 있다면 넘어가도 됩니다.)


 Detour Patching 또는 inline Function Hooking 이라고도 불리는 이 후킹 방법은 여러 방법들


중에 하나이며 그 중에서도 매우 강력한 기능을 가진 후킹 방법이라고 할 수 있습니다.


Target Function에 Detour Function 으로 점프하는 코드를 심어 Detour Function 이 실행되고


실행이 끝나면 Trampoline Function에서 다시 Target Function을 실행시키고 다시 Detour


Function으로 return할 수 있도록 하는 후킹 기술입니다.

 

 

 


출처 : http://research.microsoft.com/apps/pubs/default.aspx?id=68568


위의 그림처럼 Target Function 보다 Detour Function 이 먼저 실행되고 또 Detour


Function으로 return되기 때문에 어떤 작업을 하거나 결과 값을 수정 할 수 있습니다.


실제 함수 전, 후로 전부 후킹이 되기 때문에 매우 효과적인 조작이 가능합니다.

 

 

 

후킹 방식은 위의 그림과 같이 Trampoline Function에서 Target Function에서 jmp 코드가

 
덮어쓴 Function Instruction을 수행하고 Target Function에서 해당 Function Instruction이

실행된 이후 번지로 점프하여 Target Function 함수가 정상적으로 호출 된 것처럼 실행되도록

 

합니다. 이 문서에서는 D3D Hooking에서 함수 후킹 할 때 Detours Hook을 사용합니다.

 

Detours Hook 에 관련된 내용은 다음 강의를 통해 자세히 다루겠습니다.

 

 

void *DetourFunc(BYTE *src, const BYTE *dst, const int len) 
{
        BYTE *jmp = (BYTE*)malloc(len+5);
        DWORD dwback;
        VirtualProtect(src, len, PAGE_READWRITE, &dwback);

         memcpy(jmp, src, len); jmp += len;
        jmp[0] = 0xE9;         *(DWORD*)(jmp+1) = (DWORD)(src+len - jmp) - 5;
        src[0] = 0xE9;         *(DWORD*)(src+1) = (DWORD)(dst - src) - 5;
        VirtualProtect(src, len, dwback, &dwback);    

        return (jmp-len);
}      

 - 이 강의에서 사용하는 Detours function 소스 (자세한 설명은 뒤에서 하겠습니다.)

 

3-2-1. vTable 이란? (vTable에 대해 알고 있다면 넘어가도 됩니다.)

 

vTable(virtual table)이란 가상 함수의 번지 목록을 가지는 일종의 포인터 배열이다.


즉, 이 클래스에 소속된 가상 함수들이 어떤 번지에 저장되어 있는지를 표 형태로 저장해 놓은


목록이다. 컴파일러는 가상 함수를 단 하나라도 가진 클래스에 대해 vTable을 작성하는데


이 테이블에는 클래스에 소속된 가상 함수들의 실제 번지들이 선언된 순서대로 기록되어 있다.


그리고 이 테이블 타입의 객체가 생성될 때, 각 객체의 선두에 vTable의 번지인 vptr을 기록


한다. 간단한 소스와 그림을 통해 vTable의 구조와 원리를 간단하게 살펴보고 넘어가도록 하자.

 

 

 #include <iostream.h>
class B{
private:         int memB;
public:
        b() : memB(0x11111111){}
        virtual void f1() { puts("B::f1");}
        virtual void f2() { puts("B::f2");}
        virtual void f3() { puts("B::f3");}
        void normal() { puts("non virtual");}
};  class D : public B
{
private:         int memD;
public:
        D() : memD(0x22222222){}
        virtual void f1() { puts("D::f1");}
        virtual void f2() { puts("D::f2");}
};  void main()
{
        B *pB;
        B b;
        D d;
       pB=&b;
        pB->f2();
        pB=&d;
        pB->f2();
        pB->f3();
}

 

실행 결과는 다음과 같다.
B::f2
D::f2
B::f3

 

B가 세 개의 가상 함수와 하나의 비가상 함수를 정의하고 있으며 이를 상속 받는 D는 그 중


f1, f2를 재정의하고 있다. 테스트의 편의를 위해 멤버 변수도 하나씩 선언했다. B와 D의 객체


b와 d가 생성되었을 때 이 객체들이 메모리에 구현된 모양을 그려 보면 다음과 같다.

 

 

컴파일러는 B 클래스를 위해 B 클래스에 속한 가상 함수의 번지를 vTable로 작성한다.


vTable은 가상 함수들의 포인터 배열이라고 할 수 있는데 비가상 함수의 번지는 목록에서


제외된다. 그래서 vTable에 normal 함수의 번지는 없는데 이 함수는 정적으로 결합되므로


테이블에 있을 필요가 없다. B 타입의 b객체에는 자신의 멤버 변수 memB앞에 B클래스의


vTable에 대한 포인터 vptr이 먼저 배치되고 이 포인터가 가리키는 vTable에는 자신이 호출


할 수 있는 가상 함수들에 대한 실제 번지들이 기록되어 있다. B 클래스는 모든 가상 함수의


코드를 정의하고 있으므로 vTable에는 자신의 멤버 함수들에 대한 번지만 있다.


 D클래스도 가상 함수를 가지고 있으므로 컴파일러는 D에 대해서도 vTable을 작성한다. 이


테이블의 f1, f2는 D가 재 정의한 함수를 가리키고 있으며 f3은 B로부터 상속받은 B::f3을


가리키고 있다. 이 표에 의해 D타입의 객체가 f1, f2를 호출하면 D::f1, D::f2가 호출되지만 f3에


대해서는 상속받은 B::f3이 호출되어야 한다는 것을 알 수 있다. D타입의 객체 d에는 상속받은


memB와 memD 앞에 D클래스의 vTable을 가리키는 포인터 vptr이 배치되어 있다.


즉, vTable의 주소를 알면 선언된 순서대로 위치하기 때문에 vTable의 주소 + 함수 offset을


통해 Target Function 위치를 알 수 있다.


참고 : http://winapi.co.kr/clec/cpp3/30-1-4.png

 

 

 

 

 

저작자 표시 비영리 변경 금지
신고

트랙백과 댓글 여닫기

트랙백 0 댓글 1

2. Direct3D

글 정보

Category
● 프로그래밍/다이렉트 후킹[D3D]
2014.05.14 00:21

본문

2. Direct3D
 2-1. Direct3D 란?
 Direct3D는 마이크로소프트의 DirectX API에서 3차원 그래픽 연산과 출력을 담당하는 부분
이다. 마이크로소프트의 윈도 운영체제(윈도 95이상)에서만 작동하며, Xbox와 Xbox360 게임
콘솔의 그래픽 API로 사용되고 있다. Direct3D와 비슷한 역할을 하는 API로는 OpenGL이
있으며 역할은 같지만 각자가 서로 다른 장단점을 가지고 있다.
출처 : http://ko.wikipedia.org/wiki/Direct3D
요약해보자면 3D게임이나 3D를 요구하는 작업에서 뭔가를 그릴 때 사용하는 게 Direct3D이다.

 

void init( void )
{
    g_pD3D = Direct3DCreate9( D3D_SDK_VERSION );  
        if( g_pD3D == NULL )

         {
                // TO DO: Respond to failure of Direct3DCreate8
                return;

         }
 
    D3DDISPLAYMODE d3ddm;  


    if( FAILED( g_pD3D->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &d3ddm ) ) )

         {
                // TO DO: Respond to failure of GetAdapterDisplayMode
                return;

         }
 
        HRESULT hr;  
        if( FAILED( hr = g_pD3D->CheckDeviceForma( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,             d3ddm.Format, D3DUSAGE_DEPTHSTENCIL, 
 D3DRTYPE_SURFACE, D3DFMT_D16 ) ) )

         {
                if( hr == D3DERR_NOTAVAILABLE )

                         // POTENTIAL PROBLEM: We need at least a 16-bit z-buffer!

                         return;

         }
 
        // 

 // Do we support hardware vertex processing? if so, use it.

         // If not, downgrade to software.

         //  
        D3DCAPS9 d3dCaps;  
        if( FAILED( g_pD3D->GetDeviceCaps( D3DADAPTER_DEFAULT,                                                D3DDEVTYPE_HAL, &d3dCaps ) ) )

         {
                // TO DO: Respond to failure of GetDeviceCaps
                return;

         }
 
        DWORD dwBehaviorFlags = 0;  
        if( d3dCaps.VertexProcessingCaps != 0 )
                dwBehaviorFlags |= D3DCREATE_HARDWARE_VERTEXPROCESSING;         else
                dwBehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;  
        //

         // Everything checks out - create a simple, windowed device.

         //  
        D3DPRESENT_PARAMETERS d3dpp;

         memset(&d3dpp, 0, sizeof(d3dpp));  
    d3dpp.BackBufferFormat 

      = d3ddm.Format;
    d3dpp.SwapEffect

             = D3DSWAPEFFECT_DISCARD;
    d3dpp.Windowed

               = TRUE;
    d3dpp.EnableAutoDepthStencil = TRUE;
    d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
    d3dpp.PresentationInterval   = D3DPRESENT_INTERVAL_IMMEDIATE;  
    if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, g_hWnd,                                       dwBehaviorFlags, &d3dpp, &g_pd3dDevice ) ) )

         {
                return;

         }
}

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void shutDown( void )
{
    if( g_pd3dDevice != NULL )
        g_pd3dDevice->Release();  
    if( g_pD3D != NULL )
        g_pD3D->Release();
}
//----------------------------------------------------------------------------- 
//-----------------------------------------------------------------------------
void render( void )
{
    g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,                          D3DCOLOR_COLORVALUE(0.0f,1.0f,0.0f,1.0f), 1.0f, 0 );  
    g_pd3dDevice->BeginScene();  
    g_pd3dDevice->EndScene();  
    g_pd3dDevice->Present( NULL, NULL, NULL, NULL );

}

 

[출처] http://www.codesampler.com/dx9src.htm

위의 sample source는 D3D 관련 함수 부분만 첨부했다.
D3D 코딩 경험이 없다면 한번 보는 것이 좋다. 이 소스코드를 후킹 관점에서 본다면
Direct3DCreate9(), CreateDevice(), EndScene() 이므로 다른 함수들은 물론 이 함수들이
낯설다면 msdn을 통해 함수에 대해 꼭 숙지하고 넘어가자.


 

 

저작자 표시 비영리 변경 금지
신고

트랙백과 댓글 여닫기

트랙백 0 댓글 0

1. 개요

글 정보

Category
● 프로그래밍/다이렉트 후킹[D3D]
2014.05.14 00:14

본문

1. 개요

 Direct3D(이하 D3D) Hooking은 이전부터 온라인 게임분야, 특히 FPS 게임에서 Wall Hack 

이라는 것으로 게임 진행에서 일반 유저들에게 심각한 피해를 입히는 Game Hack으로 사용된 

기술입니다. 

보안 분야를 공부하고 연구하는 입장에서 해당 D3D Hooking 에 대해 방어할 방법을 찾기 위해

D3D Hooking 소스를 분석해 보았으며 본 문서에선 d3d 관련 파일들을 분석하며 알아낸 내용들

을 다른 분들과 정보공유를 통해 좀 더 깊은 내용을 배우고 방어 방법에 대해 같이 생각해보기 

위해 부족한 실력에도 불구하고 이렇게 문서를 작성하게 되었습니다. 끝으로 D3D Hooking을 

연구 하면서 얻은 기술이나 지식을 공유하고자 최대한 노력하여 본 문서를 작성하였습니다.


1-1. Direct3D Hooking에 필요한 선행 지식

 - Assembly

 - C++

 - Hooking에 대한 이해

 - Debugger

 - DirectX SDK

 - dll

1. Assembly

 - dll이나 타겟 프로그램을 분석할 때 Assembly로 출력되기 때문에 해당 지식 필요

2. C++

 - D3DX는 클래스로 이루어져 있기 때문에 C++지식이 필요하다.

3. Hooking에 대한 이해

 - 이 문서에서 D3D Hooking은 수많은 Hooking 중 하나이기 때문에 만약 Hooking에 대한

 이해를 하고 있다면 좀 더 수월하게 이해를 할 수 있다.

4. Debugger

 - d3dx.dll 에 대해 분석하기 위해서는 Debugger 경험이 있으면 좀 더 쉽게 이해할 수 있다.

5. DirectX SDK

 - 이건 D3D 이기 때문에 DirectX SDK 를 사용해봤다면 코드 부분이나 함수 활용부분에서

 매우 쉽게 이해 할 수 있긴 하겠지만, 필수는 아니다. 필자도 이번에 분석하면서 처음 D3D를

 접했으며 분석하며 모르는 부분은 인터넷을 찾으며 정보를 수집했다.

6. Dll

 - d3dx.dll을 분석하는 것이기 때문에 dll이 윈도우에서 어떤 역할을 하는지 어떻게 동작하는지

 정도는 알아야 이해하기가 쉬울 것이다.

저작자 표시 비영리 변경 금지
신고

트랙백과 댓글 여닫기

트랙백 0 댓글 0

Direct3D Hooking 강의 에 앞서..

글 정보

Category
● 프로그래밍/다이렉트 후킹[D3D]
2014.05.14 00:12

본문

Direct3D Hooking 강의에 앞서


게임 이나 프로그램에 해킹,크랙,조작 등을 통한 악용은


정보통신망 이용 촉진 및 정보보호 등에 관한 법률 제48조 에 의거 처벌될수있음을 알려드립니다.


또한 위 D3D 후킹 강의의 출처는 여기 에 있으며 작성자는  NullBr4in (NullBr4in@gmail.com) 입니다.

 

또한 편집 및 수정을 엄격히 금지하는 바입니다.


※ 목차 


1. 개요

1-1. Direct3D Hooking에 필요한 선행 지식

 2.Direct3D

 2-1. Direct3D 란?

 2-2. Direct3D 샘플 소스

 3. Direct3D Hooking

 3-1. Direct3D Hooking 이란?

 3-2. D3D Hooking 원리

 3-2-1. Detours Hook 이란?

 3-2-2. vTable 이란?

 3-3. D3D Hooking 실습

 3-3-1. D3D Hooking에 대한 실습과 설명

 3-3-2. 패턴은 어떻게 찾아낼까?

 3-3-3. vTable에서 함수의 위치를 어떻게 찾아낼까?

 4. 끝맺음

 5. 전체 소스 



저작자 표시 비영리 변경 금지
신고

트랙백과 댓글 여닫기

트랙백 0 댓글 0

페이징

PREV NEXT

1

TOP

티스토리 툴바