Skip to content

Instantly share code, notes, and snippets.

@CrCrisan
Last active July 14, 2023 02:35
Show Gist options
  • Save CrCrisan/2e699478ce8063bb11dd69c36daf749a to your computer and use it in GitHub Desktop.
Save CrCrisan/2e699478ce8063bb11dd69c36daf749a to your computer and use it in GitHub Desktop.
Alternative for WinDbg !pte command
"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.dirty + "), ";
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()
{
}
@CrCrisan
Copy link
Author

Fixed. Thanks @meir555!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment