Exemplo n.º 1
0
        private void ReadMethodBody(BinaryReader reader, MethodDefinition mdef, uint codeOffset)
        {
            reader.PreserveCurrentPosition(codeOffset, () =>
            {
                var registersSize    = reader.ReadUInt16();
                var incomingArgsSize = reader.ReadUInt16();
                var outgoingArgsSize = reader.ReadUInt16();
                var triesSize        = reader.ReadUInt16();
                var debugOffset      = reader.ReadUInt32();

                mdef.Body = new MethodBody(mdef, registersSize)
                {
                    IncomingArguments = incomingArgsSize, OutgoingArguments = outgoingArgsSize
                };

                var ireader = new InstructionReader(Dex, mdef);
                ireader.ReadFrom(reader);

                if ((triesSize != 0) && (ireader.Codes.Length % 2 != 0))
                {
                    reader.ReadUInt16();                     // padding (4-byte alignment)
                }
                if (triesSize != 0)
                {
                    ReadExceptionHandlers(reader, mdef, ireader, triesSize);
                }

                if (debugOffset != 0)
                {
                    ReadDebugInfo(reader, mdef, debugOffset);
                }
            });
        }
Exemplo n.º 2
0
        private void ReadMethodBody(BinaryReader reader, MethodDefinition mdef, uint codeOffset)
        {
            reader.PreserveCurrentPosition(codeOffset, () =>
            {
                var registersSize = reader.ReadUInt16();
                var incomingArgsSize = reader.ReadUInt16();
                var outgoingArgsSize = reader.ReadUInt16();
                var triesSize = reader.ReadUInt16();
                var debugOffset = reader.ReadUInt32();

                mdef.Body = new MethodBody(mdef, registersSize)
                {
                    IncomingArguments = incomingArgsSize,
                    OutgoingArguments = outgoingArgsSize
                };

                var ireader = new InstructionReader(Dex, mdef);
                ireader.ReadFrom(reader);

                if ((triesSize != 0) && (ireader.Codes.Length % 2 != 0))
                    reader.ReadUInt16(); // padding (4-byte alignment)

                if (triesSize != 0)
                    ReadExceptionHandlers(reader, mdef, ireader, triesSize);

                if (debugOffset != 0)
                    ReadDebugInfo(reader, mdef, debugOffset);
            });
        }
Exemplo n.º 3
0
        private void ReadExceptionHandlers(BinaryReader reader, MethodDefinition mdef, InstructionReader instructionReader, ushort triesSize)
        {
            var exceptionLookup = new Dictionary<uint, List<ExceptionHandler>>();
            for (var i = 0; i < triesSize; i++)
            {
                var startOffset = reader.ReadUInt32();
                var insCount = reader.ReadUInt16();
                var endOffset = startOffset + insCount - 1;
                uint handlerOffset = reader.ReadUInt16();

                var ehandler = new ExceptionHandler();
                mdef.Body.Exceptions.Add(ehandler);
                if (!exceptionLookup.ContainsKey(handlerOffset))
                {
                    exceptionLookup.Add(handlerOffset, new List<ExceptionHandler>());
                }
                exceptionLookup[handlerOffset].Add(ehandler);
                ehandler.TryStart = instructionReader.Lookup[(int)startOffset];
                // The last code unit covered (inclusive) is start_addr + insn_count - 1
                ehandler.TryEnd = instructionReader.LookupLast[(int)endOffset];
            }

            var baseOffset = reader.BaseStream.Position;
            var catchHandlersSize = reader.ReadULEB128();
            for (var i = 0; i < catchHandlersSize; i++)
            {
                var itemoffset = reader.BaseStream.Position - baseOffset;
                var catchTypes = reader.ReadSLEB128();
                var catchAllPresent = catchTypes <= 0;
                catchTypes = Math.Abs(catchTypes);

                for (var j = 0; j < catchTypes; j++)
                {
                    var typeIndex = reader.ReadULEB128();
                    var offset = reader.ReadULEB128();
                    var @catch = new Catch
                    {
                        Type = Dex.TypeReferences[(int) typeIndex],
                        Instruction = instructionReader.Lookup[(int) offset]
                    };

                    // As catch handler can be used in several tries, let's clone the catch
                    foreach (var ehandler in exceptionLookup[(uint)itemoffset])
                        ehandler.Catches.Add(@catch.Clone());
                }

                if (!catchAllPresent)
                    continue;

                var caOffset = reader.ReadULEB128();
                foreach (var ehandler in exceptionLookup[(uint)itemoffset])
                    ehandler.CatchAll = instructionReader.Lookup[(int)caOffset];
            }
        }
Exemplo n.º 4
0
        private void ReadExceptionHandlers(BinaryReader reader, MethodDefinition mdef, InstructionReader instructionReader, ushort triesSize)
        {
            var exceptionLookup = new Dictionary <uint, List <ExceptionHandler> >();

            for (var i = 0; i < triesSize; i++)
            {
                var  startOffset   = reader.ReadUInt32();
                var  insCount      = reader.ReadUInt16();
                var  endOffset     = startOffset + insCount - 1;
                uint handlerOffset = reader.ReadUInt16();

                var ehandler = new ExceptionHandler();
                mdef.Body.Exceptions.Add(ehandler);
                if (!exceptionLookup.ContainsKey(handlerOffset))
                {
                    exceptionLookup.Add(handlerOffset, new List <ExceptionHandler>());
                }

                exceptionLookup[handlerOffset].Add(ehandler);
                ehandler.TryStart = instructionReader.Lookup[(int)startOffset];
                // The last code unit covered (inclusive) is start_addr + insn_count - 1
                ehandler.TryEnd = instructionReader.LookupLast[(int)endOffset];
            }

            var baseOffset        = reader.BaseStream.Position;
            var catchHandlersSize = reader.ReadULEB128();

            for (var i = 0; i < catchHandlersSize; i++)
            {
                var itemoffset      = reader.BaseStream.Position - baseOffset;
                var catchTypes      = reader.ReadSLEB128();
                var catchAllPresent = catchTypes <= 0;
                catchTypes = Math.Abs(catchTypes);

                for (var j = 0; j < catchTypes; j++)
                {
                    var typeIndex = reader.ReadULEB128();
                    var offset    = reader.ReadULEB128();
                    var @catch    = new Catch {
                        Type = Dex.TypeReferences[(int)typeIndex], Instruction = instructionReader.Lookup[(int)offset]
                    };

                    // As catch handler can be used in several tries, let's clone the catch
                    foreach (var ehandler in exceptionLookup[(uint)itemoffset])
                    {
                        ehandler.Catches.Add(@catch.Clone());
                    }
                }

                if (!catchAllPresent)
                {
                    continue;
                }

                var caOffset = reader.ReadULEB128();
                foreach (var ehandler in exceptionLookup[(uint)itemoffset])
                {
                    ehandler.CatchAll = instructionReader.Lookup[(int)caOffset];
                }
            }
        }