Пример #1
0
        private IEnumerable <ProgramState> ProcessSwt(ILInstruction instruction, ProgramState next)
        {
            var result = new List <ProgramState>();

            var symbolicTableSlot = next.Stack.Pop();
            var symbolicValue     = next.Stack.Pop();

            instruction.Dependencies.AddOrMerge(0, symbolicTableSlot);
            instruction.Dependencies.AddOrMerge(1, symbolicValue);

            var annotation = new JumpAnnotation
            {
                InferredPopCount  = instruction.Dependencies.Count,
                InferredPushCount = 0
            };

            ulong tableAddress = symbolicTableSlot.InferStackValue().U8;

            var reader = KoiStream.Contents.CreateReader();

            reader.Offset = (uint)(tableAddress - 2);

            ushort count = reader.ReadUInt16();

            for (int i = 0; i < count; i++)
            {
                int   relativeOffset = reader.ReadInt32();
                ulong nextIp         = (ulong)((long)next.IP + relativeOffset);

                Logger.Debug2(Tag, $"Inferred edge IL_{instruction.Offset:X4} -> IL_{nextIp:X4}");

                var caseState = next.Copy();
                caseState.IP = nextIp;
                result.Add(caseState);

                annotation.InferredJumpTargets.Add(nextIp);
            }

            result.Add(next);
            instruction.Annotation = annotation;
            return(result);
        }
Пример #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);
        }