Example #1
0
        /// <summary>Build source code for a single method.</summary>
        /// <param name="method"></param>
        /// <returns></returns>
        private string BuildSourceCode(IMethod method, AstNode methodRootNode,
            Dictionary<string, string> namespaceByImportedType)
        {
            byte[] byteCode = method.GetByteCode();
            if (null == byteCode) { return ""; }
            StringBuilder resultBuilder = new StringBuilder();
            int opCodeIndex = 0;
            SortedList<uint, uint> exclusions = new SortedList<uint, uint>();

            GenerateMethodHeader(method, resultBuilder, namespaceByImportedType);
            throw new NotImplementedException();
            //SourceCodeWalkerContext sourceCodeWalkerContext = new SourceCodeWalkerContext(resultBuilder);
            //methodRootNode.Walk(SourceCodeWalker, WalkMode.TransitBeforeAndAfter,
            //    sourceCodeWalkerContext);
            //foreach(InstructionAstNode scannedNode in methodRootNode.WalkLeaf<InstructionAstNode>()) {
            //    resultBuilder.AppendLine(scannedNode.AssemblyCode);
            //}
            //IEnumerator<ITryBlock> tryBlocksEnumerator = method.EnumerateTryBlocks().GetEnumerator();
            //ITryBlock nextGuardedBlock =
            //    tryBlocksEnumerator.MoveNext() ? tryBlocksEnumerator.Current : null;
            //Stack<ITryBlock> partialTryBlocks = new Stack<ITryBlock>();
            //while (byteCode.Length > opCodeIndex)
            //{
            //    // Check for next guarded block beginning.
            //    while ((null != nextGuardedBlock)
            //        && ((sizeof(ushort) * nextGuardedBlock.StartAddress) == opCodeIndex))
            //    {
            //        // The current block is starting at current decoder position.
            //        resultBuilder.Append("try { \n");
            //        partialTryBlocks.Push(nextGuardedBlock);
            //        // Acquire next guarded block if any and loop again. This is because this
            //        // new guarded block may share the same start offset than the one we just
            //        // handled.
            //        nextGuardedBlock =
            //            tryBlocksEnumerator.MoveNext() ? tryBlocksEnumerator.Current : null;
            //    }

            //    // Decode current instruction.
            //    resultBuilder.Append(OpCodeDecoder.Decode(null, byteCode, method.ByteCodeRawAddress,
            //        _objectResolver, exclusions, ref opCodeIndex));

            //    // Handle partial guarded block termination.
            //    while (true)
            //    {
            //        if (0 == partialTryBlocks.Count) { break; }
            //        ITryBlock nextClosingBlock = partialTryBlocks.Peek();
            //        int lastCoveredOpCodeIndex = (int)(sizeof(ushort) *
            //            (nextClosingBlock.StartAddress + nextClosingBlock.InstructionsCount - 1));
            //        if (lastCoveredOpCodeIndex >= opCodeIndex) { break; }
            //        // This test for code robustness. Should never be true.
            //        if (lastCoveredOpCodeIndex != (opCodeIndex - sizeof(ushort)))
            //        {
            //            throw new ApplicationException();
            //        }
            //        // Current block terminates here.
            //        nextClosingBlock = partialTryBlocks.Pop();
            //    }
            //}
            //if (0 != partialTryBlocks.Count) { throw new REException(); }
            //if (byteCode.Length != opCodeIndex) { throw new REException(); }
            //if (0 < exclusions.Count) { throw new REException(); }
            resultBuilder.Append("}");
            return resultBuilder.ToString();
        }
Example #2
0
        /// <summary>Decode instructions for the given method.</summary>
        /// <param name="method">The method to be decoded.</param>
        /// <param name="objectResolver">An implementation of an object resolver to be
        /// used for retrieving classes and constant strings referenced from the bytecode.
        /// </param>
        /// <returns>An array indexed by the offset within method byte code and storing
        /// the instruction starting at this offset (if any).</returns>
        private static DalvikInstruction[] BuildInstructionList(IMethod method,
            IResolver objectResolver)
        {
            DalvikInstruction[] result = new DalvikInstruction[method.ByteCodeSize];
            byte[] byteCode = method.GetByteCode();
            List<uint> pendingInstructionsOffset = new List<uint>();

            // Add entry point.
            pendingInstructionsOffset.Add(0);
            // As well as catch blocks from the exception because they aren't
            // referenced from normal code.
            foreach (ITryBlock tryBlock in method.EnumerateTryBlocks()) {
                foreach (IGuardHandler handler in tryBlock.EnumerateHandlers()) {
                    uint addedOffset = handler.HandlerMethodOffset;
                    // For debugging purpose. Should never occur.
                    if (addedOffset >= byteCode.Length) { throw new ApplicationException(); }
                    pendingInstructionsOffset.Add(addedOffset);
                }
            }
            Console.WriteLine(
                "Decoding '{0}' method bytecode on {1} bytes starting at 0x{2:X8}.",
                Helpers.BuildMethodDeclarationString(method), byteCode.Length,
                method.ByteCodeRawAddress);

            while (0 < pendingInstructionsOffset.Count) {
                uint opCodeIndex = pendingInstructionsOffset[0];
                pendingInstructionsOffset.RemoveAt(0);
                bool fallInSequence = true;

                while (fallInSequence) {
                    // Avoid targeting twice a single instruction.
                    if (null != result[opCodeIndex]) { break; }
                    DalvikInstruction newNode = OpCodeDecoder.Decode(byteCode,
                        method.ByteCodeRawAddress, objectResolver, result,
                        ref opCodeIndex);

                    // Analyse possible targets after this instruction and augment
                    // pending instructions list accordingly.
                    fallInSequence = newNode.ContinueInSequence;
                    uint[] otherTargetMethodOffsets = newNode.AdditionalTargetMethodOffsets;
                    if (null != otherTargetMethodOffsets) {
                        for(int index = 0; index < otherTargetMethodOffsets.Length; index++) {
                            uint targetOffset = otherTargetMethodOffsets[index];

                            if (targetOffset >= byteCode.Length) { throw new ApplicationException(); }
                            if (!pendingInstructionsOffset.Contains(targetOffset)
                                && (null == result[targetOffset])) {
                                pendingInstructionsOffset.Add(targetOffset);
                            }
                        }
                    }
                }
            }
            return result;
        }