首页
社区
课程
招聘
[原创]虚拟机视角-读写客户机任意内存(win10)
发表于: 2024-9-26 17:32 7778

[原创]虚拟机视角-读写客户机任意内存(win10)

2024-9-26 17:32
7778

图片描述
基于windows的内存分页机制,进程间的隔离让我们无法直接读写其他进程的地址空间,又因为copy on write让我们即使patch了系统dll也无法影响其他进程。但是这一根内存条就插在主板上,就不能有个方法能看到内容么?
在裸机上如果没有定制的外设是无解了,但是在虚拟化的框架下,这一切都显得再正常不过。

在虚拟化的框架下,客户机的“内存条”实际上是宿主机上申请的一段普通内存,如果我们能够找到GVA与HVA之间的映射关系,就可以绕开任何限制,直接在宿主机上读写任意位置的客户机内存。

我们先暂停vm后,通过KVM_GET_SREGS即可获取cr3寄存器。

gs寄存器在R0下存放的是KPCR,在R3下存放的是TEB

通过偏移计算KTHREAD->KPROCESS->EPROCESS->active_process_links获得这个进程双链表结构,通过遍历active_process_links我们可以获取当前系统所有进程,包括每个进程的CR3。

图片描述
关于windows的分页机制,文档很多不赘述直接贴出部分代码

在能够获取所有进程cr3后,加上页表解析,可以轻松的在host上读写任意guest内存。当我们尝试在host抹掉guest进程notepad中的ntdll的PE头后,由于系统dll的特殊性加上直接修改了物理内存,系统也随之陷入一片混乱 图片描述
图片描述

https://github.com/tenclass/mvisor
使用右ctrl+F8唤起debug窗口,目前仅支持win10 guest。

machine_->Pause();
 
