首页
社区
课程
招聘
[求助]接上贴求教hook SSDT
发表于: 2014-3-19 17:54 6702

[求助]接上贴求教hook SSDT

2014-3-19 17:54
6702
上贴http://bbs.pediy.com/showthread.php?p=1269090
说到Win7 32位Hook NtCreateThread无效,原因是Win7下NtCreateThread不再使用(感谢上贴回复的各位)。
转而想Hook ZwCreateThread(但是这个函数和NtCreateThread服务号等)一样,无法hook

于是打起了ZwCreateThreadex的主意(NtCreateThreadZx参数更蛋疼...所以选前者)
http://bbs.pediy.com/showthread.php?t=174534 得到如下结构@cvcvxk

typedef NTSTATUS (NTAPI *_ZwCreateThreadEx)(
  OUT PHANDLE ThreadHandle,
  IN ACCESS_MASK DesiredAccess,
  IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
  IN HANDLE ProcessHandle,
  IN PTHREAD_START_ROUTINE StartRoutine,
  IN PVOID StartContext,
  IN ULONG CreateThreadFlags,
  IN SIZE_T ZeroBits OPTIONAL,
  IN SIZE_T StackSize OPTIONAL,
  IN SIZE_T MaximumStackSize OPTIONAL,
  IN PPROC_THREAD_ATTRIBUTE_LIST AttributeList
  );


在下想在以上函数中得到线程ID号和threadContext->eax

