首页 > 系统相关 >驱动内存加载[理论]

驱动内存加载[理论]

时间:2024-05-18 17:34:17浏览次数:14  
标签:eax init cookie 内存 驱动 DWORD security ___ 加载

07 驱动内存加载

驱动加载介绍

内存驱动加载不需要签名

双击一个PE程序的时候发生了什么

1.通过explorer.exe(资源管理器)定位到双击的文件

2.资源管理器通过CreatProcess创建进程

3.创建进程的时候开辟一块空间

此时在R3(PEB)和R0(填充基址)需要的地方挂上R3的物理页

4.通过文件路径载入PE

5.接下来是修复和解析

  1. 解析PE头,将对应的数据目录存放到内存相关的偏移地址
  2. 修复重定位,有可能出现随机基址,或者指定的地址被占用,这样的话基址就被修改了,所以要修复重定位
  3. 修复IAT(系统相关函数)导入表,比如在win7、win10都有一个函数,但是函数地址不一样
  4. 修复TLS(线程)
  5. 修复延迟导入表,再一次去用才修复的
  6. 修复SEH异常
  7. 获取入口点
  8. call 入口点

上面的这些驱动加载的时候都有,唯一不同的是驱动加载的时候没有修复和解析中的45也就是修复TLS,和修复异常导入表,不过在驱动中多修复一个cookie

实验(COOKIE不对的情况)

这里为了做演示将Driver Settings -> Target OS Version改成Win10

然后在win7虚拟机里面执行会蓝屏

接下来分析一下

可以在IP这里看到这里有个security_init_cookie出问题了

从调用栈这里也可以看到

先是DriverEntry驱动入口点,然后执行了一个__security_init_cookie+0x1b的操作,然后就发生错误(RtlFailFast)

但是很显然这个__security_init_cookie不是我们自己写的,所以接下来用ida看一下

然后我们进去看一下这个call的cookie做了什么操作

代码很简单,可以直接看下面的说明

; void __cdecl __security_init_cookie()
___security_init_cookie proc near       ; CODE XREF: DriverEntry+5↑p
mov     eax, ___security_cookie         ; 获取当前的security_cookie值保存到eax中
test    eax, eax                        ; 将eax值与运算,判断eax是否是0
jz      short loc_404028                ; 如果是是0,崩溃

cmp     eax, 0BB40E64Eh                 ; 将eax值与0BB40E64Eh比较
jz      short loc_404028                ; 相等崩溃

not     eax                             ; 将eax取反
mov     dword_403004, eax               ; dword_403004 = eax
retn                                    ; 返回

; ---------------------------------------------------------------------------

loc_404028:                             ; CODE XREF: ___security_init_cookie+7↑j
                                        ; ___security_init_cookie+E↑j
push    6
pop     ecx
int     29h                             ; Win8: RtlFailFast(ecx)

___security_init_cookie endp

也可以看一下伪c代码,基本一样

接下来我们把Driver Settings -> Target OS Version改成Win7,再编译一样,放到ida看一下

; void __cdecl __security_init_cookie()
___security_init_cookie proc near       ; CODE XREF: DriverEntry+5↑p
mov     edi, edi
push    ebp
mov     ebp, esp
push    ecx
push    ecx
mov     eax, ___security_cookie         ; 将当前的cookie值保存到eax
mov     ecx, 0BB40E64Eh                 ; ecx = 0BB40E64Eh
test    eax, eax                        ; 比较eax是否是0
jz      short loc_404029                ; 如果真,跳到loc_404029

cmp     eax, ecx                        ; 比较eax和ecx
jnz     short loc_40403E                ; 如果真,跳到loc_40403E


loc_404029:                             ; CODE XREF: ___security_init_cookie+13↑j
rdtsc                                   ; 获取CPU运行至今的时间周期,eax保存低位,edx保存高位
xor     eax, offset ___security_cookie  ; 将eax值与cookie异或,因为能够跳到这里的cookie都是0,所以eax不变
mov     ___security_cookie, eax         ; cookie = eax
jnz     short loc_40403E                ; eax值取反

