Zero Code

零度代码

2011年5月11日 #

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 @ 2011-05-11 16:10 cntrump 阅读(598) | 评论 (0)编辑 收藏

2011年5月10日 #

Ring3 Api Hook (1) 古老的 inline Hook

最古老的 Hook ,非常不稳定。
 1#pragma pack(push,1)
 2typedef struct  
 3{
 4  BYTE op;
 5  DWORD dwOffset;
 6}
HookCode;
 7#pragma pack(pop)
 8
 9HookCode oldCode, newCode;
10LPBYTE pOrgAddress = NULL;
11
12HANDLE WINAPI fakeCreateFileW(DWORD dwReturnAddress, __in LPCWSTR lpFileName, __in DWORD dwDesiredAccess, __in DWORD dwShareMode, 
13                __in_opt LPSECURITY_ATTRIBUTES lpSecurityAttributes, __in DWORD dwCreationDisposition, 
14                __in DWORD dwFlagsAndAttributes, __in_opt HANDLE hTemplateFile )
15{
16  DWORD dwOldProtect;
17  VirtualProtect(pOrgAddress, sizeof(HookCode), PAGE_EXECUTE_READWRITE, &dwOldProtect);
18  CopyMemory(pOrgAddress, &oldCode, sizeof(HookCode));
19  VirtualProtect(pOrgAddress, sizeof(HookCode), dwOldProtect, &dwOldProtect);
20
21  MessageBoxW(NULL, lpFileName, NULL, MB_OK);
22
23  return   CreateFileW(lpFileName, dwDesiredAccess, dwShareMode,
24    lpSecurityAttributes, dwCreationDisposition,
25    dwFlagsAndAttributes, hTemplateFile);
26}

