吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 6305|回复: 5
收起左侧

[其他转载] [WIN32]简单的办法获取父进程信息(PID|进程名)

[复制链接]
lovingxiaobing 发表于 2019-2-9 13:16


硬核开场~~~~


下面是例子用到的相关的函数:
。NtQueryInformationProcess
。QueryFullProcessImageName
。GetProcessImageFileName
。OpenProcess
。GetCurrentProcessId
。PathStripPath


这些函数以及参数的解释在MSDN上都可以查到,虽然有一个“NtQueryInformationProcess”是“未公开函数”,但是在头文件"winternl.h"中提供了它的声明。


NtQueryInformationProcess 函数用到了一个重要的结构:
[C++] 纯文本查看 复制代码
typedef struct _PROCESS_BASIC_INFORMATION {
    PVOID Reserved1;
    PPEB PebBaseAddress;
    PVOID Reserved2[2];
    ULONG_PTR UniqueProcessId;
    PVOID Reserved3;
} PROCESS_BASIC_INFORMATION;
typedef PROCESS_BASIC_INFORMATION *PPROCESS_BASIC_INFORMATION;



经过前辈的探索,得知结构体中的"Reserved3"字段就是父进程的PID
得到父进程PID后我们再打开这个进程就可以获取到这个进程的相关信息了。
在使用QueryFullProcessImageName、NtQueryInformationProcess或者GetProcessImageFileName时,要求用PROCESS_QUERY_INFORMATION的方式打开


因为这只是获取信息,我们不希望去打扰人家。。。
但是“QueryFullProcessImageName”和“GetProcessImageFileName”这两个函数的要求时必须用PROCESS_QUERY_INFORMATION PROCESS_QUERY_LIMITED_INFORMATION的方式打开的进程句柄。


[C++] 纯文本查看 复制代码
#ifndef UNICODE
#define UNICODE
#endif // UNICODE
#ifndef _UNICODE
#define _UNICODE
#endif // _UNICODE

#include <stdio.h>
#include <tchar.h>
#include <Windows.h>
#include <winternl.h>
#include <Shlwapi.h>

/*
/// GetProcessImageFileName 函数
//windows7: kernel32.dll|.lib
// windows r8+: psapi.dll|.lib
#include <psapi.h>
*/

#pragma comment(lib, "shlwapi.lib")

#define SETVALUEFROMPOINTER(p, v) (*p=v)
#if defined(UNICODE) || defined(_UNICODE)
#define OutPutStr(f, v) wprintf_s(L##f, v)
#else
#define OutPutStr(f, v) printf_s(f, v)
#endif


DWORD GetParentPIDAndName( DWORD ProcessID, LPTSTR lpszBuffer_Parent_Name, PDWORD ErrCodeForBuffer );

int main(int argc, const char* argv[]) {
    DWORD pid;
    TCHAR buf[BUFSIZ] = {0};
    DWORD err_code;

    pid = GetParentPIDAndName(GetCurrentProcessId(), buf, &err_code);

    if ( err_code ) {
        fprintf(stderr, "GetProcessName--> err code: %lu\n", err_code);
    }

    OutPutStr("ParentProcessPID: %lu\n", pid);
    OutPutStr("ParentProcessFullName: %s\n", buf);
    PathStripPath(buf);
    OutPutStr("ParentProcessName: %s\n", buf);

    return 0;
}

typedef
__kernel_entry NTSTATUS
(NTAPI*NQIP)(
    IN HANDLE ProcessHandle,
    IN PROCESSINFOCLASS ProcessInformationClass,
    OUT PVOID ProcessInformation,
    IN ULONG ProcessInformationLength,
    OUT PULONG ReturnLength OPTIONAL
    );

