3.4 DLL注入:全局消息钩子注入

lyshark
全栈领域优质创作者
博客专家认证
2023-11-21 09:11:29

SetWindowHookEx 是Windows系统的一个函数,可用于让一个应用程序安装全局钩子,但读者需要格外注意该方法安装的钩子会由操作系统注入到所有可执行进程内,虽然该注入方式可以用于绕过游戏保护实现注入,但由于其属于全局注入所以所有的进程都会受到影响,而如果想要解决这个问题,则需要在DllMain()也就是动态链接库开头位置进行判断,如果是我们所需操作的进程则执行该DLL模块内的功能,如果不是则自动跳过不执行任何操作即可实现指定进程的注入方式。

首先我们先来看一下该函数的原型定义;

HHOOK SetWindowsHookEx(
  int       idHook,
  HOOKPROC  lpfn,
  HINSTANCE hMod,
  DWORD     dwThreadId
);

参数说明如下:

  • idHook:钩子类型,标识了钩子函数要监视哪种事件。可以是整数值或预定义的常量值(如WH_MOUSE、WH_KEYBOARD、WH_SHELL等)。
  • lpfn:钩子函数的地址。
  • hMod:把钩子函数插入挂钩链中的应用程序的句柄,该参数通常被设置为包含钩子函数代码的DLL模块的句柄。
  • dwThreadId:要设置钩子的线程标识符或进程标识符,如果为 0,则钩子通常与所有线程的输入消息联系起来。

在安装全局消息钩子时,读者需要在DLL中对外暴漏两个接口,其中SetHook()用于设置钩子,UnHook()则用于取消钩子,在DLL入口处,通过调用GetFristModuleName()我们可以判断当前进程是否为我们所需操作的进程,如果是则执行进程内的流程,如果不是则跳过执行,这个流程可以描述为如下样子,读者可自行将如下代码编译为DLL文件。

#include <iostream>
#include <TlHelp32.h>
#include <windows.h>
#include <tchar.h>

// 指定全局变量
HHOOK global_Hook;

// 判断是否是需要注入的进程
BOOL GetFristModuleName(DWORD Pid, LPCTSTR ExeName)
{
  MODULEENTRY32 me32 = { 0 };
  me32.dwSize = sizeof(MODULEENTRY32);
  HANDLE hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, Pid);

  if (INVALID_HANDLE_VALUE != hModuleSnap)
  {
    // 先拿到自身进程名称
    BOOL bRet = Module32First(hModuleSnap, &me32);

    // 对比如果是需要注入进程,则返回真
    if (!_tcsicmp(ExeName, (LPCTSTR)me32.szModule))
    {
      CloseHandle(hModuleSnap);
      return TRUE;
    }
    CloseHandle(hModuleSnap);
    return FALSE;
  }
  CloseHandle(hModuleSnap);
  return FALSE;
}

// 获取自身DLL名称
char* GetMyDllName()
{
  char szFileFullPath[MAX_PATH], szProcessName[MAX_PATH];

  // 获取文件路径
  GetModuleFileNameA(NULL, szFileFullPath, MAX_PATH);
  
  int length = strlen(szFileFullPath);

  // 从路径后面开始找\,即倒着找右斜杠
  for (int i = length - 1; i >= 0; i--)
  {
    // 找到第一个\就可以马上获取进程名称了
    if (szFileFullPath[i] == '\\')
    {
      i++;
      // 结束符\0不能少 即i=length
      for (int j = 0; i <= length; j++)
      {
        szProcessName[j] = szFileFullPath[i++];
      }
      break;
    }
  }
  return szProcessName;
}

// 设置全局消息回调函数
LRESULT CALLBACK MyProc(int nCode, WPARAM wParam, LPARAM lParam)
{
  return CallNextHookEx(global_Hook, nCode, wParam, lParam);
}

// 安装全局钩子 此处的 GetMyDllName()函数 可以是外部其他DLL,可将任意DLL进行注入
extern "C" __declspec(dllexport) void SetHook()
{
  global_Hook = SetWindowsHookEx(WH_CBT, MyProc, GetModuleHandleA(GetMyDllName()), 0);
}

// 卸载全局钩子
extern "C" __declspec(dllexport) void UnHook()
{
  if (global_Hook)
  {
    UnhookWindowsHookEx(global_Hook);
  }
}

