某P保护之调戏权限清0的学习。
来源:互联网 发布:mp3音量调节软件 编辑:程序博客网 时间:2024/05/17 23:26
废话不多说啦,直接开干。
我们先来看看ValidAccessMask的值。
通过NtCreateDebugObject来定位。
uf NtCreateDebugObject
地址为fffff800`04011f40
第一个地址就是_object_type的地址
我们想得到的ValidAccessMask存在TypeInfo中,偏移为0x40
由上图可以看出ValidAccessMask的默认值为0x1f000f,此值为0时OD将无法附加,测试一下看看,我们将ValidAccessMask修改为0。
进程已无法附加,可见ValidAccessMask的值的确对我们附加进程造成影响,参考资料得TP是循环的将ValidAccessMask清0,即得出解决方法:1)自己恢复原来的值 2)找到TP清零的位置Nop掉 3)对ValidAccessMask进行移位,这里用最简单的方法一。
写代码时候发现了许多问题。NtCreateDebugObject这个函数在SSDT中,而X64已经没有导出KeServiceDescriptorTable,这里参考了TA大的Win64驱动开发教程,代码拿来即可用,抱着学习的心态来,学习方法和原理,动手。
反汇编KiSystemCall64,这里是内核函数入口。
uf KiSystemCall64,代码很多,贴出关键部分
特征码是:4c8d15c
内核代码开始的地址保存在C0000082寄存器中,读取这个寄存器也很方便,可用__readmsr()函数读取(MSR中文是特别寄存器块),
WinDbg测试看看。
地址相同。
接下来就是获取SSDT函数的地址了,获取地址需要得到函数的Index,方法也简单,也可通过工具获得,还是为了学知识,简单了解一下了。
看框内代码几乎相同,唯一不同的就是第二行代码。(注:这里出了一些问题,在Win10上测试与Win7不同,后续继续研究。)
xxH即为Index,90h转为十进制为144。
至此NtCreateDebugObject地址也得到。
接下来我们要取得ValidAccessMask的地址,还是用特征码定位的方式
至此全部完成,开个定时器修改ValidAccessMask的值就行了,参考了论坛上一位大大的方法,谢谢啦,编译,最激动人心的时候要到了。
成功了尽然,抽根烟压压惊,剩下的路还很长,学习的还很多,继续努力得到第一篇精华。
新手发帖无任何技术含量,望大牛轻喷啊,最后附上源码,代码测试用的,有些凌乱,见谅。
PS:感谢TA大牛提供的Win64驱动编程基础教程与看雪上前辈们分享的文章。
我们先来看看ValidAccessMask的值。
通过NtCreateDebugObject来定位。
uf NtCreateDebugObject
地址为fffff800`04011f40
第一个地址就是_object_type的地址
我们想得到的ValidAccessMask存在TypeInfo中,偏移为0x40
由上图可以看出ValidAccessMask的默认值为0x1f000f,此值为0时OD将无法附加,测试一下看看,我们将ValidAccessMask修改为0。
进程已无法附加,可见ValidAccessMask的值的确对我们附加进程造成影响,参考资料得TP是循环的将ValidAccessMask清0,即得出解决方法:1)自己恢复原来的值 2)找到TP清零的位置Nop掉 3)对ValidAccessMask进行移位,这里用最简单的方法一。
写代码时候发现了许多问题。NtCreateDebugObject这个函数在SSDT中,而X64已经没有导出KeServiceDescriptorTable,这里参考了TA大的Win64驱动开发教程,代码拿来即可用,抱着学习的心态来,学习方法和原理,动手。
反汇编KiSystemCall64,这里是内核函数入口。
uf KiSystemCall64,代码很多,贴出关键部分
特征码是:4c8d15c
内核代码开始的地址保存在C0000082寄存器中,读取这个寄存器也很方便,可用__readmsr()函数读取(MSR中文是特别寄存器块),
WinDbg测试看看。
地址相同。
Code:
/************************************************************************函数名称:GetKeServiceDescriptorTable64函数功能:得到GetKeServiceDescriptorTable64地址************************************************************************/ULONGLONG GetKeServiceDescriptorTable64(){ PUCHAR StatrtSearchAddr = (PUCHAR)__readmsr(0xc0000082); PUCHAR EndSearchAddr = StatrtSearchAddr + 0x500; PUCHAR i = NULL; UCHAR b1 = 0, b2 = 0, b3 = 0; ULONG templong = 0; ULONGLONG addr = 0; for (i = StatrtSearchAddr; i < EndSearchAddr; i++) { if (MmIsAddressValid(i) && MmIsAddressValid(i + 1) && MmIsAddressValid(i + 2)) { b1 = *i; b2 = *(i + 1); b3 = *(i + 2); //fffff800`01ad0772 4c8d15c7202300 lea r10,[nt!KeServiceDescriptorTable (fffff800`01d02840)] if (b1 == 0x4c && b2 == 0x8d && b3 == 0x15) { memcpy(&templong,i + 3,4); addr = (ULONGLONG)templong + (ULONGLONG)i + 7; return addr; } } } return 0;}
看框内代码几乎相同,唯一不同的就是第二行代码。(注:这里出了一些问题,在Win10上测试与Win7不同,后续继续研究。)
xxH即为Index,90h转为十进制为144。
Code:
/************************************************************************函数名称:GetSSDTFunctionAddress函数功能:获得SSDT表地址参 数 :ID号注意:计算方法 ServiceTableBase[index] >> 4 + ServiceTableBase************************************************************************/ULONGLONG GetSSDTFunctionAddress(ULONG id){ LONG dwtmp = 0; PULONG ServiceTableBase = NULL; PSYSTEM_SERVICE_TABLE ssdt = (PSYSTEM_SERVICE_TABLE)GetKeServiceDescriptorTable64(); ServiceTableBase = (PULONG)ssdt->ServiceTableBase; dwtmp = ServiceTableBase[id]; dwtmp = dwtmp >> 4; return dwtmp + (ULONGLONG)ServiceTableBase;}
接下来我们要取得ValidAccessMask的地址,还是用特征码定位的方式
Code:
/************************************************************************函数名称:PassValidAccessMask函数功能:修改ValidAccessMask值为0x1F000F思路:解决调试权限清零 dt _OBJECT_TYPE_INITIALIZER fffffa80`03cdd380+40eq fffffa8003cdd380+40+0x1c 00000000 为0后无法附加************************************************************************/VOID PassValidAccessMask(){ PUCHAR StartSearchAddress = (PUCHAR)GetSSDTFunctionAddress(144); pNtCreateDebugObject = (PVOID)GetSSDTFunctionAddress(144); DbgPrint("pNtCreateDebugObject:%p\n",pNtCreateDebugObject); pTargetAddr = (PVOID)(((ULONG64)pNtCreateDebugObject) + 0x7c); DbgPrint("pTargetAddr:%p\n", pTargetAddr); PUCHAR EndSearchAddress = StartSearchAddress + 0x100; PUCHAR i = 0; UCHAR b1 = 0, b2 = 0, b3 = 0; LONG temp = 0; LONGLONG addr = 0; for (i = StartSearchAddress; i < EndSearchAddress; i++) { if (MmIsAddressValid(i) && MmIsAddressValid(i + 1) && MmIsAddressValid(i + 2)) { b1 = *i; b2 = *(i + 1); b3 = *(i + 2); if (b1 == 0x48 && b2 == 0x8b && b3 == 0x15) { memcpy_s(&temp, 4, i + 3, 4); addr = (LONGLONG)temp + (LONGLONG)i + 7; DbgPrint("ValidAccessMask:%llx\n", *(ULONG *)((*(ULONGLONG *)addr) + 0x40 + 0x1C)); *(ULONG *)((*(ULONGLONG *)addr) + 0x40 + 0x1C) = 0x1f000f; } } }}
成功了尽然,抽根烟压压惊,剩下的路还很长,学习的还很多,继续努力得到第一篇精华。
新手发帖无任何技术含量,望大牛轻喷啊,最后附上源码,代码测试用的,有些凌乱,见谅。
PS:感谢TA大牛提供的Win64驱动编程基础教程与看雪上前辈们分享的文章。
0 0
- 某P保护之调戏权限清0的学习。
- 某P保护之调戏权限清0的学习
- 蓝牙学习之①:调戏小米手环
- 1080P,720P等高清分辨率的含义
- 1080P,720P等高清分辨率的含义
- 1080P,720P等高清分辨率的含义
- 1080P,720P等高清分辨率的含义
- 高清播放知识之 480P、720P、1080P
- Makefile学习之清空目标文件的规则
- camtasia studio导出1080p高清视频的设置
- 保护模式的学习
- 学习笔记:一个操作系统的实现--保护模式之基础知识
- C++ 学习之路(7):共享数据的保护
- 【xv6学习之番外篇】保护
- Android 权限的申明与保护
- C语言之小函数调戏软件
- 调戏源码之Spring MVC(一)
- 调戏源码之Spring MVC(二)
- github常用命令
- MFC中List box的用法
- 礼物[Codevs1321]
- 动态规划
- 在Visual Studio 2010/2012/2013/2015上使用C#开发Android/IOS安装包和操作步骤
- 某P保护之调戏权限清0的学习。
- linux驱动一 设备号的分配和管理
- 判别模型(Discriminative model)和生成模型(Generative model)
- shell脚本设置守护进程
- Android总结--SQLite
- Sublime Text3注册码(可用)
- phpstrom2016.1.2运行项目设置
- 软件工程师必读技术书籍推荐
- 数组中的逆序对37