阅读:1370回复:1
MmCreateVirtualMappingUnsafe这个内核函数是否有bug(见我的注释)
NTSTATUS
NTAPI MmCreateVirtualMappingUnsafe(PEPROCESS Process, PVOID Address, ULONG flProtect, PPFN_TYPE Pages, ULONG PageCount) { ULONG Attributes; PVOID Addr; ULONG i; ULONG oldPdeOffset, PdeOffset; BOOLEAN NoExecute = FALSE; DPRINT("MmCreateVirtualMappingUnsafe(%x, %x, %x, %x (%x), %d)\n", Process, Address, flProtect, Pages, *Pages, PageCount); if (Process == NULL) { if (Address < MmSystemRangeStart) { DPRINT1("No process\n"); KEBUGCHECK(0); } if (PageCount > 0x10000 || (ULONG_PTR) Address / PAGE_SIZE + PageCount > 0x100000) { DPRINT1("Page count to large\n"); KEBUGCHECK(0); } } else { if (Address >= MmSystemRangeStart) { DPRINT1("Setting kernel address with process context\n"); KEBUGCHECK(0); } if (PageCount > (ULONG_PTR)MmSystemRangeStart / PAGE_SIZE || (ULONG_PTR) Address / PAGE_SIZE + PageCount > (ULONG_PTR)MmSystemRangeStart / PAGE_SIZE) { DPRINT1("Page Count to large\n"); KEBUGCHECK(0); } } Attributes = ProtectToPTE(flProtect); if (Attributes & 0x80000000) { NoExecute = TRUE; } Attributes &= 0xfff; if (Address >= MmSystemRangeStart) { Attributes &= ~PA_USER; if (Ke386GlobalPagesEnabled) { Attributes |= PA_GLOBAL; } } else { Attributes |= PA_USER; } Addr = Address; if (Ke386Pae) { ....//此处是支持Pae情况暂且不考虑 } else { PULONG Pt = NULL; ULONG Pte; oldPdeOffset = ADDR_TO_PDE_OFFSET(Addr) + 1; for (i = 0; i < PageCount; i++, Addr = (PVOID)((ULONG_PTR)Addr + PAGE_SIZE)) { if (!(Attributes & PA_PRESENT) && Pages(i)!= 0))//((i)方括号显示不出)这个条件中要是是0号页面就不满足条件不出错误无论在内存标志存在与否 { DPRINT1("Setting physical address but not allowing access at address " "0x%.8X with attributes %x/%x.\n", Addr, Attributes, flProtect); KEBUGCHECK(0); } PdeOffset = ADDR_TO_PDE_OFFSET(Addr); if (oldPdeOffset != PdeOffset) { MmUnmapPageTable(Pt); Pt = MmGetPageTableForProcess(Process, Addr, TRUE); if (Pt == NULL) { KEBUGCHECK(0); } } else { Pt++; } oldPdeOffset = PdeOffset; Pte = *Pt; MmMarkPageMapped(Pages(i));//此处如果是0号页面仍然增加mappingcount和refcount吗 if (PAGE_MASK((Pte)) != 0 && !((Pte) & PA_PRESENT))//此处如果是0号页面就不会错误 { KEBUGCHECK(0); } if (PAGE_MASK((Pte)) != 0) { MmMarkPageUnmapped(PTE_TO_PFN((Pte)));//此处如果是0号页面就不会减少 //mapcount和refcount与上面的Pages(i)的情况是否矛盾 } (void)InterlockedExchangeUL(Pt, PFN_TO_PTE(Pages(i)) | Attributes);//0号页面可以被替换映射或者替换已有映射吗 if (Address < MmSystemRangeStart && ((PMADDRESS_SPACE)&Process->VadRoot)->PageTableRefCountTable != NULL && Attributes & PA_PRESENT) { PUSHORT Ptrc; Ptrc = ((PMADDRESS_SPACE)&Process->VadRoot)->PageTableRefCountTable; Ptrc[ADDR_TO_PAGE_TABLE(Addr)]++; } //上面这个if语句块貌似没有我写的下面这个(/*...*/)注释括起来的if语句块合理些 /*if((Address<MmSystemRangeStart)&&(((PMADDRESS_SPACE)&Process->VadRoot)->PageTableRefCountTable!=NULL)) { PUSHORT ptrc=((PMADDRESS_SPACE)&Process->VadRoot)->PageTableRefCountTable; if((Attributes&PA_PRESENT)&&(!(pte & PA_PRESENT))) { ptrc[ADDR_TO_PAGE_TABLE(Addr)]++; } else if((!(Attributes&PA_PRESENT))&&(pte & PA_PRESENT)) { ptrc[ADDR_TO_PAGE_TABLE(Addr)]--; } }//貌似上面我写的这个比原来的合理些*/ if (Pte != 0) { if (Address > MmSystemRangeStart || (Pt >= (PULONG)PAGETABLE_MAP && Pt < (PULONG)PAGETABLE_MAP + 1024*1024)) { MiFlushTlb(Pt, Address);//还有这儿,如何失效别的进程的用户空间地址的块表中 //相应的页面映射表项呢 } } } if (Addr > Address) { MmUnmapPageTable(Pt); } } return(STATUS_SUCCESS); } |
|
沙发#
发布于:2012-06-14 01:46
没有导出的函数,也没有文档
肯定不安全 |
|