Win7 64位的SSDTHOOK(2)---64位SSDT hook的实现
Hook之前要干掉PG:http://www.m5home.com/bbs/thread-5893-1-1.html
上篇文章知道了寻找SSDT表的方法,这篇记录一下如何实现SSDT表的Hook。
下面以Hook NtOpenProcess为例,之前我查SSDT表发现NtOpenProcess函数的标号为35,用XT等工具也能查看。
废话不多说,上代码。
- 首先感谢老大(Tesla.Angela)对我的帮助
- //相关声明
- __int64 __readmsr(int register);
- unsigned __int64 __readcr0(void);
- void __writecr0(
- unsigned __int64 Data
- );
- void _disable(void);
- void _enable(void);
- //_SYSTEM_SERVICE_TABLE结构声明
- typedef struct _SYSTEM_SERVICE_TABLE{
- PVOID ServiceTableBase;
- PVOID ServiceCounterTableBase;
- ULONGLONG NumberOfServices;
- PVOID ParamTableBase;
- } SYSTEM_SERVICE_TABLE, *PSYSTEM_SERVICE_TABLE;
- //_SERVICE_DESCRIPTOR_TABLE结构声明
- typedef struct _SERVICE_DESCRIPTOR_TABLE{
- SYSTEM_SERVICE_TABLE ntoskrnl; // ntoskrnl.exe (native api)
- SYSTEM_SERVICE_TABLE win32k; // win32k.sys (gdi/user)
- SYSTEM_SERVICE_TABLE Table3; // not used
- SYSTEM_SERVICE_TABLE Table4; // not used
- }SERVICE_DESCRIPTOR_TABLE,*PSERVICE_DESCRIPTOR_TABLE;
- //声明要寻找进程名用的函数
- NTKERNELAPI UCHAR * PsGetProcessImageFileName(PEPROCESS Process);
- //定义NTOPENPROCESS
- typedef NTSTATUS (__stdcall *NTOPENPROCESS)(OUT PHANDLE ProcessHandle,
- IN ACCESS_MASK DesiredAccess,
- IN POBJECT_ATTRIBUTES ObjectAttributes,
- IN OPTIONAL PCLIENT_ID ClientId);
- NTOPENPROCESS OldOpenProcess = NULL;
- ULONG OldTpVal;
- //定义自己的NtOpenProcess
- NTSTATUS __stdcall Fake_NtOpenProcess(OUT PHANDLE ProcessHandle,
- IN ACCESS_MASK DesiredAccess,
- IN POBJECT_ATTRIBUTES ObjectAttributes,
- IN OPTIONAL PCLIENT_ID ClientId)
- {
- PEPROCESS process = NULL;
- NTSTATUS st = ObReferenceObjectByHandle(<span style="font-family: Arial, Helvetica, sans-serif;">ClientId->processid</span>
- ,0,*PsProcessType,KernelMode,&process,NULL);
- DbgPrint("进入HOOK函数.\n");
- if (NT_SUCCESS(st))
- {
- if (!_stricmp((char*)PsGetProcessImageFileName(process),"CrackMe3.exe"))
- {
- return STATUS_ACCESS_DENIED;
- }
- else
- {
- return OldOpenProcess(ProcessHandle,DesiredAccess,ObjectAttributes,ClientId);
- }
- }
- else
- {
- return STATUS_ACCESS_DENIED;
- }
- }
- //关闭页面保护
- KIRQL WPOFFx64()
- {
- KIRQL irql=KeRaiseIrqlToDpcLevel();
- UINT64 cr0=__readcr0();
- cr0 &= 0xfffffffffffeffff;
- __writecr0(cr0);
- _disable();
- return irql;
- }
- //开启页面保护
- void WPONx64(KIRQL irql)
- {
- UINT64 cr0=__readcr0();
- cr0 |= 0x10000;
- _enable();
- __writecr0(cr0);
- KeLowerIrql(irql);
- }
- //老外定位KeServiceDescriptorTable的方法
- ULONGLONG GetKeServiceDescriptorTable64()
- {
- char KiSystemServiceStart_pattern[] = "\x8B\xF8\xC1\xEF\x07\x83\xE7\x20\x25\xFF\x0F\x00\x00"; //特征码
- ULONGLONG CodeScanStart = (ULONGLONG)&_strnicmp;
- ULONGLONG CodeScanEnd = (ULONGLONG)&KdDebuggerNotPresent;
- UNICODE_STRING Symbol;
- ULONGLONG i, tbl_address, b;
- for (i = 0; i < CodeScanEnd - CodeScanStart; i++)
- {
- if (!memcmp((char*)(ULONGLONG)CodeScanStart +i, (char*)KiSystemServiceStart_pattern,13))
- {
- for (b = 0; b < 50; b++)
- {
- tbl_address = ((ULONGLONG)CodeScanStart+i+b);
- if (*(USHORT*) ((ULONGLONG)tbl_address ) == (USHORT)0x8d4c)
- return ((LONGLONG)tbl_address +7) + *(LONG*)(tbl_address +3);
- }
- }
- }
- return 0;
- }
- //根据KeServiceDescriptorTable找到SSDT基址
- PULONG GetSSDTBaseAddress()
- {
- PULONG addr = NULL;
- PSYSTEM_SERVICE_TABLE ssdt = (PSYSTEM_SERVICE_TABLE)GetKeServiceDescriptorTable64();
- addr = (PULONG)(ssdt->ServiceTableBase);
- return addr;
- }
- //根据标号找到SSDT表中函数的地址
- ULONGLONG GetFuncAddr(ULONG id)
- {
- LONG dwtmp = 0;
- ULONGLONG addr = 0;
- PULONG stb = NULL;
- stb = GetSSDTBaseAddress();
- dwtmp = stb[id];
- dwtmp = dwtmp >> 4;
- addr = (LONGLONG)dwtmp + (ULONGLONG)stb;
- DbgPrint("SSDT TABLE BASEADDRESS:%llx",addr);
- return addr;
- }
- //设置函数的偏移地址,注意其中参数的处理。低四位放了参数个数减4个参数。如果参数小于等于4的时候为0
- #define SETBIT(x,y) x|=(1<<y) //将X的第Y位置1
- #define CLRBIT(x,y) x&=~(1<<y) //将X的第Y位清0
- #define GETBIT(x,y) (x & (1 << y)) //取X的第Y位,返回0或非0
- ULONG GetOffsetAddress(ULONGLONG FuncAddr, CHAR paramCount)
- {
- LONG dwtmp = 0,i;
- CHAR b = 0, bits[4] = {0};
- PULONG stb = NULL;
- stb = GetSSDTBaseAddress();
- dwtmp = (LONG)(FuncAddr - (ULONGLONG)stb);
- dwtmp = dwtmp << 4;
- if (paramCount>4)
- {
- paramCount = paramCount - 4;
- }
- else
- {
- paramCount = 0;
- }
- memcpy(&b,&dwtmp,1);
- for (i=0;i<4;i++)
- {
- bits[i] = GETBIT(paramCount,i);
- if (bits[i])
- {
- SETBIT(b,i);
- }
- else
- {
- CLRBIT(b,i);
- }
- }
- memcpy(&dwtmp,&b,1);
- return dwtmp;
- }
- //内核中用不到的方法,二次跳转用(自己的NtOpenProcess跳到KeBugCheckEx函数,然后再KeBugCheckEx函数跳到要Hook的NtOpenProcess)
- VOID FuckKeBugCheckEx()
- {
- KIRQL irql;
- ULONGLONG myfun;
- UCHAR jmp_code[]="\xFF\x25\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF";
- myfun=(ULONGLONG)Fake_NtOpenProcess;
- memcpy(jmp_code+6,&myfun,8);
- irql=WPOFFx64();
- memset(KeBugCheckEx,0x90,15);
- memcpy(KeBugCheckEx,jmp_code,14);
- WPONx64(irql);
- }
- //Hook ssdt
- VOID HookSSDT()
- {
- KIRQL irql;
- LONG dwtmp = 0;
- PULONG stb = NULL;
- //1.get old address
- OldOpenProcess = (NTOPENPROCESS)GetFuncAddr(35);
- DbgPrint("Old_NtOpenProcess:%llx",(ULONGLONG)OldOpenProcess);
- //2.show new address
- stb = GetSSDTBaseAddress();
- //3.get offset value
- dwtmp = GetOffsetAddress((ULONGLONG)KeBugCheckEx,4);
- //set kebugcheckex
- FuckKeBugCheckEx();
- //4.record old offset value
- OldTpVal = stb[35];
- irql = WPOFFx64();
- stb[35] = GetOffsetAddress((ULONGLONG)KeBugCheckEx,2);
- WPONx64(irql);
- DbgPrint("KeBugCheckEx:%llx",(ULONGLONG)KeBugCheckEx);
- DbgPrint("New_NtOpenProcess:%llx",GetFuncAddr(35));
- }
- //UN hook
- VOID UnhookSSDT()
- {
- KIRQL irql;
- PULONG stb=NULL;
- stb = GetSSDTBaseAddress();
- //老函数的地址复制回来
- irql=WPOFFx64();
- stb[35]=OldTpVal;
- WPONx64(irql);
- }
相关解释:
1.为什么要二次跳转?
WIN64内核里的每个驱动都不在同一个4GB里,4字节的整数只能表示4GB的范围,所以不管怎么修改这个4字节都不会跳到你的代理函数,因为你的驱动不可能跟NTOSKRNL在同一个4GB里面。
2.参数的处理:
函数地址的低四位存放了函数参数个数减4的数字,如果参数为5,那么低四位的数字为1,如果参数个数小于等于4个,低四位的数位0,可以再WINDBG里面查看到。
Win7 64位的SSDTHOOK(2)---64位SSDT hook的实现相关推荐
- Win7 64位的SSDTHOOK(1)---SSDT表的寻找
最近在学习64位驱动,涉及到了SSDT的知识,结果发现64位下的SSDT和32位下的SSDT有所不同. 开始发现64位下的KeServiceDescriptorTable是未导出的函数.首先要找到Ke ...
- 雨林木风 GHOST WIN7 SP1 X64旗舰装机版(64位)2014.05 系统下载
最新 雨林木风 GHOST WIN7 SP1 X64旗舰装机版(64位)2014.05 系统下载系统下载,由系统下载吧率先分享: 雨林木风 GHOST WIN7 SP1 X64旗舰装机版(64位)20 ...
- 图解无约而来Win7 33in1 V1.3 32位与64位合一(版本齐全装机利器)
图解无约而来Win7 33in1 V1.3 32位与64位合一(版本齐全装机利器) 2012-07-17 11:32:31| 分类: 默认分类 | 标签: |字号大中小 订阅 无约而来近日发布了将 ...
- 64位计算机不能运行32位游戏,我想玩个游戏,仅支援64位系统,我家电脑win7 32位的,怎么办求解决方法...
我想玩个游戏,仅支援64位系统,我家电脑win7 32位的,怎么办求解决方法以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧 ...
- Win7可用的笔记本电池校正软件( 64、32位)
Win7可用的笔记本电池校正软件( 64.32位) BatteryMon2.1-Win7可用.rar (258.7 KB)
- win7 64位系统连接xp 32位共享打印机办法
局域网内有台server2003_32位系统的共享打印机,xp系统用\\ip地址 能直接连上 但win7_64位的用\\ip 连接是连不上的 会提示缺少驱动. 我们可以在共享打印机上添加64位的驱动让 ...
- 64位 pb12 win7 数据源_64位系统用32位powerbuilder9.0链接64位oracle12c
64 位系统下用 32 位 power builder9.0 链接 64 位 oracle12c 1. 在 32 位的 power builder9.0 里链接 64 位 oracle12c 时, 会 ...
- 64 大小_电脑系统32位和64位有什么区别
众所周知,windows系统有32位和64位,但这两者有什么不同呢?什么样的电脑装什么版本的呢?笔者就简单的来讲一下两者的区别. 一.支持的内存不同 32位的操作系统,最多支持4G的内存,实际内存为3 ...
- 64位计算机安装32位,64位电脑装32位系统,小编教你64位电脑怎么装32位系统
对电脑有深入了解的用户就知道,64位电脑一般指的是CPU是64位处理器,64位机器要安装64位系统,发挥硬件最佳性能,当然了,64位电脑也可以装32位系统,因为64位电脑是向下兼容,支持64位系统也支 ...
最新文章
- javascript 通过键获取值
- win7 重启 IIS.
- python正则表达式模块_Python正则表达式函数模块
- helm离线安装helm-push插件
- cacti+nagios 整合遇到的问题
- java vector实现的接口_java的List接口的实现类 ArrayList,LinkedList,Vector 的区别
- php root权限执行命令,如何使用PHP执行需要root权限的系统命令
- 演义群侠传(五)【素材方式MC or SpriteSheet】
- linux moxa 多串口卡_MOXA多串口卡C32030TCPU模块双RISC-based处理器架构大幅提升I/O数据传输的效能达到8口或以上...
- 【Java项目实战】黄金矿工小游戏项目介绍
- Localhost到底是干什么用的?
- BZOJ 2429: [HAOI2006]聪明的猴子
- 2008年8月27号,星期三,晴。锲而舍之,朽木不折;锲而不舍,金石可镂。 ——《荀子•劝学》2008年8月27号,星期三,晴。
- 超声的pacs系统和dicom服务器,基于DICOM的PACS系统设计与实现
- 软件架构设计---软件架构风格
- 【对比分析】vipkid和51talk哪个好?说说我的亲身经历!
- axure转化成代码_​教大家如何查看Axure页面的代码
- IntelliJ idea (最新版)激活方法
- webstorm配置和使用
- Day19(可变参数,增强for循环遍历,泛型通配符<?>,TreeSet,LinkedHashSet,集合的嵌套遍历,Set集合,静态导入,)