首页
社区
课程
招聘
[求助][求助] NewBluePill 中获取Gdt描述符的 各属性字段所使用的方法
发表于: 2018-5-18 10:11 2911

[求助][求助] NewBluePill 中获取Gdt描述符的 各属性字段所使用的方法

2018-5-18 10:11
2911

typedef union
{
USHORT UCHARs;
struct
{
USHORT type:4;              /* 0;  Bit 40-43 */
USHORT s:1;                 /* 4;  Bit 44 */
USHORT dpl:2;               /* 5;  Bit 45-46 */
USHORT p:1;                 /* 7;  Bit 47 */
// gap!       
USHORT avl:1;               /* 8;  Bit 52 */
USHORT l:1;                 /* 9;  Bit 53 */
USHORT db:1;                /* 10; Bit 54 */
USHORT g:1;                 /* 11; Bit 55 */
USHORT Gap:4;
} fields;
} SEGMENT_ATTRIBUTES;

typedef struct _SEGMENT_SELECTOR
{
USHORT sel;
SEGMENT_ATTRIBUTES attributes;
ULONG limit;
ULONG64 base;
} SEGMENT_SELECTOR, *PSEGMENT_SELECTOR;

typedef struct
{
USHORT limit0;
USHORT base0;
UCHAR  base1;
UCHAR  attr0;
UCHAR  limit1attr1;
UCHAR  base2;
} SEGMENT_DESCRIPTOR2, *PSEGMENT_DESCRIPTOR2;

NTSTATUS InitializeSegmentSelector( PSEGMENT_SELECTOR SegmentSelector,      //代表 段寄存器 得结构体
                               USHORT Selector,                    //当前段寄存器得值 ,这里只是选择子得值
                               ULONG64 GdtBase )                   //GDT表得基地址   
{
PSEGMENT_DESCRIPTOR2 SegDesc;                                                                 
SegDesc = ( PSEGMENT_DESCRIPTOR2 )( ( PUCHAR ) GdtBase + ( Selector & ~0x7 ) );                           //在GDT表中得到段描述符得地址
               

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
SegmentSelector->attributes.UCHARs = SegDesc->attr0 | ( SegDesc->limit1attr1 & 0xf0 ) << 4;            

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


return STATUS_SUCCESS;
}

NTSTATUS FillGuestSelectorData(ULONG64 GdtBase, //GDT基地址  ///////////////////////////////////////////////////////////////入口在这里
                          ULONG Segreg,    // 要写入的段寄存器
                          USHORT Selector   //读取到的当前段的选择子
)
{
SEGMENT_SELECTOR SegmentSelector = { 0 };  
ULONG uAccessRights;

InitializeSegmentSelector(&SegmentSelector, Selector, GdtBase);     
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++             
uAccessRights = ((PUCHAR)& SegmentSelector.attributes)[0] + (((PUCHAR)&           
SegmentSelector.attributes)[1] << 12);
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
return STATUS_SUCCESS;
}

这是NewBluePill 中提取GDT段描述符中的  各个属性字段填写VMCS 中的段寄存器的 代码,,我想咨询的代码如下
SegmentSelector->attributes.UCHARs = SegDesc->attr0 | ( SegDesc->limit1attr1 & 0xf0 ) << 4;  
该代码提取  段描述符的属性字段  ,最终得到 attributes 的所有12个BIT 的值去除掉了Limit 位写入一个结构体 ,然吧该结构体分为两个Uchar做加法运算

uAccessRights = ((PUCHAR)& SegmentSelector.attributes)[0] + (((PUCHAR)&           

SegmentSelector.attributes)[1] << 12);

我不能理解为何要这么操作而不是在 取 attributes 的时候 直接《《8位     代码如下   
SegmentSelector->attributes.UCHARs = SegDesc->attr0 | ( SegDesc->limit1attr1 & 0xf0 ) << 8;  
这样 得到的最终 结果和 NewBluePill中得到的 attributes 值是一样的 ,,,但是当写入 vmcs中的字段并开启VT后就会出错,,
我最终想请教 大家的就是  为何NewBluePill要使用那么复杂的 方法获取  attributes ,,,而 通过《《8位的方法为什么又不行,毕竟他们最终得到的值 是相同的


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

最后于 2018-5-18 10:13 被兔oO编辑 ,原因:
收藏
免费 0
支持
分享
最新回复 (3)
雪    币: 8835
活跃值: (2404)
能力值: ( LV12,RANK:760 )
在线值:
发帖
回帖
粉丝
2
<<8和<<4怎么可能一样



2018-5-18 11:52
0
雪    币: 177
活跃值: (28)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
问题得到了解决    多谢大佬回答
2018-6-9 10:31
0
雪    币: 177
活跃值: (28)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
原来是我获取的时候出现了问题  》》新手填写这些段  寄存器  真的很苦逼~~经常出错
2018-6-10 08:21
0
游客
登录 | 注册 方可回帖
返回
//