好文档就是一把金锄头!
欢迎来到金锄头文库![会员中心]
电子文档交易市场
安卓APP | ios版本
电子文档交易市场
安卓APP | ios版本

麦洛克菲内核驱动开发第五课.ppt

42页
  • 卖家[上传人]:kms****20
  • 文档编号:51206362
  • 上传时间:2018-08-12
  • 文档格式:PPT
  • 文档大小:773KB
  • / 42 举报 版权申诉 马上下载
  • 文本预览
  • 下载提示
  • 常见问题
    • 麦洛克菲内核开发第五课 HOOK麦洛克菲 周扬荣麦洛克菲提纲nSSDTnINLINEnIRPnSYSENTERnIDTnOBJECTnR3n等等SSDT HOOKAPI 流程kernel.dll user32.dllntdll.dllAPIIRP应用层内核层数据 命令封装disk.sysntfs.sysntoskrnl.exeZW与NT函数(1)nntdll.dllqZw*与nt*函数nntoskrnl.exeqZw*与nt*函数Ntdll.dllNtoskrnl.exeNt*Zw*Nt*Zw*ZW与NT函数(2)n区别:nNtdll.dll中:完全一样nNtoskrnl.exe中:qZw*nt*,即nt函数更底层qZw*函数会把PreviousMode设置为KernelMode 然后再调用 Nt*函数,因此在Nt*函数中就不会进行参数检查而如果直 接调用Nt*函数的话 , 必须自己将PreviousMode设置为 KernelMode,否则PreviousMode很可能仍然是UserMode, 这 样的话 Nt*函数就会认为对它的调用来自用户态,从而做一些 检查,这时就会产生问题了.q因此要自己调用Nt*的话必须先将PreviousMode设为 KernelModeSSDT表索引1索引2索引3索引4索引5。

      索引N服务1服务2服务3服务4服务5服务NAPIKernel32.dllNtdll.dllsysenterZw*Nt*Uf nt!ZwReadFile:.text:00406508 mov eax, 0B7h .text:0040650D lea edx, [esp+FileHandle] .text:00406511 pushf .text:00406512 push 8 .text:00406514 call _KiSystemService .text:00406519 retn 24h .text:00406519 _ZwReadFile@36 endpAPI调用流程nNtdll.dll 中的 API 是一个简单的包装函数n当 Kernel32.dll 中的 API 通过 Ntdll.dll 时,会 完成参数的检查再调用一个中断(int 2Eh 或者 SysEnter 指令),从而实现从 Ring3 进入 Ring0 层n并且将所要调用的服务号(也就是在 SSDT 数 组中的索引值)存放到寄存器 EAX 中n再根据存放在 EAX 中的索引值来在 SSDT 数 组中调用指定的服务即Nt*系列函数SSDT表结构n结构: #pragma pack(1) typedef struct ServiceDescriptorEntry {unsigned int *ServiceTableBase;unsigned int *ServiceCounterTableBase; unsigned int NumberOfServices;unsigned char *ParamTableBase; } ServiceDescriptorTableEntry_t,*PServiceDescriptorTableEntry_t; #pragma pack()n导出: __declspec(dllimport) ServiceDescriptorTableEntry_t KeServiceDescriptorTable;n引用:#define SYSTEMSERVICE(_function) KeServiceDescriptorTable.ServiceTableBase[ *(PULONG)((PUCHAR)_function+1)]#define SDT SYSTEMSERVICE要HOOK的APItypedef NTSTATUS (*ZWCREATESECTION)(OUT PHANDLE SectionHandle,IN ULONG DesiredAccess,IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,IN PLARGE_INTEGER MaximumSize OPTIONAL,IN ULONG PageAttributess,IN ULONG SectionAttributes,IN HANDLE FileHandle OPTIONAL );static ZWCREATESECTION OldZwCreateSection;NTSTATUS NTAPI HOOK_NtCreateSection(PHANDLE SectionHandle,ACCESS_MASK DesiredAccess,POBJECT_ATTRIBUTES ObjectAttributes,PLARGE_INTEGER SectionSize,ULONG Protect,ULONG Attributes,HANDLE FileHandle) { return OldZwCreateSection(SectionHandle,DesiredAccess,ObjectAttributes,SectionSize,Protect,Attributes,FileHandle); }HOOK(1)void StartHook (void) {//获取未导出的服务函数索引号HANDLE hFile;PCHAR pDllFile;ULONG ulSize;ULONG ulByteReaded;__asm{push eaxmov eax, CR0and eax, 0FFFEFFFFhmov CR0, eaxpop eax}OldZwCreateSection = (ZWCREATESECTION)InterlockedExchange((PLONG)//关闭__asm{push eaxmov eax, CR0or eax, NOT 0FFFEFFFFhmov CR0, eaxpop eax}return ; }HOOK(2)void RemoveHook (void) {__asm{push eaxmov eax, CR0and eax, 0FFFEFFFFhmov CR0, eaxpop eax}InterlockedExchange( (PLONG) __asm{push eaxmov eax, CR0or eax, NOT 0FFFEFFFFhmov CR0, eaxpop eax} }一个稳定的基本框架n查看HOOK之后的SSDT表nx nt!kes*des*table*ndds addrndds addr Llength进程保护nHook_ZwTerminateProcess驱动加载监控nHook_ZwLoadDriver进程创建监控nHook_ZwOpenSectionXP: CreateProcessW CreateProcessInternalW NtCreateProcessEx ZwCreateSectionVISTA以上: CreateProcessW CreateProcessInternalW NtCreateUserProcess ZwCreateSection注册表操作监控nHook_ZwSetValueKeyInline hookInline hook原理图Inline hook的步骤n1。

      获得要inline hook的函数在内存中的地址n2实现T_MyFunc()与MyFunc函数,在该函 数中将参数压栈并调用MyFunc函数处理HOOK保存函数开头的指令到某个内存 中,并在该内存末尾附加JMP指令到开头指令 的后面的指令并将开头的指令替换为JMP T_MyFunc地址在T_MyFunc执行完MyFunc之后,调用保 存的指令,跳回去如何找到函数的首地址?n未导出函数:暴力搜索n导出函数:直接引用或者 MmGetSystemRoutineAddressT_MyFunc_declspec(naked) T_MyFunc(……) { _asm { mov edi, edi push ebp mov ebp ,esp //参数压栈,传给MyFunc push [ebp+0ch] push [ebp+8] call MyFunc //获得结果,并跳回原来的 指令 cmp eax,1 jz end mov eax,FuncAddress add eax,5 jmp eaxend: //恢复栈 pop ebp retn 8 } }Naked call 编译器不会给这种函数增加初始化和清理代码,不能用return返回返回值, 只能用插入汇编返回结果。

      //naked 调用约定用户自己清理堆栈不能进行原型声明,否则错误 __declspec(naked) int add(int a,int b) {__asm push ebp //必须加上两句修改栈帧,否则引用了错误的数据__asm mov ebp, esp__asm mov eax, a__asm add eax, b__asm pop ebp__asm ret }这个修饰是和__stdcall及cdecl结合使用的,前面是它和cdecl结合使用的代 码,对于和stdcall结合的代码,则变成: __declspec(naked) int __stdcall function(int a,int b) {__asm mov eax, a__asm add eax, b__asm ret 8 //注意后面的8 }cdecl/fastcall/stdcall/thiscall/nakedcall扩展阅读(重要):Calling convention: T_MyFunc_asm { CLI MOV EAX, CR0 AND EAX, NOT 10000H MOV CR0, EAX } RtlCopyMemory(…);SwapContext inline hookObReferenceObjectByHandleHookPspTerminateProcessHook练习n对这些HOOK加弹框达到允许和禁止目的作业IRP HOOK pDriverObjectMajorFunction[…]IRP HOOKPFILE_OBJECT pFile_tcp = NULL; PDEVICE_OBJECT pDev_tcp = NULL; PDRIVER_OBJECT pDrv_tcpip = NULL; WCHAR deviceTCPName[] = L“\\Device\\Tcp“;typedef NTSTATUS (*OLDIRPMJDEVICECONTROL)(IN PDEVICE_OBJECT, IN PIRP); OLDIRPMJDEVICECONTROL OldIrpMjDeviceControl;NTSTATU。

      点击阅读更多内容
      关于金锄头网 - 版权申诉 - 免责声明 - 诚邀英才 - 联系我们
      手机版 | 川公网安备 51140202000112号 | 经营许可证(蜀ICP备13022795号)
      ©2008-2016 by Sichuan Goldhoe Inc. All Rights Reserved.