november
驱动牛犊
驱动牛犊
  • 注册日期2002-11-10
  • 最后登录2005-05-30
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1187回复:0

请教一个关于进程的问题

楼主#
更多 发布于:2003-12-14 12:26
今天在驱网的技术资料里看到这篇文章,看了之后不太理解。。。在驱动里没有进程这个概念,,,文章里说的获取当前进程名到底是什么的进程名?


如何在驱动程序中得到当前进程的完整路径和进程名?
作者:朱艳辉
首先利用PsGetCurrentProcess或IoGetCurrentProcess函数得到当前进程的句柄,这个句柄是指向_EPROCESS结构的指针,_EPROCESS的结构如下:

typedef struct _EPROCESS
    {
    KPROCESS                     Pcb;
    NTSTATUS                     ExitStatus;
    KEVENT                       LockEvent;
    DWORD                        LockCount;
    QWORD                        CreateTime;
    QWORD                        ExitTime;
    PVOID                        LockOwner;
    DWORD                        UniqueProcessId;
    QWORD                        ActiveProcessLinks;
    DWORD                        QuotaPeakPoolUsage [2]; // NP, P
    DWORD                        QuotaPoolUsage     [2]; // NP, P
    DWORD                        PagefileUsage;
    DWORD                        CommitCharge;
    DWORD                        PeakPagefileUsage;
    DWORD                        PeakVirtualSize;
    QWORD                        VirtualSize;
    DWORD                        Vm [12];
    DWORD                        LastProtoPteFault;
    DWORD                        DebugPort;
    DWORD                        ExceptionPort;
    DWORD                        ObjectTable;
   DWORD                        Token;
    DWORD                        WorkingSetLock [8];
    DWORD                        WorkingSetPage;
    BOOLEAN                      ProcessOutswapEnabled;
    BOOLEAN                      ProcessOutswapped;
    BOOLEAN                      AddressSpaceInitialized;
    BOOLEAN                      AddressSpaceDeleted;
    DWORD                        AddressCreationLock [9];
    DWORD                        ForkInProgress;
    DWORD                        VmOperation;
    DWORD                        VmOperationEvent;
    DWORD                        PageDirectoryPte;
    QWORD                        LastFaultCount;
    PVOID                        VadRoot;
    DWORD                        VadHint;
    DWORD                        CloneRoot;
    DWORD                        NumberOfPrivatePages;
    DWORD                        NumberOfLockedPages;
    WORD                         w184;
    BOOLEAN                      ExitProcessCalled;
    BOOLEAN                      CreateProcessReported;
    HANDLE                       SectionHandle;
    struct _PEB                 *Peb;        // offset 0x1B0
    PVOID                        SectionBaseAddress;
    PVOID                        QuotaBlock;
    NTSTATUS                     LastThreadExitStatus;
    PROCESS_WS_WATCH_INFORMATION WorkingSetWatch;
    DWORD                        InheritedFromUniqueProcessId;
    ACCESS_MASK                  GrantedAccess;
    DWORD                        DefaultHardErrorProcessing;
    DWORD                        LdtInformation;
    DWORD                        VadFreeHint;
    DWORD                        VdmObjects;
    KMUTANT                      ProcessMutant;
    BYTE                         ImageFileName [16];        // offset 0x1FC
    DWORD                        VmTrimFaultValue [2];
    PVOID                        Win32Process;
    DWORD                        d1F8;
    DWORD                        d1FC;
    }
        EPROCESS,
     * PEPROCESS,
**PPEPROCESS;

从上面这个结构可以看出,进程名称就是ImageFileName,只要用_EPROCESS的基地址加上偏移地址0x1FC就可以得到进程名称的地址,代码如下:

char *ProcessName = (char*)PsGetCurrentProcess() + 0x1FC;
KdPrint((“Current Process Name: %s\\n”, ProcessName));

要得到完整路径还需要利用_EPROCESS结构中的_PEB结构指针来得到ProcessParameters的地址。ProcessParameters保存着进程的完整路径。可以通过DDK附带的WinDbg工具打开一个可执行程序,然后用!peb命令来显示_PEB的结构信息。如下所示:

