public VMSlot InferStackValue() { var emulator = new InstructionEmulator(); var pushValue = DataSources.First(); // TODO: might need to verify multiple data sources. emulator.EmulateDependentInstructions(pushValue); emulator.EmulateInstruction(pushValue); return(emulator.Stack.Pop()); }
private JumpAnnotation InferJumpTargets(ILInstruction instruction) { try { var metadata = new JumpAnnotation(); var symbolicAddress = instruction.Dependencies[instruction.Dependencies.Count - 1]; foreach (var dataSource in symbolicAddress.DataSources) { var emulator = new InstructionEmulator(); emulator.EmulateDependentInstructions(dataSource); emulator.EmulateInstruction(dataSource); // After partial emulation, IP is on stack. uint nextIp = (uint)emulator.Stack.Pop().U8; Logger.Debug2(Tag, $"Inferred edge IL_{instruction.Offset:X4} -> IL_{nextIp:X4}"); if (nextIp > (ulong)KoiStream.Contents.GetPhysicalSize()) { Logger.Warning(Tag, $"Jump instruction at IL_{instruction.Offset:X4} " + $"transfers control to an instruction outside of the KoiVM stream (IL_{nextIp:X4}."); } metadata.InferredJumpTargets.Add(nextIp); } instruction.Annotation = metadata; return(metadata); } catch (NotSupportedException e) { Logger.Warning(Tag, $"Could not infer jump target for {instruction.Offset:X4}. {e.Message}"); } return(null); }