diff --git a/objfile/objfile.go b/objfile/objfile.go index 971ad77..ddb18a8 100644 --- a/objfile/objfile.go +++ b/objfile/objfile.go @@ -24,6 +24,10 @@ import ( "github.com/mandiant/GoReSym/debug/gosym" ) +const ( + MAX_TREE_SIZE = 4096 +) + type StompMagicCandidate struct { PclntabVa uint64 SuspectedModuleDataVa uint64 @@ -253,7 +257,7 @@ func (e *Entry) PCLineTable(versionOverride string, knownPclntabVA uint64, known } if knownGofuncVA != 0 { - candidate.GofuncVA + candidate.GofuncVA = knownGofuncVA } parsedTable, err := gosym.NewTable(candidate.Symtab, gosym.NewLineTable(candidate.Pclntab, candidate.SecStart, candidate.GofuncVA), versionOverride) @@ -261,9 +265,37 @@ func (e *Entry) PCLineTable(versionOverride string, knownPclntabVA uint64, known continue } - // the first good one happens to be correct more often than the last candidate.ParsedPclntab = parsedTable + // add in inline func resolution + for _, fn := range candidate.ParsedPclntab.Funcs { + // calc inline data VAs + pcd_InlIndex, fnd_InlTree := fn.HasInline() + if pcd_InlIndex == 0 && fnd_InlTree == 0 { + // no inline tree data for this function + continue + } + fmt.Println("func ", fn.Name) + + // calc where tree starts + treeBaseVA := candidate.GofuncVA + uint64(fnd_InlTree) + + // extract relevant bytes + treeBytes, err := e.raw.read_memory(treeBaseVA, MAX_TREE_SIZE) + if err != nil { + fmt.Errorf("failed to get tree bytes for inline function inside %s\n", fn.Name) + continue + } + + // save results for each function + inlineCallList := fn.GetInlinedCalls(treeBytes) + fmt.Printf("\t got %d bytes with %d entries\n", len(treeBytes), len(inlineCallList)) + + for _, elt := range inlineCallList { + fmt.Println("\tadding inlined ", elt.Funcname) + fn.InlinedList = append(fn.InlinedList, elt) + } + } finalCandidates = append(finalCandidates, candidate) atLeastOneGood = true }