/// <summary> /// TODO: import intra/block stuff from EhTrace Agasm.cpp /// * Then we can do local: blah stuff etc... maybe do a little graph mode with MSAGL /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnDiss_Click(object sender, RoutedEventArgs e) { MemNavViewModel vm = DataContext as MemNavViewModel; if (vm != null && vm.SelectedProc != null) { IHighlightingDefinition instructionSyntax = null; using (Stream s = typeof(MemNavWin).Assembly.GetManifestResourceStream("inVteroUI.InstructionSyntax.xshd")) { if (s != null) { using (XmlReader reader = new XmlTextReader(s)) instructionSyntax = ICSharpCode.AvalonEdit.Highlighting.Xshd.HighlightingLoader.Load(reader, HighlightingManager.Instance); } } avaEdit.SyntaxHighlighting = instructionSyntax; ulong DisAddr = 0; ulong.TryParse(tbAddress.Text, NumberStyles.AllowHexSpecifier, System.Globalization.CultureInfo.InvariantCulture, out DisAddr); if (DisAddr != 0) { var asmBytes = vm.SelectedProc.GetVirtualByte((long)DisAddr); var asmCodes = Capstone.Dissassemble(asmBytes, asmBytes.Length, DisAddr, true); StringBuilder sb = new StringBuilder(); foreach (var code in asmCodes) { sb.AppendLine($"0x{code.insn.address:X} \t {code.insn.mnemonic} \t {code.insn.operands}"); } avaEdit.Text = sb.ToString(); } } }
/// <summary> /// Process specialized /// /// This is a cheat function to basically force deferred execution to occur. /// /// All of this sort of late bound meta-data from the system needs to be carefully written to not be too expensive. /// (e.g. use the .OffsetPos rather than too heavy on dynamic resolution) /// /// Ensure we have symbols & kernel meta data parsed into our type info /// /// Also We need vtero.WalkProcList to have been called which isolates vadroot /// /// </summary> public void MergeVAMetaData(bool DoStackCheck = false) { // setup kernel in optimized scan ScanAndLoadModules(); // Load as much as possible from full user space scan for PE / load debug data ScanAndLoadModules("", false, false); var codeRanges = new ConcurrentDictionary <long, long>(); /// All page table entries /// including kernel var execPages = PT.FillPageQueue(false, true); foreach (var pte in execPages) { codeRanges.TryAdd(pte.VA.Address, pte.VA.Address + (pte.PTE.LargePage ? MagicNumbers.LARG_PAGE_SIZE : MagicNumbers.PAGE_SIZE)); } // Walk Vad and inject into 'sections' // scan VAD data to additionally bind ListVad(VadRootPtr); // Dig all threads if (DoStackCheck) { LoadThreads(); var checkPtrs = new ConcurrentBag <long>(); // instead of using memsections we should use apge table info // then push in memsection after this round Parallel.Invoke(() => { // each stack foreach (var userRange in UserThreadStacks) { // every value foreach (var pointer in userRange.Item2) { if (pointer > -4096 && pointer < 4096) { continue; } // see if in range of code foreach (var codeRange in codeRanges) { // if so we need to double check that the code ptr is a good one if (pointer >= codeRange.Key && pointer < codeRange.Value) { checkPtrs.Add(pointer); } } } } }, () => { // each stack foreach (var kernelRange in ThreadStacks) { // every value foreach (var pointer in kernelRange.Item2) { if (pointer > -4096 && pointer < 4096) { continue; } // see if in range of code foreach (var codeRange in codeRanges) { // if so we need to double check that the code ptr is a good one if (pointer >= codeRange.Key && pointer < codeRange.Value) { checkPtrs.Add(pointer); } } } } }); // validate checkPtrs pointers here // TODO: group pointers so we can minimize page reads foreach (var ptr in checkPtrs) { var idx = ptr & 0xfff; if (idx < 10) { continue; } // every pointer needs to be a function start // or a properly call/ret pair var ptrTo = VGetBlock(ptr); //BYTE* bp = (BYTE*)RefFramePtr; var IsCCBefore = ptrTo[idx - 1]; var IsCallE8 = ptrTo[idx - 5]; var IsCallE8_second = ptrTo[idx - 3]; var IsCall9A = ptrTo[idx - 5]; var IsCall9A_second = ptrTo[idx - 7]; bool FoundFFCode = false; // scan from RoPCheck for (int i = 2; i < 10; i++) { var a = ptrTo[idx - i]; var b = ptrTo[idx - i + 1]; if (i < 8) { if ((a == 0xff) && (b & 0x38) == 0x10) { FoundFFCode = true; break; } } if ((a == 0xff) && (b & 0x38) == 0x18) { FoundFFCode = true; break; } } if (!FoundFFCode && IsCCBefore != 0xcc && IsCallE8 != 0xe8 && IsCallE8_second != 0xe8 && IsCall9A != 0x9a && IsCall9A_second != 0x9a) { WriteColor(ConsoleColor.Cyan, $"Stack pointer is wild {ptr:x}"); var cs = Capstone.Dissassemble(ptrTo, ptrTo.Length, (ulong)(ptr & -4096)); for (int i = 0; i < cs.Length; i++) { if (cs[i].insn.address == (ulong)ptr) { WriteColor(ConsoleColor.Yellow, $"{cs[i - 1].insn.address:x} {cs[i - 1].insn.bytes[0]:x} {cs[i - 1].insn.mnemonic} {cs[i - 1].insn.operands}"); WriteColor(ConsoleColor.Yellow, $"{cs[i].insn.address:x} {cs[i].insn.bytes[0]:x} {cs[i].insn.mnemonic} {cs[i].insn.operands}"); } } } } } // find section's with no "Module" foreach (var sec in Sections.Values) { if (sec.Module == null) { var test = GetVirtualByte(sec.VadAddr); var ext = Extract.IsBlockaPE(test); sec.Module = ext; } } }