update 18/2/2020

This commit is contained in:
2020-02-18 17:39:31 +07:00
parent c53fb94ddf
commit 0bb4ecd0e3
2 changed files with 618 additions and 101 deletions

View File

@ -10,8 +10,9 @@ use pdb::PDB;
use pdb::SymbolData;
use pdb::TypeData;
use pdb::ClassType;
use pdb::FallibleIterator;
use pdb::ModifierType;
use pdb::FallibleIterator;
use pdb::TypeFinder;
use pdb::TypeIndex;
@ -30,6 +31,78 @@ fn get_type_as_str(type_finder: &TypeFinder, typ: &TypeIndex) -> String {
TypeData::Pointer(pt) => {
format!("{}*", get_type_as_str(type_finder, &pt.underlying_type))
},
TypeData::StaticMember(st) => {
format!("static {}", get_type_as_str(type_finder, &st.field_type))
},
TypeData::Array(at) => {
format!("{}{:?}",
get_type_as_str(type_finder, &at.element_type), /* get_type_as_str(type_finder, &at.indexing_type), */ at.dimensions)
},
// TypeData::Enumeration(et) => {
// format!("enumeration")
// },
// TypeData::Enumerate(et) => {
// format!("enumerate")
// },
// TypeData::MemberFunction(mft) => {
// format!("member function")
// },
// TypeData::OverloadedMethod(ovmt) => {
// format!("overloaded method")
// },
// TypeData::Nested(nt) => {
// format!("nested")
// },
// TypeData::BaseClass(bct) => {
// format!("base class")
// },
// TypeData::VirtualBaseClass(vbct) => {
// format!("virtual base class")
// },
// TypeData::VirtualFunctionTablePointer(vftpt) => {
// format!("virtual function table pointer")
// },
TypeData::Procedure(pt) => {
let rettype = match pt.return_type {
Some(rt) => get_type_as_str(type_finder, &rt),
_ => "UNKNOWN".to_string()
};
format!("{}({})", rettype, get_type_as_str(type_finder, &pt.argument_list))
},
TypeData::Modifier(mt) => {
match mt {
ModifierType { constant: true, volatile: true, unaligned: true, .. } =>
format!("const volatile unaligned {}", get_type_as_str(type_finder, &mt.underlying_type)),
ModifierType { constant: true, volatile: true, unaligned: false, .. } =>
format!("const volatile {}", get_type_as_str(type_finder, &mt.underlying_type)),
ModifierType { constant: true, volatile: false, unaligned: true, .. } =>
format!("const unaligned {}", get_type_as_str(type_finder, &mt.underlying_type)),
ModifierType { constant: false, volatile: true, unaligned: true, .. } =>
format!("volatile unaligned {}", get_type_as_str(type_finder, &mt.underlying_type)),
ModifierType { constant: true, volatile: false, unaligned: false, .. } =>
format!("const {}", get_type_as_str(type_finder, &mt.underlying_type)),
ModifierType { constant: false, volatile: true, unaligned: false, .. } =>
format!("volatile {}", get_type_as_str(type_finder, &mt.underlying_type)),
ModifierType { constant: false, volatile: false, unaligned: true, .. } =>
format!("unaligned {}", get_type_as_str(type_finder, &mt.underlying_type)),
_ => format!("modifier {}", get_type_as_str(type_finder, &mt.underlying_type))
}
},
// TypeData::Union(ut) => {
// format!("union")
// },
// TypeData::Bitfield(bft) => {
// format!("bitfield")
// },
TypeData::FieldList(_flt) => {
format!("fieldlist")
},
// TypeData::ArgumentList(alt) => {
// format!("arglist")
// },
// TypeData::MethodList(mlt) => {
// format!("methodlist")
// },
unk => {
match unk.name() {
Some(s) => format!("{}", s.to_string()),
@ -48,13 +121,23 @@ fn parse_pdb() {
println!("PDB for {}, guid: {}, age: {},", dbi.machine_type().unwrap(), info.guid, dbi.age().unwrap_or(0));
println!("");
let type_information = pdb.type_information().expect("Cannot get type information");
let mut type_finder = type_information.type_finder();
let mut iter = type_information.iter();
while let Some(_typ) = iter.next().unwrap() {
type_finder.update(&iter);
}
// find global symbols offset
let addr_map = pdb.address_map().expect("Cannot get address map");
let glosym = pdb.global_symbols().expect("Cannot get global symbols");
let mut symbols = glosym.iter();
let need_symbols = [
"PsLoadedModuleList", "PsActiveProcessHead", "KeNumberNodes",
// "PoolVector", "ExpNumberOfNonPagedPools",
"KdDebuggerDataBlock", "MmNonPagedPoolStart", "MmNonPagedPoolEnd", // Windows XP
"MiNonPagedPoolStartAligned", "MiNonPagedPoolEnd", "MiNonPagedPoolBitMap", // Windows 7, 8
"MiNonPagedPoolBitMap", "MiNonPagedPoolVaBitMap",
"MiState" // Windows 10
];
while let Some(symbol) = symbols.next().unwrap() {
@ -64,7 +147,8 @@ fn parse_pdb() {
for sym in need_symbols.iter() {
if &name == sym {
let rva = data.offset.to_rva(&addr_map).unwrap_or_default();
println!("{} {} {}:{}", name, rva, data.offset.section, data.offset.offset);
println!("{} {} {} {}:{}",
get_type_as_str(&type_finder, &(symbol.raw_kind() as u32)), name, rva, data.offset.section, data.offset.offset);
}
}
},
@ -76,6 +160,10 @@ fn parse_pdb() {
println!("");
let mut need_structs = HashMap::new();
// need_structs.insert("_KLDR_DATA_TABLE_ENTRY", vec![]);
need_structs.insert("_PEB", vec![]);
need_structs.insert("_LIST_ENTRY", vec![]);
need_structs.insert("_EPROCESS", vec![]);
need_structs.insert("_KDDEBUGGER_DATA64", vec![
"MmNonPagedPoolStart", "MmNonPagedPoolEnd", // Windows XP
"MiNonPagedPoolStartAligned", "MiNonPagedPoolEnd", "MiNonPagedPoolBitMap", // Windows 7, 8 -- not sure, global symbols
@ -84,26 +172,29 @@ fn parse_pdb() {
// these struct supports finding NonPagedPool{First,Last}Va in windows 10
need_structs.insert("_MI_SYSTEM_INFORMATION", vec![
"Hardware", // windows 10 2016+
"SystemNodeInformation" // windows 10 2015
"Hardware", // windows 10 2016+
"SystemNodeInformation" // windows 10 2015
]);
need_structs.insert("_MI_HARDWARE_STATE", vec![
"SystemNodeInformation", // till windows 10 1900
"SystemNodeNonPagedPool" // windows insider, 2020
"SystemNodeInformation", // till windows 10 1900
"SystemNodeNonPagedPool" // windows insider, 2020
]);
need_structs.insert("_MI_SYSTEM_NODE_INFORMATION", vec![ // till windows 10 1900
"NonPagedPoolFirstVa", "NonPagedPoolLastVa",
"NonPagedBitMap" // missing on windows 10 1900+
"NonPagedBitMap", // missing on windows 10 1900+
"DynamicBitMapNonPagedPool" // some weird field
]);
need_structs.insert("_MI_SYSTEM_NODE_NONPAGED_POOL", vec![ // windows insider, 2020
"NonPagedPoolFirstVa", "NonPagedPoolLastVa"
"NonPagedPoolFirstVa", "NonPagedPoolLastVa",
"DynamicBitMapNonPagedPool" // some weird field
]);
need_structs.insert("_MI_DYNAMIC_BITMAP", vec![]);
need_structs.insert("_RTL_BITMAP", vec![]); // windows 10 until 2020
need_structs.insert("_RTL_BITMAP_EX", vec![]); // windows insider, 2020
let type_information = pdb.type_information().expect("Cannot get type information");
let mut type_finder = type_information.type_finder();
let mut iter = type_information.iter();
iter = type_information.iter();
while let Some(typ) = iter.next().unwrap() {
type_finder.update(&iter);
// type_finder.update(&iter);
match typ.parse() {
Ok(TypeData::Class(ClassType {name, fields: Some(fields), ..})) => {
let n = name.to_string();
@ -111,22 +202,23 @@ fn parse_pdb() {
if !need_structs.contains_key(&*n) {
continue;
}
println!("struct {}", name);
println!("beginstruct {}", name);
match type_finder.find(fields).unwrap().parse().unwrap() {
TypeData::FieldList(list) => {
// `fields` is a Vec<TypeData>
for field in list.fields {
if let TypeData::Member(member) = field {
let mem_typ = get_type_as_str(&type_finder, &member.field_type);
println!(" - field {} {} at offset {:x}", mem_typ, member.name, member.offset);
println!("\t0x{:x} {} {}", member.offset, mem_typ, member.name);
} else {
println!("\tmember_func");
// handle member functions, nested types, etc.
}
}
}
_ => {}
}
println!("");
println!("endstruct\n");
},
_ => {}
}