微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Windows提高_1.2进程、模块

进程

  • 什么是进程?

    • 通俗的来讲,进程就是一个运行中的程序,最少包含一个虚拟空间,通常是 4 GB大小,一组提供数据和代码的模块,通产是 dll 和 exe 文件一个进程内核对象和最少一个线程。

    • 进程类似于一个容器,提供给线程一块空间和需要执行的操作,线程用于进行执行。

  • 什么是模块?

    • 提供代码和数据的可执行文件,主要有 exe 和 dll。可以通过 VS 的调试->窗口->模块进行查看

       

       

  • 创建进程

    // 结构体用于设置进程的初始化信息
    STARTUPINFO StartupInfo = { sizeof(STARTUPINFO) };
    ​
    // 用于保存被创建的进程的 id 和句柄
    PROCESS_informatION ProcessInfomation = { 0 };
    ​
    // 创建第一个进程,使用 CreateProcess
    BOOL IsOk = CreateProcess(
        L"C:\\Windows\\System32\\calc.exe",         // 用于创建进程的 exe 路径
        NULL,                                       // 命令行参数
        NULL,                                       // 进程的安全属性, NULL 表示使用认值
        NULL,                                       // 线程的安全属性
        FALSE,                                      // 子进程是否拥有父进程的句柄
        NULL,                                       // 进程创建标志,(挂起\调试\在新窗口打开)
        NULL,                                       // 环境变量
        NULL,                                       // 程序的工作目录)
        &StartupInfo,                               // 输入的进程设置
        &ProcessInfomation);                        // 输出的进程信息
    ​
    // 为了防止泄露关闭进程和线程句柄
    CloseHandle(ProcessInfomation.hThread);
    CloseHandle(ProcessInfomation.hProcess);
    ​
    // * 创建进程的时候,创建出的进程和线程的句柄会被返回,所以[当前进程]中
    // 线程句柄和进程句柄都被打开了一次。[被创建]的进程中拥有自己的进程内
    // 核对象和线程内核对象。*
    ​
    // 还有 n 多的创建进程的方式,比如 system,ShellExecute, Winexec
    system("start calc.exe");

     

  • 操作进程

    // 0. 通过窗口句柄动态的查找 pid
    DWORD Pid = 0;
    HWND hWnd = FindWindow(NULL, L"无标题 - 记事本");
    GetwindowThreadProcessId(hWnd, &Pid);
    ​
    // 1. 获取进程内核对象的句柄
    HANDLE ProcessHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, Pid);
    ​
    // 2. 结束其它进程,需要一定的权限
    TerminateProcess(ProcessHandle, 0);
    ​
    // 3. 手动的关闭内核对象
    CloseHandle(ProcessHandle);
    ​
    // 4. 直接关闭自己的进程
    ExitProcess(-1);

     

  • 遍历进程

    // 1. 包含创建快照需要用到的头文件 TlHelp32.h 
    #include <TlHelp32.h>
    ​
    // 2. 开始拍摄快照,第一个参数指定快照的类型
    HANDLE Snapshot = Createtoolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    ​
    // 3. 判断快照是否拍摄成功
    if (Snapshot == INVALID_HANDLE_VALUE)
    {
        MessageBox(NULL, L"进程快照创建失败", L"警告", MB_OK | MB_ICONERROR);
        ExitProcess(-1);
    }
    ​
    // 4. 创建结构体用于保存遍历的进程信息
    PROCESSENTRY32 ProcessInfo = { sizeof(PROCESSENTRY32) };
    ​
    // 5. 尝试从快照中获取一个进程
    if (Process32First(Snapshot, &ProcessInfo))
    {
        do {
            // 6. 输出进程的信息
            printf("ProcessName: %ls", ProcessInfo.szExeFile);
    ​
            // DWORD   th32ProcessID;           // 进程的 id
            // DWORD   cntThreads;              // 线程的数量
            // DWORD   th32ParentProcessID;     // 父进程 id
            // DWORD   dwFlags;                 // 线程的标志
            // CHAR    szExeFile[MAX_PATH];     // 进程的名字
    ​
            // 6.1 以查询的权限打开进程句柄
            HANDLE Handle = OpenProcess(PROCESS_QUERY_informatION,
                                        FALSE, ProcessInfo.th32ProcessID);
    ​
            // 6.2 获取进程文件所在的路径
            DWORD PathSize = MAX_PATH;
            WCHAR Path[MAX_PATH] = { 0 };
            QueryFullProcessImageName(Handle, 0, Path, &PathSize);
    ​
            // 6.3 输出文件的路径
            printf("\t%ls\n", Path);
    ​
            // 6.4 关闭句柄
            CloseHandle(Handle);
    ​
            // 7. 继续遍历下一个进程信息
        } while (Process32Next(Snapshot, &ProcessInfo));
    }

     

  • 遍历模块

    // 1. 包含创建快照需要用到的头文件 TlHelp32.h 
    #include <TlHelp32.h>
    ​
    int main()
    {
        // 2. 开始拍摄快照,第一个参数指定快照的类型,参数 2 表示某一个进程的模块
        HANDLE Snapshot = Createtoolhelp32Snapshot(TH32CS_SNAPMODULE, 1360);
    ​
        // 3. 判断快照是否拍摄成功
        if (Snapshot == INVALID_HANDLE_VALUE)
        {
            MessageBox(NULL, L"模块快照创建失败", L"警告", MB_OK | MB_ICONERROR);
            ExitProcess(-1);
        }
    ​
        // 4. 创建结构体用于保存遍历的进程信息
        MODULEENTRY32 ModuleInfo = { sizeof(MODULEENTRY32) };
    ​
        // 5. 尝试从快照中获取一个模块
        if (Module32First(Snapshot, &ModuleInfo))
        {
            do {
                // 6. 输出模块的信息
    ​
                // DWORD   th32ProcessID;       // 父进程 id
                // HMODULE hModule;             // 模块句柄,模块在虚拟空间的起始位置
                // char    szModule[];          // 模块的名称
                // char    szExePath[MAX_PATH]; // 模块的路径
    ​
                printf("%ls: %ls\n", ModuleInfo.szModule, ModuleInfo.szExePath);
    ​
                // 7. 继续遍历下一个模块信息
            } while (Module32Next(Snapshot, &ModuleInfo));
        }
    ​
        return 0;
    }

     

  •  

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