求助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编辑
,原因: