예제 #1
0
        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());
        }
예제 #2
0
        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);
        }