摘除XP系统LoadImageNotifyRoutine回调例程

在XP系统下调用PsSetLoadImageNotifyRoutine注册LoadImage回调例程,就能够在每个进程或者DLL加载的时候注册的例程得到回调。

看看PsSetLoadImageNotifyRoutine的代码

kd> u PsSetLoadImageNotifyRoutine L22

nt!PsSetLoadImageNotifyRoutine:

805c718c 8bff            mov     edi,edi

805c718e 55              push    ebp

805c718f 8bec            mov     ebp,esp

805c7191 53              push    ebx

805c7192 57              push    edi

805c7193 33ff            xor     edi,edi

805c7195 57              push    edi

805c7196 ff7508          push    dword ptr [ebp+8]

805c7199 e87cd10300      call    nt!ExAllocateCallBack (8060431a)

805c719e 8bd8            mov     ebx,eax

805c71a0 3bdf            cmp     ebx,edi

805c71a2 7507            jne     nt!PsSetLoadImageNotifyRoutine+0x1f (805c71ab)

805c71a4 b89a0000c0      mov     eax,0C000009Ah

805c71a9 eb2a            jmp     nt!PsSetLoadImageNotifyRoutine+0x49 (805c71d5)

805c71ab56             push    esi

805c71acbe80b25580      mov     esi,offset nt!PspLoadImageNotifyRoutine(8055b280)

805c71b1 6a00            push    0

805c71b3 53              push    ebx

805c71b4 56              push    esi

805c71b5 e890d10300      call    nt!ExCompareExchangeCallBack (8060434a)

805c71ba 84c0            test    al,al

805c71bc 751d            jne     nt!PsSetLoadImageNotifyRoutine+0x4f (805c71db)

805c71be 83c704          add     edi,4

805c71c1 83c604          add     esi,4

805c71c4 83ff20          cmp     edi,20h

805c71c7 72e8            jb      nt!PsSetLoadImageNotifyRoutine+0x25 (805c71b1)

805c71c9 53              push    ebx

805c71ca e819d00300      call    nt!RtlpFreeAtom (806041e8)

805c71cf b89a0000c0      mov     eax,0C000009Ah

805c71d4 5e              pop     esi

805c71d5 5f              pop     edi

805c71d6 5b              pop     ebx

805c71d7 5d              pop     ebp

805c71d8 c20400          ret     4

以上0x56和0xbe是特征码


对应的C代码(摘自WRK 1.2)

NTSTATUS

PsSetLoadImageNotifyRoutine(

    __in PLOAD_IMAGE_NOTIFY_ROUTINE NotifyRoutine

    )

{

    ULONG i;

    PEX_CALLBACK_ROUTINE_BLOCK CallBack;

 

    PAGED_CODE();

    //Allocate a new callback block.

    CallBack = ExAllocateCallBack ((PEX_CALLBACK_FUNCTION) NotifyRoutine, NULL);

    if (CallBack == NULL) {

        return STATUS_INSUFFICIENT_RESOURCES;

    }

 

    for (i = 0; i < PSP_MAX_LOAD_IMAGE_NOTIFY; i++) {

        // Try and swap a null entry for the new block.

        if (ExCompareExchangeCallBack (&PspLoadImageNotifyRoutine[i],

                                       CallBack,

                                       NULL)) {

            InterlockedIncrement ((PLONG) &PspLoadImageNotifyRoutineCount);

            PsImageNotifyEnabled = TRUE;

            return STATUS_SUCCESS;

        }

    }

    // No slots left. Free the block and return.

    ExFreeCallBack (CallBack);

    return STATUS_INSUFFICIENT_RESOURCES;

}


看到PspLoadImageNotifyRoutine是一个数组,定义如下:

EX_CALLBACK PspLoadImageNotifyRoutine[PSP_MAX_LOAD_IMAGE_NOTIFY];

要摘除回调例程就必须得到PspLoadImageNotifyRoutine变量的地址,这就使用了特征码搜索法来定位变量位置(相关文章可在看雪上面找到)

这里附上摘除回调函数的代码

 

// LoadImage回调结构体(摘自WRK)

#pragma pack(1)           

typedef struct _EX_FAST_REF

{

    union

    {

        PVOID Object;

        ULONG_PTR RefCnt:3;

        ULONG_PTR Value;

    };

} EX_FAST_REF, *PEX_FAST_REF;

 

typedef struct _EX_CALLBACK_ROUTINE_BLOCK

{

    EX_RUNDOWN_REF RundownProtect;

    PEX_CALLBACK_FUNCTION Function;

    PVOID Context;

} EX_CALLBACK_ROUTINE_BLOCK, *PEX_CALLBACK_ROUTINE_BLOCK;

