内核安全笔记

分段模式复习问答
1. 段描述符保存在什么位置? 怎么找到它?
1.1 段描述符保存在内存中, 其内存首地址记录在GDTR寄存器中, GDTR寄存器的是48位.高32位保存地址,低16保存长度.
可以通过`lgdt`指令来设置GDTR寄存器, 通过`sgdt`来获取GDTR寄存器的值.


2. 段描述符都描述了什么?
2.1 描述了段的长度,基地址,属性
2.1.1 P - 描述符是否有效
2.1.2 G - 粒度影响段限长的
2.1.3 S - 段的种类
2.1.3.1 S==1 代码段/数据段
2.1.3.1 S==0 系统段
2.1.4 Type - 段的类型, 受到S位的影响.
2.1.4.1  S==1 代码段/数据段,
2.1.4.1.1  Type最高位 == 1 - 代码段
2.1.4.1.1  Type最高位 == 0 - 数据段
2.1.4.2  S==0
2.1.4.2.1 Type的值表示门描述符的种类
2.1.5 DPL - 段描述符的特权等级
2.1.6 D/B位 - 针对不同的段
2.1.6.1 对于CS段 - 等于1表示32位寻址模式,等于0表示十六位.
2.1.6.2 对于SS段, 等于1默认寄存器是ESP,等于0默认寄存器是SP
2.1.7 AVL - 供软件使用
2.1.8 L - 等于1表示64位代码


3. 段寄存器中保存的值是什么?
3.1 保存的是段选择子, 格式为13-1-2
3.1.1 其中13位表示是段描述符表的下标
3.1.2 其中1位保存的是T1,保存是使用哪个描述符表,等于0表示使用GDT表. 后2位表示RPL(请求特权等级),如果这个段寄存器是CS的话,那么这后2位表示CPL(当前特权等级).

4. 对于下面的指令,执行之后功能是什么?
    mov ax,0x30 ; ax=0x30
    mov fs,ax   ; fs=
    0x30==>13-1-2 ==> 6-0-0
    将GDT表中第6个段描述符加载到FS段寄存器的不可见部分,然后将段选择子0x30保存到FS的可见部分,
    在加载时CPU会做权限检查:
                                      P Si Gr Pr Lo
Sel    Base     Limit     Type    l ze an es ng Flags
---- -------- -------- ---------- - -- -- -- -- --------
0030 84176c00 00003748 Data RW Ac 0 Bg By P  Nl 00000493
    检查的方式是:
    if( CPL <= DPL && RPL <= DPL ){
        // 可以加载
    }
    else{
        // 触发一个异常.
    }
    
    
分页模式复习问答
1. 在非物理地址扩展模式下, 一个虚拟地址的格式是什么? 开启了物理地址扩展模式之后又是什么?
1.1 非PAE模式,虚拟地址格式是: 10-10-12
    10位 - 是页目录首地址
    10位 - 页表首地址
    12位 - 页内偏移
1.2 PAE模式,虚拟地址格式是: 2-9-9-12
    2 - 页目录指针表首地址
    9 - 页目录表首地址
    9 - 页表首地址
   12 - 页内偏移
   
2. 非物理地址扩展模式下,一个进程的页目录基址保存在什么地方?
2.1 保存在CR3寄存器中.

3. 页目录,页表,页内偏移的关系是什么?
3.1 页内偏移总大小占12个比特,然后一个分页是4Kb,12个比特位最大值就是4Kb, 能够表示一个分页内的所有字节.页表保存的是内存分页的首地址, 页目录保存的是页表的首地址.

4. 虚拟地址转译成物理地址的方法是什么?
4.1 根据当前内存管理模式拆成10-10-12/2-9-9-12的格式,
4.2 再找页目录表首地址, 根据虚拟地址拆出来第一部分的值找到页目录的地址.
4.3 再根据虚拟地址拆出来第二部分的值找到页表地址
4.4 再根据虚拟地址拆出来第三部分的值定位到页内偏移.


驱动编程复习问答
1. 内核中的文件路径怎么表示?
1.1 \\??\\文件路径, 用户层的文件路径前加上"\??\"前缀即可.


2. 在内核中,有当前进程的概念, 内核和进程是什么关系, 怎么获取当前进程?
2.1 内核包含了进程 , 一个内核中可以运行多个进程,
2.2 获取当前进程: PsGetCurrentProcess()

