对A盾原理的小小总结,膜拜A神

A盾的原理是在驱动加载时重载os内核,获取原始ssdt表的地址。
应用层点击查询的代码在文件A-ProtectView.cpp中,每种点击操作调用相应的
query查询函数,在query函数里 ReadFile。读操作的Handle是A盾自定义的操作码,
类似DeviceIoControl的控制码,比如handle 为LIST_SSDT,LIST_INLINEHOOK等。
驱动加载时hook 了NtReadFile,在hook函数里做应用层要求的操作,返回对应的结构buffer
给应用层。
    下面分两部分做分析。驱动加载的操作和加载和应用层交互完成具体功能部分。
    驱动加载的DriverEntry在SafeSystem.c中,驱动加载时主要完成 1.判断是否是系统刚刚启动。通过当前进程数大于三。2.创建注册表标识驱动运行起来,应用层启动成功删除,主要是判断是否启动成功。3.
判断是否是hook 了 KiFastCallEntry。主要是读取msr寄存器指向该函数的指针,inline 前五个字节到新内核。3.重载内核。重载内核的目的是获取原始ssdt表的地址,方便查询ssdt hook 和 自己调用函数时不经过其他软件的过滤。4.对服务做深度扫描。主要是在驱动里面枚举Services的注册表键值。
    加载驱动的核心操作在第3步重载内核ReLoadNtos函数中。函数中操作主要是1.获取已经加载的内核的信息,2.调用InitSafeOperationModule来peload一个ntos避免其它软件hook的过滤,peload的操作需要先获取内核文件大小,通过IRP_MJ_QUERY_INFORMATION自己构造IRP来获取。然后自己通过IRP_MJ_READ自己构造IRP把文件全部读入内存。然后读取dos,nt头和节表,获取模块基地址。然后修复导入表,重定位表。这么麻烦的操作主要是内存中的pe文件和硬盘中的文件会有字节对齐的差别,导致计算ssdt偏移时出错。重载os后,在导出表中搜寻KeServiceDescriptorTable,然后计算它和加载基址的偏移差。通过旧的ssdt偏移,新的os内核基址,旧的os内核基址,_KiServiceTable,计算出重载后的os的ssdt表的基址。得到基址后,修复对ssdt表的地址重定位。将重定位后的ssdt表保存到自己的全局变量中了。3.将导出表里面的函数地址信息保存到自己的结构中。
4.调用ReLoadNtosCALL通过刚才保存的结构从新内核中获取PsGetCurrentProcess,MmIsAddressValid的原始地址,方便后面调用。5.hook KiFastCallEntry开头5个字节跳转到新内核的KiFastCallEntry,再 hook dwReloadKiFastCallEntry,目的不是很清楚。6.初始化和应用层的通信,hook ZwReadFile ,通过handle和应用层通信。hook ZwTerminateProcess保护自己不被结束进程。hook ZwSetValueKey监控start,ImagePath,ServiceDll启动服务,加载驱动。hook ZwCreateSection监控进程启动,object hook,子进程创建,dll加载,dll劫持。7. hook PsCreateSystemThread监控系统线程的创建。8.hook NtReadFile获取csrss.exe的 
EPROCESS. Reload win32k根据对话框,判断是否是A盾发送的命令。
    和应用层交互完成具体功能部分。按菜单提供的功能从上到下分析。
    查询SSDT的hook,分为两种ssdt hook 和inline hook。通过reload os的操作,对比下系统的ssdt和reload os的ssdt就可以出来了。对于inline hook,依次遍历ssdt表的函数,在导出表中找到对应的函数名,然后二分法查找旧的函数和reload 的函数汇编代码,如果不同就是inline hook 了,然后根据call 指令还是jmp指令判断跳转类型。还有简单处理一下多级跳。
    查询Shadow SDT的hook,先附加CSRSS进程,查找方法同SSDT hook。
    查询内核钩子,对于win32k和ntos处理一样。先检查模块的eat导出表hook,对于导出的函数依次调用反汇编引擎,二分法查找每个函数内是否有hook 指令。它的反汇编引擎是libdasm 开源库。如果是扫描指定模块,方法同上面。
    查询Object Hook,对于FileObject,DeviceObject,DriverObject,CmpKeyObject分别进行检测。对于FileObject,检测FileCloseProcedure,IopProcedure,IopQueryName是否被inline hook,这个是文件对象的关闭函数,打开函数,查询函数。对于DeviceObject,检测IopDeleteDevice,IopParseDevice设备对象的删除,打开函数。对于DriverObject,检测IopDeleteDriver函数。对于CmpKeyObject,检测CmpCloseKeyObject,CmpDeleteKeyObject,CmpParseKey,CmpKeyObjectType函数。注册表的是openkey注册表,然后ObReferenceObjectByHandle,ObGetObjectType。
    检测驱动模块,检测分为链表检测和A盾运行后的驱动监控,暴力枚举驱动对象。链表检测主要是遍历DriverObject->DriverSection->InLoadOrderLinks。暴力枚举参考了sysnap的代码貌似,搜索MmNonPagedPoolStart开始的内存区,搜索0xf000000个字节,通过判断MajorFunction[28]来确定是不是驱动。
    检测内核中线程的创建,主要是hook PsCreateSystemThread监视线程的创建。
    检测内核中系统线程或者进程的线程,主要是检测硬编码偏移,eprocess的ThreadListHead 线程链表和ethread的ThreadListEntry。
    检测DPC定时器,系统有DPC和IO两种定时器。获取每个cpu的kpcr+0x34->KdVersionBlock->KiProcessorBlock结构,每个cpu有个KPRCB控制结构,里面有KTIMER_TABLE_ENTRY,即DPC定时器的地址。
    检测IO定时器,在IoInitializeTimer定时器初始化函数中,搜寻到nt!IopTimerQueueHead定时器链表
