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