Loading...

文章背景图

阶段四:Windows开发

a0yark a0yark
|
2025-12-03
|
0
|
-
|
- min
|

阶段四:Windows开发

📅 创建日期: 2025-01-XX
⏱️ 预计学时: 8-10 周
🎯 学习目标: 掌握 Win32 API 编程、窗口消息机制、进程线程管理
📋 前置要求: [[阶段三:进阶编程]]
🔗 返回: [[逆向与驱动开发学习路径(详细版)]]


📚 本阶段内容概览

  • [[#4.1 Win32 API编程|4.1 Win32 API编程]]
    • [[#4.1.1 窗口与消息|窗口与消息]]
    • [[#4.1.2 进程与线程|进程与线程]]
    • [[#4.1.3 内存管理|内存管理]]
    • [[#4.1.4 文件与注册表|文件与注册表]]
    • [[#4.1.5 同步机制|同步机制]]
  • [[#4.2 MFC基础|4.2 MFC基础]]
  • [[#4.3 逆向中的Windows知识|4.3 逆向中的Windows知识]]

4.1 Win32 API编程

4.1.1 窗口与消息

📝 学习笔记

窗口创建流程

#include <Windows.h>

// 窗口过程函数
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
    switch (msg) {
        case WM_CREATE:
            // 窗口创建时
            return 0;
        case WM_PAINT: {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hWnd, &ps);
            TextOut(hdc, 10, 10, L"Hello Win32!", 12);
            EndPaint(hWnd, &ps);
            return 0;
        }
        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
    }
    return DefWindowProc(hWnd, msg, wParam, lParam);
}

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR, int nCmdShow) {
    // 1. 注册窗口类
    WNDCLASS wc = {};
    wc.lpfnWndProc = WndProc;
    wc.hInstance = hInst;
    wc.lpszClassName = L"MyWindowClass";
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    RegisterClass(&wc);

    // 2. 创建窗口
    HWND hWnd = CreateWindowEx(
        0, L"MyWindowClass", L"Win32 Window",
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT, 800, 600,
        NULL, NULL, hInst, NULL
    );

    // 3. 显示窗口
    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);

    // 4. 消息循环
    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return (int)msg.wParam;
}

常用窗口消息

消息 触发时机
WM_CREATE 0x0001 窗口创建
WM_DESTROY 0x0002 窗口销毁
WM_PAINT 0x000F 需要重绘
WM_COMMAND 0x0111 菜单/按钮点击
WM_KEYDOWN 0x0100 键盘按下
WM_LBUTTONDOWN 0x0201 鼠标左键按下
WM_TIMER 0x0113 定时器触发
WM_CLOSE 0x0010 关闭请求

[!tip] 逆向技巧
在逆向 GUI 程序时,搜索窗口过程中的 switch-case 结构,通常处理 WM_COMMAND 消息的分支包含关键业务逻辑。


4.1.2 进程与线程

📝 学习笔记

创建进程

STARTUPINFO si = { sizeof(si) };
PROCESS_INFORMATION pi;

// 创建新进程
BOOL result = CreateProcess(
    L"C:\\Windows\\notepad.exe",  // 程序路径
    NULL,                          // 命令行参数
    NULL, NULL,                    // 安全属性
    FALSE,                         // 不继承句柄
    0,                             // 创建标志
    NULL,                          // 环境变量
    NULL,                          // 当前目录
    &si, &pi
);

if (result) {
    printf("PID: %d\n", pi.dwProcessId);
    printf("TID: %d\n", pi.dwThreadId);
    
    // 等待进程结束
    WaitForSingleObject(pi.hProcess, INFINITE);
    
    // 关闭句柄
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);
}

创建线程

// 线程函数
DWORD WINAPI ThreadFunc(LPVOID param) {
    int* value = (int*)param;
    printf("Thread started with value: %d\n", *value);
    return 0;
}

// 创建线程
int param = 42;
HANDLE hThread = CreateThread(
    NULL,           // 安全属性
    0,              // 栈大小(0=默认)
    ThreadFunc,     // 线程函数
    &param,         // 参数
    0,              // 创建标志
    NULL            // 线程ID输出
);

// 等待线程结束
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);

进程 / 线程常用 API

API 功能
OpenProcess 打开已有进程
TerminateProcess 终止进程
GetCurrentProcess 获取当前进程伪句柄
GetCurrentProcessId 获取当前进程ID
CreateRemoteThread 在其他进程创建线程
SuspendThread/ResumeThread 挂起/恢复线程
GetThreadContext/SetThreadContext 获取/设置线程上下文

4.1.3 内存管理

📝 学习笔记

虚拟内存 API

// 在当前进程分配内存
LPVOID addr = VirtualAlloc(
    NULL,                    // 让系统选择地址
    4096,                    // 大小
    MEM_COMMIT | MEM_RESERVE,// 分配类型
    PAGE_READWRITE           // 保护属性
);

// 修改内存保护属性
DWORD oldProtect;
VirtualProtect(addr, 4096, PAGE_EXECUTE_READ, &oldProtect);

// 释放内存
VirtualFree(addr, 0, MEM_RELEASE);

跨进程内存操作

// 打开目标进程
HANDLE hProcess = OpenProcess(
    PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION,
    FALSE,
    targetPid
);

// 在目标进程分配内存
LPVOID remoteAddr = VirtualAllocEx(
    hProcess,
    NULL,
    4096,
    MEM_COMMIT | MEM_RESERVE,
    PAGE_EXECUTE_READWRITE
);

// 写入内存
SIZE_T written;
WriteProcessMemory(hProcess, remoteAddr, localData, dataSize, &written);

// 读取内存
SIZE_T read;
ReadProcessMemory(hProcess, remoteAddr, localBuffer, bufferSize, &read);

// 释放
VirtualFreeEx(hProcess, remoteAddr, 0, MEM_RELEASE);
CloseHandle(hProcess);

内存保护属性

属性 说明
PAGE_NOACCESS 0x01 禁止访问
PAGE_READONLY 0x02 只读
PAGE_READWRITE 0x04 读写
PAGE_EXECUTE 0x10 可执行
PAGE_EXECUTE_READ 0x20 可执行+可读
PAGE_EXECUTE_READWRITE 0x40 可执行+读写
PAGE_GUARD 0x100 保护页(访问触发异常)

[!warning] 安全提示
修改其他进程的内存需要相应权限,且可能被安全软件拦截。在逆向分析时,这些 API 是常见的代码注入技术基础。


4.1.4 文件与注册表

📝 学习笔记

文件操作

// 创建/打开文件
HANDLE hFile = CreateFile(
    L"test.txt",
    GENERIC_READ | GENERIC_WRITE,
    FILE_SHARE_READ,
    NULL,
    CREATE_ALWAYS,     // 创建新文件,覆盖已有
    FILE_ATTRIBUTE_NORMAL,
    NULL
);

// 写入文件
const char* data = "Hello World";
DWORD written;
WriteFile(hFile, data, strlen(data), &written, NULL);

// 设置文件指针
SetFilePointer(hFile, 0, NULL, FILE_BEGIN);

// 读取文件
char buffer[256];
DWORD read;
ReadFile(hFile, buffer, sizeof(buffer), &read, NULL);

// 关闭
CloseHandle(hFile);

内存映射文件

// 创建文件映射
HANDLE hFile = CreateFile(L"large.dat", GENERIC_READ, FILE_SHARE_READ, 
                          NULL, OPEN_EXISTING, 0, NULL);
HANDLE hMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);

// 映射到内存
LPVOID data = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);

// 使用数据...
BYTE* bytes = (BYTE*)data;

// 解除映射
UnmapViewOfFile(data);
CloseHandle(hMapping);
CloseHandle(hFile);

注册表操作

HKEY hKey;

// 创建/打开键
RegCreateKeyEx(
    HKEY_CURRENT_USER,
    L"Software\\MyApp",
    0, NULL,
    REG_OPTION_NON_VOLATILE,
    KEY_ALL_ACCESS,
    NULL,
    &hKey,
    NULL
);

// 写入值
DWORD value = 42;
RegSetValueEx(hKey, L"Setting", 0, REG_DWORD, (BYTE*)&value, sizeof(value));

// 读取值
DWORD data, size = sizeof(data);
RegQueryValueEx(hKey, L"Setting", NULL, NULL, (BYTE*)&data, &size);

// 关闭
RegCloseKey(hKey);

4.1.5 同步机制

📝 学习笔记

临界区 (Critical Section)

CRITICAL_SECTION cs;

// 初始化
InitializeCriticalSection(&cs);

// 进入临界区
EnterCriticalSection(&cs);
// 临界区代码...
LeaveCriticalSection(&cs);

// 尝试进入(非阻塞)
if (TryEnterCriticalSection(&cs)) {
    // 获得锁
    LeaveCriticalSection(&cs);
}

// 删除
DeleteCriticalSection(&cs);

互斥量 (Mutex)

// 创建互斥量
HANDLE hMutex = CreateMutex(NULL, FALSE, L"Global\\MyMutex");

// 等待获取
WaitForSingleObject(hMutex, INFINITE);

// 释放
ReleaseMutex(hMutex);

// 关闭
CloseHandle(hMutex);

事件 (Event)

// 创建事件
HANDLE hEvent = CreateEvent(
    NULL,   // 安全属性
    TRUE,   // 手动重置
    FALSE,  // 初始无信号
    NULL    // 名称
);

// 线程A: 等待事件
WaitForSingleObject(hEvent, INFINITE);

// 线程B: 触发事件
SetEvent(hEvent);

// 重置事件(手动重置时需要)
ResetEvent(hEvent);

同步对象对比

对象 跨进程 特点
CriticalSection 最快,仅进程内
Mutex 可跨进程,支持超时
Event 信号通知机制
Semaphore 计数器,控制并发数

4.2 MFC基础

📝 学习笔记

MFC 程序结构

// 应用程序类
class CMyApp : public CWinApp {
public:
    virtual BOOL InitInstance() {
        CMyFrame* pFrame = new CMyFrame();
        pFrame->Create(NULL, _T("MFC Window"));
        pFrame->ShowWindow(SW_SHOW);
        m_pMainWnd = pFrame;
        return TRUE;
    }
};

// 框架窗口类
class CMyFrame : public CFrameWnd {
    DECLARE_MESSAGE_MAP()
public:
    afx_msg void OnPaint();
    afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
};

// 消息映射
BEGIN_MESSAGE_MAP(CMyFrame, CFrameWnd)
    ON_WM_PAINT()
    ON_WM_LBUTTONDOWN()
END_MESSAGE_MAP()

// 全局应用对象
CMyApp theApp;

MFC 消息映射宏

用途
ON_WM_* 标准Windows消息
ON_COMMAND 菜单/按钮命令
ON_BN_CLICKED 按钮点击
ON_EN_CHANGE 编辑框内容改变
ON_NOTIFY 通用通知消息

[!important] 逆向 MFC 程序
MFC 程序的消息映射表在二进制中有特定结构,可通过分析 AFX_MSGMAP 结构定位消息处理函数。


4.3 逆向中的Windows知识

📝 学习笔记

PEB/TEB 结构

// TEB (Thread Environment Block) 关键字段
struct TEB {
    NT_TIB NtTib;                    // +0x000
    PVOID EnvironmentPointer;        // +0x038
    CLIENT_ID ClientId;              // +0x040 (进程ID, 线程ID)
    // ...
    PPEB ProcessEnvironmentBlock;    // +0x060
    // ...
};

// PEB (Process Environment Block) 关键字段  
struct PEB {
    BOOLEAN InheritedAddressSpace;   // +0x000
    BOOLEAN ReadImageFileExecOptions;// +0x001
    BOOLEAN BeingDebugged;           // +0x002  <-- 反调试检测
    // ...
    PPEB_LDR_DATA Ldr;              // +0x018  <-- 模块列表
    PRTL_USER_PROCESS_PARAMETERS ProcessParameters; // +0x020
    // ...
    DWORD NtGlobalFlag;             // +0x0BC  <-- 调试标志
};

获取模块列表

// 通过PEB遍历加载的模块
void EnumModules() {
    PPEB peb = (PPEB)__readgsqword(0x60);
    PPEB_LDR_DATA ldr = peb->Ldr;
    
    PLIST_ENTRY head = &ldr->InLoadOrderModuleList;
    PLIST_ENTRY curr = head->Flink;
    
    while (curr != head) {
        PLDR_DATA_TABLE_ENTRY entry = 
            CONTAINING_RECORD(curr, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
        
        wprintf(L"Base: %p, Name: %s\n", 
                entry->DllBase, 
                entry->BaseDllName.Buffer);
        
        curr = curr->Flink;
    }
}

PE 文件解析要点

// 获取DOS头
PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)moduleBase;

// 获取NT头
PIMAGE_NT_HEADERS ntHeaders = (PIMAGE_NT_HEADERS)
    ((BYTE*)moduleBase + dosHeader->e_lfanew);

// 获取导出表
DWORD exportRVA = ntHeaders->OptionalHeader.DataDirectory
    [IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
PIMAGE_EXPORT_DIRECTORY exportDir = (PIMAGE_EXPORT_DIRECTORY)
    ((BYTE*)moduleBase + exportRVA);

// 遍历导出函数
DWORD* names = (DWORD*)((BYTE*)moduleBase + exportDir->AddressOfNames);
for (DWORD i = 0; i < exportDir->NumberOfNames; i++) {
    char* name = (char*)((BYTE*)moduleBase + names[i]);
    printf("Export: %s\n", name);
}

✅ 阶段检查点

Win32 API检查

  • [ ] 能独立创建Windows窗口程序
  • [ ] 理解消息循环和窗口过程
  • [ ] 掌握进程创建和线程创建
  • [ ] 熟悉VirtualAlloc/VirtualProtect等内存API
  • [ ] 能进行跨进程内存读写
  • [ ] 了解各种同步对象的使用场景

Windows内部结构检查

  • [ ] 理解PEB/TEB结构
  • [ ] 能通过PEB遍历模块列表
  • [ ] 了解PE文件结构基础
  • [ ] 能解析导入表/导出表

MFC基础检查

  • [ ] 理解MFC程序结构
  • [ ] 了解消息映射机制
  • [ ] 能识别MFC程序的特征

📖 学习资料

资源类型 名称 说明
📕 书籍 Windows核心编程 (第5版) Windows开发圣经
📕 书籍 Windows via C/C++ 深入Windows编程
📕 书籍 Programming Windows (Petzold) 经典Win32教程
🌐 网站 MSDN文档 官方API参考
🌐 网站 ReactOS源码 Windows开源实现参考

🔗 导航

← [[阶段三:进阶编程]] | [[逆向与驱动开发学习路径(详细版)| 返回主目录]] | [[阶段五:核心逆向技术]] →

分享文章

未配置分享平台

请在主题设置中启用分享平台

评论