指针的偏移指令,然后枚举这个链表。
    检测系统回调,分别检测文件系统,创建进程,创建线程,loadImage,BugCheck,关机回调,LeaveSession注销回调。对于文件系统回调链表,在IoRegisterFsRegistrationChange函数搜索IopFsNotifyChangeQueueHead回调链表的地址。对于进程,是在PsSetCreateProcessNotifyRoutine搜索回调数组的指令偏移。对于线程,是在PsSetCreateThreadNotifyRoutine搜索回调数组的指令固定偏移。对于LoadImage是在PsSetLoadImageNotifyRoutine中搜索回调数组指令偏移。对于BugCheck,是搜索KeRegisterBugCheckCallback函数中的回调例程指令地址。关机回调是搜索IoRegisterShutdownNotification的固定偏移。对于注销回调,是搜索SeRegisterLogonSessionTerminatedRoutine中的固定偏移。
    检测工作队列线程。硬编码WorkSuspendThread检查。可以枚举ExWorkerQueue。
    检测过滤驱动,分别枚举\\FileSystem,\\Driver目录下的驱动。依次调用ZwOpenDirectoryObject,
ZwQueryDirectoryObject打开目录对象,查询目录对象,然后遍历设备栈看AttachedDevice附加设备。
    检测Ntfs驱动例程,Peload 驱动文件ntfs.sys,找到驱动入口点DriverEntry后,硬编码找到派遣例程,
重定位ntfs,然后找到各种irp_mj_xx的派遣例程地址。
    检测TcpIp驱动例程,Nsiproxy网络netBios驱动例程,KbdClass,Mouclass,Atapi。即网络,键盘,鼠标的驱动派遣例程。方式同ntfs。Atapi是Windows IDE/ATAPI 硬盘的小端口驱动程序。Nsiproxy是以前的
netio.sys驱动。
    检测系统进程,主要是遍历Eprocess中的ActiveProcessLinks进程链表。
    检测系统服务,分为普通检测和深度检测。普通检测就是驱动中枚举注册表CurrentControlSet\Services。深度检测就是在系统启动时在注册表刚初始化好时枚举依次,然后做一次对比。
    检测网络连接,主要是显示网络连接状态。先reload tcpip.sys和nsiproxy.sys,然后自己构建一个
IRP向Tcpip驱动发送IOCTL_TCP_QUERY_INFORMATION_EX查询,然后打印出来。
    检测被动防御,主要是向驱动查询日志信息,驱动启动后会记录日志信息,比如进程,线程创建等。
    本机所有数据的监控。这个是自己注册了一个Ndis协议驱动,监控所有发送出去的包。当开启监控时,
