示例#1
0
 private object[] ReadValues(BinaryReader reader)
 {
     var size = reader.ReadULEB128();
     var array = new ArrayList();
     for (uint i = 0; i < size; i++)
     {
         array.Add(ReadValue(reader));
     }
     return array.ToArray();
 }
示例#2
0
        private void PrefetchClassDefinition(BinaryReader reader, uint classDataOffset)
        {
            reader.PreserveCurrentPosition(classDataOffset, () =>
            {
                var staticFieldSize = reader.ReadULEB128();
                var instanceFieldSize = reader.ReadULEB128();
                var directMethodSize = reader.ReadULEB128();
                var virtualMethodSize = reader.ReadULEB128();

                PrefetchFieldDefinitions(reader, staticFieldSize);
                PrefetchFieldDefinitions(reader, instanceFieldSize);
                PrefetchMethodDefinitions(reader, directMethodSize);
                PrefetchMethodDefinitions(reader, virtualMethodSize);
            });
        }
示例#3
0
        private void ReadFieldDefinitions(BinaryReader reader, ClassDefinition classDefinition, uint fieldcount)
        {
            uint fieldIndex = 0;
            for (var i = 0; i < fieldcount; i++)
            {
                fieldIndex += reader.ReadULEB128();
                var accessFlags = reader.ReadULEB128();

                var fdef = (FieldDefinition)Dex.FieldReferences[(int)fieldIndex];
                fdef.AccessFlags = (AccessFlags)accessFlags;
                fdef.Owner = classDefinition;

                classDefinition.Fields.Add(fdef);
            }
        }
示例#4
0
        private void ReadMethodDefinitions(BinaryReader reader, ClassDefinition classDefinition, uint methodcount, bool isVirtual)
        {
            uint methodIndex = 0;
            for (var i = 0; i < methodcount; i++)
            {
                methodIndex += reader.ReadULEB128();
                var accessFlags = reader.ReadULEB128();
                var codeOffset = reader.ReadULEB128();

                var mdef = (MethodDefinition)Dex.MethodReferences[(int)methodIndex];
                mdef.AccessFlags = (AccessFlags)accessFlags;
                mdef.Owner = classDefinition;
                mdef.IsVirtual = isVirtual;

                classDefinition.Methods.Add(mdef);

                if (codeOffset > 0)
                    ReadMethodBody(reader, mdef, codeOffset);
            }
        }
示例#5
0
        private Annotation ReadEncodedAnnotation(BinaryReader reader)
        {
            var typeIndex = (int)reader.ReadULEB128();
            var elementSize = (int)reader.ReadULEB128();

            var annotation = new Annotation {Type = (ClassReference) Dex.TypeReferences[typeIndex]};

            for (var i = 0; i < elementSize; i++)
            {
                var argument = new AnnotationArgument();
                var nameIndex = (int)reader.ReadULEB128();
                argument.Name = Dex.Strings[nameIndex];
                argument.Value = ReadValue(reader);
                annotation.Arguments.Add(argument);
            }

            return annotation;
        }
示例#6
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];
            }
        }
示例#7
0
        private void ReadClassDefinition(BinaryReader reader, ClassDefinition classDefinition, uint classDataOffset)
        {
            reader.PreserveCurrentPosition(classDataOffset, () =>
            {
                var staticFieldSize = reader.ReadULEB128();
                var instanceFieldSize = reader.ReadULEB128();
                var directMethodSize = reader.ReadULEB128();
                var virtualMethodSize = reader.ReadULEB128();

                ReadFieldDefinitions(reader, classDefinition, staticFieldSize);
                ReadFieldDefinitions(reader, classDefinition, instanceFieldSize);
                ReadMethodDefinitions(reader, classDefinition, directMethodSize, false);
                ReadMethodDefinitions(reader, classDefinition, virtualMethodSize, true);
            });
        }