27
28DWORD GetRealAddress(LPVOID pFunc)
29{
30  // 计算函数真实地址
31  LPBYTE funaddr= (LPBYTE)pFunc;
32  if(funaddr[0]==0xE9)// 判断是否为虚拟函数地址,E9为jmp指令
33  {
34    DWORD realaddr=(DWORD)pFunc;
35    realaddr += funaddr[2]*0x100 +funaddr[1+5;
36    return realaddr;
37  }
 
38
39  return (DWORD)pFunc;
40}

41
42int _tmain(int argc, _TCHAR* argv[])
43{
44
45  pOrgAddress = (LPBYTE)GetProcAddress(LoadLibrary(_T("kernel32.dll")), "CreateFileW");
46
47  DWORD dwOldProtect;
48  VirtualProtect(pOrgAddress, sizeof(HookCode), PAGE_EXECUTE_READWRITE, &dwOldProtect);
49  CopyMemory(&oldCode, pOrgAddress, sizeof(HookCode));
50
51  newCode.op = 0xE8;
52  DWORD dwPatch = GetRealAddress(fakeCreateFileW);
53  newCode.dwOffset = dwPatch - (DWORD)pOrgAddress - 5;
54  CopyMemory(pOrgAddress, &newCode, sizeof(HookCode));
55  VirtualProtect(pOrgAddress, sizeof(HookCode), dwOldProtect, &dwOldProtect);
56
57  CreateFileW(L"C:\\a.txt", GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
58
59    return 0;
60}

61
62

posted @ 2011-05-10 23:23 cntrump 阅读(476) | 评论 (0)编辑 收藏

2011年5月4日 #

使用 Gdiplus 将图片设置为窗口背景

 1 在窗口创建时加载一幅图作为背景
 2 
 3     case WM_CREATE:
 4         {
 5             Gdiplus::GdiplusStartup(&token, &input, NULL);
 6             pImage = new Gdiplus::Image(L"pic02.png");
 7         }
 8         break;
 9 
10 在 WM_ERASEBKGND 消息中显示图片,也可以直接返回 TRUE ,而在 WM_PAINT 中显示图片。
11 
12     case WM_ERASEBKGND:
13         {
14             HDC hdc = (HDC)wParam;
15             RECT rc;
16             GetClientRect(hWnd, &rc);
17             HDC hMemDC = CreateCompatibleDC(hdc);
18             HBITMAP hMemBmp = CreateCompatibleBitmap(hdc, rc.right, rc.bottom);
19             SelectObject(hMemDC, hMemBmp);
20             FillRect(hMemDC, &rc, GetSysColorBrush(COLOR_WINDOW)); // 把透明背景填充为系统窗口颜色
21             Gdiplus::Graphics g(hMemDC);
22             g.DrawImage(pImage, 00, rc.right, rc.bottom);
23             BitBlt(hdc, 00, rc.right, rc.bottom, hMemDC, 00, SRCCOPY);
24             DeleteObject(hMemBmp);
25             DeleteDC(hMemDC);
26         }
27         return TRUE;
28 
29 对于一般窗口这样就可以了,网上的很多代码也是这样写的,但是用于对话框时,就会有问题,在拖动改变对话框大小之后,背景图片会有残留。需要在 WM_SIZE 中 调用 RedrawWindow 进行处理:
30 
31     case WM_SIZE:
32         RedrawWindow(hWnd, NULL, NULL, RDW_INVALIDATE);
33         return 0;
34 
35 这样就完美了。
36  
37 

posted @ 2011-05-04 14:10 cntrump 阅读(921) | 评论 (0)编辑 收藏

2011年5月3日 #

XmlHelper 一个简单的 MSXml 包装类

     摘要: 下载 : http://www.cppblog.com/Files/cntrump/XmlHelper.rar   1// module:XmlHelper.h  2// author:cntrump  3// create:2011-05-02  4  5#ifnd...  阅读全文

posted @ 2011-05-03 00:31 cntrump 阅读(582) | 评论 (0)编辑 收藏

2011年4月25日 #

在桌面上显示画图

1     g_hDesktopDC = GetDC(NULL);
2     SetBkMode(g_hDesktopDC, TRANSPARENT);
3     SetTextColor(g_hDesktopDC, RGB(196,196,196));
4     HFONT hFont = (HFONT)SendMessage(GetDesktopWindow(), WM_GETFONT, 00);
5     SelectObject(g_hDesktopDC, hFont);
6     TextOut(g_hDesktopDC, 5050, _T("显示文字测试"), 6);
7     DeleteDC(g_hDesktopDC); // 不删除获取的桌面DC,将无法显示文字

posted @ 2011-04-25 01:34 cntrump 阅读(431) | 评论 (0)编辑 收藏

2011年4月18日 #

使用系统的 SDK 创建多级目录

 

 1#include <shlobj.h>
 2#include <string>
 3
 4#pragma comment(lib, "shell32.lib")
 5
 6BOOL CreateDir(LPCTSTR pszDirPath)
 7{
 8#if defined(UNICODE) || defined(_UNICODE)
 9    std::wstring strDirPath = pszDirPath;
10#else
11    std::string strDirPath = pszDirPath;
12#endif
13
14    if (strDirPath.empty())
15        return FALSE;
16
17    TCHAR szPreFix[] = _T("\\\\?\\");
18    if (0 != strDirPath.find(szPreFix))
19    {    
20        strDirPath = szPreFix;
21        strDirPath += pszDirPath;
22    }

23
24    INT nErrorCode = SHCreateDirectoryEx(NULL, strDirPath.c_str(), NULL);
25
26    switch (nErrorCode)
27    {
28    case ERROR_SUCCESS:
29        return TRUE;
30    case ERROR_ALREADY_EXISTS:
31    case ERROR_FILE_EXISTS:
32        if (FILE_ATTRIBUTE_DIRECTORY & GetFileAttributes(strDirPath.c_str()))
33            return TRUE;
34    // no default
35    }

36
37    return FALSE;
38}

39
40int _tmain(int argc, _TCHAR* argv[]) 
41{
42    CreateDir(_T("d:\\a\\b\\c\\d\\e\\f"));
43    return 0;
44}

posted @ 2011-04-18 01:03 cntrump 阅读(253) | 评论 (0)编辑 收藏

2011年4月14日 #

调用系统的文件复制,移动和删除功能

  1 #include "stdafx.h"
  2 
  3 // 利用Shell复制多个文件,以|分隔,末尾以两个|结束
  4 // 返回 0 表示全部复制成功
  5 // 否则表示操作被中止
  6 LONG ShellCopyFile(__in LPCTSTR pszSrc, __in LPCTSTR pszDest)
  7 {
  8     size_t srclen = lstrlen(pszSrc)+2;
  9     size_t destlen = lstrlen(pszDest)+2;
 10     LPTSTR pszSrcBuffer = new TCHAR[srclen];
 11     LPTSTR pszDestBuffer = new TCHAR[destlen];
 12 
 13     ZeroMemory(pszSrcBuffer, srclen*sizeof(TCHAR));
 14     ZeroMemory(pszDestBuffer, destlen*sizeof(TCHAR));
 15 
 16     lstrcpy(pszSrcBuffer, pszSrc);
 17     lstrcpy(pszDestBuffer, pszDest);
 18 
 19     LPTSTR p;
 20 
 21     p = pszSrcBuffer;
 22     while (*p)
 23     {
 24         if (*== _T('|'))
 25             *= 0;
 26 
 27         ++p;
 28     }
 29 
 30     p = pszDestBuffer;
 31     while (*p)
 32     {
 33         if (*== _T('|'))
 34             *= 0;
 35 
 36         ++p;
 37     }
 38 
 39     SHFILEOPSTRUCT shFileOperation;
 40     ZeroMemory(&shFileOperation, sizeof(shFileOperation));
 41     shFileOperation.fFlags = FOF_ALLOWUNDO|FOF_MULTIDESTFILES|FOF_NOCONFIRMATION;
 42     shFileOperation.wFunc = FO_COPY;
 43     shFileOperation.pFrom = pszSrcBuffer;
 44     shFileOperation.pTo = pszDestBuffer;
 45 
 46     SHFileOperation(&shFileOperation);
 47 
 48     delete pszSrcBuffer;
 49     delete pszDestBuffer;
 50 
 51     return shFileOperation.fAnyOperationsAborted;
 52 }
 53 
 54 // 利用Shell删除文件(到 回收站)
 55 // 删除多个文件用|分隔,末尾以两个|结束
 56 // 返回值为 0 表示所有文件删除成功
 57 LONG ShellDeleteFile(__in LPCTSTR pszSrc)
 58 {
 59     size_t len = lstrlen(pszSrc)+2;
 60     LPTSTR pszSrcBuffer = new TCHAR[len];
 61     ZeroMemory(pszSrcBuffer, len*sizeof(TCHAR));
 62     lstrcpy(pszSrcBuffer, pszSrc);
 63 
 64     LPTSTR p = pszSrcBuffer;
 65     while (*p)
 66     {
 67         if (*== _T('|'))
 68             *= 0;
 69 
 70         ++p;
 71     }
 72 
 73     SHFILEOPSTRUCT shFileOperation;
 74     ZeroMemory(&shFileOperation, sizeof(shFileOperation));
 75     shFileOperation.wFunc = FO_DELETE;
 76     shFileOperation.fFlags = FOF_MULTIDESTFILES|FOF_ALLOWUNDO|FOF_NOCONFIRMATION;
 77     shFileOperation.pFrom = pszSrcBuffer;
 78     SHFileOperation(&shFileOperation);
 79     delete pszSrcBuffer;
 80 
 81     return shFileOperation.fAnyOperationsAborted;
 82 }
 83 
 84 // 利用Shell移动文件或文件夹
 85 // 返回 0 表示所有文件或文件夹操作成功
 86 // 多个文件用|分隔,最后以两个|结束
 87 LONG ShellMoveFile(__in LPCTSTR pszSrc, __in LPCTSTR pszDest)
 88 {
 89     size_t srclen = lstrlen(pszSrc)+2;
 90     size_t destlen = lstrlen(pszDest)+2;
 91 
 92     LPTSTR pszSrcBuffer = new TCHAR[srclen];
 93     LPTSTR pszDestBuffer = new TCHAR[destlen];
 94     ZeroMemory(pszSrcBuffer, srclen*sizeof(TCHAR));
 95     ZeroMemory(pszDestBuffer, destlen*sizeof(TCHAR));
 96     lstrcpy(pszSrcBuffer, pszSrc);
 97     lstrcpy(pszDestBuffer, pszDest);
 98 
 99     LPTSTR p = pszSrcBuffer;
100     while (*p)
101     {
102         if (*== _T('|'))
103             *= 0;
104 
105         ++p;
106     }
107 
108     p = pszDestBuffer;
109     while (*p)
110     {
111         if (*== _T('|'))
112             *= 0;
113 
114         ++p;
115     }
116 
117     SHFILEOPSTRUCT shFileOperation;
118     ZeroMemory(&shFileOperation, sizeof(shFileOperation));
119     shFileOperation.wFunc = FO_MOVE;
120     shFileOperation.fFlags = FOF_ALLOWUNDO|FOF_MULTIDESTFILES|FOF_NOCONFIRMATION;
121     shFileOperation.pFrom = pszSrcBuffer;
122     shFileOperation.pTo = pszDestBuffer;
123     SHFileOperation(&shFileOperation);
124 
125     return shFileOperation.fAnyOperationsAborted;
126 }
127 
128 int _tmain(int argc, _TCHAR* argv[])
129 {
130 //    ShellMoveFile(_T("D:\\*.rar"), _T("E:\\"));
131 //    ShellDeleteFile(_T("D:\\eHomeNet.rar"));
132 //    ShellCopyFile(L"D:\\video\\AV\\*.*", L"E:\\");
133     return 0;
134 }
135 

posted @ 2011-04-14 01:51 cntrump 阅读(1100) | 评论 (0)编辑 收藏

仅列出标题  

My Links

Blog Stats

常用链接

留言簿

随笔档案

搜索

最新评论

阅读排行榜

评论排行榜