首页
社区
课程
招聘
[旧帖] [求助][求助]ssdt问题 获取进程commandline 0.00雪花
发表于: 2016-4-2 22:42 2333

[旧帖] [求助][求助]ssdt问题 获取进程commandline 0.00雪花

2016-4-2 22:42
2333
最近在xp下做一个SSDT,hook NtCreateProcessEx 后想获取进程的commandline,想采取这样的思路:EPROCESS---->PEB----->_RTL_USER_PROCESS_PARAMETERS。
_RTL_USER_PROCESS_PARAMETERS地址里面有commandline,但调试的时候总是得到
_RTL_USER_PROCESS_PARAMETERS地址无效,不知道哪位大侠可以解觉?能不能帮一下忙,感激不尽!,或者还有没有更好的办法,获取进程的commandline也可以

EPROCESS 部分结构
+0x158 PageDirectoryPte : _HARDWARE_PTE
   +0x158 Filler           : 0
   +0x160 Session          : 0xf79bf000 Void
   +0x164 ImageFileName    : [16]  "CreateProcess.e"
   +0x174 JobLinks         : _LIST_ENTRY [ 0x0 - 0x0 ]
   +0x17c LockedPagesList  : (null)
   +0x180 ThreadListHead   : _LIST_ENTRY [ 0x877ebf08 - 0x877ebf08 ]
   +0x188 SecurityPort     : (null)
   +0x18c PaeTop           : 0xf7a523e0 Void
   +0x190 ActiveThreads    : 0
   +0x194 GrantedAccess    : 0x1f0fff
   +0x198 DefaultHardErrorProcessing : 0
   +0x19c LastThreadExitStatus : 0n0
   +0x1a0 Peb              : 0x7ffdb000 _PEB
   +0x1a4 PrefetchTrace    : _EX_FAST_REF
   +0x1a8 ReadOperationCount : _LARGE_INTEGER 0x0
   +0x1b0 WriteOperationCount : _LARGE_INTEGER 0x0
   +0x1b8 OtherOperationCount : _LARGE_INTEGER 0x0
   +0x1c0 ReadTransferCount : _LARGE_INTEGER 0x0
   +0x1c8 WriteTransferCount : _LARGE_INTEGER 0x0

这里有个疑惑:那个进程名为什么不完整,而且每次都是这样的。

PEB部分结构

kd> dt _PEB 0x7ffdb000
nt!_PEB
   +0x000 InheritedAddressSpace : 0x90 ''
   +0x001 ReadImageFileExecOptions : 0xf8 ''
   +0x002 BeingDebugged    : 0xef ''
   +0x003 BitField         : 0 ''
   +0x003 ImageUsesLargePages : 0y0
   +0x003 SpareBits        : 0y0000000 (0)
   +0x004 Mutant           : 0x00f00000 Void
   +0x008 ImageBaseAddress : 0x00ef2000 Void
   +0x00c Ldr              : (null)
   +0x010 ProcessParameters : 0x00001e00 _RTL_USER_PROCESS_PARAMETERS
   +0x014 SubSystemData    : (null)
   +0x018 ProcessHeap      : 0x7ffdb000 Void
   +0x01c FastPebLock      : (null)
   ...................

ProcessParameters 结构找到了,接下来看这个结构:
kd> dt _RTL_USER_PROCESS_PARAMETERS 0x00001e00
nt!_RTL_USER_PROCESS_PARAMETERS
   +0x000 MaximumLength    : ??
   +0x004 Length           : ??
   +0x008 Flags            : ??
   +0x00c DebugFlags       : ??
   +0x010 ConsoleHandle    : ????
   +0x014 ConsoleFlags     : ??
   +0x018 StandardInput    : ????
   +0x01c StandardOutput   : ????
   +0x020 StandardError    : ????
   +0x024 CurrentDirectory : _CURDIR
   +0x030 DllPath          : _UNICODE_STRING
   +0x038 ImagePathName    : _UNICODE_STRING
   +0x040 CommandLine      : _UNICODE_STRING
   +0x048 Environment      : ????
   +0x04c StartingX        : ??
   +0x050 StartingY        : ??
   +0x054 CountX           : ??
   +0x058 CountY           : ??

为什么会出现这样的问题。
调试的时候自己写了一个测试程序,具体为:
WCHAR wszCommand[] = L"\"C:\\windows\\system32\\notepad.exe\" 123 456";
CreateProcessW(
                NULL,
                wszCommand,
                NULL,
                NULL,
                FALSE,
                0,
                NULL,
                NULL,
                &si,
                &pi);

结果在内核下总得不到commandline,

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (2)
雪    币: 284
活跃值: (3824)
能力值: ( LV5,RANK:75 )
在线值:
发帖
回帖
粉丝
2
你应该先逆一下 kernel32 CreateProcessW,看命令行是由谁在什么时候写进去的

+0x164 ImageFileName    : [16]  "CreateProcess.e"

Kernel32->BasePushProcessParameters():

  status = RtlCreateProcessParameters(
             &ProcessParameters,
             &CommandLine,
             &DestinationString,
             (PUNICODE_STRING)(a5 != 0 ? (unsigned int)&v31 : 0),
             &usCommandLine,                    // 真正的命令行
             (PVOID)a7,
             &WindowTitle,
             &DesktopInfo,
             &ShellInfo,
             &RuntimeData);

Ntdll->RtlCreateProcessParameters():

    v24 = p + 656;
    RtlpCopyProcString((void **)&v24, (PUNICODE_STRING)(p + 36), (PUNICODE_STRING)a4, 520);
    RtlpCopyProcString((void **)&v24, (PUNICODE_STRING)(p + 48), (PUNICODE_STRING)a3, 0);
    RtlpCopyProcString((void **)&v24, (PUNICODE_STRING)(p + 56), a2, a2->Length + 2);
    if ( pusCommandLine1->Length == pusCommandLine1->MaximumLength )  // 命令行在这里被写入buf
      RtlpCopyProcString((void **)&v24, (PUNICODE_STRING)(p + 64), pusCommandLine1, 0);
    else
      RtlpCopyProcString((void **)&v24, (PUNICODE_STRING)(p + 64), pusCommandLine1, pusCommandLine1->Length + 2);
    RtlpCopyProcString((void **)&v24, (PUNICODE_STRING)(p + 112), (PUNICODE_STRING)a7, 0);
    RtlpCopyProcString((void **)&v24, (PUNICODE_STRING)(p + 120), (PUNICODE_STRING)a8, 0);
    RtlpCopyProcString((void **)&v24, (PUNICODE_STRING)(p + 128), (PUNICODE_STRING)a9, 0);

本来p + 64处是 usCommandLine 的 UNICODE_STRING 结构,经过后面的 RtlDeNormalizeProcessParams,
UNICODE_STRING 里的 Buffer 变成了一个 相对于 p 的偏移。

回到 Kernel32->BasePushProcessParameters():
v23 = p_NtWriteVirtualMemory(ProcessHandle, BaseAddress, ProcessParameters, ProcessParameters->Length, 0);

命令行在这里应该就被写进去了!
2016-4-3 00:04
0
雪    币: 1
活跃值: (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
多谢了,不是很理解。那如果我要hook的话,具体应该hook哪个函数,才能截获命令行
2016-4-3 08:28
0
游客
登录 | 注册 方可回帖
返回