mov     eax, ecx                        ; eax = ecx = 0BB40E64Eh
mov     ___security_cookie, eax         ; cookie = eax


loc_40403E:                             ; CODE XREF: ___security_init_cookie+17↑j
                                        ; ___security_init_cookie+25↑j
not     eax                             ; eax值取反
mov     dword_403004, eax               ; dword_403004 = eax
leave
retn

___security_init_cookie endp

可以很明显的看出来Win7有自我修复的步骤,一旦cookie不存在或者是特定值都会进行自我修复

这也是为什么在Win7下可以不修复cookie但是在win10高版本下必须要修复cookie,因为win10的这个蓝屏机制就是通过检查cookie来防止内存加载

修复方式

但是这个SecurityCookie是在IMAGE_LOAD_CONFIG_DIRECTORY结构体中的(不知道为什么Windbg找不到这个结构体)

这个结构体分32位和64位,具体可以看微软文档

从中可以很明显的看到这个Cookie

IMAGE_LOAD_CONFIG_DIRECTORY结构体

typedef struct _IMAGE_LOAD_CONFIG_DIRECTORY32 {
  DWORD                            Size;
  DWORD                            TimeDateStamp;
  WORD                             MajorVersion;
  WORD                             MinorVersion;
  DWORD                            GlobalFlagsClear;
  DWORD                            GlobalFlagsSet;
  DWORD                            CriticalSectionDefaultTimeout;
  DWORD                            DeCommitFreeBlockThreshold;
  DWORD                            DeCommitTotalFreeThreshold;
  DWORD                            LockPrefixTable;
  DWORD                            MaximumAllocationSize;
  DWORD                            VirtualMemoryThreshold;
  DWORD                            ProcessHeapFlags;
  DWORD                            ProcessAffinityMask;
  WORD                             CSDVersion;
  WORD                             DependentLoadFlags;
  DWORD                            EditList;
  DWORD                            SecurityCookie;
  DWORD                            SEHandlerTable;
  DWORD                            SEHandlerCount;
  DWORD                            GuardCFCheckFunctionPointer;
  DWORD                            GuardCFDispatchFunctionPointer;
  DWORD                            GuardCFFunctionTable;
  DWORD                            GuardCFFunctionCount;
  DWORD                            GuardFlags;
  IMAGE_LOAD_CONFIG_CODE_INTEGRITY CodeIntegrity;
  DWORD                            GuardAddressTakenIatEntryTable;
  DWORD                            GuardAddressTakenIatEntryCount;
  DWORD                            GuardLongJumpTargetTable;
  DWORD                            GuardLongJumpTargetCount;
  DWORD                            DynamicValueRelocTable;
  DWORD                            CHPEMetadataPointer;
  DWORD                            GuardRFFailureRoutine;
  DWORD                            GuardRFFailureRoutineFunctionPointer;
  DWORD                            DynamicValueRelocTableOffset;
  WORD                             DynamicValueRelocTableSection;
  WORD                             Reserved2;
  DWORD                            GuardRFVerifyStackPointerFunctionPointer;
  DWORD                            HotPatchTableOffset;
  DWORD                            Reserved3;
  DWORD                            EnclaveConfigurationPointer;
  DWORD                            VolatileMetadataPointer;
  DWORD                            GuardEHContinuationTable;
  DWORD                            GuardEHContinuationCount;
  DWORD                            GuardXFGCheckFunctionPointer;
  DWORD                            GuardXFGDispatchFunctionPointer;
  DWORD                            GuardXFGTableDispatchFunctionPointer;
  DWORD                            CastGuardOsDeterminedFailureMode;
  DWORD                            GuardMemcpyFunctionPointer;
} IMAGE_LOAD_CONFIG_DIRECTORY32, *PIMAGE_LOAD_CONFIG_DIRECTORY32;

很显然,既然结构体里面有,我们就能改

32位程序内存加载

其中签名目录记录了程序的签名信息,可以通过这个目录得到程序的签名

其中异常目录在x86下一直是空的,x64下才有值,因为x86不使用资源目录保存异常

