private void ReadMapList(BinaryReader reader) { reader.PreserveCurrentPosition(header.MapOffset, () => { var mapsize = reader.ReadUInt32(); for (var i = 0; i < mapsize; i++) { var type = (TypeCodes)reader.ReadUInt16(); reader.ReadUInt16(); // unused var size = reader.ReadUInt32(); var offset = reader.ReadUInt32(); map.Add(type, size, offset); } }); }
private void ReadTypesReferences(BinaryReader reader) { reader.PreserveCurrentPosition(Header.TypeReferencesOffset, () => { for (var i = 0; i < Header.TypeReferencesSize; i++) { var descriptorIndex = reader.ReadInt32(); var descriptor = Dex.Strings[descriptorIndex]; TypeDescriptor.Fill(descriptor, Dex.TypeReferences[i], Dex); } }); }
private void ReadParameters(BinaryReader reader, Prototype prototype, uint parametersOffset) { reader.PreserveCurrentPosition(parametersOffset, () => { var typecount = reader.ReadUInt32(); for (var j = 0; j < typecount; j++) { var parameter = new Parameter(); var typeIndex = reader.ReadUInt16(); parameter.Type = Dex.TypeReferences[typeIndex]; prototype.Parameters.Add(parameter); } }); }
private void ReadStaticValues(BinaryReader reader, ClassDefinition classDefinition, uint staticValuesOffset) { reader.PreserveCurrentPosition(staticValuesOffset, () => { var values = ReadValues(reader); for (var j = 0; j < values.Length; j++) classDefinition.Fields[j].Value = values[j]; }); }
private void ReadInterfaces(BinaryReader reader, ClassDefinition classDefinition, uint interfaceOffset) { reader.PreserveCurrentPosition(interfaceOffset, () => { var typecount = reader.ReadUInt32(); for (var j = 0; j < typecount; j++) { var typeIndex = reader.ReadUInt16(); classDefinition.Interfaces.Add((ClassReference)Dex.TypeReferences[typeIndex]); } }); }
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); }); }
private void ReadMethodReferences(BinaryReader reader) { reader.PreserveCurrentPosition(header.MethodReferencesOffset, () => { for (int i = 0; i < header.MethodReferencesSize; i++) { int classIndex = reader.ReadUInt16(); int prototypeIndex = reader.ReadUInt16(); int nameIndex = reader.ReadInt32(); var mref = new MethodReference(); mref.Owner = (CompositeType) typeReferences[classIndex]; // Clone the prototype so we can annotate & update it easily mref.Prototype = prototypes[prototypeIndex].Clone(); mref.Name = strings[nameIndex]; methodReferences.Add(mref); } }); }
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 ReadAnnotationDirectory(BinaryReader reader, ClassDefinition classDefinition, uint annotationOffset) { reader.PreserveCurrentPosition(annotationOffset, () => { uint classAnnotationOffset = reader.ReadUInt32(); uint annotatedFieldsSize = reader.ReadUInt32(); uint annotatedMethodsSize = reader.ReadUInt32(); uint annotatedParametersSize = reader.ReadUInt32(); if (classAnnotationOffset > 0) classDefinition.Annotations = ReadAnnotationSet(reader, classAnnotationOffset); for (int j = 0; j < annotatedFieldsSize; j++) ((FieldDefinition) fieldReferences[reader.ReadInt32()]).Annotations = ReadAnnotationSet(reader, reader.ReadUInt32()); for (int j = 0; j < annotatedMethodsSize; j++) ((MethodDefinition) methodReferences[reader.ReadInt32()]).Annotations = ReadAnnotationSet(reader, reader.ReadUInt32()); for (int j = 0; j < annotatedParametersSize; j++) { int methodIndex = reader.ReadInt32(); uint offset = reader.ReadUInt32(); var annotations = ReadAnnotationSetRefList(reader, offset); var mdef = (methodReferences[methodIndex] as MethodDefinition); for (int i = 0; i < annotations.Count; i++) { if (annotations[i].Count > 0) { mdef.Prototype.Parameters[i].Annotations = annotations[i]; } } } }); }
private void ReadFieldReferences(BinaryReader reader) { reader.PreserveCurrentPosition(header.FieldReferencesOffset, () => { for (int i = 0; i < header.FieldReferencesSize; i++) { int classIndex = reader.ReadUInt16(); int typeIndex = reader.ReadUInt16(); int nameIndex = reader.ReadInt32(); var fref = new FieldReference(); fref.Owner = (ClassReference) typeReferences[classIndex]; fref.Type = typeReferences[typeIndex]; fref.Name = strings[nameIndex]; fieldReferences.Add(fref); } }); }
private void PrefetchTypeReferences(BinaryReader reader) { reader.PreserveCurrentPosition(header.TypeReferencesOffset, () => { reader.BaseStream.Seek(header.TypeReferencesOffset, SeekOrigin.Begin); for (int i = 0; i < header.TypeReferencesSize; i++) { int descriptorIndex = reader.ReadInt32(); string descriptor = strings[descriptorIndex]; typeReferences.Add(TypeDescriptor.Allocate(descriptor)); } }); }
private void PrefetchClassDefinitions(BinaryReader reader, bool prefetchMembers) { reader.PreserveCurrentPosition(header.ClassDefinitionsOffset, () => { for (int i = 0; i < header.ClassDefinitionsSize; i++) { int classIndex = reader.ReadInt32(); ClassDefinition cdef; if (typeReferences[classIndex] is ClassDefinition) { cdef = (ClassDefinition) typeReferences[classIndex]; } else { cdef = new ClassDefinition((ClassReference) typeReferences[classIndex]); typeReferences[classIndex] = cdef; classes.Add(cdef); } reader.ReadInt32(); // skip access_flags reader.ReadInt32(); // skip superclass_idx reader.ReadInt32(); // skip interfaces_off reader.ReadInt32(); // skip source_file_idx reader.ReadInt32(); // skip annotations_off uint classDataOffset = reader.ReadUInt32(); if ((classDataOffset > 0) && prefetchMembers) { PrefetchClassDefinition(reader, cdef, classDataOffset); } reader.ReadInt32(); // skip static_values_off } }); }
private void ReadTypesReferences(BinaryReader reader) { reader.PreserveCurrentPosition(header.TypeReferencesOffset, () => { for (int i = 0; i < header.TypeReferencesSize; i++) { int descriptorIndex = reader.ReadInt32(); string descriptor = strings[descriptorIndex]; TypeDescriptor.Fill(descriptor, typeReferences [i]); } }); }
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 ReadPrototypes(BinaryReader reader) { reader.PreserveCurrentPosition(header.PrototypesOffset, () => { for (int i = 0; i < header.PrototypesSize; i++) { long thisOffset = reader.BaseStream.Position; int shortyIndex = reader.ReadInt32(); int returnTypeIndex = reader.ReadInt32(); uint parametersOffset = reader.ReadUInt32(); var prototype = new Prototype(); prototype.ReturnType = typeReferences[returnTypeIndex]; if (parametersOffset > 0) { ReadParameters(reader, prototype, parametersOffset); } prototype.Freeze(); // cache the signature and hashcode. // ReSharper disable once ReturnValueOfPureMethodIsNotUsed prototype.GetHashCode(); prototype.ToSignature(); prototypes.Add(prototype); } }); }
private void ReadClassDefinitions(BinaryReader reader) { reader.PreserveCurrentPosition(Header.ClassDefinitionsOffset, () => { for (var i = 0; i < Header.ClassDefinitionsSize; i++) { var classIndex = reader.ReadUInt32(); var cdef = (ClassDefinition)Dex.TypeReferences[(int)classIndex]; cdef.AccessFlags = (AccessFlags)reader.ReadUInt32(); var superClassIndex = reader.ReadUInt32(); if (superClassIndex != DexConsts.NoIndex) cdef.SuperClass = (ClassReference)Dex.TypeReferences[(int)superClassIndex]; var interfaceOffset = reader.ReadUInt32(); var sourceFileIndex = reader.ReadUInt32(); var annotationOffset = reader.ReadUInt32(); var classDataOffset = reader.ReadUInt32(); var staticValuesOffset = reader.ReadUInt32(); if (interfaceOffset > 0) ReadInterfaces(reader, cdef, interfaceOffset); if (sourceFileIndex != DexConsts.NoIndex) cdef.SourceFile = Dex.Strings[(int)sourceFileIndex]; if (classDataOffset > 0) ReadClassDefinition(reader, cdef, classDataOffset); if (annotationOffset > 0) ReadAnnotationDirectory(reader, cdef, annotationOffset); if (staticValuesOffset > 0) ReadStaticValues(reader, cdef, staticValuesOffset); } }); }
private void ReadTypesReferences(BinaryReader reader) { reader.PreserveCurrentPosition(header.TypeReferencesOffset, () => { for (int i = 0; i < header.TypeReferencesSize; i++) { int descriptorIndex = reader.ReadInt32(); string descriptor = strings[descriptorIndex]; TypeDescriptor.Fill(descriptor, typeReferences[i]); // freeze the references and cache the encoded value. typeReferences[i].Freeze(); TypeDescriptor.Encode(typeReferences[i]); } }); }
private void ReadFieldReferences(BinaryReader reader) { reader.PreserveCurrentPosition(Header.FieldReferencesOffset, () => { for (var i = 0; i < Header.FieldReferencesSize; i++) { var classIndex = reader.ReadUInt16(); var typeIndex = reader.ReadUInt16(); var nameIndex = reader.ReadInt32(); var fref = new FieldReference { Owner = (ClassReference) Dex.TypeReferences[classIndex], Type = Dex.TypeReferences[typeIndex], Name = Dex.Strings[nameIndex] }; Dex.FieldReferences.Add(fref); } }); }
private void PrefetchClassDefinitions(BinaryReader reader, bool prefetchMembers) { reader.PreserveCurrentPosition(Header.ClassDefinitionsOffset, () => { for (var i = 0; i < Header.ClassDefinitionsSize; i++) { var classIndex = reader.ReadInt32(); var reference = Dex.TypeReferences[classIndex] as ClassDefinition; if (reference == null) { var cdef = new ClassDefinition((ClassReference)Dex.TypeReferences[classIndex]); Dex.TypeReferences[classIndex] = cdef; Dex.Classes.Add(cdef); } reader.ReadInt32(); // skip access_flags reader.ReadInt32(); // skip superclass_idx reader.ReadInt32(); // skip interfaces_off reader.ReadInt32(); // skip source_file_idx reader.ReadInt32(); // skip annotations_off var classDataOffset = reader.ReadUInt32(); if ((classDataOffset > 0) && prefetchMembers) { PrefetchClassDefinition(reader, classDataOffset); } reader.ReadInt32(); // skip static_values_off } }); }
private void ReadMapList(BinaryReader reader) { reader.PreserveCurrentPosition(Header.MapOffset, () => { uint mapsize = reader.ReadUInt32(); for (int i = 0; i < mapsize; i++) { var item = new MapItem {Type = (TypeCodes) reader.ReadUInt16()}; reader.ReadUInt16(); // unused item.Size = reader.ReadUInt32(); item.Offset = reader.ReadUInt32(); Map.Add(item.Type, item); } }); }
private void PrefetchTypeReferences(BinaryReader reader) { reader.PreserveCurrentPosition(Header.TypeReferencesOffset, () => { reader.BaseStream.Seek(Header.TypeReferencesOffset, SeekOrigin.Begin); for (var i = 0; i < Header.TypeReferencesSize; i++) { var descriptorIndex = reader.ReadInt32(); var descriptor = Dex.Strings[descriptorIndex]; Dex.TypeReferences.Add(TypeDescriptor.Allocate(descriptor)); } }); }
private void ReadMethodReferences(BinaryReader reader) { reader.PreserveCurrentPosition(Header.MethodReferencesOffset, () => { for (var i = 0; i < Header.MethodReferencesSize; i++) { int classIndex = reader.ReadUInt16(); int prototypeIndex = reader.ReadUInt16(); int nameIndex = reader.ReadInt32(); var mref = new MethodReference { Owner = (CompositeType) Dex.TypeReferences[classIndex], // Clone the prototype so we can annotate & update it easily Prototype = Dex.Prototypes[prototypeIndex].Clone(), Name = Dex.Strings[nameIndex] }; Dex.MethodReferences.Add(mref); } }); }
private Annotation ReadAnnotation(BinaryReader reader, uint annotationOffset) { Annotation annotation = null; reader.PreserveCurrentPosition(annotationOffset, () => { var visibility = reader.ReadByte(); annotation = ReadEncodedAnnotation(reader); annotation.Visibility = (AnnotationVisibility)visibility; }); return annotation; }
private void ReadPrototypes(BinaryReader reader) { reader.PreserveCurrentPosition(Header.PrototypesOffset, () => { for (var i = 0; i < Header.PrototypesSize; i++) { //var thisOffset = reader.BaseStream.Position; /*var shortyIndex =*/ reader.ReadInt32(); var returnTypeIndex = reader.ReadInt32(); var parametersOffset = reader.ReadUInt32(); var prototype = new Prototype {ReturnType = Dex.TypeReferences[returnTypeIndex]}; if (parametersOffset > 0) { ReadParameters(reader, prototype, parametersOffset); } Dex.Prototypes.Add(prototype); } }); }
private void ReadAnnotationDirectory(BinaryReader reader, IAnnotationProvider provider, uint annotationOffset) { reader.PreserveCurrentPosition(annotationOffset, () => { uint classAnnotationOffset = reader.ReadUInt32(); uint annotatedFieldsSize = reader.ReadUInt32(); uint annotatedMethodsSize = reader.ReadUInt32(); uint annotatedParametersSize = reader.ReadUInt32(); if (classAnnotationOffset > 0) provider.Annotations = ReadAnnotationSet(reader, classAnnotationOffset); for (var j = 0; j < annotatedFieldsSize; j++) { var fieldDefinition = Dex.FieldReferences[reader.ReadInt32()] as FieldDefinition; if (fieldDefinition != null) fieldDefinition.Annotations = ReadAnnotationSet(reader, reader.ReadUInt32()); } for (var j = 0; j < annotatedMethodsSize; j++) { var methodDefinition = Dex.MethodReferences[reader.ReadInt32()] as MethodDefinition; if (methodDefinition != null) methodDefinition.Annotations = ReadAnnotationSet(reader, reader.ReadUInt32()); } for (var j = 0; j < annotatedParametersSize; j++) { var methodIndex = reader.ReadInt32(); var offset = reader.ReadUInt32(); var annotations = ReadAnnotationSetRefList(reader, offset); var mdef = (Dex.MethodReferences[methodIndex] as MethodDefinition); if (mdef == null) break; for (var i = 0; i < annotations.Count; i++) { if (annotations[i].Count <= 0) continue; mdef.Prototype.Parameters[i].Annotations = annotations[i]; } } }); }
private void ReadStrings(BinaryReader reader) { reader.PreserveCurrentPosition(Header.StringsOffset, () => { var stringsDataOffset = reader.ReadUInt32(); reader.BaseStream.Seek(stringsDataOffset, SeekOrigin.Begin); for (var i = 0; i < Header.StringsSize; i++) { Dex.Strings.Add(reader.ReadMUTF8String()); } }); }
private List<List<Annotation>> ReadAnnotationSetRefList(BinaryReader reader, uint annotationOffset) { var result = new List<List<Annotation>>(); reader.PreserveCurrentPosition(annotationOffset, () => { var size = reader.ReadUInt32(); for (uint i = 0; i < size; i++) { var offset = reader.ReadUInt32(); result.Add(ReadAnnotationSet(reader, offset)); } }); return result; }
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 ReadPrototypes(BinaryReader reader) { reader.PreserveCurrentPosition(header.PrototypesOffset, () => { for (int i = 0; i < header.PrototypesSize; i++) { long thisOffset = reader.BaseStream.Position; int shortyIndex = reader.ReadInt32(); int returnTypeIndex = reader.ReadInt32(); uint parametersOffset = reader.ReadUInt32(); var prototype = new Prototype(); prototype.ReturnType = typeReferences[returnTypeIndex]; if (parametersOffset > 0) { ReadParameters(reader, prototype, parametersOffset); } prototypes.Add(prototype); } }); }