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(); }
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); }); }
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); } }
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); } }
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; }
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]; } }
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); }); }
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; } } }); }
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; } }
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; } }
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; }
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; } }
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; } }