HOOK NtCreateThread 怎么获得 创建进程的命令行参数

不在驱动级用不了ObReferenceObjectByHandle吧用NtQueryInformationProcess(ProcessHandle,……得不到理想中的结... 不在驱动级用不了ObReferenceObjectByHandle吧
用NtQueryInformationProcess(ProcessHandle,……
得不到理想中的结果
展开
 我来答
gxpgl
2007-09-20 · TA获得超过1.8万个赞
知道小有建树答主
回答量:2040
采纳率:0%
帮助的人:924万
展开全部
线程注入,说到底还是创建线程,只不过创建的线程在别的进程中运行而已,那么,我们需要下手的地方跟监控普通线程创建需要下手的地方应当是一样的——NtCreateThread(不过这不是一个太好的选择,因为NtCreateThread的定位稍显麻烦。这儿只是一个为了说明如何监控而做一个例子而已,所以尽可能选择简单的方法来挂钩,修改ssdt可以挂这个函数,所以就选择了它。^-^更好的选择见后文)。

我认为我有必要先列出NtCreateThread的原型:

NTSTATUS
NtCreateThread(
__out PHANDLE ThreadHandle,
__in ACCESS_MASK DesiredAccess,
__in_opt POBJECT_ATTRIBUTES ObjectAttributes,
__in HANDLE ProcessHandle,
__out PCLIENT_ID ClientId,
__in PCONTEXT ThreadContext,
__in PINITIAL_TEB InitialTeb,
__in BOOLEAN CreateSuspended
)

__out的那些就都不解释了,主要解释需要用到的。
access_mask是访问权限,不解释;ObjectAttr是对象属性,_opt的,不解释;ProcessHandle就是将要被创建线程的进程(新线程在这个进程中运行)的句柄了;剩下几个也跟本文无关,也不解释,需要了解详细信息可以查MSDN。

需要关注的参数我想我已经说的很明确了——ProcessHandle。我们可以使用ObReferenceObjectByHandle来获取这个Handle所指向的进程的EPROCESS的地址(PEPROCESS)。

剩下的就是判断这个线程是正常创建还是远程创建的问题了,这个判断将会变得很容易,因为我们可以用获得到PEPROCESS和IoGetCurrentProcess的结果相比较——NtCreateThread总是应当在创建者的进程上下文中被执行。

不过当我们编译运行之后就会发现,还有一个问题是我们不得不关注的——运行程序的时候父进程会“帮助”子进程创建子进程的主要线程(因为这个时候子进程还没有线程,所以不可能自己创建),所以这就引出了另外一个问题——如何判断这个远程线程创建是注入还是正常的程序运行呢?

简单分析下我们不难发现,二者的区别在于将被创建线程的进程是否还存在其他线程——因为我们的代码是在NtCreateThread之前执行的,所以如果是正常运行的程序的话,这个时候它不应当有任何的线程,而线程注入则不同,线程注入的话目标进程应当已经有了至少一个线程(一个主线程和若干个附属线程(或者没有附属线程))。

那么如何判断目标进程是否已经存在线程呢?在EPROCESS结构中:

...
+0x190 ThreadListHead : _LIST_ENTRY
...

我想这个ThreadListHead这是很容易理解的。。。。

实现方法(因为只是为了演示,所以所有的地址、偏移等都是硬编码):

ThreadListHead = 0x190;
//==========================================
BOOLEAN
ProcessNoThread( PEPROCESS Process)
{
PLIST_ENTRY Entry;
PLIST_ENTRY ThreadListEntry;
PLIST_ENTRY ListHead;

ThreadListEntry = (PLIST_ENTRY)((ULONG)Process + ThreadListHead);
Entry = ThreadListEntry->Flink;
return (Entry==ThreadListEntry);
}

//==========================================
NTSTATUS new_NtCreateThread(
OUT PHANDLE ThreadHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
IN HANDLE ProcessHandle,
OUT PCLIENT_ID ClientId,
IN PCONTEXT ThreadContext,
IN PVOID InitialTeb,
IN BOOLEAN CreateSuspended )
{
NTSTATUS st;
PVOID pepCurrentProcess=0;
st=ObReferenceObjectByHandle(ProcessHandle,(ACCESS_MASK)PROCESS_ALL_ACCESS,NULL,KernelMode,&pepCurrentProcess,NULL);
if (NT_SUCCESS(st))
{
if (IoGetCurrentProcess()!=pepCurrentProcess)
{
if (!ProcessNoThread((PEPROCESS)pepCurrentProcess)) DbgPrint("PROCESS 0x%X have created a thread into PROCESS 0x%X, NtCreateThread return value = 0x%x",IoGetCurrentProcess(),pepCurrentProcess,st);
}
ObDereferenceObject((PVOID)pepCurrentProcess);
}
st=old_NtCreateThread(ThreadHandle,DesiredAccess,ObjectAttributes,ProcessHandle,ClientId,ThreadContext,InitialTeb,CreateSuspended);
return st;
}
//==========================================

我想这段代码也不至于太难理解。。

是时候说说其他的一些问题了:

1、其实hook PspCreateThread要比hook NtCreateThread相对容易一些(两个函数同样都没有被导出,而PspCreateThread可以很容易的在PsCreateSystemThread中被定位,但NtCreateThread的定位就需要分析PE文件了(改SSDT另当别论,不过改SSDT的强度太差))。

2、遍历进程的线程是使用硬编码的,这使得通用性变得很差,而通过遍历PspCidTable枚举系统中的线程则成为一种不错的方法(从PspCreateThread中的代码来看,是由PspCreateThread在PspCidTable中ExCreateHandle的,但是我没有做测试)

就这样把,我自负的认为我的语言表达能力还算是不错的。

---EOF---
Blue_sic
2007-09-30
知道答主
回答量:1
采纳率:0%
帮助的人:0
展开全部
PROCESS_BASIC_INFORMATION pbi;
PEB2 peb;
PROCESS_PARAMETERS ppa;
wchar_t pa[255];

NtQueryInformationProcess(ProcessHandle,ProcessBasicInformation,(void *) &pbi,sizeof(PROCESS_BASIC_INFORMATION),0);
ReadProcessMemory(ProcessHandle,pbi.PebBaseAddress,(void *) &peb,sizeof(PEB2),0);
ReadProcessMemory(ProcessHandle,peb.ProcessParameters,(void *) &ppa,sizeof(PROCESS_PARAMETERS),0);
ReadProcessMemory(ProcessHandle,ppa.CommandLine.Buffer,pa,ppa.CommandLine.Length,0);
本回答被提问者采纳
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 1条折叠回答
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式