Api Hijacking (sample included

来源:互联网 发布:手机抢购软件 编辑:程序博客网 时间:2024/04/29 18:43
something i've written for w3hackit (www.gamehackers.net),
thought some of you might find this code interesting.

hijacking api is a good way to control how external dll's manipulate a program.
you can write a universal keybind feature or even a speed hack.
but this all really comes down to how much a game depends on function imports.

normally i wouldn't use the C-lib *hides*, but i wanted to write a quick sample to explain whats going on in the background.

Code: #include<windows.h>
#include<stdio.h>

union BaseData {
   PBYTE         pImageBase;
   PIMAGE_DOS_HEADER pImageHeader;
};

typedef BaseData* pBaseData;
typedef PIMAGE_FILE_HEADER pFileHeader;
typedef PIMAGE_OPTIONAL_HEADER pExtraHeader;
typedef PIMAGE_SECTION_HEADER  pSectionHeader;
#define InitConsts()/
m_BaseData(*pBaseData(&pImageBase)),/
m_pFileHeader(pFileHeader(DWORD(m_BaseData.pImageBase)+DWORD(m_BaseData.pImageHeader->e_lfanew)+sizeof(DWORD))),/
m_pExtraHeader(pExtraHeader(DWORD(m_pFileHeader) + sizeof(IMAGE_FILE_HEADER))),/
m_pSectionHeader(pSectionHeader(DWORD(m_pExtraHeader) + sizeof(IMAGE_OPTIONAL_HEADER)))

//macro from bo2k [RVATOVA updated for our C++ class]
#define RVATOVA(type,offset) ((type)((DWORD)(PBYTE(*this))+(DWORD)(offset)))

class peControl {
   public:
   peControl(PBYTE pImageBase);
   virtual ~peControl();

   //returns original.
   FARPROC InterceptImport(FARPROC pFuncOrigApi, FARPROC pFuncNewApi);
   FARPROC InterceptImport(LPCSTR pDllName, LPCSTR pApiName, FARPROC pFuncNewApi);

   operator PBYTE() const { return m_BaseData.pImageBase; }
   operator PIMAGE_FILE_HEADER() const { return m_pFileHeader; }
   operator PIMAGE_OPTIONAL_HEADER() const { return m_pExtraHeader; }
   operator PIMAGE_SECTION_HEADER() const { return m_pSectionHeader; }


   protected:

   private:
   
   const BaseData        m_BaseData;
   const pFileHeader     m_pFileHeader;
   const pExtraHeader    m_pExtraHeader;
   const pSectionHeader  m_pSectionHeader;
   
};

peControl::peControl(PBYTE pImageBase) : InitConsts() {
   return;
}

peControl::~peControl() {
   return;
}

//InterceptImport concept by goldfinder
FARPROC peControl::InterceptImport(FARPROC pFuncOrigApi, FARPROC pFuncNewApi) {
   PIMAGE_IMPORT_DESCRIPTOR pImportDesc = RVATOVA(PIMAGE_IMPORT_DESCRIPTOR, PIMAGE_OPTIONAL_HEADER(*this)->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
   if(PBYTE(pImportDesc) == PBYTE(*this)) return NULL;

   for(;pImportDesc->Name; pImportDesc++) {
      for(PIMAGE_THUNK_DATA pThunk = RVATOVA(PIMAGE_THUNK_DATA, pImportDesc->FirstThunk);
                        pThunk->u1.Function; pThunk++) {
         
         if (FARPROC(pThunk->u1.Function) == pFuncOrigApi) {
               DWORD dwProtect;
               __try {
                  pThunk->u1.Function = DWORD(pFuncNewApi);      
               } __except(EXCEPTION_EXECUTE_HANDLER) {
                  if(!VirtualProtect((LPVOID)(&pThunk->u1.Function), sizeof(DWORD), PAGE_EXECUTE_READWRITE, &dwProtect)) return NULL;
                  pThunk->u1.Function = DWORD(pFuncNewApi);
               }
               VirtualProtect((LPVOID)(&pThunk->u1.Function), sizeof(DWORD), PAGE_EXECUTE, &dwProtect);
               return pFuncOrigApi;
         }
      }
      
   }
   return NULL;
}

FARPROC peControl::InterceptImport(LPCSTR pDllName, LPCSTR pApiName, FARPROC pFuncNewApi) {
   FARPROC pCurrentApi = GetProcAddress(GetModuleHandle(pDllName), pApiName);
   if(pCurrentApi) {
      return InterceptImport(pCurrentApi, pFuncNewApi);
   }
   return NULL;
}

DWORD WINAPI newGetTickCount(VOID) {
   return 0x31337;
}

int main(void) {
   class peControl *pe = new peControl(PBYTE(GetModuleHandle(NULL)));
   FARPROC pOriginalGTC;
   printf("hijacking GetTickCount.../n");
   printf("original GetTickCount address = 0x%X/n", pOriginalGTC=pe->InterceptImport("kernel32","GetTickCount", FARPROC(newGetTickCount)));
   printf("GetTickCount() returned 0x%X/n", GetTickCount());

   printf("recalling old GetTickCount.../n");
   pe->InterceptImport( FARPROC(newGetTickCount), pOriginalGTC);
   printf("GetTickCount() returned 0x%X/n", GetTickCount());
   delete pe;

   return 0;
}


console output wrote:
hijacking GetTickCount...
original GetTickCount address = 0x77E7A29B
GetTickCount() returned 0x31337
recalling old GetTickCount...
GetTickCount() returned 0xEC9319
原创粉丝点击