20楼#
发布于:2007-09-10 13:28
引用第19楼GNiDiA于2007-09-10 10:50发表的 : 如果给钱,SKG很愿意提供几款可以跳过的~ |
|
|
21楼#
发布于:2007-09-10 13:54
引用第15楼doskey于2007-09-09 15:34发表的 : 有理!很多技术在实验上都是可行的,但是真正用于商业上,稳定性还是不够。很多时候,做产品为了稳定性及其它的因素,往往只使用成熟的技术,而不是最强悍,最新的。 另一方面,说到抄作嘛,也是很正常的。只要能赚钱,能抄是一种本事!就像一些有钱人,他们用什么方式,怎么赚到钱的,都不重要,重要的是人家成功了。。Money是最实际的,不是吗?有多少人还记得那些失败者。。能活下来的,都是强者! |
|
|
22楼#
发布于:2007-09-10 15:48
引用第20楼killvxk于2007-09-10 13:28发表的 : SKG是什么东东? |
|
23楼#
发布于:2007-09-10 15:56
到处都在弄虚拟机,叫俺的赛扬633怎么活?
|
|
驱动小牛
|
24楼#
发布于:2007-09-10 16:02
漏了,自己先漏了
非感染型的,感染型的游戏客户端自己会搞定,--------------------------------------------------------------- 漏了,自己先漏了. 不过仍然很佩服doskey了,对我们菜鸟来说, inline hook KiSystemService 来过滤eax值已经是非常妙的想法了,仅代表菜鸟说话,呵呵. |
25楼#
发布于:2007-09-10 18:11
Re:漏了,自己先漏了
引用第24楼wangjianfeng于2007-09-10 16:02发表的 漏了,自己先漏了 : 该方法与2005年baiyuanfan的sysmon一样,不过360safebox功能比较多,sysmon只是监控~ |
|
|
26楼#
发布于:2007-09-12 10:19
.text:00004FF8 sub_4FF8 proc near ; CODE XREF: sub_504C+1Ep
.text:00004FF8 .text:00004FF8 ProcessHandle = dword ptr -4 .text:00004FF8 arg_0 = dword ptr 8 .text:00004FF8 .text:00004FF8 mov edi, edi .text:00004FFA push ebp .text:00004FFB mov ebp, esp .text:00004FFD push ecx .text:00004FFE lea eax, [ebp+arg_0] .text:00005001 push eax .text:00005002 push [ebp+arg_0] .text:00005005 call ds:PsLookupProcessByProcessId .text:0000500B test eax, eax .text:0000500D jl short loc_502F .text:0000500F lea eax, [ebp+ProcessHandle] .text:00005012 push eax .text:00005013 mov eax, ds:PsProcessType .text:00005018 push 0 .text:0000501A push dword ptr [eax] .text:0000501C push 1 .text:0000501E push 0 .text:00005020 push 0 .text:00005022 push [ebp+arg_0] .text:00005025 call ds:ObOpenObjectByPointer .text:0000502B test eax, eax .text:0000502D jnz short loc_5033 .text:0000502F .text:0000502F loc_502F: ; CODE XREF: sub_4FF8+15j .text:0000502F xor al, al .text:00005031 jmp short locret_5043 .text:00005033 ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪? .text:00005033 .text:00005033 loc_5033: ; CODE XREF: sub_4FF8+35j .text:00005033 push 0 ; ExitStatus .text:00005035 push [ebp+ProcessHandle] ; ProcessHandle .text:00005038 call ds:ZwTerminateProcess .text:0000503E neg eax .text:00005040 sbb eax, eax .text:00005042 inc eax .text:00005043 .text:00005043 locret_5043: ; CODE XREF: sub_4FF8+39j .text:00005043 leave .text:00005044 retn 4 .text:00005044 sub_4FF8 endp 360box中的safemode.sys中的这个代码片段有意思,首指令居然是mov edi,edi .编译器会生成这样的指令?是不是硬编码inline hook。 NTSTATUS PsLookupProcessByProcessId(IN ULONG ulProcId, OUT PEPROCESS * pEProcess); lea eax, [ebp+arg_0] .text:00005001 push eax .text:00005002 push [ebp+arg_0] .text:00005005 call ds:PsLookupProcessByProcessId 这段指令更有意思,都有点糊涂了,如果说arg_0是进程句柄的话,同时它又在调用后返回了 pEProcess指针。 为什么不是 push [ebp+ProcessHandle] push [ebp+arg_0] .text:00005005 call ds:PsLookupProcessByProcessId 对照isdrv120的代码 .text:00020052 sub_20052 proc near ; CODE XREF: .text:000129E3p .text:00020052 .text:00020052 var_34 = byte ptr -34h .text:00020052 var_30 = dword ptr -30h .text:00020052 var_2C = dword ptr -2Ch .text:00020052 var_28 = dword ptr -28h .text:00020052 Handle = dword ptr -20h .text:00020052 var_1C = dword ptr -1Ch .text:00020052 var_18 = dword ptr -18h .text:00020052 var_10 = dword ptr -10h .text:00020052 var_4 = dword ptr -4 .text:00020052 arg_0 = dword ptr 8 .text:00020052 arg_4 = dword ptr 0Ch .text:00020052 .text:00020052 push ebp .text:00020053 mov ebp, esp .text:00020055 push 0FFFFFFFFh .text:00020057 push offset dword_11728 .text:0002005C push offset loc_221C4 .text:00020061 mov eax, large fs:0 .text:00020067 push eax .text:00020068 mov large fs:0, esp .text:0002006F sub esp, 24h .text:00020072 push ebx .text:00020073 push esi .text:00020074 push edi .text:00020075 mov [ebp+var_18], esp .text:00020078 xor ebx, ebx .text:0002007A push ebx .text:0002007B call sub_1CEA2 .text:00020080 mov edi, eax .text:00020082 mov [ebp+var_30], edi .text:00020085 cmp edi, 0FFFFFFFFh .text:00020088 jnz short loc_20091 .text:0002008A push 0FFFFFFF6h .text:0002008C jmp loc_20126 .text:00020091 ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪? .text:00020091 .text:00020091 loc_20091: ; CODE XREF: sub_20052+36j .text:00020091 call KeGetCurrentThread .text:00020096 mov esi, eax .text:00020098 mov [ebp+var_1C], esi .text:0002009B call sub_1F754 .text:000200A0 xor eax, eax .text:000200A2 mov [ebp+var_28], eax .text:000200A5 .text:000200A5 loc_200A5: ; CODE XREF: sub_20052+D0j .text:000200A5 cmp eax, [ebp+arg_4] .text:000200A8 jge short loc_20124 .text:000200AA lea ecx, [ebp+var_2C] .text:000200AD push ecx .text:000200AE mov ecx, [ebp+arg_0] .text:000200B1 push dword ptr [ecx+eax*4] .text:000200B4 call ds:PsLookupThreadByThreadId .text:000200BA test eax, eax .text:000200BC jl short loc_2011C .text:000200BE lea eax, [ebp+Handle] .text:000200C1 push eax .text:000200C2 push ebx .text:000200C3 mov eax, ds:PsThreadType .text:000200C8 push dword ptr [eax] .text:000200CA push 1F03FFh .text:000200CF push ebx .text:000200D0 push ebx .text:000200D1 push [ebp+var_2C] .text:000200D4 call ds:ObOpenObjectByPointer .text:000200DA cmp eax, ebx .text:000200DC jl short loc_2011C .text:000200DE mov al, [esi+edi] .text:000200E1 mov [ebp+var_34], al .text:000200E4 mov [esi+edi], bl .text:000200E7 mov [ebp+var_4], ebx .text:000200EA push ebx .text:000200EB push [ebp+Handle] .text:000200EE call ds:dword_36508 .text:000200F4 or [ebp+var_4], 0FFFFFFFFh .text:000200F8 jmp short loc_2010D .text:000200FA ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪? .text:000200FA .text:000200FA loc_200FA: ; DATA XREF: .text:0001172Co .text:000200FA push 1 .text:000200FC pop eax .text:000200FD retn .text:000200FE ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪? .text:000200FE .text:000200FE loc_200FE: ; DATA XREF: .text:00011730o .text:000200FE mov esp, [ebp-18h] .text:00020101 or dword ptr [ebp-4], 0FFFFFFFFh .text:00020105 xor ebx, ebx .text:00020107 mov edi, [ebp-30h] .text:0002010A mov esi, [ebp-1Ch] .text:0002010D .text:0002010D loc_2010D: ; CODE XREF: sub_20052+A6j .text:0002010D mov al, [ebp+var_34] .text:00020110 mov [esi+edi], al .text:00020113 push [ebp+Handle] ; Handle .text:00020116 call ds:ZwClose .text:0002011C .text:0002011C loc_2011C: ; CODE XREF: sub_20052+6Aj .text:0002011C ; sub_20052+8Aj .text:0002011C inc [ebp+var_28] .text:0002011F mov eax, [ebp+var_28] .text:00020122 jmp short loc_200A5 .text:00020124 ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪? .text:00020124 .text:00020124 loc_20124: ; CODE XREF: sub_20052+56j .text:00020124 push 1 .text:00020126 .text:00020126 loc_20126: ; CODE XREF: sub_20052+3Aj .text:00020126 pop eax .text:00020127 mov ecx, [ebp+var_10] .text:0002012A mov large fs:0, ecx .text:00020131 pop edi .text:00020132 pop esi .text:00020133 pop ebx .text:00020134 leave .text:00020135 retn 8 .text:00020135 sub_20052 endp killvxk提到hook某些Ob*函数可以防止被某些程序终止,但是ob*函数的入口参数往往是借助于PsLookupThreadByThreadId或者PsLookupProcessByProcessId得到的。PsLookupProcessByProcessId比较好说,它就是进程pid。而PsLookupThreadByThreadId呢?我怎么得到一个进程的这个threadid。这个threadid是否包含在CLIENT_ID里面。调用_ZwQueryInformationThread?太烦琐了吧 |
|
27楼#
发布于:2007-09-12 10:36
参考网文
有来信询问进程结束的有关问题,下面就这个问题简单讨论一下(下面的讨论基于2000,其他NT系统也类似)。 首先看看一个应用程序想要强制结束另一个进程所要做的事:首先获得目标的进程ID,接着利用OpenProcess获取进程句柄(确保足够权限),最后将句柄传给TerminateProcess了结那个进程。 1、OpenProcess通过本机系统服务接口进入核心态,随后调用ntoskrnl的NtOpenProcess。在服务函数里,系统使用 SeSinglePrivilegeCheck检查调用者是否有DEBUG权限(SeDebugPrivilege),若有,则修改 AccessState使得在后面的操作中获取允许任意进程访问操作的句柄。最后通过ObOpenObjectByName或 PsLookupProcess*** + ObOpenObjectByPointer来打开进程(创建并返回进程句柄)。 2、TerminateProcess通过本机系统服务接口进入核心态,随后调用ntoskrnl的NtTerminateProcess。系统首先调用 ObReferenceObjectByHandle获取进程执行体块,执行体块的DebugPort指出进程是否处于调试状态,若处于调试状态且传入的 ExitStatus为DBG_TERMINATE_PROCESS则返回失败禁止结束进程。随后服务函数转入正题: 系统利用ThreadListHead枚举进程的每一个线程,使用PspTerminateThreadByPointer来结束它们。注意并不是对每个线程系统都会忠实地执行你的命令:若枚举到的线程是系统线程则不会继续执行而是返回STATUS_INVALID_PARAMETER。判断的方法是线程的Teb为零或者Teb的值在内核地址空间。有人问2000下为何csrss.exe进程杀不死,很简单,打开IceSword,在进程栏利用右键菜单的 “线程信息”看一下,看到那几个Teb为零的线程没有?(注意是针对windows2000,XP下不同。另外一点就是csrss中其它非系统线程的线程是很容易被杀死的,试图结束csrss时也可以看到在Teb为零的线程前面的线程已被杀掉,只是操作停在了Teb为零的线程这里)再看看system进程,呵呵。IceSword也并未提供杀除这种进程的功能,因为觉得没有需求。在最后一个线程结束时,进程的生命也结束了,随着 PspExitProcess/ObKillProcess灰飞烟灭。 另一方面,线程是怎样结束的呢。PspTerminateThreadByPointer并不是直接“杀掉”指定线程,实质上线程是“自杀”的,呵呵。系统简单的使用KeInitializeApc/KeInsertQueueApc插入了一个核心态的APC调用,若是用户线程,会再插入用户态的APC调用,最终线程在自己的执行环境中使用PspExitThread(...=>KeTerminateThread=> KiSwapThread)悲壮的自行了断。 有人问起为什么IceSword有时杀不死除那三个有系统线程的进程(两个是csrss、system,而idle是个非常奇特的存在,与众不同,这里不多废话了)外的其它进程。从上面的讨论可以找到答案。这种情况往往是目标进程的某用户态线程进入核心态后,系统出了某些问题挂死在核心态,无法返回执行 Apc例程的缘故。IceSword未强制除去它们是考虑此刻系统可能已经有某些问题,强制删除操作更有可能使系统崩溃,不过有了不少用户要求有这项功能,所以以后有空可能会加上(已经有一大堆杂七杂八的要求了,很难有时间升级一下版本,~_~)。 一般来说,要干掉一个进程,有了Debug权限就可以了,若别人有了保护,那就要发挥你的能力了。 我想上面的讨论对于想要杀除进程、保护进程的人有一些启发了吧。 |
|
28楼#
发布于:2007-09-12 10:41
mov edi, edi就是编译器生成的。。。
lea eax, [ebp+arg_0] .text:00005001 push eax .text:00005002 push [ebp+arg_0] .text:00005005 call ds:PsLookupProcessByProcessId 是编译器优化的结果 |
|
|
29楼#
发布于:2007-09-12 13:51
hook PspTerminateThreadByPointer 保护进程效果挺好的
|
|
|
30楼#
发布于:2007-09-12 15:20
Negative,应该是最让人想不到的办法就是最好的办法。
|
|
31楼#
发布于:2007-09-12 15:38
引用第29楼rhettxie于2007-09-12 13:51发表的 : 楼上问几个问题: 1.PspTerminateThreadByPointer肯定是未公开函数,如果希望hook该函数,必须知道两点,第一函数的调用规范,第二函数的入口地址,网上一篇文章提到这个函数在不同的操作系统下,参数个数不同,windows 2000是三个,windows xp是两个,是这样吗?另外这个函数没有导出,是否需要从 ntoskrnl.exe!NtTerminateProcess=>PspTerminateThreadByPointer函数的实现代码中,借助于sizeofcode,对指令编码进行搜索,找到PspTerminateThreadByPointer 被call的地址,然后推算PspTerminateThreadByPointer 地址进行hook。 2.对于一个受保护进程来说,我们最容易得到其pid,而PspTerminateThreadByPointer却需要一个thread参数,如何把该pid和thread联系起来? NTSTATUS NtTerminateProcess( __in_opt HANDLE ProcessHandle, __in NTSTATUS ExitStatus ) { //省略... st = STATUS_NOTHING_TO_TERMINATE; for (Thread = PsGetNextProcessThread (Process, NULL); Thread != NULL; Thread = PsGetNextProcessThread (Process, Thread)) { st = STATUS_SUCCESS; if (Thread != Self) { PspTerminateThreadByPointer (Thread, ExitStatus, FALSE); } } //省略... return st; } NTSTATUS PspTerminateProcess( PEPROCESS Process, NTSTATUS ExitStatus ) { PETHREAD Thread; NTSTATUS st; PAGED_CODE(); if (Process->Flags & PS_PROCESS_FLAGS_BREAK_ON_TERMINATION) { PspCatchCriticalBreak("Terminating critical process 0x%p (%s)\n", Process, Process->ImageFileName); } PS_SET_BITS (&Process->Flags, PS_PROCESS_FLAGS_PROCESS_DELETE); st = STATUS_NOTHING_TO_TERMINATE; for (Thread = PsGetNextProcessThread (Process, NULL); Thread != NULL; Thread = PsGetNextProcessThread (Process, Thread)) { st = STATUS_SUCCESS; PspTerminateThreadByPointer (Thread, ExitStatus, FALSE); } if (st == STATUS_NOTHING_TO_TERMINATE || Process->DebugPort != NULL) { ObClearProcessHandleTable (Process); st = STATUS_SUCCESS; } return st; } 通过 PsGetNextProcessThread (Process, Thread)遍历目标进程的每一个线程,然后利用得到的thread实例和PspTerminateThreadByPointer入口参数进行比较,相同就返回STATUS_ACCESS_DENIED.这样可行吗? |
|
32楼#
发布于:2007-09-12 15:50
也就是说有没有比较简单办法判断PspTerminateThreadByPointer入口参数是受保护进程的某个线程?
|
|
33楼#
发布于:2007-09-12 21:23
1 PspTerminateThreadByPointer 函数的原型在各个系统下是不是一样的我不肯定,反正我参考wrk源码后hook这个参数,在win2000下能跑的很好。
2 这个确实没被导出,不过没导出的函数如何去hook已经不是新鲜话题了。 3 PspTerminateThreadByPointer 的参数中有一个ethread, 从ethread判断是否在你保护的进程中就行了。 |
|
|
34楼#
发布于:2007-09-12 22:11
无所谓了~hook吧,我不杀进程,只是把进程内存都改成0xCC~~
|
|
|
35楼#
发布于:2007-09-12 23:07
以后考虑在VMM中保护内存,对所有物理地址访问进行过滤控制。
|
|
|
36楼#
发布于:2007-09-13 00:09
那就放老V,上GDI HACK
|
|
|
37楼#
发布于:2007-09-13 08:27
引用第34楼killvxk于2007-09-12 22:11发表的 : 没用,再牛,也不能吹口气,就能飘进来。我只要见到一个文件里面包含killvxk字符,直接把文件删掉。你还能把自己伪装在微软的升级包里?就是你把进程的内存全部填充为0xcc,重启系统不照样还是魂飞湮灭,你能阻挡一个正义的软件和一个正义的用户把你清掉吗?当然作为一个刚刚会使用鼠标的网民,我认了。 |
|
38楼#
发布于:2007-09-13 09:31
引用第35楼wowocock于2007-09-12 23:07发表的 : Warning: CPU 试图执行如下指令:XOR EAX,EAX,该指令会导致EAX寄存器内容全部丢失,是否允许? |
|
39楼#
发布于:2007-09-13 12:22
引用第37楼guaiguaiguan于2007-09-13 08:27发表的 : 我也是杀邪恶软件的~~ 正义软件算是盟友啦~~ |
|
|