3.2 DLL注入:远程APC异步注入

微软技术分享 微软最有价值专家
全栈领域优质创作者
博客专家认证
2023-11-21 09:10:56

APC(Asynchronous Procedure Call)异步过程调用是一种Windows操作系统的核心机制,它允许在进程上下文中执行用户定义的函数,而无需创建线程或等待OS执行完成。该机制适用于一些频繁的、短暂的或非常细微的操作,例如改变线程优先级或通知线程处理任务。在APC机制中,当某些事件发生时(例如文件IO,网络IO或定时器触发),这些事件将被操作系统添加到一个APC队列中,该队列绑定到执行线程。在下一次发生ALERTABLE的事件时(例如调用SleepEx或SignalObjectAndWait时),OS将弹出APC函数并在执行线程上下文中调用该函数,并在执行完毕后恢复线程执行。

APC机制与DLL注入的关系在于,可以使用APC机制将某些代码注入到另一个进程中,并由该进程执行。读者可以使用NtQueueApcThreadQueueUserAPC等函数将用户定义的函数添加到目标进程中的APC队列中,目标线程将在调用SleepExSignalObjectAndWait等函数时执行注入函数。但读者需要注意,注入函数必须是一个简短的、没有长时间阻塞的代码块,通常会加载DLL或者在目标线程中打开其他进程。

QueueUserAPC 函数允许将一个用户定义的函数添加到指定线程对应的APC队列中。该函数中的APC指异步过程调用,是指通过消息的方式将一段代码投递给线程去执行的一种机制,常用于处理异步操作,该函数的函数原型如下:

DWORD WINAPI QueueUserAPC(
  PAPCFUNC  pfnAPC,
  HANDLE    hThread,
  ULONG_PTR dwData
);

参数说明如下:

  • pfnAPC: 一个指向线程函数的函数指针,在本函数被执行时调用。
  • hThread: 目标线程的句柄。
  • dwData: 传递给线程函数的参数。

当调用QueueUserAPC函数时,该函数将在目标线程的APC队列中添加一个APC入口,APC的入口点为pfnAPC。当目标线程处于alertable状态时,即调用了如SleepEx等同于处理APCs的等待函数时,系统会将APC从队列中弹出,并调用pfnAPC。在DLL注入中,可以使用QueueUserAPC函数向目标进程内的线程的APC队列中插入一个我们定义的函数的指针,使该函数在目标线程执行时运行,从而实现DLL注入的目的。

APC一部注入原理可以总结为如下几个步骤,每个线程在可被唤醒时在其APC链中的函数将有机会执行被执行,每一个线程都具有一个APC链,那么只要在APC链中添加一个APC,就可以完成我们所需要的DLL注入的功能;

  • 1.WriteProcessMemory 将需要加载的DLL的完整路径写入目标进程空间
  • 2.获得LoadLibraryA函数的地址,当然也可以是LoadLibraryW函数的地址
  • 3.枚举目标进程中的所有线程,为每个线程添加一个APC函数,这样增加了注入成功的机会.

利用当线程被唤醒时APC中的注册函数会被执行的机制,并以此去执行我们的DLL加载代码,进而完成DLL注入的目的,通过APC注入的流程步骤大致如下;

  • 1.当进程里某个线程执行到SleepEx()或者WaitForSingleObjectEx()时,系统就会产生一个软中断
  • 2.当线程再次被唤醒时,此线程会首先执行APC队列中的被注册的函数
  • 3.利用QueueUserAPC()可以在软中断时向线程的APC队列插入一个函数指针,此处插入Loadlibrary()
  • 4.当插入函数被执行时则会加载Loadlibrary并将其指向的DLL模块插入到进程内

但读者需要注意一点,不论如何目标程序必须有执行SleepEx()或者WaitForSingleObjectEx()否则DLL不会加载,读者可自行做实验测试是否可以注入成功;

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

// 传入进程名称返回该进程PID
DWORD FindProcessID(LPCTSTR szProcessName)
{
    DWORD dwPID = 0xFFFFFFFF;
    HANDLE hSnapShot = INVALID_HANDLE_VALUE;
    PROCESSENTRY32 pe;
    pe.dwSize = sizeof(PROCESSENTRY32);
    hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, NULL);
    Process32First(hSnapShot, &pe);
    do
    {
        if (!_tcsicmp(szProcessName, (LPCTSTR)pe.szExeFile))
        {
            dwPID = pe.th32ProcessID;
            break;
        }
    } while (Process32Next(hSnapShot, &pe));
    CloseHandle(hSnapShot);
    return dwPID;
}

// APC注入
BOOL ApcInjectDll(DWORD dwPid, char* szDllName)
{
    // 得到文件完整路径长度
    int nDllLen = lstrlen(szDllName) + sizeof(char);

    // 打开目标进程
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);
    if (hProcess == NULL)
    {
        return FALSE;
    }

    // 在对端开辟内存空间
    PVOID pDllAddr = VirtualAllocEx(hProcess, NULL, nDllLen, MEM_COMMIT, PAGE_READWRITE);
    if (pDllAddr == NULL)
    {
        CloseHandle(hProcess);
        return FALSE;
    }

    // 根据不同位数写出DLL文件路径
#ifdef _WIN64
    size_t dwWriteNum = 0;
    WriteProcessMemory(hProcess, pDllAddr, szDllName, nDllLen, &dwWriteNum);
#else
    DWORD dwWriteNum = 0;
    WriteProcessMemory(hProcess, pDllAddr, szDllName, nDllLen, &dwWriteNum);
#endif
    CloseHandle(hProcess);

    THREADENTRY32 te = { 0 };
    te.dwSize = sizeof(THREADENTRY32);

    // 得到线程快照
    HANDLE handleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
    if (INVALID_HANDLE_VALUE == handleSnap)
    {
        CloseHandle(hProcess);
        return FALSE;
    }

    // 得到LoadLibraryA函数的地址
    FARPROC pFunAddr = GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
    DWORD dwRet = 0;

    // 得到第一个线程
    if (Thread32First(handleSnap, &te))
    {
        do
        {
            // 进程ID对比是否为传入的进程
            if (te.th32OwnerProcessID == dwPid)
            {
                // 打开线程,得到线程句柄
                HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, te.th32ThreadID);
                if (hThread)
                {
                    // 向线程插入APC队列
                    dwRet = QueueUserAPC((PAPCFUNC)pFunAddr, hThread, (ULONG_PTR)pDllAddr);

                    // 关闭句柄
                    CloseHandle(hThread);
                }
            }
            // 循环下一个线程
        } while (Thread32Next(handleSnap, &te));
    }

    // 关闭句柄
    CloseHandle(handleSnap);
    return TRUE;
}

int main(int argc, char *argv[])
{
    DWORD pid = FindProcessID("lyshark.exe");
    std::cout << "进程PID: " << pid << std::endl;

    bool flag = ApcInjectDll(pid, (char *)"d://hook.dll");
    std::cout << "注入状态: " << flag << std::endl;

    return 0;
}
...全文
7 回复 打赏 收藏 转发到动态 举报
写回复
用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

479

社区成员

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

微软技术社区为中国的开发者们提供一个技术干货传播平台,传递微软全球的技术和产品最新动态,分享各大技术方向的学习资源,同时也涵盖针对不同行业和场景的实践案例,希望可以全方位地帮助你获取更多知识和技能。

予力众生,成就不凡!微软致力于用技术改变世界,助力企业实现数字化转型。

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