标签:eax,init,cookie,内存,驱动,DWORD,security,___,加载
From: https://www.cnblogs.com/murkuo/p/18199524

相关文章

  • 驱动通信2
    06通信封装缓冲区模式看这段代码#defineTESTCTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS)其中的METHOD_BUFFERED字符就是缓冲区模式f12进去后可也发现有三种缓冲区模式#defineMETHOD_BUFFERED0//缓冲#defineMETHO......
  • 驱动内存加载[实战]
    08驱动内存加载[项目]目标:实现一个加载器,让驱动不落地加载DOS头和NT头DOS头kd>dt_IMAGE_DOS_HEADER-r3ntdll!_IMAGE_DOS_HEADER+0x000e_magic:Uint2B+0x002e_cblp:Uint2B+0x004e_cp:Uint2B+0x006e_crlc......
  • 驱动基础
    01HelloWorld驱动基础知识驱动不是进程,本质上和DLL一样是模块NT驱动:如果绑定设备,不能卸载WDM驱动:热拔插,可以更新卸载WDF驱动:简化开发,相当于事件驱动机制,依赖环境KWDF驱动:内核驱动框架UWDF驱动:用户驱动框架(支持在用户下运行的)学的主要是NF和WDM驱动驱动内存不共享驱动文......
  • 驱动基础2
    02驱动基础基础类型基础数据类型在驱动中用基础数据类型需要用大写R3R0intINTshortSHORTcharCHARlongLONGunsightedcharUCHAR指针是在前面加PNTSTATUSNTSTATUS本质上是LONGNTSTATUS>=0成功NTSTATUS<0失败判断NTSTATUS是否成......
  • 驱动断链
    03驱动断链获取驱动信息的途径是从Driver和FileSystem两个目录下获得的正常情况下我们自己做驱动遍历只能便利Driver下的所有驱动,也就是驱动链表里的驱动分析这里我们F12进去找一下DRIVER_OBJECT的结构typedefstruct_DRIVER_OBJECT*PDRIVER_OBJECT;WinDbg里dt一下kd......
  • Angular-测试驱动开发-全-
    Angular测试驱动开发(全)原文:zh.annas-archive.org/md5/60F96C36D64CD0F22F8885CC69A834D2译者:飞龙协议:CCBY-NC-SA4.0前言本书将为读者提供一个关于JavaScript测试驱动开发(TDD)的完整指南,然后深入探讨Angular的方法。它将提供清晰的、逐步的示例,不断强调TDD的最佳实......
  • ServiceHub.DataWarehouseHost.exe内存占用过高
    最近在优化WCS系统中同层调度多辆车子的功能,功能写完后,顺手写了个仿真的脚本,模拟车辆动作。准备测试下合理性。但是使用VS2022进行调试时,刚调试时程序响应很快,因为总是被领导喊去参加各种会议,忙完回来,准备继续测试时,程序响应总是很慢,一开始没注意,以为是许久不开发,电脑配置跟......
  • [转帖]JVM内存配置最佳实践
     https://help.aliyun.com/zh/sae/use-cases/best-practices-for-jvm-heap-size-configuration   如果JVM堆空间大小设置过大,可能会导致Linux系统的OOMKiller被激活,进而结束(kill)Java应用进程,在容器环境下可能会表现为频繁异常重启。本文介绍在容器环境下JVM......
  • Golang初学:获取程序内存使用情况,std runtime
    goversiongo1.22.1windows/amd64Windows11+amd64x86_64x86_64GNU/Linux--- 序章本文介绍golang程序占用内存的监控:使用stdruntime的ReadMemStats函数。 ReadMemStats函数https://pkg.go.dev/[email protected]//函数funcReadMemStats(m*MemStats......
  • struct和malloc内存互转例子
    #include<iostream>typedefstructDS1001{unsignedinta;unsignedcharb;unsignedintc;unsignedchard;unsignedshorte;}DS1001;voidTestMallocToStruct(){intnsize=sizeof(DS1001);unsignedchar*mallocdat......