―――――――――――――――――――――――――――――――――――――――
> !peb
Debugger extension library [F:\\WINNT\\system32\\ntsdexts] loaded
PEB at 7FFDF000
    InheritedAddressSpace:    No
    ReadImageFileExecOptions: No
    BeingDebugged:            Yes
    ImageBaseAddress:         00400000
    Ldr.Initialized: Yes
    Ldr.InInitializationOrderModuleList: 131f88 . 132998
    Ldr.InLoadOrderModuleList: 131ee0 . 132988
    Ldr.InMemoryOrderModuleList: 131ee8 . 132990
        00400000 D:\\NtSysInfo.exe
        77F80000 F:\\WINNT\\System32\\ntdll.dll
        77E60000 F:\\WINNT\\system32\\KERNEL32.dll
        77DF0000 F:\\WINNT\\system32\\USER32.dll
        77F40000 F:\\WINNT\\system32\\GDI32.DLL
        76AF0000 F:\\WINNT\\system32\\comdlg32.dll
        70BD0000 F:\\WINNT\\system32\\SHLWAPI.DLL
        77D90000 F:\\WINNT\\system32\\ADVAPI32.dll
        77D20000 F:\\WINNT\\system32\\RPCRT4.DLL
        71700000 F:\\WINNT\\system32\\COMCTL32.DLL
        77560000 F:\\WINNT\\system32\\SHELL32.DLL
        78000000 F:\\WINNT\\system32\\MSVCRT.DLL
        777C0000 F:\\WINNT\\System32\\WINSPOOL.DRV
    SubSystemData:     0
    ProcessHeap:       130000
    ProcessParameters: 20000
        WindowTitle:  \'D:\\NtSysInfo.exe\'
        ImageFile:    \'D:\\NtSysInfo.exe\'
        CommandLine:  \'\"D:\\NtSysInfo.exe\" \'
        DllPath:      \'D:\\;.;F:\\WINNT\\System32;F:\\WINNT\\system;F:\\WINNT;F:\\WINNT\\system32;F:\\WINNT;F:\\WINNT\\System32\\Wbem;J:\\WINDOWS;J:\\WINDOWS\\COMMAND;E:\\WINDOWS\\SYSTEM\\WBEM;J:\\WINDOWS;J:\\WINDOWS\\COMMAND;E:\\WINDOWS\\SYSTEM\\WBEM;J:\\WINDOWS;J:\\WINDOWS\\
COMMAND\'
        Environment:  0x10000


从WinDbg输出的PEB结构信息可以看出ProcessParameters的地址为0x20000,ImageFile字段就是进程的完整路径。那么PorcessParamters的地址又保存在_PEB结构的什么地方呢?_PEB结构的基地址为0x7ffdf000,通过WinDbg的“db 0x7ffdf000” 命令显示0x7ffdf000地址的信息可以发现ProcessParameters的地址保存在_PEB结构的0x10偏移量处,内容为0x20000。
继续用“db 0x20000”命令显示ProcessParameters地址的内容,偏移量为0x3C处保存完整路径的地址,0x3C处的内容如果是:0x20670,利用“db 0x20670”即可显示出完整路径。完整路径用UNICODE格式保存。
我们利用程序模拟上面的步骤则可以得到当前进程的完整路径,代码如下:

PCWSTR GetCurrentProcessFileName()
{
    DWORD dwAddress = (DWORD)PsGetCurrentProcess();
    if(dwAddress == 0 || dwAddress == 0xFFFFFFFF)
        return NULL;
    dwAddress += 0x1B0;
    if((dwAddress = *(DWORD*)dwAddress) == 0) return 0;
    dwAddress += 0x10;
    if((dwAddress = *(DWORD*)dwAddress) == 0) return 0;
    dwAddress += 0x3C;
    if((dwAddress = *(DWORD*)dwAddress) == 0) return 0;
    KdPrint((“Current Process Full Path Name: %ws\\n”,  (PCWSTR)dwAddress));
    return (PCWSTR)dwAddress;
}

Windows NT与Windows 2000的_EPROCESS结构略有不同,所以偏移地址也不相同,故此上面的程序不能正常运行于Windows NT。要想在Windows NT下获得进程名和完整路径可以用类似的方法得出正确的偏移地址,进而编写出正确的程序。
如果想得到关于如何在Windows 9x的驱动程序(VXD)中得到当前进程的进程名和完整路径或者其他更多知识,可以访问费尔安全实验室的网站:
游客

返回顶部