首页
社区
课程
招聘
[旧帖] PsSetCreateProcessNotifyRoutine 0.00雪花
发表于: 2013-10-14 01:17 8236

[旧帖] PsSetCreateProcessNotifyRoutine 0.00雪花

2013-10-14 01:17
8236
我想问下.PsSetCreateProcessNotifyRoutine这个函数是在哪个DLL
汇编要怎么引用此函数呢.....求指点

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (2)
雪    币: 160
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
ntoskrnl.exe
2013-10-14 11:08
0
雪    币: 36
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
【转】关于PsSetCreateProcessNotifyRoutine函数的分析和简单利用
这是从别人那转来的,下面所看见的汇编代码跟我不同。

我的XP SP3,获取m_address_3的偏移是0x8A,而这里是0x8B。

分析PsSetCreateProcessNotifyRoutine函数:

nt!PsSetCreateProcessNotifyRoutine:

805c56d2 8bff             mov      edi,edi

805c56d4 55               push     ebp

805c56d5 8bec             mov      ebp,esp

805c56d7 53               push     ebx

805c56d8 33db             xor      ebx,ebx

805c56da 385d0c           cmp      byte ptr [ebp+0Ch],bl

805c56dd 56               push     esi

805c56de 57               push     edi

805c56df 7465             je       nt!PsSetCreateProcessNotifyRoutine+0x74 (805c5746)

805c56e1 bfe0a35580       mov      edi,offset nt!PspCreateProcessNotifyRoutine (8055a3e0)

//这儿的PspCreateProcessNotifyRoutine就是用来记录所有的监控函数的数组!

//这儿可以得到PspCreateProcessNotifyRoutine的地址-----Address_1

805c56e6 57               push     edi

805c56e7 e848d50300       call     nt!ExReferenceCallBackBlock (80602c34)

// ExReferenceCallBackBlock对PspCreateProcessNotifyRoutine进行处理,所以,我们还要定位到函数

// ExReferenceCallBackBlock

805c56ec 8bf0             mov      esi,eax

805c56ee 85f6             test     esi,esi

805c56f0 741f             je       nt!PsSetCreateProcessNotifyRoutine+0x3f (805c5711)

805c56f2 56               push     esi

805c56f3 e82af9fcff       call     nt!IopGetRelationsTaggedCount (80595022)

//这儿是通过调用IopGetRelationsTaggedCount函数处理ExReferenceCallBackBlock(& PspCreateProcessNotifyRoutine[i])的返回值!

…….

805c572f 8d049de0a35580   lea      eax,nt!PspCreateProcessNotifyRoutine (8055a3e0)[ebx*4]

//这儿可以得到PspCreateProcessNotifyRoutine的地址-----Address_2

………

805c575c bfe0a35580       mov      edi,offset nt!PspCreateProcessNotifyRoutine (8055a3e0)

//这儿可以得到PspCreateProcessNotifyRoutine的地址-----Address_3

……

当然,仅通过一个就可以得到PspCreateProcessNotifyRoutine的地址,同时得到3个,比较是否相同,提高准确率!呵呵!看看代码是如何得到的:

如何得到PspCreateProcessNotifyRoutine数组的地址?

ULONG GetPspCreateProcessNotifyRoutineAddress()

{

ULONG m_PspCreateProcessNotifyRoutine=0;//记录PspCreateProcessNotifyRoutine地址

ULONG m_address_1=(ULONG)((ULONG)PsSetCreateProcessNotifyRoutine+0x10);

ULONG m_address_2=(LONG)((ULONG)PsSetCreateProcessNotifyRoutine+0x60);

ULONG m_address_3=(ULONG)((ULONG)PsSetCreateProcessNotifyRoutine+0x8B);

//这儿明显的看出程序的不兼容性

ULONG m_address=(ULONG)PsSetCreateProcessNotifyRoutine;

__asm

{

push eax;

mov   eax,m_address_1;

mov   eax,[eax];

mov   m_address_1,eax;

mov   eax,m_address_2;

mov   eax,[eax];

mov   m_address_2,eax;

mov   eax,m_address_3;

mov   eax,[eax];

mov   m_address_3,eax;

pop   eax;

}//将得到的地址转换为对应的值

DbgPrint("地址为:x%x\n",m_address);

DbgPrint("地址为:x%x\n",m_address_1);

DbgPrint("地址为:x%x\n",m_address_2);

DbgPrint("地址为:x%x\n",m_address_3);

if((m_address_1==m_address_2)&&(m_address_1==m_address_3))

{

DbgPrint("地址找到了!\n");

m_PspCreateProcessNotifyRoutine=m_address_1;

}

return m_PspCreateProcessNotifyRoutine;

}