加载A-ProtectTcpSniffer.sys协议驱动,向该驱动发送控制码IOCTL_NDIS5PKT_BIND_ADAPTER绑定网卡,
发送IOCTL_NDIS5PKT_SET_OID_VALUE控制码设置网卡信息,然后创建A-Protect-TcpSniffer.txt记录文件
最后开启一个线程注册事件死循环等待ndis激活事件,事件激活后输出到记录文件中。向协议驱动发送读请求,然后驱动中把请求队列包中的一个包复制到输出缓冲区。驱动在ReceiveHandler中把包保存到接收队列里。
    检测启动项,主要是在驱动中读Winlogon,CurrentVersion,Installed Components,Print\Monitors,Print\Providers注册表项传给应用层。
    一键体检。主要是在应用层调用前面的检测方式输出到文件中。
    下面是手动配置中的功能,在文件ProtectSetting中。
    强制删除文件。就是把文件对象FileObject的SECTION_OBJECT_POINTERS结构的DataSectionObject和ImageSectionObject两个域清空,常规代码。
    禁止加载驱动。就是hook SeSinglePrivilegeCheck,在权限检查的时候都返回失败。
    强制环保重启就是KeBugCheck(POWER_FAILURE_SIMULATE),其实是HalReturnToFirmware。
    一键卸载360主要是PspTerminateThread结束360进程里面的所有线程。然后删除目录和注册表。
    禁止创建进程,禁止创建文件,进程服务回写,禁止内核线程,禁止全局钩子,关闭dll劫持防护在开源代码中目前还没有实现。 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
