首页
社区
课程
招聘
[已解决] x64 远程跳转实验
发表于: 2020-8-6 12:50 4017

[已解决] x64 远程跳转实验

2020-8-6 12:50
4017

求助x64 远程跳转 需要执行的步骤,以下的代码会导致死机。
使用的步骤是
申请2块内存 p1和p2, p1用来存放当前信息,p2用来存放目标区域信息

 

创建目标区域cr3内存,并将CR3初始化,添加将要用到的TLB条目
在AsmTest1中保存当前信息
加装gdtr, idtr(目前使用的是系统的,将来准备自己创建)
加装目标代码 CR3
加装选择子 ds es ss fs
希望通过 retfq 跳转到 AsmTest2 死机了。
求大神指点,跨段跳转的具体步骤与正确方法。

Idtr64 struct
    limit   WORD    ?
    base    QWORD   ?
Idtr64 ends
Gdtr64 struct
    limit   WORD    ?
    base    QWORD   ?
Gdtr64 ends
context_info    struct
    gdtr        Gdtr64      <>
    idtr        Idtr64      <>
    reg_cr0     QWORD       ?
    reg_cr3     QWORD       ?
    reg_ss      WORD        ?
    reg_ds      WORD        ?
    reg_es      WORD        ?
    reg_fs      WORD        ?
    reg_rbx     QWORD       ?
    reg_rsi     QWORD       ?
    reg_rdi     QWORD       ?
    reg_rbp     QWORD       ?
    reg_rsp     QWORD       ?
    reg_r12     QWORD       ?
    reg_r13     QWORD       ?
    reg_r14     QWORD       ?
    reg_r15     QWORD       ?
context_info    ends
.CODE
AsmTest2 proc
    mov     rsp, [rdi].context_info.reg_rsp
    mov     r8, [rdi].context_info.reg_cr0
    mov     r9, [rdi].context_info.reg_cr3
    movzx    rax, [rdi].context_info.reg_ss
    movzx     rbx, [rdi].context_info.reg_ds
    movzx     rcx, [rdi].context_info.reg_es
    movzx     rdx, [rdi].context_info.reg_fs
    lgdt    fword ptr [rdi].context_info.gdtr
    lidt    fword ptr [rdi].context_info.idtr
    mov     cr0, r8
    mov     cr3, r9
    mov     ds, rbx
    mov     es, rcx
    mov     fs, rdx
    mov     ss, rax
    retfq
AsmTest2 endp
AsmTest1 proc
    PUSHAQ
    cli
    mov     rdi, rcx
    mov     rsi, rdx
    mov     ax, cs
    push    rax
    lea     rax, offset lable_ret
    push    rax
    mov     [rdi].context_info.reg_rsp, rsp
    mov     rax, cr0
    mov     [rdi].context_info.reg_cr0, rax
    mov     rax, cr3
    mov     [rdi].context_info.reg_cr3, rax
    sgdt    [rdi].context_info.gdtr
    sidt    [rdi].context_info.idtr
    mov     [rdi].context_info.reg_ss, ss
    mov     [rdi].context_info.reg_ds, ds
    mov     [rdi].context_info.reg_es, es
    mov     [rdi].context_info.reg_fs, fs
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    mov     rsp, [rsi].context_info.reg_rsp
    mov     r8, [rsi].context_info.reg_cr0
    mov     r9, [rsi].context_info.reg_cr3
    movzx     rax, [rsi].context_info.reg_ss
    movzx     rbx, [rsi].context_info.reg_ds
    movzx     rcx, [rsi].context_info.reg_es
    movzx     rdx, [rsi].context_info.reg_fs
    lgdt    fword ptr [rsi].context_info.gdtr
    lidt    fword ptr [rsi].context_info.idtr
    mov     cr0, r8
    mov     cr3, r9
    mov     ds, rbx ;这里会导致死机。
    mov     es, rcx
    mov     fs, rdx
    mov     ss, rax
    retfq
lable_ret:
    sti
    POPAQ
    ret
AsmTest1 endp

c++ 代码