3. 在内核中能够随意读写其它进程的内存吗? 怎么解决?
3.1 不能,因为一个虚拟地址要被读写,它先要转换成物理地址,而虚拟地址转换物理地址,需要用到本进程的DirBase(页目录基址),在内核中去读写一个用户层的虚拟地址的时候,默认是使用当前进程的页目录基址去转译虚拟地址的, 因此如果读写其它进程的虚拟地址的话,就需要用到其它进程的页目录基址来转译虚拟地址.
通过进程挂靠可以改变内核中的当前进程.
 - KeStackAttachProcess
 - KeUnstackDetachProcess


4. 进程内核对象和线程内核对象分别使用哪两个结构体表示?
4.1 进程内核对象 - EPROCESS(KPROCESS)
4.2 线程内核对象 - ETHREAD(KTHREAD)


5. 在内核编程中, 如果一个虚拟地址不可写入, 如何将其改为可写?
5.1 MDL ,MDL能够将一个虚拟地址重新映射成另外一个虚拟地址,然后在映射的时候还可以指定这个新的虚拟地址的属性. 映射出来的新虚拟地址和映射前的虚拟地址它们共用一个物理地址.因此,改掉其中一个,物理内存都会产生变化.


驱动通讯复习问答
1. 设备名的格式是什么?
1.1 "\\Device\\设备名"


2. 符号链接名的格式是什么?
2.1 "\\DosDevices\\符号链接名"


4. 打开设备之后, 调用ReadFile时,哪个派遣函数被调用? 怎么在派遣函数中得到ReadFile的参数?
ReadFile(hDevice , pBuff , 100, &size, NULL);
派遣函数 : IRP_MJ_READ 被调用
参数位置 : 
    - 输入缓冲区的保存位置:
          输入缓冲区保存在IRP结构体变量中,
          - UserBuffer : 是用户层直接传进来的虚拟地址
          - Assoxx.SystemBuffer : 系统创建缓冲区,拷贝了用户传入进来的缓冲区的内容.也就是用户缓冲区的一个副本.
          - MdlAddress : 将用户缓冲区使用MDL重新映射.
    - 输入缓冲区的字节数 :
        保存在IO_STACK_COMPLATE中,IO_STACK_COMPLATE.Parmaer.Read.Length.
        

5. DeviceIoControl的CTL_CODE有何作用?
    CTL_CODE由四部分组成:
    - 设备类型 : 一般和设备对象创建时的类型一致.
    - 功能代码 : 自定义的数值, 0~0x800被微软使用了,只能使用0x800以上的代码.
    - 传输类型 : 
        - METHOD_BUFFER : 对缓冲区进行拷贝
        - METHOD_IN_DRIRECT : 对输出缓冲区进行缓冲,对输入的缓冲区使用MDL映射
        - METHOD_OUT_DRIRECT : 对输入缓冲区进行缓冲,对输出缓冲区使用MDL映射
        - METHOD_NEITHER : 两者都不缓冲.
    - 访问权限
        - 对设备对象的访问权限.

6. DeviceIoControl被调用后,内核的哪个派遣函数被调用?输入缓冲区的字节数在派遣上中怎么获取到,输出缓冲区的字节数在派遣上中怎么获取到?
 
6.1 IRP_MJ_DEVICE_CONTROL被调用
6.2 参数保存位置;
    - 输入缓冲区的位置 : Irp.ASSSCXXX.SystemBuffer
    - 输出缓冲区的位置 : 如果使用METHOD_OUT_DRIRECT,则保存在Irp.MdlAddress,如果没有使用, 则还是使用Irp.ASSSCXXX.SystemBuffer(也就是输入和输出缓冲区是同一个)
    - 输入/输出缓冲区的字节数 : IO_STACK_COMPLATE.Parmaer.DeviceContol.InputLenght/IO_STACK_COMPLATE.Parmaer.DeviceContol.OutputLenght
    
 
 
# OBJECT HOOK原理
1. 找到对象原型地址表:ObTypeIndexTable
2. 在表中找到要HOOK的对象的原型,遍历表,使用类型名来找出原型.
3. 通过`OBJECT_TYPE`结构体中的`TypeInfo` 就能找到原型中保存的函数指针
4. 将自定义的函数保存到要HOOK的函数指针中.


BYTE sig[]={0x12,0x34,0x56,0x78,0x9A};
for(BYTE* addr = (BYTE*)0x80000000;
   addr <= 0xFFFFFFFF;
   addr += sizeof(sig))
{
    if(memcmp(addr ,sig,sizeof(sig) ) == 0){
        break;    
    }    
}

1. sdk,DLL工程
1.1 文件的操作,进程/线程API
2. 线程同步/异步IO/网络套接字
3. PE文件格式
4. Windows内存管理
5. Windows的注入和HOOK
6. 异常处理/调试器原理

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值