bool success = false;
for (auto vcpu : machine_->vcpus()) {
 struct kvm_sregs sregs;
 if (ioctl(vcpu->fd(), KVM_GET_SREGS, &sregs) < 0)
   MV_PANIC("KVM_GET_REGS failed");
...
machine_->Pause();
 
bool success = false;
for (auto vcpu : machine_->vcpus()) {
 struct kvm_sregs sregs;
 if (ioctl(vcpu->fd(), KVM_GET_SREGS, &sregs) < 0)
   MV_PANIC("KVM_GET_REGS failed");
...
...
if ((sregs.cs.base & 3) != 0) {
  MV_LOG("current vcpu=%d is in usermode", vcpu->vcpu_id());
  continue;
}
 
auto kpcr = (uint8_t*)GuestVAToHostAddress((uint64_t)sregs.gs.base, sregs.cr3);
...
...
if ((sregs.cs.base & 3) != 0) {
  MV_LOG("current vcpu=%d is in usermode", vcpu->vcpu_id());
  continue;
}
 
auto kpcr = (uint8_t*)GuestVAToHostAddress((uint64_t)sregs.gs.base, sregs.cr3);
...
//0xb080 bytes (sizeof)
struct _KPCR
{
    union
    {
        struct _NT_TIB NtTib;                                               //0x0
        struct
        {
            union _KGDTENTRY64* GdtBase;                                    //0x0
            struct _KTSS64* TssBase;                                        //0x8
            ULONGLONG UserRsp;                                              //0x10
            struct _KPCR* Self;                                             //0x18
            struct _KPRCB* CurrentPrcb;                                     //0x20
            struct _KSPIN_LOCK_QUEUE* LockArray;                            //0x28
            VOID* Used_Self;                                                //0x30
        };
    };
    union _KIDTENTRY64* IdtBase;                                            //0x38
    ULONGLONG Unused[2];                                                    //0x40
    UCHAR Irql;                                                             //0x50
    UCHAR SecondLevelCacheAssociativity;                                    //0x51
    UCHAR ObsoleteNumber;                                                   //0x52
    UCHAR Fill0;                                                            //0x53
    ULONG Unused0[3];                                                       //0x54
    USHORT MajorVersion;                                                    //0x60
    USHORT MinorVersion;                                                    //0x62
    ULONG StallScaleFactor;                                                 //0x64
    VOID* Unused1[3];                                                       //0x68
    ULONG KernelReserved[15];                                               //0x80
    ULONG SecondLevelCacheSize;                                             //0xbc
    ULONG HalReserved[16];                                                  //0xc0
    ULONG Unused2;                                                          //0x100
    VOID* KdVersionBlock;                                                   //0x108
    VOID* Unused3;                                                          //0x110
    ULONG PcrAlign1[24];                                                    //0x118
    struct _KPRCB Prcb;                                                     //0x180
};
 
//0x700 bytes (sizeof)
struct _KPRCB
{
    ULONG MxCsr;                                                            //0x0
    UCHAR LegacyNumber;                                                     //0x4
    UCHAR ReservedMustBeZero;                                               //0x5
    UCHAR InterruptRequest;                                                 //0x6
    UCHAR IdleHalt;                                                         //0x7
    struct _KTHREAD* CurrentThread;                                         //0x8
    struct _KTHREAD* NextThread;                                            //0x10
    struct _KTHREAD* IdleThread;                                            //0x18
    UCHAR NestingLevel;                                                     //0x20
    UCHAR ClockOwner;                                                       //0x21
    union
    {
        UCHAR PendingTickFlags;                                             //0x22
        struct
        {
            UCHAR PendingTick:1;                                            //0x22
            UCHAR PendingBackupTick:1;                                      //0x22
        };
    };
    UCHAR IdleState;                                                        //0x23
    ULONG Number;                                                           //0x24
    ULONGLONG RspBase;                                                      //0x28
    ULONGLONG PrcbLock;                                                     //0x30
    CHAR* PriorityState;                                                    //0x38
    CHAR CpuType;                                                           //0x40
    CHAR CpuID;                                                             //0x41
    union
    {
        USHORT CpuStep;                                                     //0x42
        struct
        {
            UCHAR CpuStepping;                                              //0x42
            UCHAR CpuModel;                                                 //0x43
        };
    };
    ULONG MHz;                                                              //0x44
    ULONGLONG HalReserved[8];                                               //0x48
    USHORT MinorVersion;                                                    //0x88
    USHORT MajorVersion;                                                    //0x8a
    UCHAR BuildType;                                                        //0x8c
    UCHAR CpuVendor;                                                        //0x8d
    UCHAR LegacyCoresPerPhysicalProcessor;                                  //0x8e
    UCHAR LegacyLogicalProcessorsPerCore;                                   //0x8f
    ULONGLONG TscFrequency;                                                 //0x90
    ULONG CoresPerPhysicalProcessor;                                        //0x98
    ULONG LogicalProcessorsPerCore;                                         //0x9c
    ULONGLONG PrcbPad04[4];                                                 //0xa0
    struct _KNODE* ParentNode;                                              //0xc0
    ULONGLONG GroupSetMember;                                               //0xc8
    UCHAR Group;                                                            //0xd0
    UCHAR GroupIndex;                                                       //0xd1
    UCHAR PrcbPad05[2];                                                     //0xd2
    ULONG InitialApicId;                                                    //0xd4
    ULONG ScbOffset;                                                        //0xd8
    ULONG ApicMask;                                                         //0xdc
    VOID* AcpiReserved;                                                     //0xe0
    ULONG CFlushSize;                                                       //0xe8
    ULONGLONG PrcbPad11[2];                                                 //0xf0
    struct _KPROCESSOR_STATE ProcessorState;                                //0x100
    struct _XSAVE_AREA_HEADER* ExtendedSupervisorState;                     //0x6c0
    ULONG ProcessorSignature;                                               //0x6c8
    ULONG ProcessorFlags;                                                   //0x6cc
    ULONGLONG PrcbPad12a;                                                   //0x6d0
    ULONGLONG PrcbPad12[3];                                                 //0x6d8
};
//0xb080 bytes (sizeof)
struct _KPCR
{
    union
    {
        struct _NT_TIB NtTib;                                               //0x0
        struct
        {
            union _KGDTENTRY64* GdtBase;                                    //0x0
            struct _KTSS64* TssBase;                                        //0x8
            ULONGLONG UserRsp;                                              //0x10
            struct _KPCR* Self;                                             //0x18
            struct _KPRCB* CurrentPrcb;                                     //0x20
            struct _KSPIN_LOCK_QUEUE* LockArray;                            //0x28
            VOID* Used_Self;                                                //0x30
        };
    };
    union _KIDTENTRY64* IdtBase;                                            //0x38
    ULONGLONG Unused[2];                                                    //0x40
    UCHAR Irql;                                                             //0x50
    UCHAR SecondLevelCacheAssociativity;                                    //0x51
    UCHAR ObsoleteNumber;                                                   //0x52
    UCHAR Fill0;                                                            //0x53
    ULONG Unused0[3];                                                       //0x54
    USHORT MajorVersion;                                                    //0x60
    USHORT MinorVersion;                                                    //0x62
    ULONG StallScaleFactor;                                                 //0x64
    VOID* Unused1[3];                                                       //0x68
    ULONG KernelReserved[15];                                               //0x80
    ULONG SecondLevelCacheSize;                                             //0xbc
    ULONG HalReserved[16];                                                  //0xc0
    ULONG Unused2;                                                          //0x100
    VOID* KdVersionBlock;                                                   //0x108
    VOID* Unused3;                                                          //0x110
    ULONG PcrAlign1[24];                                                    //0x118
    struct _KPRCB Prcb;                                                     //0x180
};
 
//0x700 bytes (sizeof)
struct _KPRCB
{
    ULONG MxCsr;                                                            //0x0
    UCHAR LegacyNumber;                                                     //0x4
    UCHAR ReservedMustBeZero;                                               //0x5
    UCHAR InterruptRequest;                                                 //0x6
    UCHAR IdleHalt;                                                         //0x7
    struct _KTHREAD* CurrentThread;                                         //0x8
    struct _KTHREAD* NextThread;                                            //0x10
    struct _KTHREAD* IdleThread;                                            //0x18
    UCHAR NestingLevel;                                                     //0x20
    UCHAR ClockOwner;                                                       //0x21
    union
    {
        UCHAR PendingTickFlags;                                             //0x22
        struct
        {
            UCHAR PendingTick:1;                                            //0x22
            UCHAR PendingBackupTick:1;                                      //0x22
        };
    };
    UCHAR IdleState;                                                        //0x23
    ULONG Number;                                                           //0x24
    ULONGLONG RspBase;                                                      //0x28
    ULONGLONG PrcbLock;                                                     //0x30
    CHAR* PriorityState;                                                    //0x38
    CHAR CpuType;                                                           //0x40
    CHAR CpuID;                                                             //0x41
    union
    {
        USHORT CpuStep;                                                     //0x42
        struct
        {
            UCHAR CpuStepping;                                              //0x42
            UCHAR CpuModel;                                                 //0x43
        };
    };

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

最后于 2024-9-27 13:39 被Justgoon编辑 ,原因:
收藏
免费 7
支持
分享
最新回复 (6)
雪    币: 30
活跃值: (799)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
楼主太帅了1
2024-10-6 18:40
0
雪    币: 4776
活跃值: (4474)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
KVM_GET_REGS是编译的kvm的源码吗
2024-10-6 18:53
0
雪    币: 413
活跃值: (722)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
4
牛人,真是不错。术业有专攻
2024-10-9 09:58
0
雪    币: 635
活跃值: (1021)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
5
木志本柯 KVM_GET_REGS是编译的kvm的源码吗
kvm提供的接口,用来获取vm寄存器信息的,mvisor/qemu这样的虚拟机都是通过kvm的接口来控制虚拟机
2024-10-10 23:49
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
6
这个方法有时候会解析不正确是啥导致的
2024-12-5 05:34
0
雪    币: 635
活跃值: (1021)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
7
mb_juuexlrb 这个方法有时候会解析不正确是啥导致的
不正确是什么意思?出发page fault了么,guest里面如果缺页目前没有处理,没想到好办法,如果想验证的话可以用processhacker在vm内访问一下那块内存,然后就可以在外面解出来了;也有可能是windows10版本问题,我用的偏移是22h2 19045
5天前
0
游客
登录 | 注册 方可回帖
返回
//