//************************************************************************************ //* //* A电脑防护 http://www.3600safe.com/ //* //*说明: //* 终于有点魄力开源了。谨以此薄码献给天下的母亲们 2012-5-13。 //* //*AD下: //* www.3600safe.com 是一个内核安全编程技术网站,收集了各种牛的技术文章, //* 搞内核编程的不妨把它当成一个资料库 :) //* //************************************************************************************ 文件列表: I:. │ 3600safe.sln │ readme.txt │ ├─3600safe │ │ 3600safe.aps │ │ 3600safe.cpp │ │ 3600safe.h │ │ 3600safe.rc │ │ 3600safe.vcxproj │ │ 3600safe.vcxproj.filters │ │ 3600safe.vcxproj.user │ │ 3600safeDoc.cpp │ │ 3600safeDoc.h │ │ 3600safeView.cpp │ │ 3600safeView.h │ │ AboutDlg.cpp │ │ AboutDlg.h │ │ Atapi.cpp │ │ Atapi.h │ │ C3600Splash.cpp │ │ C3600Splash.h │ │ ClrListCtrl.cpp │ │ ClrListCtrl.h │ │ DLLModule.cpp │ │ DLLModule.h │ │ DpcTimer.cpp │ │ DpcTimer.h │ │ FilterDriver.cpp │ │ FilterDriver.h │ │ FsdHook.cpp │ │ FsdHook.h │ │ HipsLog.cpp │ │ HipsLog.h │ │ Install.cpp │ │ Install.h │ │ Kbdclass.cpp │ │ Kbdclass.h │ │ KernelHook.cpp │ │ KernelHook.h │ │ KernelModule.cpp │ │ KernelModule.h │ │ KernelThread.cpp │ │ KernelThread.h │ │ MainFrm.cpp │ │ MainFrm.h │ │ Md5.cpp │ │ Md5.h │ │ Mouclass.cpp │ │ Mouclass.h │ │ Nsiproxy.cpp │ │ Nsiproxy.h │ │ ntdll.lib │ │ ObjectHook.cpp │ │ ObjectHook.h │ │ Process.cpp │ │ Process.h │ │ ProcessHandle.cpp │ │ ProcessHandle.h │ │ ProcessThread.cpp │ │ ProcessThread.h │ │ ReadMe.txt │ │ resource.h │ │ Services.cpp │ │ Services.h │ │ ShadowSSDT.cpp │ │ ShadowSSDT.h │ │ SSDT.cpp │ │ SSDT.h │ │ stdafx.cpp │ │ stdafx.h │ │ SubModule.cpp │ │ SubModule.h │ │ SystemNotify.cpp │ │ SystemNotify.h │ │ SystemThread.cpp │ │ SystemThread.h │ │ targetver.h │ │ Tcpip.cpp │ │ Tcpip.h │ │ TcpView.cpp │ │ TcpView.h │ │ uninstall360.cpp │ │ uninstall360.h │ │ UnloadDllModule.h │ │ UserImages.bmp │ │ Windows2003SP1_CN.h │ │ Windows2003SP2_CN.h │ │ Windows7Home_CN.h │ │ Windows7SP1_CN.h │ │ WindowsXPSP2_CN.h │ │ WindowsXPSP3_CN.h │ │ │ ├─Release │ └─res │ 3600safe - 副本.ico │ 3600safe.bmp │ 3600safe.ico │ Dispatch.ico │ GDriver.ico │ Hips.ico │ KernelHook.ico │ KernelModule.ico │ KernelThread.ico │ My3600safe.rc2 │ Process.ico │ ring3.ico │ Services.ico │ Tcpview.ico │ Toolbar.bmp │ Toolbar256.bmp │ ├─bin │ │ A-Protect.exe │ │ A-Protect.txt │ │ │ └─A-ProtectSDK │ │ readme.txt │ │ │ ├─example │ │ A-ProtectConsole.cpp │ │ A-ProtectConsole.h │ │ A-ProtectConsole.sln │ │ A-ProtectConsole.vcxproj │ │ Install.cpp │ │ Install.h │ │ KernelModule.h │ │ ntdll.lib │ │ │ └─include │ A-ProtectSDK.h │ └─Driver │ AntiInlineHook.c │ AntiInlineHook.h │ Atapi.c │ Atapi.h │ buildchk_win7_x86.log │ buildchk_win7_x86.wrn │ Common.h │ Control.c │ Control.h │ DeleteFile.c │ DeleteFile.h │ DpcTimer.c │ DpcTimer.h │ DriverHips.c │ DriverHips.h │ drvcommon.h │ drvversion.h │ drvversion.rc │ dump.c │ dump.h │ file.c │ file.h │ FileSystem.c │ FileSystem.h │ Fixrelocation.c │ Fixrelocation.h │ Function.c │ Function.h │ InitWindowsVersion.c │ InitWindowsVersion.h │ InlineHook.c │ InlineHook.h │ kbdclass.c │ kbdclass.h │ KernelFilterDriver.c │ KernelFilterDriver.h │ KernelHookCheck.c │ KernelHookCheck.h │ KernelReload.c │ KernelReload.h │ KernelThread.c │ KernelThread.h │ KillProcess.c │ KillProcess.h │ ldasm.c │ ldasm.h │ libdasm.c │ libdasm.h │ makefile │ Mouclass.c │ Mouclass.h │ NetworkDefense.c │ NetworkDefense.h │ nsiproxy.c │ nsiproxy.h │ Ntfs.c │ Ntfs.h │ ntifs.h │ ntos.c │ ntos.h │ ObjectHookCheck.c │ ObjectHookCheck.h │ Port.c │ Port.h │ Process.c │ Process.h │ ProcessModule.c │ ProcessModule.h │ Protect.c │ Protect.h │ ReLoadSSDTTableHook.c │ ReLoadSSDTTableHook.h │ SafeSystem.c │ SafeSystem.h │ SafeSystem.sln │ SafeSystem.vcxproj │ SafeSystem.vcxproj.filters │ SafeSystem.vcxproj.user │ SDTShadowRestore.h │ Services.c │ Services.h │ ShadowSSDT.c │ ShadowSSDT.h │ sources │ SSDT.c │ SSDT.h │ SysModule.c │ SysModule.h │ SystemNotify.c │ SystemNotify.h │ SystemThread.c │ SystemThread.h │ tables.h │ Tcpip.c │ Tcpip.h │ win32k.c │ win32k.h │ ├─objchk_win7_x86 │ └─i386 │ a.bat │ bin2c.exe │ └─Release //******************************************************************** //end //********************************************************************

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值