HOOK NtCreateThread 怎么获得 创建进程的命令行参数
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HOOK NtCreateThread 怎么获得 创建进程的命令行参数相关的知识,希望对你有一定的参考价值。
不在驱动级用不了ObReferenceObjectByHandle吧
用NtQueryInformationProcess(ProcessHandle,……
得不到理想中的结果
我认为我有必要先列出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--- 参考技术A 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);本回答被提问者采纳
app检测到hook打不开
参考技术A app检测到hook打不开,有hook风险可以下载手机管家或者360管家清理相关垃圾,并且删除一些乱七八糟的软件,可能会好一点。 参考技术B 有hook风险可以下载手机管家或者360管家清理相关垃圾,并且删除一些乱七八糟的软件,可能会好一点。以上是关于HOOK NtCreateThread 怎么获得 创建进程的命令行参数的主要内容,如果未能解决你的问题,请参考以下文章