线程调度的监视

  pjf(jfpan20000@sina.com)
    接着上次的小话题说。
    上次提到因为想要无需硬编码的方案从而未选用SwapContext,后来又想了想用SwapContext也基本不用硬编码,但因为用了其它做法,没有再实现hook SwapContext了。前两天难得放假,写了一下看看效果。
    首先进入2000的SwapContext中,看看它作了什么。

0008:8040422C  OR        CL,CL
0008:8040422E  MOV       BYTE PTR ES:[ESI+2D],02
0008:80404233  PUSHFD                                          //ESP+4 -> EFLAGS
0008:80404234  MOV       ECX,[EBX]
0008:80404236  CMP       DWORD PTR [EBX+0000080C],00
0008:8040423D  PUSH      ECX                                 //ESP -> exception list 
0008:8040423E  JNZ       80404338
0008:80404244  MOV       EBP,CR0
0008:80404247  MOV       EDX,EBP
0008:80404249  MOV       CL,[ESI+2C]
0008:8040424C  MOV       [EBX+50],CL
0008:8040424F  CLI
0008:80404250  MOV       [EDI+28],ESP                    //将ESP存入了KTHREAD的KernelStack
0008:80404253  MOV       EAX,[ESI+18]
0008:80404256  MOV       ECX,[ESI+1C]
... ...
    很明显,ESP+8的地方就是在KiSwapThread中的调用SwapContext的返回地址,可由它得到SwapContext函数地址,但没必要,直接hook这个在KiSwapThread中的地址更好些。也可以直接修改上面那条Call指令。
    下面的问题就是找出一个KernelStack可访问的非当前线程,这个很容易。示例代码片断(在2000/XP测试):

以下内容为程序代码:

PCHAR GetSwapAddr()
{
PCHAR res = 0;
NTSTATUS  Status;
PETHREAD Thread;

if (*NtBuildNumber <= 2195)
Status = PsLookupThreadByThreadId((PVOID)4, &Thread);
else
Status = PsLookupThreadByThreadId((PVOID)8, &Thread);

if (NT_SUCCESS(Status))
{
if (MmIsAddressValid(Thread))
res = (PCHAR)*PULONG(PCHAR(Thread)+0x28);
if (MmIsAddressValid(res+8))
res = (PCHAR)*PULONG(res+8);
else
res = 0;
}

return res;
}

PBYTE GoBackAddr = 0;
__declspec(naked) VOID HookSwap()
{
_asm pushad
DbgPrint("%08x/n", KeGetCurrentThread());
_asm popad
_asm jmp DWORD PTR[GoBackAddr]
}

HookSwapFunc()
{
... ...
PCHAR SwapAddr = GetSwapAddr();
if (SwapAddr)
GoBackAddr = HookFunction(SwapAddr, HookSwap);
... ...
}


    HookFunction代码的具体实现自然是仁者见仁了。
    下面是一些结果:

 4.343  Default    SwapAddr=80404141
 4.343  Default    813b8c00
 4.343  Default    fe995480
 4.359  Default    81429660
 4.359  Default    81429260
 4.359  Default    805e5520
 4.359  Default    813e15c0
 4.359  Default    8139f500
 4.359  Default    8139f260
 4.375  Default    805e5520
 4.375  Default    812ea140
 4.390  Default    805e5520
 4.390  Default    8139f500
 4.390  Default    8139f260
 4.406  Default    805e5520
 4.422  Default    805e5520
 4.422  Default    fe995480
 4.422  Default    fe995480
 4.422  Default    fe995480
 4.422  Default    8139f500
 4.422  Default    8139f260
 4.422  Default    813a66e0

    没仔细想,可能有错,欢迎指出。
冰刃IceSword 1.22 简介 IceSword是一斩断黑手的利刃(所以取这土名,有点搞e,呵呵)。它适用于Windows 2000/XP/2003/Vista操作系统,用于查探系统中的幕后黑手(木马后门)并作出处理,当然使用它需要用户有一些操作系统的知识。 在对软件做讲解之前,首先说明第一注意事项 :此程序运行时不要激活内核调试器(如softice),否则系统可能即刻崩溃。另外使用前请保存好您的数据,以防万一未知的Bug带来损失。 IceSword目前只为使用32位的x86兼容CPU的系统设计,另外运行IceSword需要管理员权限。 如果您使用过老版本,请一定注意,使用新版本前要重新启动系统,不要交替使用二者。 IceSword内部功能是十分强大的。可能您也用过很多类似功能的软件,比如一些进程工具、端口工具,但是现在的系统级后门功能越来越强,一般都可轻而易举地隐藏进程、端口、注册表、文件信息,一般的工具根本无法发现这些“幕后黑手”。IceSword使用大量新颖的内核技术,使得这些后门躲无所躲。 如何退出IceSword:直接关闭,若你要防止进程被结束时,需要以命令行形式输入:IceSword.exe /c,此时需要Ctrl+Alt+D才能关闭(使用三键前先按一下任意键)。 如果最小化到托盘时托盘图标又消失了:此时可以使用Ctrl+Alt+S将IceSword主界面唤出。因为偷懒没有重绘图标,将就用吧^_^。 您无须为此软件付费,但如果您使用时发现了什么Bug,请mail to me:[email protected] ,十分感谢。 更新说明: 1.20:(1)恢复了插件功能,并提供一个文件注册表的小插件,详见FileReg.chm;(2)对核心部分作了些许改动,界面部分仅文件菜单有一点变化。 1.20(SubVer 111E3):添加对32位版本Vista(NtBuildNumber:6000)的支持。 1.22:(1)增加普通文件、ADS、注册表、模块的搜索功能;(2)隐藏签名项;(3)添加模块的HOOK扫描;(4)核心功能的加强。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值