Skip to content

Commit fda718f

Browse files
committed
Implement symbol retrieval for method parameters
1 parent f1c5141 commit fda718f

File tree

4 files changed

+56
-13
lines changed

4 files changed

+56
-13
lines changed

src/rpc.v

+6-6
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ pub struct RpcMethod {
111111
offset u32
112112
pub mut:
113113
name string
114+
symbols []string
114115
}
115116

116117
// RpcType is used to determine the type if RPC servers that are associated with a process.
@@ -319,9 +320,7 @@ pub fn (mut pi RpvProcessInformation) update(mut resolver SymbolResolver)!
319320
for mut method in intf_info.methods
320321
{
321322
method.name = resolver.load_symbol(intf_info.location.path, method.addr) or { method.name }
322-
323-
// TODO
324-
resolver.load_symbols(intf_info.location.path, method.addr)
323+
method.symbols = resolver.load_symbols(intf_info.location.path, method.addr) or { []string{} }
325324
}
326325

327326
if intf_info.sec_callback.addr != &voidptr(0)
@@ -651,15 +650,16 @@ pub fn (interface_info RpcInterfaceBasicInfo) enrich_h(process_handle win.HANDLE
651650
base := win.read_proc_mem_s[usize](process_handle, unsafe { midl_server_info.DispatchTable + ctr }) or { break }
652651
fmt := win.read_proc_mem_s[u16](process_handle, unsafe { &u16(midl_server_info.FmtStringOffset) + ctr }) or { break }
653652

654-
// TODO
655-
resolver.load_symbols(location_info.path, u64(base))
653+
name := resolver.load_symbol(location_info.path, u64(base)) or { 'Proc${ctr}' }
654+
symbols := resolver.load_symbols(location_info.path, u64(base)) or { []string{} }
656655

657656
unsafe {
658657
rpc_methods << RpcMethod {
659658
addr: voidptr(base)
660659
fmt: voidptr(&u8(midl_server_info.ProcString) + fmt)
661660
offset: u32(usize(base) - usize(location_info.base))
662-
name: resolver.load_symbol(location_info.path, u64(base)) or { 'Proc${ctr}' }
661+
name: name
662+
symbols: symbols
663663
}
664664
}
665665
}

src/symbol-resolver.v

+21-3
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import toml
1111
pub struct SymbolResolver {
1212
mut:
1313
symbols map[string][]Symbol
14+
params map[string][]SymbolSet
1415
uuids map[string]InterfaceData
1516
has_pdb bool
1617
pdb_resolver win.PdbResolver
@@ -27,6 +28,13 @@ struct Symbol {
2728
offset u64
2829
}
2930

31+
// SymbolSet represents a set of symbols like method parameter names.
32+
struct SymbolSet {
33+
mut:
34+
names []string
35+
offset u64
36+
}
37+
3038
// InterfaceData is used to associate names with RPC interfaces. Moreover, the struct
3139
// contains notes for the interface itself and for associated RPC methods.
3240
struct InterfaceData {
@@ -134,11 +142,21 @@ pub fn (resolver SymbolResolver) load_symbol(location string, offset u64)? strin
134142
return none
135143
}
136144

137-
// load_symbols attempts to resolve the location + offset information to a symbol
138-
// name. If successful, the symbol name is returned. If the symbol cannot be found
139-
// the function returns none.
145+
// load_symbols attempts to resolve function parameter names from the specified location
146+
// and offset.
140147
pub fn (resolver SymbolResolver) load_symbols(location string, offset u64)? []string
141148
{
149+
if location in resolver.params
150+
{
151+
for symbol_set in resolver.params[location]
152+
{
153+
if symbol_set.offset == offset
154+
{
155+
return symbol_set.names
156+
}
157+
}
158+
}
159+
142160
if resolver.has_pdb
143161
{
144162
return resolver.pdb_resolver.load_symbols(offset) or { return none }

win/interop.v

+16
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,20 @@ pub struct C.COMM_FAULT_OFFSETS {
174174
FaultOffset u16
175175
}
176176

177+
@[typedef]
178+
pub struct C.IMAGEHLP_STACK_FRAME {
179+
InstructionOffset ULONG64
180+
ReturnOffset ULONG64
181+
FrameOffset ULONG64
182+
StackOffset ULONG64
183+
BackingStoreOffset ULONG64
184+
FuncTableEntry ULONG64
185+
Params[4] ULONG64
186+
Reserved[5] ULONG64
187+
Virtual BOOL
188+
Reserved2 ULONG
189+
}
190+
177191
// C.GUID represents the well known GUID struct from widows. In rpv,
178192
// it is used for different purposes. Mainly to identify RPC interfaces,
179193
// that all contain GUIDs as part of their internal definition.
@@ -1938,6 +1952,8 @@ fn C.SHGetFileInfoA(path &char, file_attrs DWORD, fileinfo &C.SHFILEINFOA, file_
19381952
fn C.SymCleanup(process_handle HANDLE)
19391953
fn C.SymFromAddr(process_handle HANDLE, address DWORD64, displacement &DWORD64, symbol &SymbolInfoV) bool
19401954
fn C.SymEnumSymbolsForAddr(process_handle HANDLE, address DWORD64, callback fn(&SymbolInfoV, ULONG), context voidptr) bool
1955+
fn C.SymEnumSymbols(process_handle HANDLE, base ULONG64, mask &char, callback fn(&SymbolInfoV, ULONG), context voidptr) bool
1956+
fn C.SymSetContext(process_handle HANDLE, frame &C.IMAGEHLP_STACK_FRAME, context voidptr) bool
19411957
fn C.SymInitialize(process_handle HANDLE, search_path &char, invade_process BOOL) bool
19421958
fn C.SymLoadModuleEx(process_handle HANDLE, file_handle HANDLE, image PCSTR, mod PCSTR, dll_base u64, dll_size u32, data voidptr, flags u32) u64
19431959
fn C.SymUnloadModule(process_handle HANDLE, module_base u32)

win/pdb-resolver.v

+13-4
Original file line numberDiff line numberDiff line change
@@ -76,15 +76,24 @@ pub fn (context PdbResolver) load_symbol(symbol u64)! string
7676
pub fn (context PdbResolver) load_symbols(symbol u64)! []string
7777
{
7878
symbols := []string{}
79+
symbols_ref := &symbols
7980

80-
symbol_closure := fn [symbols] (symbol_info &SymbolInfoV, symbol_size u32) {
81+
frame := C.IMAGEHLP_STACK_FRAME{
82+
InstructionOffset: symbol
83+
}
84+
85+
if !C.SymSetContext(context.process_handle, &frame, &voidptr(0))
86+
{
87+
return error('Unable to set symbol context to 0x${symbol}')
88+
}
89+
90+
symbol_closure := fn [symbols_ref] (symbol_info &SymbolInfoV, symbol_size u32) {
8191
unsafe {
82-
symbols << "Dummy"
83-
println('[+] Closure Test: ${cstring_to_vstring(&char(symbol_info.name[..].data))}')
92+
symbols_ref << cstring_to_vstring(&char(symbol_info.name[..].data))
8493
}
8594
}
8695

87-
if !C.SymEnumSymbolsForAddr(context.process_handle, symbol, symbol_closure, &voidptr(0))
96+
if !C.SymEnumSymbols(context.process_handle, 0, &voidptr(0), symbol_closure, &voidptr(0))
8897
{
8998
return error('Unable to resolve symbols at 0x${symbol} via SymEnumSymbolsForAddr')
9099
}

0 commit comments

Comments
 (0)