Skip to content

Instantly share code, notes, and snippets.

@n4r1b
Created April 18, 2020 15:45
Show Gist options
  • Save n4r1b/2d913f50e9de4767df96bf0fc01b757b to your computer and use it in GitHub Desktop.
Save n4r1b/2d913f50e9de4767df96bf0fc01b757b to your computer and use it in GitHub Desktop.
A js script for windbg to list the registry keys that are being monitored by WdFilter.
"use strict";
// remove [Object object]
delete Object.prototype.toString;
function add(address, val)
{
return host.Int64(address).add(val);
}
class MpClientValue
{
constructor (addr) {
this.pMpClientValue = addr != host.Int64(0) ? host.createPointerObject(addr, "nt", "unsigned __int64 *") : host.Int64(0);
}
get getClientValue() {
return this.__create()
}
toString() {
return this.pMpClientValue.address.toString() + " [Type: MP_CLIENT_VALUE *]";
}
__create() {
if (this.pMpClientValue == host.Int64(0)) {
return host.createPointerObject(host.Int64(0), "nt", "unsigned __int64 *");
}
var NextClientValue = this.pMpClientValue.isNull ? host.Int64(0) : new MpClientValue(this.pMpClientValue.dereference());
return {
NextClientValue,
ValueHash : host.memory.readMemoryValues(add(this.pMpClientValue.address, 0x8), 16, 1, false),
KeyRules : host.createTypedObject(add(this.pMpClientValue.address, 0x18), "nt", "unsigned __int64")
}
}
}
class MpKeyValue
{
constructor(addr) {
this.pMpKeyValue = addr != host.Int64(0) ? host.createPointerObject(addr, "nt", "unsigned __int64 *") : host.Int64(0);
}
toString() {
return this.pMpKeyValue.address.toString() + " [Type: MP_KEY_VALUE *]";
}
get getKeyValue() {
return this.__create()
}
__create() {
if (this.pMpKeyValue == host.Int64(0)) {
return host.createPointerObject(host.Int64(0), "nt", "unsigned __int64 *");
}
var NextKeyValue = this.pMpKeyValue.isNull ? host.Int64(0) : new MpKeyValue(this.pMpKeyValue.dereference());
var ClientValue = this.pMpKeyValue.add(2).isNull ? host.Int64(0) : new KeyIterator(this.pMpKeyValue.add(2).dereference(), "MP_CLIENT_VALUE");
return {
NextKeyValue,
KeyValueName : host.createPointerObject(this.pMpKeyValue.add(1).dereference(), "nt", "wchar_t *"),
ClientValue
}
}
}
class MpKeyEntry
{
constructor(addr) {
this.pMpKeyEntry = addr != host.Int64(0) ? host.createPointerObject(addr, "nt", "unsigned __int64 *") : host.Int64(0);
}
get getEntry() {
return this.__create();
}
toString() {
if (this.pMpKeyEntry == host.Int64(0)) {
return "0x0 [Type: MP_KEY_ENTRY *]"
}
return this.pMpKeyEntry.address.toString() + " [Type: MP_KEY_ENTRY *]";
}
__create() {
if (this.pMpKeyEntry == host.Int64(0)) {
return host.createPointerObject(host.Int64(0), "nt", "unsigned __int64 *");
}
var SubKey = this.pMpKeyEntry.isNull ? null : new MpKeyEntry(this.pMpKeyEntry.dereference());
var NextKey = this.pMpKeyEntry.add(1).isNull ? null : new MpKeyEntry(this.pMpKeyEntry.add(1).dereference());
var ClientList = this.pMpKeyEntry.add(4).isNull ? null : new KeyIterator(this.pMpKeyEntry.add(4).dereference(), "MP_CLIENT_VALUE");
var ValuesList = this.pMpKeyEntry.add(5).isNull ? null : new KeyIterator(this.pMpKeyEntry.add(5).dereference(), "MP_KEY_VALUE");
return {
EntryAddr : this.pMpKeyEntry.address,
SubKey,
NextKey,
KeyName : host.createPointerObject(this.pMpKeyEntry.add(2).dereference(), "nt", "wchar_t *"),
KeysToSkip : host.createTypedObject(add(this.pMpKeyEntry.address, 0x18), "nt", "unsigned short"),
ClientList,
ValuesList
}
}
}
class MpRegUserData
{
constructor(addr) {
this.DataSize = host.createTypedObject(addr, "nt", "unsigned int");
this.NumberOfEntries = host.createTypedObject(add(addr, 0x4), "nt", "unsigned int");
this.MonitoredKeysTree = new KeyIterator(host.createPointerObject(add(addr, 0x8), "nt", "unsigned __int64 *").dereference(), "MP_KEY_ENTRY");
this.MonitoredKeysRules = host.createTypedObject(add(addr, 0x10), "nt", "unsigned __int64");
}
toString() {
return " [Type: MP_REG_USER_DATA *]";
}
}
class KeyIterator
{
constructor (startAddress, type) {
this.StartAddress = startAddress;
this.Type = type
}
*[Symbol.iterator]() {
var it;
switch(this.Type) {
case "MP_KEY_ENTRY":
it = this.getMpKeyEntries(new MpKeyEntry(this.StartAddress));
break;
case "MP_KEY_VALUE":
it = this.getMpKeyValues(new MpKeyValue(this.StartAddress));
break;
case "MP_CLIENT_VALUE":
it = this.getMpClientValues(new MpClientValue(this.StartAddress));
break;
}
var res = it.next();
while(!res.done) {
yield res.value;
res = it.next();
}
}
toString() {
return this.StartAddress.toString() + " [Type: " + this.Type + " *]";
}
* getMpKeyEntries(keyEntryAddr) {
var mpKeyEntry = keyEntryAddr.getEntry;
if (mpKeyEntry.isNull) {
return;
}
yield mpKeyEntry;
yield * this.getMpKeyEntries(mpKeyEntry.SubKey);
yield * this.getMpKeyEntries(mpKeyEntry.NextKey);
}
* getMpKeyValues(keyValuesAddr) {
var mpKeyValues = keyValuesAddr.getKeyValue
if (mpKeyValues.isNull) {
return;
}
yield mpKeyValues;
yield * this.getMpKeyValues(mpKeyValues.NextKeyValue);
}
* getMpClientValues(clientValuesAddr) {
var mpClientValue = clientValuesAddr.getClientValue
if (mpClientValue.isNull) {
return;
}
yield mpClientValue;
yield * this.getMpClientValues(mpClientValue.NextClientValue);
}
}
function __DisplayRegUserData()
{
let pMpRegData = host.getModuleSymbolAddress("WdFilter", "MpRegData");
if (pMpRegData === null) {
throw new Error("Unable to find pointer MpRegData");
}
let mpRegData = host.createPointerObject(pMpRegData, "nt", "unsigned __int64 *").dereference();
if (mpRegData == host.Int64(0)) {
throw new Error("Unable to get mpRegData");
}
let pMpRegUserData = host.createPointerObject(add(mpRegData, 0x10), "nt", "unsigned __int64 *").dereference();
if (pMpRegUserData == host.Int64(0)) {
throw new Error("Unable to get MpRegUserData");
}
let mpRegUserData = new MpRegUserData(pMpRegUserData);
return { MpRegData: mpRegData, MpRegUserData: mpRegUserData };
}
class __WdFilterRegData
{
RegUserData() {
return __DisplayRegUserData();
}
CreateInstance(typeName, addrObj) {
var name = typeName.toUpperCase();
switch(name) {
case "MP_KEY_ENTRY":
case "MPKEYENTRY":
return new MpKeyEntry(addrObj).getEntry;
break;
case "MP_KEY_VALUE":
case "MPKEYVALUE":
return new MpKeyValue(addrObj).getKeyValue;
break;
case "MP_CLIENT_VALUE":
case "MPCLIENTVALUE":
return new MpClientValue(addrObj).getClientValue;
break;
default:
throw new Error("Unrecognized type name");
}
}
get [Symbol.metadataDescriptor]()
{
return {
RegUserData: { PreferShow: true,
Help: "!mpRegUserData - Returns MP_REG_USER_DATA, from here we can obtain a list of all the keys monitored by WdFilter. Remark: It relies on symbol MpRegData, so WdFilter symbols must be loaded"
},
CreateInstance: {PreferShow: true,
Help: "CreateInstance(typeName, addrObj) - Creates an instance of type MP_KEY_ENTRY, MP_KEY_VALUE or MP_CLIENT_VALUE"
}
};
}
}
class __WdFilterExtension
{
get WdFilterExtension()
{
return new __WdFilterRegData();
}
};
function initializeScript()
{
return [new host.apiVersionSupport(1, 2),
new host.functionAlias(__DisplayRegUserData, "mpRegUserData"),
new host.namespacePropertyParent(__WdFilterExtension, "Debugger.Models.Utility", "Debugger.Models.Utility.Analysis", "Analysis")];
}
@n4r1b
Copy link
Author

n4r1b commented Apr 18, 2020

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