#pragma pack()

 

// PspLoadImageNotifyRoutine数组大小

#define PSP_MAX_LOAD_IMAGE_NOTIFY           8

 

// 系统PspLoadImageNotifyRoutine变量位置

PULONG g_PspLoadImageNotifyRoutine = NULL;


// 根据特征码查找PspLoadImageNotifyRoutine变量的地址

PULONG FindPspLoadImageNotifyRoutine( PUCHAR FuncBase )

{

    ULONG nIndex;

    PULONG result = NULL;

 

    // 查找ing

    for ( nIndex = 0; nIndex < 512; ++nIndex )

    {

        // 比较头部(这里的0x56和0xbe是特征码)

        if ( (*(UCHAR*)FuncBase == 0x56) && (*(UCHAR*)(FuncBase + 1) == 0xbe) )

        {

            // 保存地址并返回

            result = *(PULONG)(FuncBase + 2);

            break;

        }

 

        // 继续遍历

        ++FuncBase;

    }

 

    return result;

}


// 检测并挂钩NP的回调函数

VOID RemoveLoadImageCallBack()

{

    PEX_FAST_REF ExRef;

    ULONG nIndex;

    NTSTATUS status;

 

    ExRef = (PEX_FAST_REF)(g_PspLoadImageNotifyRoutine);

    for ( nIndex = 0; nIndex < PSP_MAX_LOAD_IMAGE_NOTIFY; ++nIndex )

    {

        PEX_CALLBACK_ROUTINE_BLOCK Point;

        // 去掉末尾3位数

        Point = (PEX_CALLBACK_ROUTINE_BLOCK)(ExRef->Value & ~7);      // 详见WRK

        if ( MmIsAddressValid((PVOID)Point) )

        {

            // 移除注册的回调函数

            status = PsRemoveLoadImageNotifyRoutine( Point->Function );

            if ( NT_SUCCESS(status) )

            {

                KdPrint(("remove LoadImage notify success: %d.\n", nIndex));

            }

        }

        ++ExRef;

    }

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
版本:V3.4.2 目前版本主要功能: 1. 所有进程的枚举(包括内核中隐藏的进程) 2. 所有文件的枚举(包括内核中隐藏的文件) 3. 进程中所有模块的枚举(包括内核中隐藏的模块) 4. 进程的强制结束 5. 进程中模块的强制卸载 6. 模块被哪些进程加载的检索 7. 查看文件/文件夹被占用的情况 8. 可以Unlock占用文件的进程 9. 文件/文件夹的粉碎(可强删Unlocker1.8.9/金山/超级巡警文件粉碎机无法删除的顽固文件) 10. 阻止文件粉碎后用还原软件还原(采用美国国防部DOD 5220.22-m标准阻止文件还原) 11. 用磁盘解析技术检索硬盘数据 12. 内核模块和驱动的查看和管理 13. 启动项的查看和管理 14. 系统服务的查看和管理 15. 集成文件粉碎功能到系统右键菜单 16. 消息钩子的查看和卸载 17. SSDT/Shadow SSDT钩子的查看和卸载 18. 各种内核回调的查看和卸载 19. 多国语言版本的对应(中文和英文) 20. 暂停进程运行和恢复进程运行 21. 进程模块的内存的dump 22. 进程的线程的查看和结束 23. 进程的窗口的查看和控制 24. 进程的定时器的查看和摘除(该功能还没对应Windows2003) 25. 内核定时器的查看和摘除 26. 上传文件在线扫描病毒 27. 查看和摘除用户层的钩子 28. 查看和结束内核线程 29. 关机回调的清除 30. 查看和摘除mini文件驱动 31. 系统恢复功能(检测项目包括注册表关键部位,已安装的杀毒软件,AutoRun文件,Windows漏洞检测,共享文件夹) 32. 流氓快捷方式的检测和删除 33. 镜像劫持的检测和删除 34. 文件关联的检测和删除 35. IE相关的检测和删除 36. FSD Hook的检测和删除 37. Object Hook的检测和删除 38. 部分CPU/硬盘/显卡/主板的温度检测 39. 部分硬件信息的确认 40. 修复漏洞功能,可以下载和安装Windows补丁 41. IDT钩子的检测和恢复 42. 禁止进城创建,新建文件,注册表修改等配置 43. 注册表功能,几乎可以无视一切隐藏注册表的钩子 44. SPI的检测 45. 通过磁盘解析进行文件浏览 46. 文件强制拷贝功能,可拷贝网络视频的缓存文件 47. 通过磁盘解析取得和拷贝ADS流文件 48. 添加和查看文件重启删除信息 49. Disk/Atapi驱动钩子的检测和恢复 50. 进程权限的枚举和摘除 51. 检测键盘侦听软件 52. 检测被监视的文件 53. IO定时器的检测和停止 54. 工作列线程的检测和暂停 55. FAT32格式的磁盘解析 56. 新增MBR的检测和修复(可对抗鬼影等Bootkit和MBR Rootkit) 57. 新增检测被替换的或被感染的内核文件(内核文件劫持) 58. 支持多硬盘的MBR检测和恢复 59. 新增可疑设备的检测和清除
一:SSDT表的hook检测和恢复 ~!~~~ 二:IDT表的hook检测和恢复 ~~~~~~(idt多处理器的恢复没处理,自己机器是单核的,没得搞,不过多核的列举可以) 三:系统加载驱动模块的检测 通过使用一个全局hash表(以DRIVEROBJECT为对象)来使用以下的方法来存储得到的结果,最终显示出来 1.常规的ZwQuerySystemInformation来列举 2通过打开驱动对象目录来列举 3搜索内核空间匹配驱动的特征来列举(这个功能里面我自己的主机一运行就死机,别的机器都没事,手动设置热键来蓝屏都不行,没dump没法分析,哎,郁闷) 4从本驱动的Modulelist开始遍历来列举驱动 四:进程的列举和进程所加载的dll检测 采用以下方法来列举进程: 1ZwQuerySystemInformation参数SystemProcessesAndThreadsInformation来枚举 2进程EPROCESS 结构的Activelist遍历来枚举 3通过解析句柄表来枚举进程 4通过Handletablelisthead枚举进程 5进程创建时都会向csrss来注册,从这个进程里面句柄表来枚举进程 6通过自身进程的HANDLETABLE来枚举进程 7通过EPROCESS的SessionProcessLinks来枚举进程 8通过EPROCESS ---VM---WorkingSetExpansionLinks获取进程 9暴力搜索内存MmSystemRangeStart以上查找PROCESS对象 进程操作: 进程的唤醒和暂停通过获取PsSuspendProcess和PsResumeProcess来操作的 进程结束通过进程空间清0和插入apc。 采用以下方法查找DLL: 1遍历VAD来查找dll 2挂靠到对应的进程查找InLoadOrderLinks来枚举dll 3暴力搜索对应进程空间查找pe特征来枚举dll DLL的操作: Dll的卸载是通过MmUnmapViewOfSection和MmmapViewOfSection(从sdt表中相应函数搜索到的)来实现的(本来想直接清0 dll空间,有时行有时不行)(只要将这个进程的ntdll卸载了,进程就结束了,一个好的杀进程的办法撒,绿色环保无污染),注入dll使用的是插入apc实现的。(注入的dll必须是realse版的。Debug版会出现***错误,全局dll注入貌似也是)插入apc效果不是很好,要有线程有告警状态才执行。 五:线程信息的检测 遍历ThreadList来枚举线程 线程的暂停和唤醒都是通过反汇编获取PsResumeThread和PsSuspendThread直接从r3传来ETHREAD来操作的,通过插入APC来结束线程 六:shadow sdt表的hook检测与恢复 没有采用pdb来解决函数名问题,直接写入xp和03的shandow表函数名(主要是自己的网不稳定,连windbg有时都连不上微软) 七:系统所有的过滤驱动的检测 查看各device下是否挂接有驱动之类的,可直接卸载 八:系统常用回调历程的检测和清除 只检查了PsSetLoadImageNotifyRoutine PsSetCreateThreadNotifyRoutine PsSetCreateProcessNotifyRoutine CmRegisterCallback这几个,至于那个什么shutdown回调不知道是啥玩意,就没搞了,有知道的顺便告诉我下撒,谢谢 九:文件系统fat和ntfs的分发函数检测 直接反汇编fat和ntfs的DriverEntry得到对应的填充分发的偏移,然后和当前已经运行的文件系统的分发相比是否被hook,并附带恢复 十:文件查看功能 自己解析ntfs和fat的结构,来实现列举文件和直接写磁盘删除。附带有普通的删除和发生IRP来删除。不过这里面有点问题,ntfs删除有时把目录给搞坏了,大家凑合着吧, Ntfs网上删除这些操作的代码不多,就是sudami大大的利用ntfs-3g来实现的,看了下,太多了,充满了结构。然后自己对照着系统删除文件时目录的变化来自己实现的。只处理了$BITMAP对应的位清除,父目录的对应文件的索引项的覆盖,删除文件对应的filerecord清0. 另外偷懒时间都没处理,呵呵,y的,一个破时间都都搞好几个字节移来移去的。 十一:常用内核模块钩子的检测和恢复 这里只检测了主要的内核模块nkrnlpa**.exe的.win32k.sys,hal.dll,比对它们的原始文件从而查找eat inline hook,iat hook ,和inline hook。Inline是从TEXT段开始一段位置开始比较的。(有点慢貌似,等待显示扫描完成就好了) 十二:应用层进程所加载dll的钩子 应用层钩子检测和内核模块钩子检测原理一样,不过为了能读写别的进程的空间,并没有使用openprocess去打开进程,而是通过KiattachProcess挂靠到当前进程,然后通过在r0直接读写进程空间的。
郁金香VC++过驱动保护全套 免key版 天異赤提供 教程下载地址获取方法: 第一步:打开下方链接,填写QQ邮箱,系统会往QQ邮箱发一封确认订阅邮件 第二步:打开QQ邮箱查看邮件,确认订阅,订阅成功后系统会自动把下载地址和解压密码一起发送到你QQ邮箱http://list.qq.com/cgi-bin/qf_invite?id=585e150c59f30e1213af9a9352367711b2e45c217582cf35 最近时间有些多,一时对网络游戏的保护机制感兴趣了,来研究了一下,听说QQ系列的TesSafe.sys 有些强,于是拿来看看驱动都做了些什 么.以下是对DNF和QQffo(自由幻想)研究结果(xp sp2) 在网上找了些TesSafe的资料,说TesSafe并不怎么样 现在这个版本保护的结果为:任务管理器中可以看到游戏进程,但OD和CE看不见,更不用说什么调试了,iceword可以 看到EPROCSS,但WSysCheck看 郁金香驱动 不见,自己写程序,也不能注入受保护的游戏进程. 可见,NtOpenProcess被Hook了,恢复SSDT后,没有任何效果,可见是inline hook , 用一般的软件检测一下,没有发现inline hook,看来hook得比较深,在网上一找资料才发现,原来的确够隐藏的 郁金香驱动 以下是上一个TesSafe版本的分析结果 从网上找出来的资料,TesSafe.sys保护原理(DNF的保护,我听说,QQ系列游戏的保护机制都是一样的) ================================================================= 保护得比较没有意思,强度也不高.可能隐藏性稍好一些. 用IDA反汇编TesSafe.sys可以看到: 这个驱动一加载,ExAllocPoolWithTag分配了一块内存,然后将一个函数写进这块内存,接着做好保护,然后 PsCreateSystemThread()创建的 郁金香驱动 线程调用ZwUnloadDriver将驱动卸载。虽 然驱动被卸载了,但是ExAllocPoolWithTag分配的内存仍然在起作用。 具体来看它如何进行保护: 郁金香驱动 先是得到了ObOpenObjectByPointer的地址,然后在 NtOpenProcess中搜索0xe8 ,也就是跳转指令,直到遇见RET为止。 一但得到0xe8,比较后面的四个字节,如果转换后为 ObOpenObjectByPointer的地址,就把这个地址用自己代理函数的地址转换后替换掉,达到 保护自己的目的。 郁金香驱动 用WinDbg看了看,果然在我的机器上:0x80570e41这个在 NtOpenProcess中的区域被TesSafe.sys修改,原来这里是:80570e41 e87c8dffff call nt!ObOpenObjectByPointer (80569bc2) 系统通过ObOpenObjectByPointer来通过 EPROCESS得到Handle返回给调用者。TENCENT在这里下了一个跳转:(TesSafe.sys加载后。)80570e41 e826542a78 call f881626c 很明显,系统执行到这里就会调用0x6881626c的函数,也就是 TesSafe.sys的 ObOpenObjectByPointer代理函数。这 样,Client.exe就会在这里被过滤掉,从而让R3程序无法得到QQT的句柄,从而保护进程。 郁金香驱动 ================================================================================= 我手头拿到的版本是2008年8月5号的,把TesSafe逆出来一看,比上个版本有所加强. 在这个新版本中,TesSafe一共InLine Hook了六个函数,我只逆出并恢复了五个 其中: 1. KeAttachProcess NtOpenProcess NtOpenThread 这三个函数的HOOK方式与上一个版本一样,就是上面蓝色字体的方法,把本应该call ObOpenObjectByPointe的代码修改成了call他自己的代码, 然后在他自己的代码中处理保护的进程 上面三个函数,原来正常的代码为 80581ce3 e8a658ffff call nt!ObOpenObjectByPointer (8057758e) 被HOOK后的代码变成了 call a8724af4(TesSafe自己搞出来的函数) lkd> u a8724af

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值