// DLL 主函数
BOOL APIENTRY DllMain(HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
{
  switch (ul_reason_for_call)
  {
    case DLL_PROCESS_ATTACH:
    {
      // 当DLL被加载时触发,判断当前自身父进程是否为 lyshark.exe 
      BOOL flag = GetFristModuleName(GetCurrentProcessId(), TEXT("lyshark.exe"));
      if (flag == TRUE)
      {
        MessageBoxA(0, "hello lyshark", 0, 0);
      }
      break;
    }
    case DLL_THREAD_ATTACH:
    {
      break;
    }
    case DLL_THREAD_DETACH:
    {
      break;
    }
    case DLL_PROCESS_DETACH:
    {
      // DLL卸载时自动清理
      UnHook();
      break;
    }
    default:
      break;
  }
  return TRUE;
}

接着我们需要编写一个专门用来加载该DLL的程序,在调用DLL之前,我们需要通过LoadLibrary()将此模块加载到内存中,并通过GetProcAddress(hMod, "SetHook")获取到该模块的中SetHook函数的内存地址,最后直接调用SetHook()安装一个全局钩子,实现安装的代码流程如下所示;

#include <iostream>
#include <windows.h>

int main(int argc, char* argv[])
{
    HMODULE hMod = LoadLibrary(TEXT("d://hook.dll"));

    // 挂钩
    typedef void(*pSetHook)(void);
    pSetHook SetHook = (pSetHook)GetProcAddress(hMod, "SetHook");
    SetHook();

    while (1)
    {
        Sleep(1000);
    }

    // 卸载钩子
    typedef BOOL(*pUnSetHook)(HHOOK);
    pUnSetHook UnsetHook = (pUnSetHook)GetProcAddress(hMod, "UnHook");
    pUnSetHook();

    FreeLibrary(hMod);
    return 0;
}
...全文
4 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复
上传限制,共分四卷压缩。请务必下载完所有压缩包。 目录 第一篇 软件设计基础篇 第1章 软件开发起步 2 1.1 建立MFC应用程序 2 1.2 分析框架结构 4 1.2.1 框架代码文件的结构 4 1.2.2 应用程序类 5 1.2.3 对话框类 6 1.2.4 添加消息响应 7 第2章 对话框应用程序 9 2.1 模态对话框 9 2.1.1 实例:使用MFC实现模态对话框 9 2.1.2 实例:使用Win32 API实现模态对话框 10 2.2 非模态对话框 12 2.2.1 实例:使用MFC实现非模态对话框 12 2.2.2 实例:使用Win32 API实现非模态对话框 13 2.3 属性对话框 14 2.3.1 实例:多页面切换程序 14 2.3.2 实例:向导对话框 16 2.4 对话框设计技巧 17 2.4.1 控件对齐与排列 17 2.4.2 设置控件逻辑顺序 18 2.5 通用对话框 19 2.5.1 实例:通用“打开”和“另存为”对话框 19 2.5.2 实例:通用“字体”对话框 22 2.5.3 实例:通用“颜色”对话框 23 第3章 基本控件 26 3.1 按钮控件 26 3.1.1 按钮CButton类 26 3.1.2 实例:按钮控件的使用方法 28 3.2 编辑框 30 3.2.1 编辑框CEdit类 30 3.2.2 实例:编辑框的使用方法 32 3.3 列表框 33 3.3.1 列表框CListBox类 33 3.3.2 实例:列表框的使用方法 35 3.4 组合框 36 3.4.1 组合框CComboxBox类 37 3.4.2 实例:组合框的使用方法 39 3.5 进度条 41 3.5.1 进度条CProgressCtrl类 41 3.5.2 实例:进度条的使用方法 42 3.6 列表控件 44 3.6.1 列表控件CListCtrl类 44 3.6.2 实例:列表控件的使用方法 45 第4章 文档与视图 47 4.1 文档—视图结构 47 4.1.1 单文档与多文档 47 4.1.2 文档与视图体系 48 4.2 实例:单文档应用程序与文档串行化 52 第5章 GDI绘图技术 57 5.1 图形设备接口GDI 57 5.1.1 设备上下文 57 5.1.2 GDI对象 58 5.1.3 GDI绘图 58 5.2 画笔 58 5.2.1 画笔CPen类 58 5.2.2 实例:使用GDI对象CPen绘图示例 59 5.3 画刷 60 5.3.1 画刷CBrush类 60 5.3.2 实例:使用GDI对象CBrush绘图示例 61 5.4 位图 63 5.4.1 位图CBitmap 63 5.4.2 实例:使用GDI对象CBitmap示例 64 第6章 键盘与鼠标消息 67 6.1 键盘消息 67 6.1.1 键盘消息的类型 67 6.1.2 实例:响应键盘消息示例 68 6.1.3 模拟键盘消息 70 6.1.4 实例:模拟键盘消息示例 71 6.2 鼠标消息 72 6.2.1 鼠标消息的类型 72 6.2.2 实例:处理鼠标消息 73 6.2.3 实例:模拟鼠标消息 74 第二篇 软件设计综合应用篇 第7章 网络通信基础 80 7.1 网络模型 80 7.1.1 OSI参考模型 80 7.1.2 TCP/IP参考模型 81 7.2 基础协议 82 7.2.1 IP协议 82 7.2.2 TCP协议 83 7.2.3 UDP协议 84 7.2.4 ICMP协议 85 7.3 套接字编程 85 7.3.1 函数介绍 85 7.3.2 实例:Ping程序 88 7.3.3 实例:网络嗅探器 92 7.4 服务器与客户端模型 96 7.4.1 实例:TCP服务端和客户端程序 96 7.4.2 实例:UDP服务器和客户端程序 100 7.5 实例:使用分层服务提供者LSP截取网络数据包 103 7.5.1 服务提供者接口(SPI) 103 7.5.2 设计实例 103 7.5.3 枚举协议目录 106 7.5.4 LSP的安装与卸载 108 7.5.5 分层服务提供者(LSP) 113 第8章 密码学算法 118 8.1 数据加密标准(DES) 118 8.1.1 算法描述 118 8.1.2 初始置换与逆初始置换 119 8.1.3 生成子密钥 120 8.1.4 f函数的执行流程 121 8.1.5 解密过程 122 8.1.6 实例:DES算法加密解密演示 123 8.2 国际数据加密算法(IDEA) 131 8.2.1 算法描述 131 8.2.2 生成子密钥 133 8.2.3 实例:IDEA算法加密解密演示 134 8.3 Blowfish算法 139 8.3.1 算法描述 139 8.3.2 生成子密钥和S盒 141 8.3.3 实例:Blowfish算法加密解密演示 141 8.4 公钥加密算法(RSA) 146 8.4.1 算法描述 146 8.4.2 实例:RSA加密解密演示软件 147 第9章 多媒体技术 151 9.1 多媒体控件 151 9.1.1 实例:使用Animation控件播放AVI文件 151 9.1.2 实例:使用Windows Media Player控件播放多媒体文件 152 9.1.3 实例:使用Real Player控件播放多媒体文件 153 9.2 屏幕截图 154 9.2.1 位图 154 9.2.2 实例:屏幕截图 155 9.3 屏幕录像 157 9.3.1 实现原理 157 9.3.2 实例:屏幕录像 158 第10章 数据库技术 161 10.1 设置ODBC数据源 161 10.1.1 ODBC数据源 161 10.1.2 使用ODBC管理器设置Access数据源 162 10.2 MFC ODBC数据库编程 163 10.2.1 MFC ODBC概述 163 10.2.2 实例:使用MFC ODBC访问数据库 164 10.3 MFC DAO数据库编程 169 10.3.1 MFC DAO概述 169 10.3.2 实例:使用MFC DAO访问 数据库 169 第11章 综合实例开发 174 11.1 实例:Huffman编码软件 174 11.1.1 Huffman算法原理 174 11.1.2 具体实现 175 11.2 实例:八数码游戏 178 11.2.1 八数码游戏算法介绍 178 11.2.2 具体实现 179 11.3 实例:游戏寻路算法A* 183 11.3.1 A*算法原理 183 11.3.2 二叉堆在A*中的应用 184 11.3.3 具体实现 186 11.4 实例:“连连看”游戏辅助工具 190 11.4.1 “连连看”算法原理 190 11.4.2 具体实现 191 11.5 实例:“对对碰”游戏辅助工具 196 11.5.1 “对对碰”算法原理 196 11.5.2 具体实现 197 11.6 实例:拼音输入法 199 11.6.1 设计实例 200 11.6.2 拼音字典存储结构—Trie树 200 11.6.3 单字联想 205 11.7 实例:Windows二级文件系统 209 11.7.1 设计实例 209 11.7.2 具体实现 211 11.8 实例:手柄测试器 214 11.8.1 DirectInput手柄输入 214 11.8.2 设计实例 216 第三篇 Windows系统程序设计篇 第12章 进程与线程 222 12.1 进程 222 12.1.1 原理介绍 223 12.1.2 创建进程 223 12.1.3 实例:创建进程 226 12.2 线程 227 12.2.1 原理介绍 227 12.2.2 创建线程 229 12.2.3 实例:创建线程 229 12.3 枚举进程/线程信息 231 12.3.1 实例:使用PSAPI示例 231 12.3.2 实例:使用ToolHelpAPI示例 233 12.3.3 实例:使用Native API示例 235 第13章 内存管理 239 13.1 虚拟内存 239 13.1.1 进程虚拟地址空间 239 13.1.2 实例:查看虚拟内存状态 240 131.3 实例:演示虚拟内存的“保留—提交”特性 243 13.1.4 实例:游戏内存修改器 245 13.2 内存映射文件 249 13.2.1 内存映射文件的原理 249 13.2.2 实例:文件分割器 250 第14章 进程间通信 254 14.1 消息传递机制 254 14.1.1 消息传递 254 14.1.2 实例:使用WM_COPYDATA消息传递数据 254 14.2 共享内存 256 14.2.1 共享内存的原理 256 14.2.2 实例:使用共享内存示例 257 14.3 管道和邮槽 259 14.3.1 管道和邮槽通信原理 259 14.3.2 实例:使用匿名管道重定向程序输出 261 14.3.3 实例:命名管道示例 263 14.3.4 实例:邮槽通信示例 266 14.4 剪贴板 267 14.4.1 剪贴板通信机制 267 14.4.2 实例:使用剪贴板实现进程间通信示例 269 第15章 线程同步 275 15.1 原子访问 275 15.1.1 多线程访问共享数据问题 275 15.1.2 互锁系列函数 276 15.2 关键代码段 277 15.2.1 基本原理 277 15.2.2 实例:多线程环境下的数据共享 278 15.3 内核对象与等待函数 280 15.3.1 内核对象 280 15.3.2 等待函数 281 15.4 事件内核对象 283 15.4.1 基本原理 283 15.4.2 实例:使用事件内核对象示例 284 15.5 等待定时器内核对象 285 15.5.1 基本原理 285 15.5.2 实例:使用等待定时器的APC机制 287 15.6 信标内核对象 288 15.6.1 基本原理 288 15.6.2 实例:使用信标内核对象示例 289 15.7 互斥内核对象 291 15.7.1 基本原理 292 15.7.2 实例:使用互斥内核对象示例 292 第16章 动态链接库 295 16.1 DLL基础 295 16.1.1 DLL的隐式链接 295 16.1.2 DLL的显示加载 296 16.2 编写动态链接库 297 16.2.1 入口函数DllMain 297 16.2.2 实例:编写DLL实现导出变量、函数、类 298 16.3 线程本地存储器(TLS) 301 16.3.1 静态TLS和动态TLS 301 16.3.2 实例:使用静态TLS示例 303 16.3.3 实例:使用动态TLS示例 304 第17章 结构化异常处理 306 17.1 SEH的概念、特性 306 17.2 SEH的基本使用方法 307 17.2.1 结束异常程序 307 17.2.2 异常处理程序 310 17.2.3 顶层异常处理 313 17.3 VC++编译器级SEH的具体实现 313 17.3.1 SEH相关数据结构的介绍 314 17.3.2 异常处理链结构图 315 17.3.3 实例:单嵌套异常块演示程序 316 17.3.4 实例:多嵌套异常块演示程序 318 17.3.5 VC++编译器级异常帧结构 320 17.3.6 VC中的顶层异常处理 320 17.3.7 VC搜索异常处理程序流程 322 第18章 可执行文件格式 324 18.1 PE文件格式 324 18.1.1 PE文件头 324 18.1.2 可选文件头 325 18.1.3 区块表 327 18.1.4 输入表 328 18.1.5 输出表 329 18.1.6 资源表 330 18.1.7 重定位表 332 18.1.8 绑定输入表 332 18.2 综合应用 333 18.2.1 实例: PE文件资源查看器 333 18.2.2 实例: 为应用程序添加Nag窗口 337 第19章 模块注入与函数挂接技术 341 19.1 模块注入 341 19.1.1 添加导入表项 342 19.1.2 远程线程技术 344 19.1.3 实例:使用远程线程实现模块注入 345 19.1.4 异步过程调用(APC) 346 19.1.5 实例:使用APC实现模块注入 347 19.2 挂接API 349 19.2.1 重定向API 350 19.2.2 实例:重定向API MessageBoxA示例 350 19.2.3 古老的API HOOK 353 19.2.4 实例:HOOK API示例 354 19.2.5 Detours Hook 356 19.2.6 实例:使用detour库实现挂接API示例 357 19.3 钩子 359 19.3.1 钩子的基本原理 359 19.3.2 钩子类型 360 19.3.3 实例:全局鼠标钩子示例 366 19.3.4 实例:全局键盘钩子示例 369 19.3.5 实例:使用局部CBT钩子示例 370 19.3.6 实例:使用低级键盘钩子示例 371 19.4 反注入技术 372 19.4.1 实例:使用调试钩子屏蔽全局钩子 372 19.4.2 实例:检测注入模块 374 19.4.3 实例:使用DLL_THREAD_ATTACH阻止远程线程 377 19.4.4 实例:使用挂钩LoadLibraryExW屏蔽全局钩子 379 附录 光盘源码实例 381
上传限制,共分四卷压缩。请务必下载完所有压缩包。 目录 第一篇 软件设计基础篇 第1章 软件开发起步 2 1.1 建立MFC应用程序 2 1.2 分析框架结构 4 1.2.1 框架代码文件的结构 4 1.2.2 应用程序类 5 1.2.3 对话框类 6 1.2.4 添加消息响应 7 第2章 对话框应用程序 9 2.1 模态对话框 9 2.1.1 实例:使用MFC实现模态对话框 9 2.1.2 实例:使用Win32 API实现模态对话框 10 2.2 非模态对话框 12 2.2.1 实例:使用MFC实现非模态对话框 12 2.2.2 实例:使用Win32 API实现非模态对话框 13 2.3 属性对话框 14 2.3.1 实例:多页面切换程序 14 2.3.2 实例:向导对话框 16 2.4 对话框设计技巧 17 2.4.1 控件对齐与排列 17 2.4.2 设置控件逻辑顺序 18 2.5 通用对话框 19 2.5.1 实例:通用“打开”和“另存为”对话框 19 2.5.2 实例:通用“字体”对话框 22 2.5.3 实例:通用“颜色”对话框 23 第3章 基本控件 26 3.1 按钮控件 26 3.1.1 按钮CButton类 26 3.1.2 实例:按钮控件的使用方法 28 3.2 编辑框 30 3.2.1 编辑框CEdit类 30 3.2.2 实例:编辑框的使用方法 32 3.3 列表框 33 3.3.1 列表框CListBox类 33 3.3.2 实例:列表框的使用方法 35 3.4 组合框 36 3.4.1 组合框CComboxBox类 37 3.4.2 实例:组合框的使用方法 39 3.5 进度条 41 3.5.1 进度条CProgressCtrl类 41 3.5.2 实例:进度条的使用方法 42 3.6 列表控件 44 3.6.1 列表控件CListCtrl类 44 3.6.2 实例:列表控件的使用方法 45 第4章 文档与视图 47 4.1 文档—视图结构 47 4.1.1 单文档与多文档 47 4.1.2 文档与视图体系 48 4.2 实例:单文档应用程序与文档串行化 52 第5章 GDI绘图技术 57 5.1 图形设备接口GDI 57 5.1.1 设备上下文 57 5.1.2 GDI对象 58 5.1.3 GDI绘图 58 5.2 画笔 58 5.2.1 画笔CPen类 58 5.2.2 实例:使用GDI对象CPen绘图示例 59 5.3 画刷 60 5.3.1 画刷CBrush类 60 5.3.2 实例:使用GDI对象CBrush绘图示例 61 5.4 位图 63 5.4.1 位图CBitmap 63 5.4.2 实例:使用GDI对象CBitmap示例 64 第6章 键盘与鼠标消息 67 6.1 键盘消息 67 6.1.1 键盘消息的类型 67 6.1.2 实例:响应键盘消息示例 68 6.1.3 模拟键盘消息 70 6.1.4 实例:模拟键盘消息示例 71 6.2 鼠标消息 72 6.2.1 鼠标消息的类型 72 6.2.2 实例:处理鼠标消息 73 6.2.3 实例:模拟鼠标消息 74 第二篇 软件设计综合应用篇 第7章 网络通信基础 80 7.1 网络模型 80 7.1.1 OSI参考模型 80 7.1.2 TCP/IP参考模型 81 7.2 基础协议 82 7.2.1 IP协议 82 7.2.2 TCP协议 83 7.2.3 UDP协议 84 7.2.4 ICMP协议 85 7.3 套接字编程 85 7.3.1 函数介绍 85 7.3.2 实例:Ping程序 88 7.3.3 实例:网络嗅探器 92 7.4 服务器与客户端模型 96 7.4.1 实例:TCP服务端和客户端程序 96 7.4.2 实例:UDP服务器和客户端程序 100 7.5 实例:使用分层服务提供者LSP截取网络数据包 103 7.5.1 服务提供者接口(SPI) 103 7.5.2 设计实例 103 7.5.3 枚举协议目录 106 7.5.4 LSP的安装与卸载 108 7.5.5 分层服务提供者(LSP) 113 第8章 密码学算法 118 8.1 数据加密标准(DES) 118 8.1.1 算法描述 118 8.1.2 初始置换与逆初始置换 119 8.1.3 生成子密钥 120 8.1.4 f函数的执行流程 121 8.1.5 解密过程 122 8.1.6 实例:DES算法加密解密演示 123 8.2 国际数据加密算法(IDEA) 131 8.2.1 算法描述 131 8.2.2 生成子密钥 133 8.2.3 实例:IDEA算法加密解密演示 134 8.3 Blowfish算法 139 8.3.1 算法描述 139 8.3.2 生成子密钥和S盒 141 8.3.3 实例:Blowfish算法加密解密演示 141 8.4 公钥加密算法(RSA) 146 8.4.1 算法描述 146 8.4.2 实例:RSA加密解密演示软件 147 第9章 多媒体技术 151 9.1 多媒体控件 151 9.1.1 实例:使用Animation控件播放AVI文件 151 9.1.2 实例:使用Windows Media Player控件播放多媒体文件 152 9.1.3 实例:使用Real Player控件播放多媒体文件 153 9.2 屏幕截图 154 9.2.1 位图 154 9.2.2 实例:屏幕截图 155 9.3 屏幕录像 157 9.3.1 实现原理 157 9.3.2 实例:屏幕录像 158 第10章 数据库技术 161 10.1 设置ODBC数据源 161 10.1.1 ODBC数据源 161 10.1.2 使用ODBC管理器设置Access数据源 162 10.2 MFC ODBC数据库编程 163 10.2.1 MFC ODBC概述 163 10.2.2 实例:使用MFC ODBC访问数据库 164 10.3 MFC DAO数据库编程 169 10.3.1 MFC DAO概述 169 10.3.2 实例:使用MFC DAO访问 数据库 169 第11章 综合实例开发 174 11.1 实例:Huffman编码软件 174 11.1.1 Huffman算法原理 174 11.1.2 具体实现 175 11.2 实例:八数码游戏 178 11.2.1 八数码游戏算法介绍 178 11.2.2 具体实现 179 11.3 实例:游戏寻路算法A* 183 11.3.1 A*算法原理 183 11.3.2 二叉堆在A*中的应用 184 11.3.3 具体实现 186 11.4 实例:“连连看”游戏辅助工具 190 11.4.1 “连连看”算法原理 190 11.4.2 具体实现 191 11.5 实例:“对对碰”游戏辅助工具 196 11.5.1 “对对碰”算法原理 196 11.5.2 具体实现 197 11.6 实例:拼音输入法 199 11.6.1 设计实例 200 11.6.2 拼音字典存储结构—Trie树 200 11.6.3 单字联想 205 11.7 实例:Windows二级文件系统 209 11.7.1 设计实例 209 11.7.2 具体实现 211 11.8 实例:手柄测试器 214 11.8.1 DirectInput手柄输入 214 11.8.2 设计实例 216 第三篇 Windows系统程序设计篇 第12章 进程与线程 222 12.1 进程 222 12.1.1 原理介绍 223 12.1.2 创建进程 223 12.1.3 实例:创建进程 226 12.2 线程 227 12.2.1 原理介绍 227 12.2.2 创建线程 229 12.2.3 实例:创建线程 229 12.3 枚举进程/线程信息 231 12.3.1 实例:使用PSAPI示例 231 12.3.2 实例:使用ToolHelpAPI示例 233 12.3.3 实例:使用Native API示例 235 第13章 内存管理 239 13.1 虚拟内存 239 13.1.1 进程虚拟地址空间 239 13.1.2 实例:查看虚拟内存状态 240 131.3 实例:演示虚拟内存的“保留—提交”特性 243 13.1.4 实例:游戏内存修改器 245 13.2 内存映射文件 249 13.2.1 内存映射文件的原理 249 13.2.2 实例:文件分割器 250 第14章 进程间通信 254 14.1 消息传递机制 254 14.1.1 消息传递 254 14.1.2 实例:使用WM_COPYDATA消息传递数据 254 14.2 共享内存 256 14.2.1 共享内存的原理 256 14.2.2 实例:使用共享内存示例 257 14.3 管道和邮槽 259 14.3.1 管道和邮槽通信原理 259 14.3.2 实例:使用匿名管道重定向程序输出 261 14.3.3 实例:命名管道示例 263 14.3.4 实例:邮槽通信示例 266 14.4 剪贴板 267 14.4.1 剪贴板通信机制 267 14.4.2 实例:使用剪贴板实现进程间通信示例 269 第15章 线程同步 275 15.1 原子访问 275 15.1.1 多线程访问共享数据问题 275 15.1.2 互锁系列函数 276 15.2 关键代码段 277 15.2.1 基本原理 277 15.2.2 实例:多线程环境下的数据共享 278 15.3 内核对象与等待函数 280 15.3.1 内核对象 280 15.3.2 等待函数 281 15.4 事件内核对象 283 15.4.1 基本原理 283 15.4.2 实例:使用事件内核对象示例 284 15.5 等待定时器内核对象 285 15.5.1 基本原理 285 15.5.2 实例:使用等待定时器的APC机制 287 15.6 信标内核对象 288 15.6.1 基本原理 288 15.6.2 实例:使用信标内核对象示例 289 15.7 互斥内核对象 291 15.7.1 基本原理 292 15.7.2 实例:使用互斥内核对象示例 292 第16章 动态链接库 295 16.1 DLL基础 295 16.1.1 DLL的隐式链接 295 16.1.2 DLL的显示加载 296 16.2 编写动态链接库 297 16.2.1 入口函数DllMain 297 16.2.2 实例:编写DLL实现导出变量、函数、类 298 16.3 线程本地存储器(TLS) 301 16.3.1 静态TLS和动态TLS 301 16.3.2 实例:使用静态TLS示例 303 16.3.3 实例:使用动态TLS示例 304 第17章 结构化异常处理 306 17.1 SEH的概念、特性 306 17.2 SEH的基本使用方法 307 17.2.1 结束异常程序 307 17.2.2 异常处理程序 310 17.2.3 顶层异常处理 313 17.3 VC++编译器级SEH的具体实现 313 17.3.1 SEH相关数据结构的介绍 314 17.3.2 异常处理链结构图 315 17.3.3 实例:单嵌套异常块演示程序 316 17.3.4 实例:多嵌套异常块演示程序 318 17.3.5 VC++编译器级异常帧结构 320 17.3.6 VC中的顶层异常处理 320 17.3.7 VC搜索异常处理程序流程 322 第18章 可执行文件格式 324 18.1 PE文件格式 324 18.1.1 PE文件头 324 18.1.2 可选文件头 325 18.1.3 区块表 327 18.1.4 输入表 328 18.1.5 输出表 329 18.1.6 资源表 330 18.1.7 重定位表 332 18.1.8 绑定输入表 332 18.2 综合应用 333 18.2.1 实例: PE文件资源查看器 333 18.2.2 实例: 为应用程序添加Nag窗口 337 第19章 模块注入与函数挂接技术 341 19.1 模块注入 341 19.1.1 添加导入表项 342 19.1.2 远程线程技术 344 19.1.3 实例:使用远程线程实现模块注入 345 19.1.4 异步过程调用(APC) 346 19.1.5 实例:使用APC实现模块注入 347 19.2 挂接API 349 19.2.1 重定向API 350 19.2.2 实例:重定向API MessageBoxA示例 350 19.2.3 古老的API HOOK 353 19.2.4 实例:HOOK API示例 354 19.2.5 Detours Hook 356 19.2.6 实例:使用detour库实现挂接API示例 357 19.3 钩子 359 19.3.1 钩子的基本原理 359 19.3.2 钩子类型 360 19.3.3 实例:全局鼠标钩子示例 366 19.3.4 实例:全局键盘钩子示例 369 19.3.5 实例:使用局部CBT钩子示例 370 19.3.6 实例:使用低级键盘钩子示例 371 19.4 反注入技术 372 19.4.1 实例:使用调试钩子屏蔽全局钩子 372 19.4.2 实例:检测注入模块 374 19.4.3 实例:使用DLL_THREAD_ATTACH阻止远程线程 377 19.4.4 实例:使用挂钩LoadLibraryExW屏蔽全局钩子 379 附录 光盘源码实例 381
目录 第1章 面向对象编程 1.1 面向对象的基本概念 1.1.1 类和对象 1.1.2 封装、多态和继承 1.1.3 消息 1.2 面向对象的建模技术UML 1.2.1 类图 1.2.2 交互图 1.2.3 用例图 1.3 面向对象的C++语言 1.3.1 C++对象的内存布局 1.3.2 C++编程技术要点 1.4 小结 第2章 窗口 2.1 窗口结构 2.2 窗口类型 2.3 窗口关系 2.4 消息消息处理 2.4.1 系统定义的消息 2.4.2 应用程序定义的消息 2.4.3 消息参数 2.4.4 消息队列 2.4.5 消息循列 2.4.6 窗口过程 2.5 窗口应用框架 2.6 小结 第3章 MFC简介 3.1 MFC的优势 3.2 MFC中的类 3.3 用MFC开发应用的基本方法 3.4 MFC中的窗口管理 3.4.1 C++窗口对象和Windows窗体之间的关系 3.4.2 创建窗口 3.4.3 销毁窗体 3.4.4 定位窗体 3.4.5 绘图 3.4.6 消息处理 3.5 小结 第4章 CObject类 4.1 概述 4.2 创建对象 4.2.1 直接构造 4.2.2 使用new操作符 4.3 诊断功能 4.3.1 Dump成员 4.3.2 AssertValid 4.4 运行时类信息 4.4.1 CRuntimeClass结构 4.4.2 添加运行时类信息 4.4.3 IsKindOf 4.5 动态创建 4.6 序列化 4.6.1 添加序列化支持 4.6.2 CArchive类 4.6.3 对象序列化实例 4.7 小结 第5章 MFC应用框架 5.1 应用程序对象和MFC类库的交互 5.2 应用程序的初始化 5.3 消息循环 5.4 空闲处理 5.5 应用程序的退出 5.6 CWinApp提供的其他服务 5.6.1 外壳程序注册 5.6.2 文件管理器拖放 5.6.3 跟踪最近使用的文档 5.7 小结 第6章 消息映射 6.1 基本概念 6.2 消息映射表 6.3 一般窗口消息的处理成员的定位 6.4 命令处理成员的定位 6.5 消息映射宏 6.5.1 窗口映射宏 6.5.2 命令映射宏 6.5.3 控制通知消息映射宏 6.5.4 通知消息映射宏 6.5.5 反射消息映射宏 6.6 小结 第7章 消息处理 7.1 处理标准窗口消息 7.1.1 处理WM_CREATE消息 7.1.2 处理WM_DESTROY消息 7.1.3 处理WM_NCDESTORY消息 7.1.4 处理WM_CLOSE消息 7.2 处理命令消息 7.3 处理反射消息 7.4 投递和发送消息 7.4.1 投递和发送消息的概念 7.4.2 postMessage函数 7.4.3 SendMessage函数 7.4.4 SendMessage 7.5 SendNotifymessage和SendMessageCallback 7.6 使用自定义命令 7.7 使用自定义窗口消息 7.8 使用登记消息 7.9 处理线程消息 7.10 跨进程处理消息 7.11 消息钩子 7.11.1 钩子和过滤器 7.11.2 钩子的类型和范围 7.11.3 安装和解除消息钩子 7.11.4 使用线程范围和钩子实例 7.11.5 使用全局钩子实例 7.12 小结 第8章 对话框 8.1 对话框的生存期 8.1.1 对话框的创建 8.1.2 对话框的初始化 8.1.3 对话框的消息处理 8.1.4 对话框的结束 8.2 数据交换和数据验证 8.3 使用通用对话框 8.3.1 基本用法 8.3.2 定制通用对话框 8.4 运行时修改对话框 8.5 作为子窗口的对话框 8.6 HTML对话框 8.6.1 HTML资源 8.6.2 让HTML全部可见 8.6.3 混合HTML元素和窗口控件设计对话框 8.6.4 HTML消息处理 8.6.5 HTML元素和对话框成员间的数据交换 8.6.6 导航 8.6.7 基于HTML对话框的实用实例 8.7 使用属性表 8.8 使用对话栏 8.8.1 创建 8.8.2 销毁 8.8.3 处理控件消息 8.8.4 访问对话栏成员 8.8.5 实例 8.9 小结 第9章 文档和视图 9.1 文档/视图结构 9.1.1 原理 9.1.2 为什么使用文档/视图结构 9.1.3 基于文档/视图结构的应用 9.2 文档/视图结构的创建 9.2.1 文档模板的创建 9.2.2 文档的创建 9.2.3 框架的创建 9.2.4 视图的创建 9.2.5 文档/视图的初始化 9.3 深入文档模板 9.3.1 文档模板管理器 9.3.2 文档模板的创建 9.3.3 管理文档 9.3.4 其他 9.4 文档对象 9.4.1 文档的初始化 9.4.2 保存文档 9.4.3 设置修改标志和保存修改 9.4.4 关闭文档 9.4.5 管理视图 9.4.6 文档的销毁 9.4.7 命令处理 9.4.8 文档的序列化 9.4.9 设计文档的成员 9.5 视图对象 9.5.1 视图的初始化 9.5.2 视图和文档间的数据交换 9.5.3 视图的绘制 9.5.4 视图的销毁 9.6 框架窗口 9.6.1 初始化 9.6.2 和文档的交互 9.6.3 和视图的交换 9.6.4 命令处理 9.6.5 确定视图大小 9.6.6 为框架添加其他子控件 9.7 打印 9.7.1 文档/视图框架中的打印流程 9.7.2 自定义打印 9.7.3 打印预览 9.8 小结 第10章 深入视图 10.1 拆分 10.1.1 视图的创建 10.1.2 拆分窗口的命令处理 10.1.3 对拆分子窗口的管理 10.1.4 绘制 10.2 流动和缩放 10.2.1 滚动 10.2.2 缩放视图 10.3 控件视图 10.4 窗体视图 10.5 基于HTML的视图——CDHtmlView 10.5.1 加载HTML 10.5.2 事件处理 10.5.3 在新的文档中打开HTML 10.6 小结 第11章 GDI绘图 11.1 GDI绘图的编程模型 11.1.1 逻辑空间和设备空间 11.1.2 设备上下文 11.1.3 GDI对象 11.1.4 坐标变量和坐标映射 11.2 绘制图形 11.2.1 画线 11.2.2 绘制矩形 11.2.3 绘制椭圆 11.2.4 绘制弧线 11.2.5 绘制多边形 11.2.6 绘制贝济埃样条 11.2.7 使用路径 11.2.8 填充 11.2.9 区域 11.3 使用图像 11.3.1 位图的结构 11.3.2 位图类型 11.3.3 图像初始化和销毁 11.3.4 从文件加载图像文件 11.3.5 将图像保存为文件 11.3.6 图像的显示、裁剪和缩放 11.3.7 图像处理 11.4 小结 第12章 GDI+绘图 12.1 GDI+编程模型 12.1.1 GDI+的组成 12.1.2 GDI+的功能 12.1.3 GDI+编程步骤 12.1.4 新增功能 12.2 绘制基数样条曲线 12.3 独立的路径对象 12.4 Alpha混合 12.4.1 在钢笔中应用Alpha混合 12.4.2 在画刷中应用Alpha混合 12.4.3 对图像应用Alpha混合 12.5 渐变 12.5.1 线性渐变 12.5.2 轨迹渐变 12.6 变换和矩形对象 12.7 使用图像 12.8 小结 第13章 进程和线程 13.1 基本理论 13.1.1 什么是进程 13.1.2 什么是线程 13.1.3 进程地址空间 13.1.4 线程的生命周期 13.2 创建子进程 13.3 虚拟内存管理 13.4 进程间内存共享 13.5 用户界面线程 13.5.1 创建 13.5.2 退出 13.5.3 线程间通信 13.6 辅助线程 13.6.1 创建 13.6.2 退出 13.6.3 线程间通信 13.7 线程安全措施 13.7.1 需要采取线程安全措施的对象 13.7.2 线程安全的实现 13.8 小结 第14章 动态链接库 14.1 简介 14.1.1 DLL的构成 14.1.2 到DLL的链接 14.1.3 DLL映射到进程空间 14.1.4 使用动态链接的好处 14.2 规则DLL创建及其使用 14.2.1 创建规则DLL 14.2.2 规则DLL的使用 14.2.3 输出全局变量 14.2.4 输出类 14.2.5 输出进程间共享的数据 14.3 进程状态、模块状态和线程状态 14.3.1 线程局部存储 14.3.2 模块状态 14.4 创建和使用扩展DLL 14.4.1 创建 14.4.2 使用 14.5 DLL中的资源 14.5.1 资源的名字和类型 14.5.2 确定定义资源的模块 14.5.3 在模块中查找、加载资源 14.5.4 枚举资源 14.5.5 修改可执行文件的资源 14.5.6 纯资源DLL 14.5.7 附属DLL 14.6 小结 第15章 COM组件编程 15.1 COM基础知识 15.1.1 COM中的接口 15.1.2 COM对象的线程模型 15.1.3 进程内组件和进程间组件 15.1.4 COM库 15.1.5 COMK 的功能复用 15.2 IUnknown接口在MFC中的实现 15.2.1 内部类 15.2.2 接口映射类 15.2.3 聚合的实现 15.3 类厂及其MFC实现 15.3.1 ColeObjectFactory类 15.3.2 全局类厂链 15.3.3 类厂的注册/反注册 15.3.4 类厂对象的创建 15.3.5 类厂对象创建COM对象 15.3.6 为CCmdTarget添加类厂支持 15.4 用MFC实现简单的COM组件 15.4.1 创建支持自动化的规则DLL 15.4.2 定义接口文件 15.4.3 实现被聚合的COM组件 15.4.4 实现包容组件 15.4.5 编译、注册COM组件 15.4.6 创建一个对话框应用 15.5 双重接口 15.5.1 调度表 15.5.2 COleDispatchImpl 15.5.3 m_xDispatch成员 15.5.4 输出IDispatch接口 15.5.5 双重接口的客户端 15.5.6 范例 15.6 可连接对象及其MFC实现 15.6.1 用CCmdTarget实现可连接对象 15.6.2 可连接对象的客户端 15.7 封送的应用:在线程间传递接口指针 15.8 小结 第16章 .NET应用开发 16.1 C++托管扩展简介 16.1.1 什么是.NET平台 16.1.2 托管C++中的类型 16.1.3 托管C++的用途 16.1.4 为什么MFC应用添加托管支持 16.1.5 使用.NET类型 16.1.6 实例:创建手管类型 16.1.7 装箱:值类型到引用类型的转化 16.1.8 托管类型和非托管类型的混用 16.1.9 固定指针 16.2 常用的托管C++编程技能 16.2.1 声明托管类 16.2.2 声明值类型的托管类型 16.2.3 添加属性 16.2.4 定义及实现接口 16.2.5 托管数组 16.2.6 处理异常 16.2.7 定义和使用委托 16.2.8 创建对象 16.2.9 对象的序列化和反序列化 16.2.10 用ADO.NET访问数据库 16.2.11 断方和条件编译 16.3 具有双重接口功能的规则DLL 16.4 典型托管应用开发 16.4.1 控制台应用 16.4.2 类库应用 16.4.3 窗体应用 16.5 小结
《仙剑奇侠传》之父姚壮宪热情推荐,技术作家孟岩高度评价! 云风也是我在中国最佩服的游戏开发者。看了云风的研发历程,我觉得就是一部中国的游戏程序史,从最早的 Z80 , 6502 , PC8088 , 286 , 386…DOS ,保护模式, Assembler 到 C++ 的整个发展轨迹。这本书可以说横跨了游戏程序的过去、现在和未来。 书中传达的不仅是一些实用的技术经验,更是传达一种理念——虽然研发的环境随着时代而变,但研发的精神是不变的,那就是“在实践中积累”。 ——《仙剑奇侠传》之父 姚壮宪 之前我经常奇怪,云风还非常年轻,他程序思想中的那种老练的智慧是从何处得来的呢?读完这本书之后,我终于明白,还是那句话:“无他,唯手熟耳”。 面对这沉甸甸的作品,我确实感到,这是云风用心写的书。用心写的书,当然出色。 ——技术作家 孟岩 我现在是中国并不成熟的游戏制作行业中的一员,游戏给了我太多,我告诉自己需要做一点事情。分享知识和经验是我的义务,别无它。 ——云风 内容简介 本书忠实地记录了作者十余年来对游戏编程的所思、所感、所悟。全书按照作者本人学习和实践的过程,带着读者从基础的计算机知识到高级的编程技术,从非常专业的汇编优化到非常实际的项目管理进行了一次游戏开发的全景探索。 本书不仅适合游戏开发者阅读,也会给所有的开发者和程序爱好者带来启示。 作者简介 云风,时年二十七岁。自幼学习编程,十数年从未间断,对程序设计有所领悟。大学时代开发的游戏图像引擎“风魂”曾用于多家游戏公司的游戏项目。参与过《大话西游》系列、《梦幻西游》、《网易泡泡游戏》的开发。现从事新一代网络游戏引擎的研究与开发,并在游戏模式上做一些新的尝试。 性格开朗,兴趣广泛,好交友,绝非沉浸在计算机世界中的书呆子。国学、历史书籍常备案头,以先贤之教诲修其心;休息时常作户外运动,尤其喜爱攀岩。 目录 第1章 计算机,游戏,我 1 1.1 计算机 2 1.2 计算机游戏 3 1.3 计算机与我 7 1.3.1 启蒙 7 1.3.2 编程 9 第2章 算法,程序的灵魂 13 2.1 程序=算法+数据结构 14 2.1.1 算法 15 2.1.2 数据结构 17 2.2 搜索算法 23 2.2.1 地图寻路问题 23 2.2.2 博弈问题 27 2.2.3 更为广泛的运用 28 2.3 智能算法 29 2.3.1 遗传算法(Genetic Algorithm) 29 2.3.2 模拟退火算法(Simulated Annealing) 31 2.3.3 禁忌搜索(Tabu Search) 33 2.3.4 人工神经网络 (Artificial Neural Network) 34 2.4 优化 36 2.4.1 质数问题 36 1.4.2 俄罗斯方块竞赛 37 2.5 Apple II上的编程之路 39 第3章 编程语言 45 3.1 C 语言 46 3.2 BASIC 50 3.3 C++ 51 3.4 汇编语言 54 3.4.1 概述 55 3.4.2 程序的本质 57 3.4.3 寄存器 58 3.4.4 寻址方式 60 3.4.5 汇编指令 61 3.4.6 C/C++ 语言和汇编 62 3.4.7 小结 63 3.5 其他语言 63 3.5.1 Forth 63 3.5.2 Lisp 64 3.5.3 Java 64 3.5.4 Python、Lua、更多 65 第4章 前Windows 时代 67 4.1 386保护模式 68 4.2 VGA 到VESA 70 4.2.1 超越 BGI 70 4.2.2 VGA 72 4.2.3 VESA 标准 72 4.2.4 花絮 74 4.3 保护模式下的开发工具 75 4.4 闲话 Allegro 81 4.4.1 用C与汇编写成的程序库 81 4.4.2 BITMAP 82 4.4.3 Sprite 85 4.4.4 几何图形和 3D 89 4.4.5 数据文件 91 4.4.6 声音 92 4.4.7 其他的部分 93 4.4.8 小结 94 4.5 cfido 中国惠多网 94 第5章 Windows 编程 101 5.1 Windows编程入门 104 5.1.1 Windows版本综述 105 5.1.2 操作系统的核心 107 5.1.3 Windows API和DLL 110 5.1.4 COM 111 5.1.5 Windows的窗口和消息处理与传递 114 5.1.6 Windows GDI 125 5.2 控制游戏的速度 130 5.3 浅谈MFC 132 5.4 小结 132 第6章 汇编优化 135 6.1 浅谈代码优化 138 6.2 并不仅仅是汇

20

社区成员

发帖
与我相关
我的任务
社区描述
微软技术社区为中国的开发者们提供一个技术干货传播平台,传递微软全球的技术和产品最新动态,分享各大技术方向的学习资源,同时也涵盖针对不同行业和场景的实践案例,希望可以全方位地帮助你获取更多知识和技能。
windowsmicrosoft 个人社区
社区管理员
  • 微软技术分享
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