본문 바로가기
IT창고/API

API후킹 함수로 하기

by 창구창고 2007. 1. 22.

📑 목차

    반응형
    #include <stdio.h>
    #include <windows.h>
    
    // PE화일의 내용을 검색하려면 DbgHelp.dll 이 필요하다.
    #include "Dbghelp.h"
    #pragma comment(lib, "Dbghelp.lib")
    
    void Replace( HMODULE hModule, // .idata를 가진 모듈의 주소
    			  PCSTR	  dllname, // Hooking 할 함수를 가진 DLL이름
    			  PROC	  oldfunc, // 훅킹할 API 함수.
    			  PROC    newfunc) // 바꿀 함수 
    {
    	// 1. module 에서 .idata section 의주소를 찾는다.
    	ULONG sz = 0;
    	PIMAGE_IMPORT_DESCRIPTOR pImage = (PIMAGE_IMPORT_DESCRIPTOR)
    						ImageDirectoryEntryToData( hModule, TRUE,
    									IMAGE_DIRECTORY_ENTRY_IMPORT, & sz);
    
    	printf(".idata section 의 주소 : %p\n", pImage );
    
    	// 2. .idata section 에서 원하는 Dll의 위치를 찾는다. 
    	for ( ; pImage->Name; ++pImage )
    	{
    		char* p = ((char*)hModule + pImage->Name);
    
    		if ( strcmpi( p, dllname) == 0 ) break; // 찾은 경우
    	}
    	if ( pImage->Name == 0 ) 
    		printf("해당 모듈은 %s 를 import 하지 않습니다.\n", dllname);
    
    	printf("%s 모듈의 import section 주소 : %p\n", dllname, pImage );
    	//--------------------------------------------------------------
    	// 3. Thunk Table 에서 원하는 주소를 얻는다.
    	PIMAGE_THUNK_DATA pThunk = 
    				(PIMAGE_THUNK_DATA)( (char*)hModule + pImage->FirstThunk);
    
    	for ( ; pThunk->u1.Function; ++pThunk )
    	{
    		if ( (PROC)(pThunk->u1.Function) == oldfunc ) // 찾은 경우.
    		{
    			PROC* p = (PROC*)&(pThunk->u1.Function);
    
    			*p = newfunc; // 덮어 쓴다.
    		}
    	}
    }
    // user.chol.com/~downboard/dbghelp.zip  받아서 압축 푸세요..
    // dbghelp.dll 은 C:\\windows\\system32 안에 두세요..
    // .h 와 .lib 현재 작업 폴더에 복사해 오세요..
    
    
    // MessageBox를 대체할 함수.
    typedef UINT (WINAPI *F)(HWND, PCSTR, PCSTR, UINT);
    
    UINT WINAPI foo( HWND hwnd, PCSTR s, PCSTR title, UINT btn)
    {
    	printf("foo is called\n");
    	printf("Message : %s\n", s);
    	printf("TitleBar : %s\n", title );
    	
    	// 다시 원래의 MessageBox로 전달하려면 ?
    	//MessageBoxA(); // 재귀 호출..
    	// 직접 함수의 주소를 구한다.
    	HMODULE hDll = GetModuleHandle("User32.dll");
    
    	F f = (F)GetProcAddress( hDll, "MessageBoxA");
    
    	return f( hwnd, s, title, btn);  // <<!!!
    }
    
    
    void main()
    {
    	Replace( GetModuleHandle( 0 ), // exe 주소
    			 "User32.dll", (PROC)MessageBoxA, (PROC)foo );
    
    	void* p = GetModuleHandle( "User32.dll");
    
    	printf("User32.dll 의 주소 : %p\n", p );
    	printf("MessageBoxA의 주소 : %p\n", MessageBoxA );
    
    	MessageBoxA( 0, "Hello", "AAA", MB_OK);
    }
    
    반응형

    "이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다."