如何定位到函数:ExReferenceCallBackBlock?

805c56e7 e848d50300       call     nt!ExReferenceCallBackBlock (80602c34)

利用特征码得到ExReferenceCallBackBlock函数的地址!Call的偏移!

//偏移:(805c56e7-805c56d2 )=0x15!-----函数地址:A=PsSetCreateProcessNotifyRoutine+0x15!

B=[A+1];A=A+B+5;---------------A就是ExReferenceCallBackBlock 的地址!

看看具体实现的代码:

//声明ExReferenceCallBackBlock 函数原型:

typedef PVOID (*EXREFERENCECALLBACKBLOCK)(PULONG m_fun_address);

EXREFERENCECALLBACKBLOCK m_ExReferenceCallBackBlock;//声明ExReferenceCallBackBlock函数!

m_ExReference=(ULONG)PsSetCreateProcessNotifyRoutine+0x15;

__asm

{

push eax;

mov   eax,m_ExReference;

inc eax;

mov   eax,[eax];

add eax,5;

add   eax,m_ExReference;

mov   m_ExReference,eax;

pop   eax;

}

//m_ExReference的值为ExReferenceCallBackBlock的地址!

m_ExReferenceCallBackBlock=(EXREFERENCECALLBACKBLOCK)m_ExReference;

在Windbg中看看IopGetRelationsTaggedCount是如何实现的:

nt!IopGetRelationsTaggedCount:

80595022 8bff             mov      edi,edi

80595024 55               push     ebp

80595025 8bec             mov      ebp,esp

80595027 8b4508           mov      eax,dword ptr [ebp+8]

8059502a 8b4004           mov      eax,dword ptr [eax+4]

8059502d 5d               pop      ebp

8059502e c20400           ret      4

80595031 cc               int      3

很简单,还是在程序中直接用吧,不用定位了!

如何定位回调函数所在的驱动?

1.ZwQuerySystemInformation调用11号功能,查询到所有的内核模块信息!

2.判断定位到的函数在哪个内核模块内!

3.输出定位到的模块信息!

这儿的前提是ZwQuerySystemInformation没有被Hook 下的情况!否则,就定位不到了啊!

看看代码:

PVOID m_start=NULL;

int m_length=1024;

ULONG   m_real_size=0;

NTSTATUS m_status=STATUS_SUCCESS;

ULONG m_count=0;

m_start=ExAllocatePool (NonPagedPool,m_length);

//将得到的实际大小保存在m_real_size中!

m_status=ZwQuerySystemInformation (11,m_start,m_length,&m_real_size);

ExFreePool(m_start);

m_start=ExAllocatePool (NonPagedPool,m_real_size);

m_status=ZwQuerySystemInformation (11,m_start,m_real_size,NULL);

m_system_moudle_infomation=(PSYSTEM_MODULE_INFORMATION)((PULONG)m_start+1);

.....

定位到m_real_fun_address

.....

for(m_count=0;m_count<*(PULONG)m_start;m_count++)

{ if(((ULONG)m_real_fun_address>=(ULONG)m_system_moudle_infomation[m_count].Base)&&((ULONG)m_real_fun_address<=((ULONG)m_system_moudle_infomation[m_count].Base+m_system_moudle_infomation[m_count].Size)))

{

DbgPrint("函数的地址:0x%x在模块:%s中\n",m_real_fun_address,m_system_moudle_infomation[m_count].ImageName);

break;

}

}

这儿就查询到了回调函数的地址所在模块,根据列出的模块信息,就能知道到底是什么程序进行的监控!

如何清除对进程创建(卸载)的监控?

将PspCreateProcessNotifyRoutine[i]的值改为为0!

//清除所有数据的监控

VOID TryClearRoutineAddress(PULONG m_fun_address)

//m_fun_address就是得到的PspCreateProcessNotifyRoutine

{

int i=0;

__asm

{ //关闭保护

push eax;

mov   eax,CR0;

and   eax,0FFFEFFFFh;

mov   CR0,eax;

pop   eax;

}

for(i=0;i<8;i++)

{

m_fun_address[i]=0;//将所有的数据清为0;

}

__asm

{ //开启保护

push eax;

mov   eax,CR0;

or   eax, 0F0000h;

mov   CR0,eax;

pop   eax;

}

}

到这儿,就得到解决了查询进程监控模块,清除进程监控!对于线程,DLL的监控,只要采用同样的方法就能得到!
2013-10-17 00:01
0
游客
登录 | 注册 方可回帖
返回
//