DWORD GetParentPIDAndName( DWORD ProcessID, LPTSTR lpszBuffer_Parent_Name, PDWORD ErrCodeForBuffer ) {
    /// 打开给定进程PID
    HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, ProcessID);
    if ( !ProcessID ) {
        DWORD err_code = GetLastError();
        fprintf_s(stderr, "[OpenProcess]err code: %lu\n", err_code);
        return 0;
    }

    /// 下面是获取函数 NtQueryInformationProcess 的函数指针
    HMODULE hNtdll = GetModuleHandle(_T("ntdll.dll"));
    if ( !hNtdll ) {
        DWORD err_code = GetLastError();
        fprintf_s(stderr, "[GetModuleHandle]err code: %lu\n", err_code);
        CloseHandle(hProcess);
        return 0;
    }

    NQIP _NtQueryInformationProcess = (NQIP)GetProcAddress(hNtdll, "NtQueryInformationProcess");
    if ( !_NtQueryInformationProcess ) {
        DWORD err_code = GetLastError();
        fprintf_s(stderr, "[GetProcAddress]err code: %lu\n", err_code);
        CloseHandle(hProcess);
        return 0;
    }
    //***

    /// 获取打开的进程的进程进程信息
    PROCESS_BASIC_INFORMATION pbi;
    NTSTATUS status = _NtQueryInformationProcess(
                            hProcess,
                            ProcessBasicInformation,
                            (LPVOID)&pbi, sizeof(PROCESS_BASIC_INFORMATION),
                            NULL);

    DWORD dwParentID = 0;
    if ( NT_SUCCESS(status) ) {
        /// 结构体 PROCESS_BASIC_INFORMATION 的 "Reserved3"字段 是父进程的PID
        dwParentID = (LONG_PTR)pbi.Reserved3;

        if ( NULL != lpszBuffer_Parent_Name ) {
            HANDLE hParentProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, dwParentID);
            if ( hParentProcess ) {
                /// 用来接收进程文件名和路径的长度(必须!)
                DWORD bufs;
                /// 获取进程路径
                BOOL ret = QueryFullProcessImageName(hParentProcess, 0, lpszBuffer_Parent_Name, &bufs);
                if ( TRUE == ret )
					SETVALUEFROMPOINTER(ErrCodeForBuffer, 0);
                else
                    SETVALUEFROMPOINTER(ErrCodeForBuffer, GetLastError());

                /*
                /// 结果是DOS路径+文件名
                TCHAR buf[BUFSIZ];
                GetProcessImageFileName(hParentProcess, buf, BUFSIZ);
                cout << "[GetProcessImageFileName]: " << buf << endl;
                */
            }
            else {
                SETVALUEFROMPOINTER(ErrCodeForBuffer, GetLastError());
            }
            if ( hParentProcess )
                CloseHandle(hParentProcess);
        }
    }
    else {
        DWORD err_code = GetLastError();
        fprintf_s(stderr, "[NtQueryInformationProcess]err code: %lu\n", err_code);
    }

    CloseHandle(hProcess);
    return dwParentID;
}



QueryFullProcessImageName”和“GetProcessImageFileName”的区别是,前者反回的是我们平常常见且使用的win32路径,后者返回的是完整的设备路径。
GetProcessImageFileName”的介绍点击这儿

我编译运行的工具是codebocks+vs2010附带的编译工具(msvc)(cl-16.00.30319.01和link-10.00.30319.01)
codeblocks 运行一个程序是使用“cb_console_runner.exe”来启动的,所以它就是父进程。


结果:
result.PNG

完结撒花&#10048;&#10048;&#10048;&#10048;&#10048;&#10048;&#10048;&#10048;&#10048;

希望这篇文章能对有需要的朋友提供帮助。。。

免费评分

参与人数 1吾爱币 +3 热心值 +1 收起 理由
苏紫方璇 + 3 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

450046181 发表于 2019-2-9 13:47
大佬,请问这里怎么补救?
mistake.png
 楼主| lovingxiaobing 发表于 2019-2-9 13:58
本帖最后由 lovingxiaobing 于 2019-2-9 14:00 编辑
450046181 发表于 2019-2-9 13:47
大佬,请问这里怎么补救?

WTF? 您的VS没有找到这个函数。。。。
函数的MSDN文档:
https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-queryfullprocessimagenamea

如果是提示“连接不到外部符号”等类似的提示的话自己
#pragma comment(lib, "kernel32.lib")
如果还是找不到就自己用GetProcAddress导出来吧
这个函数再 “Kernel32.dll” 里
450046181 发表于 2019-2-9 14:30
头像被屏蔽
加油 发表于 2019-2-9 15:41
提示: 作者被禁止或删除 内容自动屏蔽
寻觅背影 发表于 2019-2-10 13:34 来自手机
谢谢分享
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-3-28 17:04

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表