bool TlbConstructTables(EptCommonEntry* table, ULONG table_level, void* virtual_address, ULONG64 physical_address)
{
    if (!table) {
        return false;
    }
    switch (table_level) {
    case 4: {
        // table == PML4
        const auto pxe_index = TlbAddressToPxeIndex(virtual_address);
        const auto tlb_pml4_entry = &table[pxe_index];
        if (!tlb_pml4_entry->all) {
            const auto tlb_pdpt = TlbAllocateEntryFromPool();
            if (!tlb_pdpt) {
                return false;
            }
            TlbInitTableEntry(tlb_pml4_entry, table_level, UtilPaFromVa(tlb_pdpt));
        }
        auto tlb_pdpt_table = reinterpret_cast<EptCommonEntry*>(UtilVaMapPfn(tlb_pml4_entry->fields.physial_address));
        if (tlb_pdpt_table == nullptr) {
            return false;
        }
        auto result = TlbConstructTables(tlb_pdpt_table, table_level - 1, virtual_address, physical_address);
        MmUnmapIoSpace(tlb_pdpt_table, PAGE_SIZE);
        return result;
    }
    case 3: {
        // table == PDPT
        const auto ppe_index = TlbAddressToPpeIndex(virtual_address);
        const auto tlb_pdpt_entry = &table[ppe_index];
        if (!tlb_pdpt_entry->all) {
            const auto tlb_pdt = TlbAllocateEntryFromPool();
            if (!tlb_pdt) {
                return false;
            }
            TlbInitTableEntry(tlb_pdpt_entry, table_level, UtilPaFromVa(tlb_pdt));
        }
        auto tlb_pdt_table = reinterpret_cast<EptCommonEntry*>(UtilVaMapPfn(tlb_pdpt_entry->fields.physial_address));
        if (tlb_pdt_table == nullptr) {
            return false;
        }
        auto result = TlbConstructTables(tlb_pdt_table, table_level - 1, virtual_address, physical_address);
        MmUnmapIoSpace(tlb_pdt_table, PAGE_SIZE);
        return result;
    }
    case 2: {
        // table == PDT
        const auto pde_index = TlbAddressToPdeIndex(virtual_address);
        const auto tlb_pdt_entry = &table[pde_index];
        if (!tlb_pdt_entry->all) {
            const auto tlb_pt = TlbAllocateEntryFromPool();
            if (!tlb_pt) {
                return false;
            }
            TlbInitTableEntry(tlb_pdt_entry, table_level, UtilPaFromVa(tlb_pt));
        }
        auto tlb_pt_table = reinterpret_cast<EptCommonEntry*>(UtilVaMapPfn(tlb_pdt_entry->fields.physial_address));
        if (tlb_pt_table == nullptr) {
            return false;
        }
        auto result = TlbConstructTables(tlb_pt_table, table_level - 1, virtual_address, physical_address);
        MmUnmapIoSpace(tlb_pt_table, PAGE_SIZE);
        return result;
    }
    case 1: {
        // table == PT
        const auto pte_index = TlbAddressToPteIndex(virtual_address);
        const auto tlb_pt_entry = &table[pte_index];
        TlbInitTableEntry(tlb_pt_entry, table_level, physical_address);
        return true;
    }
    }
    HYPERPLATFORM_COMMON_DBG_BREAK();
    return false;
}
void Test1()
{
        auto p1 = new BYTE[0x1000];
        auto p2 = new BYTE[0x1000];
        HYPERPLATFORM_LOG_INFO("p1 %p, p2 %p", p1, p2);
        RtlZeroMemory(p1, 0x1000);
        RtlZeroMemory(p2, 0x1000);
        auto info = (context_info*)p2;
        _sgdt(&info->gdtr);
        __sidt(&info->idtr);
        auto rsp = new BYTE[0x1000];
        RtlZeroMemory(rsp, 0x1000);
        HYPERPLATFORM_LOG_INFO("rsp %p", rsp);
        auto rip = (ULONG_PTR)&AsmTest2;
        HYPERPLATFORM_LOG_INFO("rip %p", rip);
        auto reg_rsp = (ULONG_PTR*)(rsp + 0x1000);
        reg_rsp--;
        *reg_rsp = AsmReadCS();
        reg_rsp--;
        *reg_rsp = rip;
        info->reg_rsp = (ULONG_PTR)reg_rsp;
        HYPERPLATFORM_LOG_INFO("reg_rsp %I64x", reg_rsp);
        info->reg_cr0 = __readcr0();
        auto pml4 = new BYTE[0x1000];
        RtlZeroMemory(pml4, 0x1000);
        HYPERPLATFORM_LOG_INFO("cr3 %I64x", pml4);
        info->reg_cr3 = UtilPaFromVa(pml4);
        auto pml4_table = (EptCommonEntry*)pml4;
        TlbConstructTables(pml4_table, 4, p1, UtilPaFromVa(p1));    //创建tlb条目
        TlbConstructTables(pml4_table, 4, p2, UtilPaFromVa(p2));
        auto rip_base = UtilGetVaBase((void*)rip);
        TlbConstructTables(pml4_table, 4, rip_base, UtilPaFromVa(rip_base));
        TlbConstructTables(pml4_table, 4, rsp, UtilPaFromVa(rsp));
        info->reg_ss = AsmReadSS();
        info->reg_ds = AsmReadDS();
        info->reg_es = AsmReadES();
        info->reg_fs = AsmReadFS();
        AsmTest1(p1, p2);
}

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2020-8-13 10:14 被vmdebug编辑 ,原因:
收藏
免费 1
支持
分享
最新回复 (1)
雪    币: 30
活跃值: (249)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2

问题已解决,感谢帖子 https://bbs.pediy.com/thread-250808.htm

最后于 2020-8-13 10:15 被vmdebug编辑 ,原因:
2020-8-13 10:13
0
游客
登录 | 注册 方可回帖
返回
//