首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >windbg内核调试--如何获取物理地址

windbg内核调试--如何获取物理地址
EN

Stack Overflow用户
提问于 2022-03-24 07:44:58
回答 1查看 579关注 0票数 2

我在fffff801`16e00000上加载了一个模块,希望通过!pte获得它的物理地址,但是windbg说“这个平台没有实现的级别”,这是什么原因呢?

我知道如何手动操作PML4、PDPT、PD和PT,但是为什么这个扩展不能工作呢?我在内核中调试虚拟机

EN

回答 1

Stack Overflow用户

发布于 2022-04-01 08:20:12

我曾多次遇到同样的问题,但我想不出答案。我不知道这是否会对您有所帮助,但是我编写了一个WinDbg JS脚本来再现这个特定情况下的!pte命令。

它工作在64位,只有4层分页。

代码语言:javascript
运行
复制
"use strict";

const system = x => host.namespace.Debugger.Utility.Control.ExecuteCommand(x);
const log = x => host.diagnostics.debugLog(`${x}\n`);
const convertStrToInt64 = str => host.parseInt64(str);

const replaceString = (string, search, replaceWith) => {
    return string.split(search).join(replaceWith);
}

function isBitSet(Nr, Bit)
{
    var mask = host.Int64(1).bitwiseShiftLeft(Bit);
    return Nr.bitwiseAnd(mask).compareTo(0);
}

class PageEntry
{
    constructor(Value)
    {
        this.present = isBitSet(Value, 0);
        this.write = isBitSet(Value, 1);
        this.supervisor = isBitSet(Value, 2);
        this.access = isBitSet(Value, 5);
        this.dirty = isBitSet(Value, 6);
        this.largePage = isBitSet(Value, 7);
        this.exec = isBitSet(Value, 63) == true ? 0 : 1;

        this.value = Value;

        var mask = host.Int64(1);
        mask = mask.bitwiseShiftLeft(36).subtract(1)
        this.pfn = Value.bitwiseShiftRight(12).bitwiseAnd(mask)
    }

    toString() {
        var str = "";

        str += "Value = " + this.value.toString() + "\n\t";
        str += "P(" + this.present + "), ";
        str += "W(" + this.write + "), ";
        str += "E(" + this.exec + "), ";
        str += "A(" + this.access + "), ";
        str += "D(" + this.access + "), ";
        str += "Large(" + this.largePage + ")\n\t";
        str += "Pfn: " + this.pfn.toString();

        return str;
    }
}

function getLayerOffset(Adr, Layer)
{
    var shift = 0;
    switch (Layer)
    {
        case 4:
            shift = 39;
            break;
        case 3:
            shift = 30;
            break;
        case 2:
            shift = 21;
            break;
        case 1:
            shift = 12;
            break;
        default:
            throw EvalError("Invalid layer");
    }
    return Adr.bitwiseShiftRight(shift).bitwiseAnd(0x1ff);
}

function paFromPfn(Pfn)
{
    return Pfn.bitwiseShiftLeft(12)
}

function readDword64FromPa(PhysicalAddress)
{
    var out = system("!dq " + PhysicalAddress.toString() + " L1")[0];
    // output example: #1234abc 12341234`abcdabcd
    // !sometimes the output from !dq has a space after #
    out = out.split(" ");
    var value = out[out.length - 1]
    return convertStrToInt64("0x" + value);
}

function pageWalk(TablePa, Offset, Level)
{
    if (Level == 0)
    {
        return;
    }

    var entryAdr = TablePa.add(Offset[Level-1].multiply(8));
    var entryValue = readDword64FromPa(entryAdr);
    var entry = new PageEntry(entryValue);
    var nextLayerPa = paFromPfn(entry.pfn)

    // print info
    log("Level: " + Level.toString() + ", Entry Address: " + entryAdr.toString())
    log(entry)
    log("")

    if (entry.present == 0)
    {
        log("Next layer not present");
        return;
    }
    if (entry.largePage == 1)
    {
        log("Large page present");
        return;
    }

    pageWalk(nextLayerPa, Offset, Level-1)
}

function getPml4AddressFromCr3(Cr3)
{
    var mask = host.Int64(1);
    var mask = mask.bitwiseShiftLeft(36).subtract(1)
    var pml4Pfn = Cr3.bitwiseShiftRight(12).bitwiseAnd(mask)
    return paFromPfn(pml4Pfn);
}

function translateAddress(VirtualAddress, Cr3Val=NaN)
{
    log("Virtual address: " + VirtualAddress.toString())
    
    var lv4 = getLayerOffset(VirtualAddress, 4);
    var lv3 = getLayerOffset(VirtualAddress, 3);
    var lv2 = getLayerOffset(VirtualAddress, 2);
    var lv1 = getLayerOffset(VirtualAddress, 1);

    if (isNaN(Cr3Val))
    {
        Cr3Val = host.currentThread.Registers.Kernel.cr3;
    }

    var pml4Adr = getPml4AddressFromCr3(Cr3Val);
    log("Pml 4 address: " + pml4Adr.toString())
    pageWalk(pml4Adr, [lv1, lv2, lv3, lv4], 4)
}

function initializeScript()
{
    var app = [new host.apiVersionSupport(1, 7)];

    app.push(new host.functionAlias(translateAddress, "pteV2"));

    return app;
}

function invokeScript()
{
}

要使用运行.scriptload script.js的脚本,可以使用!pteV2(Virtual_Address)!pteV2(Virtual_Address, Cr3_Value)而不是!pte

我没有使用js的经验,而且脚本没有经过很好的…测试

脚本也在github上。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71598671

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档