因为我的hook函数需要上述参数(也是受NtCreateThread启发,我在xp下hook的它)
于是自作聪明的改成了如下(服务号写的0x58)
NTSTATUS
MyZwCreateThreadEx(
				   OUT PHANDLE ThreadHandle,
				   IN ACCESS_MASK DesiredAccess,
				   IN PVOID ObjectAttributes OPTIONAL,
				   IN HANDLE ProcessHandle,
				   OUT PCLIENT_ID ClientId,
				   IN PCONTEXT ThreadContext,//StartContext
				   IN BOOL CreateSuspended,
				   IN ULONG StackZeroBits,
				   IN SIZE_T SizeOfStackCommit,
				   IN SIZE_T SizeOfStackReserve,
				   OUT PVOID lpBytesBuffer)
{
	DbgPrint(("被调用1!!!!!\n"));
	status = RealZwCreateThreadEx(
		ThreadHandle,
		DesiredAccess,
		ObjectAttributes OPTIONAL,
		ProcessHandle,
		ClientId,
		ThreadContext,//StartContext
		CreateSuspended,
		StackZeroBits,
		SizeOfStackCommit,
		SizeOfStackReserve,
		lpBytesBuffer);
		if (IsCurrentThreadSuspect())
		{
			InsertThread(ClientId->UniqueThread);
			return status;
		}
			status1 = ZwQueryInformationProcess(ProcessHandle,ProcessBasicInformation,&pbi,sizeof(pbi),NULL);		
				if ((HANDLE)pbi.UniqueProcessId == PsGetCurrentProcessId()) 
				{
					PEB = (void *)pbi.PebBaseAddress;				
					Ldr = *( ( void ** )( ( unsigned char * )PEB+0x0c ) );
					Flink = *( ( void ** )( ( unsigned char * )Ldr+ 0x14 ) );
					p = Flink;
					do
					{
						BaseAddress = *( ( void ** )( ( unsigned char * )p+ 0x10 ) );
						FullDllName = *( ( void ** )( ( unsigned char * )p+ 0x20 ) );
						SizeOfImage = *( ( void ** )( ( unsigned char * )p+ 0x18 ) );
						if (ThreadContext->Eax >= (DWORD)BaseAddress && 
							ThreadContext->Eax < (DWORD)BaseAddress+(DWORD)SizeOfImage)
						{
							//一些操作
							break;
						}
						p = *( ( void ** )p);
					}
					while ( Flink != p );
				}




问题来了,这样做后,hook函数能够执行,但是
if (ThreadContext->Eax >= (DWORD)BaseAddress &&
                                                        ThreadContext->Eax < (DWORD)BaseAddress+
越界进而BSOD。。。

求教。。。如何Win7 32 hook 底层线程创建函数...(ZwCreateThread,NtCreateThreadEX....)

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (9)
雪    币: 1
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
if (ThreadContext->Eax >= (DWORD)BaseAddress &&
              ThreadContext->Eax < (DWORD)BaseAddress+(DWORD)SizeOfImage)
            {
              //一些操作
              break;
            }
先是越界,后蓝屏。。。
2014-3-19 17:58
0
雪    币: 155
活跃值: (20)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
cvcvxk明明写的是PVOID StartContext(实际不是他搞出来的,是zzzevazzz:http://hi.baidu.com/zzzevazzz/item/b2a9c9a4ea6805f615329ba7),你怎么就那么聪明改成PCONTEXT了啊

那个叫StartContext啊,不是ThreadContext,是Thread Parameter啊。

话说楼主你光会写代码,一点点调试、DUMP分析都不会还是回家卖包子吧只靠乱猜这写驱动是不成的了。

稍微ida一下win7的CreateRemoteThread就能看到NtCreateThreadEx的第5个参数就是CreateThread/CreateRemoteThread的 lpStartAddress参数

第6个参数是ThreadParameter,就是CreateThread/CreateRemoteThread的 lpParameter参数

话说为什么要让ring3函数操作context啊,不需要啊。

我看你识别eax是不是还是照搬xp上的方法拦截线程起始地址啊,移植的时候要留心看啊,这里不需要eax了啊,直接就有lpStartAddress了啊,刚刚滴啊,已经填好了啊,不需要看什么PCONTEXT结构啊。
2014-3-19 23:05
0
雪    币: 1
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
大清早看到@kman的回复,真的受教育了!确实这几天被这个搞昏头了(也被其他事情困扰着。。。(私事)再此不述)。。。
确实自己到解决这个事情的后面有太多的欠考虑,没有仔细去研究xp下的代码。只想快点解决,结果越急越昏头。自做聪明实乃无奈之举,本想打双引号,后面发帖时手快忘了。。。
BSOD的dump文件在下也试着去分析,无奈Virtual Machine Monitor下始终拿不到dump文件

希望各位坛友对我有什么说什么,直接指出就是,在下不会生气,当作勉励。如若不改,真的该去卖包子了。。。

所以,静下心来重新分析问题。。。。
2014-3-20 09:21
0
雪    币: 1
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
太菜了,还得请教下。。。
xp下的hook函数
NTSTATUS
HookedNtCreateThread(
					 OUT PHANDLE ThreadHandle, 
					 IN ACCESS_MASK DesiredAccess, 
					 IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, 
					 IN HANDLE ProcessHandle, 
					 OUT PCLIENT_ID ClientId, 
					 IN PCONTEXT ThreadContext, 
					 IN PWORD InitialTeb, 
					 IN BOOLEAN CreateSuspended
					 )
{
   
}
由于现在hook了NtCreateThreadEx函数,参数有了变化
NTSTATUS
MyNtCreateThreadEx(
				   OUT PHANDLE ThreadHandle,
				   IN ACCESS_MASK DesiredAccess,
				   IN PVOID ObjectAttributes OPTIONAL,
				   IN HANDLE ProcessHandle,
				   IN PVOID lpStartAddress,
				   IN PVOID StartContext,//StartContext
				   IN BOOL CreateSuspended,
				   IN ULONG StackZeroBits,
				   IN SIZE_T SizeOfStackCommit,
				   IN SIZE_T SizeOfStackReserve,
				   OUT PVOID lpBytesBuffer)
{
  第一:我需要在这个函数中得到线程ID和类似于ThreadContext->Eax的起始地址。
在NtCreateThread中通过ClientId->UniqueThread和ThreadContext->Eax得到。
但在NtCreateThreadEx中,无此参数,于是线程ID无法得到(我现在用的是PsGetCurrentThread()->Cid.UniqueThread,但是我又不是很确定,因为我要获得的是被创建的线程ID,而不是创建者的)
第二:关于@kman说的 ThreadContext->Eax和lpStartAddress“相同”的说法,经过验证,也没法作用。我也不是要拦截线程起始地址,只是和PEB的范围做判断。详见这个判断
if (ThreadContext->Eax >= (DWORD)BaseAddress && 
              ThreadContext->Eax < (DWORD)BaseAddress+(DWORD)SizeOfImage)
            {
              //一些操作
              break;
            }

}

2014-3-20 20:40
0
雪    币: 1
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
第一:我需要在这个函数中得到线程ID和类似于ThreadContext->Eax的起始地址。
在NtCreateThread中通过ClientId->UniqueThread和ThreadContext->Eax得到。
但在NtCreateThreadEx中,无此参数,于是线程ID无法得到(我现在用的是PsGetCurrentThread()->Cid.UniqueThread,但是我又不是很确定,因为我要获得的是被创建的线程ID,而不是创建者的)
第二:关于@kman说的 ThreadContext->Eax和lpStartAddress“相同”的说法,经过验证,也没法作用。我也不是要拦截线程起始地址,只是和PEB的范围做判断。详见这个判断
if (ThreadContext->Eax >= (DWORD)BaseAddress &&
              ThreadContext->Eax < (DWORD)BaseAddress+(DWORD)SizeOfImage)
            {
              //一些操作
              break;
            }
2014-3-20 20:42
0
雪    币: 31
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
lpStartAddress就是线程的入口地址
创建的线程ID也简单啊,不是有返回ThreadHandle么,有了Handle你还拿不到线程ID?
2014-3-21 21:24
0
雪    币: 1
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
抱歉,现在才回复。。。。

我有了ThreadHandle,然后调用ObReferenceObjectByHandle得到 PETHREAD
然后用PsGetThreadId得到线程ID....

虽然得到了。。。但是感觉方法挺笨的。。。不知道有没有更好的办法......
2014-4-4 20:46
0
雪    币: 155
活跃值: (20)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
你自己看看我贴的那篇eva的文章,再稍微逆向下就知道怎么弄了:

从AttributeList中就可以获取ThreadId:

大概的伪代码:

for (i = 0 ; i < AttributeList->Length / sizeof(NT_PROC_THREAD_ATTRIBUTE_ENTRY) ; i++)
{
if (AttributeList->Entry[i].Attribute == 0x10003)
     tid = *Attribute->Entry[i].Value
}
当然,这里面还需要你自己做一些容错的处理代码。
2014-4-5 00:53
0
雪    币: 31
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
方法笨没有关系,关键是兼容性好,能达到目标就好,又不会有什么性能开销。写驱动很多时候笨的方法最好,想很多别的方法反而可能出各种问题。
2014-4-6 13:01
0
游客
登录 | 注册 方可回帖
返回
//