示例#8
0
        private void ReadDebugInfo(BinaryReader reader, MethodDefinition mdef, uint debugOffset)
        {
            reader.PreserveCurrentPosition(debugOffset, () =>
            {
                var debugInfo = new DebugInfo(mdef.Body);
                mdef.Body.DebugInfo = debugInfo;

                var lineStart = reader.ReadULEB128();
                debugInfo.LineStart = lineStart;

                var parametersSize = reader.ReadULEB128();
                for (var i = 0; i < parametersSize; i++)
                {
                    var index = reader.ReadULEB128P1();
                    string name = null;
                    if (index != DexConsts.NoIndex && index >= 0)
                        name = Dex.Strings[(int)index];
                    debugInfo.Parameters.Add(name);
                }

                while (true)
                {
                    var ins = new DebugInstruction {OpCode = (DebugOpCodes) reader.ReadByte()};
                    debugInfo.DebugInstructions.Add(ins);

                    uint registerIndex;
                    long nameIndex;
                    string name;

                    switch (ins.OpCode)
                    {
                        case DebugOpCodes.AdvancePc:
                            // uleb128 addr_diff
                            var addrDiff = reader.ReadULEB128();
                            ins.Operands.Add(addrDiff);
                            break;
                        case DebugOpCodes.AdvanceLine:
                            // sleb128 line_diff
                            var lineDiff = reader.ReadSLEB128();
                            ins.Operands.Add(lineDiff);
                            break;
                        case DebugOpCodes.EndLocal:
                        case DebugOpCodes.RestartLocal:
                            // uleb128 register_num
                            registerIndex = reader.ReadULEB128();
                            ins.Operands.Add(mdef.Body.Registers[(int)registerIndex]);
                            break;
                        case DebugOpCodes.SetFile:
                            // uleb128p1 name_idx
                            nameIndex = reader.ReadULEB128P1();
                            name = null;
                            if (nameIndex != DexConsts.NoIndex && nameIndex >= 0)
                                name = Dex.Strings[(int)nameIndex];
                            ins.Operands.Add(name);
                            break;
                        case DebugOpCodes.StartLocalExtended:
                        case DebugOpCodes.StartLocal:
                            // StartLocalExtended : uleb128 register_num, uleb128p1 name_idx, uleb128p1 type_idx, uleb128p1 sig_idx
                            // StartLocal : uleb128 register_num, uleb128p1 name_idx, uleb128p1 type_idx
                            var isExtended = ins.OpCode == DebugOpCodes.StartLocalExtended;

                            registerIndex = reader.ReadULEB128();
                            ins.Operands.Add(mdef.Body.Registers[(int)registerIndex]);

                            nameIndex = reader.ReadULEB128P1();
                            name = null;
                            if (nameIndex != DexConsts.NoIndex && nameIndex >= 0)
                                name = Dex.Strings[(int)nameIndex];
                            ins.Operands.Add(name);

                            var typeIndex = reader.ReadULEB128P1();
                            TypeReference type = null;
                            if (typeIndex != DexConsts.NoIndex && typeIndex >= 0)
                                type = Dex.TypeReferences[(int)typeIndex];
                            ins.Operands.Add(type);

                            if (isExtended)
                            {
                                var signatureIndex = reader.ReadULEB128P1();
                                string signature = null;
                                if (signatureIndex != DexConsts.NoIndex && signatureIndex >= 0)
                                    signature = Dex.Strings[(int)signatureIndex];
                                ins.Operands.Add(signature);
                            }

                            break;
                        case DebugOpCodes.EndSequence:
                            return;
                        //case DebugOpCodes.Special:
                        // between 0x0a and 0xff (inclusive)
                        //case DebugOpCodes.SetPrologueEnd:
                        //case DebugOpCodes.SetEpilogueBegin:
                        //default:
                        //    break;
                    }
                }
            });
        }
示例#9
0
        private void PrefetchMethodDefinitions(BinaryReader reader, uint methodcount)
        {
            var methodIndex = 0;
            for (var i = 0; i < methodcount; i++)
            {
                if (i == 0)
                    methodIndex = (int)reader.ReadULEB128();
                else
                    methodIndex += (int)reader.ReadULEB128();

                reader.ReadULEB128();
                reader.ReadULEB128();
                var mdef = new MethodDefinition(Dex.MethodReferences[methodIndex]);
                Dex.MethodReferences[methodIndex] = mdef;
            }
        }
示例#10
0
        private void PrefetchFieldDefinitions(BinaryReader reader, uint fieldcount)
        {
            var fieldIndex = 0;
            for (var i = 0; i < fieldcount; i++)
            {
                if (i == 0)
                    fieldIndex = (int)reader.ReadULEB128();
                else
                    fieldIndex += (int)reader.ReadULEB128();

                reader.ReadULEB128();
                var fdef = new FieldDefinition(Dex.FieldReferences[fieldIndex]);
                Dex.FieldReferences[fieldIndex] = fdef;
            }
        }
示例#11
0
        private Annotation ReadEncodedAnnotation(BinaryReader reader)
        {
            var typeIndex = (int) reader.ReadULEB128();
            var elementSize = (int) reader.ReadULEB128();

            var annotation = new Annotation();
            annotation.Type = (ClassReference) typeReferences[typeIndex];

            for (int i = 0; i < elementSize; i++)
            {
                var nameIndex = (int) reader.ReadULEB128();
                var name = strings[nameIndex];
                var value = ReadValue(reader);
                var argument = new AnnotationArgument(name, value);
                annotation.Arguments.Add(argument);
            }

            return annotation;
        }
示例#12
0
 private void PrefetchMethodDefinitions(BinaryReader reader, ClassDefinition classDefinition, uint methodcount)
 {
     int methodIndex = 0;
     for (int i = 0; i < methodcount; i++)
     {
         if (i == 0)
         {
             methodIndex = (int) reader.ReadULEB128();
         }
         else
         {
             methodIndex += (int) reader.ReadULEB128();
         }
         reader.ReadULEB128();
         reader.ReadULEB128();
         var mdef = new MethodDefinition(methodReferences[methodIndex]);
         methodReferences[methodIndex] = mdef;
     }
 }
示例#13
0
 private void PrefetchFieldDefinitions(BinaryReader reader, ClassDefinition classDefinition, uint fieldcount)
 {
     int fieldIndex = 0;
     for (int i = 0; i < fieldcount; i++)
     {
         if (i == 0)
         {
             fieldIndex = (int) reader.ReadULEB128();
         }
         else
         {
             fieldIndex += (int) reader.ReadULEB128();
         }
         reader.ReadULEB128();
         var fdef = new FieldDefinition(fieldReferences[fieldIndex]);
         fieldReferences[fieldIndex] = fdef;
     }
 }