Zero Code

零度代码

Ring3 Api Hook (2) Hot patching inline hook

  1 #pragma once
  2 #include <stdio.h>
  3 // module: InlineHook.h 
  4 // author: cntrump
  5 // create: 2011-05-11
  6 
  7 #if defined(DEBUG)||defined(_DEBUG)
  8 #define HOOKTRACE Trace
  9 #else
 10 #define HOOKTRACE
 11 #endif
 12 
 13 static inline void Trace(LPCWSTR fmt, )
 14 {
 15     WCHAR wzOut[MAX_PATH];
 16     ZeroMemory(wzOut, sizeof(wzOut));
 17     va_list arg_list;
 18     va_start(arg_list, fmt);
 19     _vswprintf_p(wzOut, _countof(wzOut), fmt, arg_list);
 20     va_end(arg_list);
 21 
 22     OutputDebugStringW(wzOut);
 23 }
 24 
 25 class CHotPatchInlineHook
 26 {
 27 public:
 28     CHotPatchInlineHook(HANDLE hProcess, LPVOID pRealFuncAddress, LPVOID pFakeFuncAddress)
 29         :m_hProcess(hProcess) 
 30         ,m_pRealFuncAddress(pRealFuncAddress)
 31     {
 32         if (!WriteLongJmp(pRealFuncAddress, pFakeFuncAddress))
 33             HOOKTRACE(L"WriteLongJmp error");
 34 
 35         if (!WriteShortJmp(pRealFuncAddress))
 36             HOOKTRACE(L"WriteShortJmp error");
 37     }
 38 
 39     ~CHotPatchInlineHook() 
 40     { 
 41         UnHook();
 42     }
 43 
 44     VOID UnHook()
 45     {
 46         UnloadShortJmp();
 47         UnloadLongJmp();
 48     }
 49 protected:
 50     BOOL WriteShortJmp(LPVOID pRealFuncAddress)
 51     {
 52         DWORD dwOldProtect;
 53         BOOL bRet;
 54         bRet = VirtualProtectEx(m_hProcess, pRealFuncAddress, sizeof(ShortJmp), PAGE_EXECUTE_READWRITE, &dwOldProtect);
 55 
 56         if (!bRet)
 57             return FALSE;
 58 
 59         HOOKTRACE(L"Org Address: %X", (DWORD)pRealFuncAddress);
 60 
 61         CopyMemory(&m_orgShortJmp, pRealFuncAddress, sizeof(ShortJmp));
 62         CopyMemory(&m_shortJmp, pRealFuncAddress, sizeof(ShortJmp));
 63         // 构造 jmp $-5
 64         m_shortJmp.op = 0xEB;
 65         m_shortJmp.offset = 0xF9;
 66         DWORD dwNumberOfByteWritten;
 67         bRet = WriteProcessMemory(m_hProcess, pRealFuncAddress, &m_shortJmp, sizeof(ShortJmp), &dwNumberOfByteWritten);
 68         VirtualProtectEx(m_hProcess, pRealFuncAddress, sizeof(ShortJmp), dwOldProtect, &dwOldProtect);
 69 
 70         return bRet;
 71     }
 72 
 73     BOOL WriteLongJmp(LPVOID pRealFuncAddress, LPVOID pFakeFuncAddress)
 74     {
 75         DWORD dwRealFuncAddress = GetRealFuncAddress(pFakeFuncAddress);
 76         // 构造 call xxxxxxxx
 77         m_longJmp.op = 0xE8;
 78         m_longJmp.offset = GetFuncOffset((LPBYTE)pRealFuncAddress-5, (LPVOID)dwRealFuncAddress, 5);
 79         DWORD dwOldProtect;
 80         VirtualProtectEx(m_hProcess, (LPBYTE)pRealFuncAddress-5sizeof(LongJmp), PAGE_EXECUTE_READWRITE, &dwOldProtect);
 81         CopyMemory(&m_orgLongJmp, (LPBYTE)pRealFuncAddress-5sizeof(LongJmp));
 82         DWORD dwNumberOfByteWritten;
 83         BOOL bRet;
 84         bRet = WriteProcessMemory(m_hProcess, (LPBYTE)pRealFuncAddress-5&m_longJmp, sizeof(LongJmp), &dwNumberOfByteWritten);
 85         VirtualProtectEx(m_hProcess, (LPBYTE)pRealFuncAddress-5sizeof(LongJmp), dwOldProtect, &dwOldProtect);
 86         return bRet;
 87     }
 88 
 89     BOOL UnloadShortJmp()
 90     {
 91         DWORD dwOldProtect;
 92         DWORD dwNumberOfBytesWritten;
 93         BOOL bRet;
 94         VirtualProtectEx(m_hProcess, m_pRealFuncAddress, sizeof(ShortJmp), PAGE_EXECUTE_READWRITE, &dwOldProtect);
 95         bRet = WriteProcessMemory(m_hProcess, m_pRealFuncAddress, &m_orgShortJmp, sizeof(ShortJmp), &dwNumberOfBytesWritten);
 96         VirtualProtectEx(m_hProcess, m_pRealFuncAddress, sizeof(ShortJmp), dwOldProtect, &dwOldProtect);
 97         
 98         return bRet;
 99     }
100 
101     BOOL UnloadLongJmp()
102     {
103         DWORD dwOldProtect;
104         DWORD dwNumberOfBytesWritten;
105         BOOL bRet;
106         VirtualProtectEx(m_hProcess, (LPBYTE)m_pRealFuncAddress-5sizeof(LongJmp), PAGE_EXECUTE_READWRITE, &dwOldProtect);
107         bRet = WriteProcessMemory(m_hProcess, (LPBYTE)m_pRealFuncAddress-5&m_longJmp, sizeof(LongJmp), &dwNumberOfBytesWritten);
108         VirtualProtectEx(m_hProcess, (LPBYTE)m_pRealFuncAddress-5sizeof(LongJmp), dwOldProtect, &dwOldProtect);
109 
110         return bRet;
111     }
112 
113 protected:
114     HANDLE m_hProcess;
115     LPVOID m_pRealFuncAddress;
116 protected:
117 
118     DWORD GetRealFuncAddress(LPVOID pFunc)
119     {
120         DWORD realaddr = (DWORD)pFunc;
121         LongJmp longJmp;
122         CopyMemory(&longJmp, pFunc, sizeof(longJmp));
123 
124 
125         if (longJmp.op == 0xE9)
126         {
127             realaddr += longJmp.offset + 5;
128         }
129 
130         return realaddr;
131     }
132 
133     DWORD GetFuncOffset(LPVOID pInAddress, LPVOID pFuncAddress, UINT nCodeLen)
134     {
135         return (DWORD)pFuncAddress - (DWORD)pInAddress - nCodeLen;
136     }
137 
138 #pragma pack(push,1)
139 
140     struct LongJmp  
141     {
142         BYTE op;
143         DWORD offset;
144     }m_longJmp, m_orgLongJmp; // 把长跳转写入 nop 块
145 
146     struct ShortJmp 
147     {
148         BYTE op;
149         BYTE offset;
150     }m_shortJmp, m_orgShortJmp; // 短跳,用于跳转到前面的 nop 块
151 
152 #pragma pack(pop)
153 };

posted on 2011-05-11 16:10 cntrump 阅读(598) 评论(0)  编辑 收藏 引用


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理


My Links

Blog Stats

常用链接

留言簿

随笔档案

搜索

最新评论

阅读排行榜

评论排行榜