k0de
  less

████████╗██╗  ██╗███████╗    ██████╗  ██████╗  ██████╗ ███╗   ███╗
╚══██╔══╝██║  ██║██╔════╝    ██╔══██╗██╔═══██╗██╔═══██╗████╗ ████║
   ██║   ███████║█████╗      ██║  ██║██║   ██║██║   ██║██╔████╔██║
   ██║   ██╔══██║██╔══╝      ██║  ██║██║   ██║██║   ██║██║╚██╔╝██║
   ██║   ██║  ██║███████╗    ██████╔╝╚██████╔╝╚██████╔╝██║ ╚═╝ ██║
   ╚═╝   ╚═╝  ╚═╝╚══════╝    ╚═════╝  ╚═════╝  ╚═════╝ ╚═╝     ╚═╝
    

Using KUNAI (Chapter2 - Disassembler)

by Fare9

Introduction to Kunai’s disassembler

In the previous post, we saw an introduction to Kunai, a static analysis tool aimed to analyze DEX files, both from the DEX perspective, and also from a Intermmediate Representation perspective. We could also see a brief introduction to the architecture of the tool graphically with two schemas.

In this post we will see a brief introduction to the Disassembler, in this case we will just focus on the next part of the architecture:

KUNAI Disassembler

As we can see in the picture, the disassembler of Kunai is a Linear Sweep Disassembly and Recursive Traversal Disassembly, an idea for the future is implementing different algorithms of disassembly improving the efficiency of the algorithm.

Two main algorithms exist for disassembly:

Both algorithms have pros and cons, for example the former while it will disassembly all the bytes, it can misdisassembly some data bytes as instructions, since the algorithm is not able to differentiate them. Then the latter, while it can avoid data after jump instructions, it can leave some bytes out of the process if there’s not a control flow that jumps directly to those bytes (e.g. indirect jumps).

In the paper Practical Analysis of Stripped Binary Code, you can find an algorithm that uses the Recursive Traversal Disassembly algorithm, together with a collection of heuristics in order to increase precision of the disassembly, this algorithm contains two functions, one very common in Recursive Traversal Disassembly that starts disassembly process, and looks for new possible paths to continue disassembly (FindFunctions), and once this process has finished, it runs another function that uses a set of precalculated function prologues in order to discover newer functions that were not discovered in previous process (FindPrologues), more information about the process can be found in Chapter 3 of the book Surreptitious Software: Obfuscation, Watermarking and Tamperproofing for software protection, also you can find a whole chapter about this in the book Practical Binary Analysis, and different papers exists about the topic, for example Disassembly of Executable Code Revisited. It’s planned to include some improvements of the linear sweep and also other algorithms to Kunai’s disassembler.

Using Kunai’s disassembler

After all the theory about disassemblers, we’ll start working with the disassembler from Kunai. Kunai implements both a Linear Sweep Disassembly and Recursive Traversal algorithm, in Dalvik the disassembly process commonly is easier because the bytes that belongs to a method are given by the method itself, we do not have to create any algorithm to recover the methods from the code.

In the previous post, we already said that Kunai when it receives a DEX file, it does nothing more than parsing its header, so whenever we want to use another analysis from Kunai, we have to get a reference to the object, and then ask the object to apply the analysis. Same will happen with the disassembler, if we want Kunai to disassembly our target, we will have to obtain a reference to disassembler object, and then apply it. Why don’t we directly apply the analysis? this is an easy to answer question, Kunai tries to be as modular as possible. Avoiding doing expensive analysis, give the chance to some analyst to obtain results quickly, if you just one to obtain data from the header, it will take seconds in a long DEX to finish, instead of several minutes to apply disassembly, and then cross-references and so on.

In the example we’ll see in this post, we will create a very basic disassembler (similar to objdump tool in Linux), and then we will count all the different instructions that appear in the method, and how many times repeat each one.

Let’s start with the headers and the beginning of the code:

#include <iostream>
#include <list>

#include <KUNAI/DEX/dex.hpp>

int
main(int argc, char **argv)
{
    bool use_recursive = false;

    if (argc == 1 || (argc > 1 && !strcmp("-h", argv[1])))
    {
        std::cerr << "[-] USAGE: " << argv[0] << " <dex_file> <class_name> <method_name> [-r]\n";
        std::cerr << "\t-r: optional argument, use recursive disassembly algorithm\n";
        return 1;
    }

    // check that 4 arguments were given
    if (argc < 4)
    {
        std::cerr << "[-] USAGE: " << argv[0] << " <dex_file> <class_name> <method_name> [-r]\n";
        std::cerr << "\t-r: optional argument, use recursive disassembly algorithm\n";
        return 1;
    }

    // check if one argument more was given
    // check if it is correct
    if (argc > 4 && strcmp("-r", argv[4]))
    {
        std::cerr << "The option " << argv[4] << " is not recognized...\n\n\n";
        std::cerr << "[-] USAGE: " << argv[0] << " <dex_file> <class_name> <method_name> [-r]\n";
        std::cerr << "\t-r: optional argument, use recursive disassembly algorithm\n";
        return 1;
    }else if (argc > 4 && !strcmp("-r", argv[4]))
    {
        use_recursive = true;
    }

We will use the common std::cout and std::cerr to show the information and the errors of the programs, so we will need to use the iostream library. Then we will go with Kunai, this time, we will use the dex.hpp which contains the classes to manage the DEX file. Then, we will start the main function that will be the only one we will have as it is a simple “script”. Inside of the main function we will check that 4 arguments are given, being the first one the name of the program (argv[0]), and then: DEX file, class name and finally method name. We will use the two arguments to retrieve the method we want to disassembly. We will include some other arguments parsing in order to allow a user use or not the recursive traversal disassembler, the kind of disassembler to use have to be configured, being by default a linear sweep disassembly algorithm.

Let’s continue with something we already saw in previous post, the parsing of the DEX file using the DEX object from Kunai.

    // watch info and error messages from Kunai
    spdlog::set_level(spdlog::level::err);

    auto class_name = std::string(argv[2]);
    auto method_name = std::string(argv[3]);

    std::ifstream dex_file;

    dex_file.open(argv[1], std::ios::binary);

    auto fsize = dex_file.tellg();
    dex_file.seekg(0, std::ios::end);
    fsize = dex_file.tellg() - fsize;
    dex_file.seekg(0);

    auto dex_object = KUNAI::DEX::get_unique_dex_object(dex_file, fsize);

    if (!dex_object->get_parsing_correct())
    {
        std::cerr << "Error analyzing " << argv[1] << ", maybe DEX file is not correct...\n";
        return 2;
    }

Again we set the log level from Kunai using spdlog (library used by Kunai for logging). After that, we save in string objects the arguments with the class name, and the argument with the method name. Then we can start opening the DEX file given, and after calculating its size, we create a unique DEX object, this is a std::unique_ptr which holds the DEX information in Kunai. Finally we’ll check if the parsing process was correct.

    // first of all obtain the disassembler object
    auto dex_disassembler = dex_object->get_dex_disassembler();

    // if recursive disassembly is requested by the user
    // use this one!
    if (use_recursive)
        dex_disassembler->set_disassembler_type(KUNAI::DEX::RECURSIVE_TRAVERSAL_DISASSEMBLER);

    // because obtaining the dex object does not apply
    // any analysis, we have to apply disassembly by
    // ourselves
    dex_disassembler->disassembly_analysis();

    // check that all the disassembly was correct
    if (!dex_disassembler->get_disassembly_correct())
    {
        std::cerr << "Error in the disassembly of " << argv[1] << ", maybe some method was incorrect...\n";
        return 3;
    }

From the DEX object we obtain the DexDisassembler object, with this object we can decide if we want the recursive traversal disassembler, in that case we will set it using a specific enum for it (KUNAI::DEX::RECURSIVE_TRAVERSAL_DISASSEMBLER). Then we will apply the disassembly process, that once it finishes it will contain the instructions for each method. From the DexDisassembler object we run its method disassembly_analysis, this will traverse all the methods from the DEX file, and will fill the previous commented variable with all the instructions. Then we can check if the process was correct or not for showing information to the user.

    // instruction_map_t = std::map<std::tuple<classdef_t, encodedmethod_t>, std::map<std::uint64_t, instruction_t>>;
    // instruction_map_t is a map that contains as key a tuple with the class and method
    // and as value a map that contains ordered the address of the instruction
    // and the instruction.
    auto instruction_map = dex_disassembler->get_instructions();

Then we obtain a reference to the instructions structure, this variable is a std::map with a little bit complex structure, the key for the map is a std::tuple that contains a classdef_t object and encodedmethod_t object. Finally the value is a std::map that contains a std::uint64_t with the address or idx of the instruction in the method, and finally the instruction_t object.

Let’s go over this structure looking for the class and the method we want:

    // let's create the variable that will hold all those instructions
    // that appear and how many times appear.
    std::unordered_map<std::uint32_t, size_t> instruction_counter;

    for (const auto& disassembly : instruction_map)
    {

        auto& classdef = std::get<0>(disassembly.first);
        auto& encoded_method = std::get<1>(disassembly.first);

        if (classdef == nullptr || encoded_method == nullptr)
            continue;
        
        if (!class_name.compare(classdef->get_class_idx()->get_name()) &&
            !method_name.compare(*encoded_method->get_method()->get_method_name()))
        {
            std::cout << "Disassembly of " << class_name << "->" << method_name << "\n";

            for (const auto &instructions : disassembly.second)
            {
                std::cout << std::right << std::setfill('0') << std::setw(8) << std::hex << instructions.first << "  ";

                auto &raw_values = instructions.second->get_raw();

                if (raw_values.size() > 8)
                {
                    auto remaining = 8 - (raw_values.size() % 8);

                    size_t aux = 0;

                    for (auto value : raw_values)
                    {
                        std::cout << std::right << std::setfill('0') << std::setw(2) << std::hex << (std::uint32_t)value << " ";
                        aux++;
                        if (aux % 8 == 0)
                        {
                            std::cout << "\n"
                                      << "          ";
                        }
                    }

                    for (std::uint8_t i = 0; i < remaining; i++)
                        std::cout << "   ";
                }
                else
                {
                    for (auto value : raw_values)
                        std::cout << std::right << std::setfill('0') << std::setw(2) << std::hex << (std::uint32_t)value << " ";

                    for (std::uint8_t i = 0, remaining_size = 8 - raw_values.size(); i < remaining_size; i++)
                        std::cout << "   ";
                }

                instructions.second->show_instruction();
                std::cout << std::endl;

                auto &instr = instructions.second;
                auto op = instr->get_OP();

                if (instruction_counter.find(op) == instruction_counter.end())
                    instruction_counter[op] = 0;

                instruction_counter[op] += 1;
            }

            break;
        }
    }

First of all we will create the std::unordered_map that will hold the instructions and the count of those instructions, then we will go through the instructions structure, we want to obtain data only from a specific method, then we will compare names in order to obtain that data. To do that we will have to retrieve name from the classdef_t object, first obtaining the class_t object, and from it the name of the class. And from the encodedmethod_t we obtain the methodid_t and from it the method name. Once we have found the method we are interested, we can go over the instructions.

As we said at the beginning, what we’ll do is to write a disassembler, then we will print the name of the method to disassembly, and after that we will go over each of the instructions, first we show the address, second the bytes of the instruction (using a format similar to other disassemblers), and after that we invoke the method show_instruction that will format the disassembly of that specific instruction, so we do not have to care about what kind of Instruction object is (check the picture at the beginning of the post to see all the instruction types). Then, we will retrieve its op-code, and we’ll start counting instructions.

    std::cout << "\n\nInstruction counter program\n";
    std::cout << "Number of different instructions present in the method: " << instruction_counter.size() << "\n";
    for (const auto & op_instr : instruction_counter)
    {
        auto op_num = op_instr.first;
        auto op_str = dex_object->get_dalvik_opcode_object()->get_instruction_name(op_num);
        
        std::cout << op_str << " [" << op_num << "] appears: " << op_instr.second << " times\n";
    }

    return 0;
}

Finally we will go over the variable we created to count the instructions, and we’ll show what instruction appears in the method, and how many times appear. Let’s compile the program, and run it with a example DEX:

$ g++ -std=c++17 instruction-counter.cpp -o instruction-counter -lkunai
$ ./instruction-counter ../tests/test-modexp/Main.dex "LMain;" "modexp"
Disassembly of LMain;->modexp
00000000  00 00                   nop                      
00000002  00 00                   nop                      
00000004  12 00                   const/4                  v0, 0
00000006  12 11                   const/4                  v1, 1
00000008  12 02                   const/4                  v2, 0
0000000a  12 13                   const/4                  v3, 1
0000000c  35 60 13 00             if-ge                    v0, p2, 19
00000010  44 02 05 00             aget                     v2, p1, v0
00000014  33 12 07 00             if-ne                    v2, v1, 7
00000018  92 03 03 04             mul-int                  v3, v3, p0
0000001c  b4 73                   rem-int/2addr            v3, p3
0000001e  01 32                   move                     v2, v3
00000020  28 02                   goto                     2
00000022  01 32                   move                     v2, v3
00000024  92 03 02 02             mul-int                  v3, v2, v2
00000028  b4 73                   rem-int/2addr            v3, p3
0000002a  00 00                   nop                      
0000002c  d8 00 00 01             add-int/lit8             v0, v0, 1
00000030  28 ee                   goto                     -18
00000032  0f 02                   return                   v2


Instruction counter program
Number of different instructions present in the method: b
return [f] appears: 1 times
add-int/lit8 [d8] appears: 1 times
rem-int/2addr [b4] appears: 2 times
if-ne [33] appears: 1 times
mul-int [92] appears: 2 times
aget [44] appears: 1 times
goto [28] appears: 2 times
move [1] appears: 2 times
if-ge [35] appears: 1 times
const/4 [12] appears: 4 times
nop [0] appears: 3 times

Here we can see the output of the disassembler, and finally the instruction counting. As we can see only 11 (0xb) different instructions exists, and as the method is not so big, they do not appear so many times.

Let’s go now with a method used as interpreter in a VM-based obfuscation:

$ ./instruction-counter ../tests/test-vm/PCodeVM.dex "LPCodeVM;" "exec"
Disassembly of LPCodeVM;->exec
00000000  00 00                   nop                      
00000002  13 00 ff 00             const/16                 v0, 255
00000006  13 01 80 00             const/16                 v1, 128
0000000a  12 52                   const/4                  v2, 5
0000000c  12 73                   const/4                  v3, 7
0000000e  12 64                   const/4                  v4, 6
00000010  12 35                   const/4                  v5, 3
00000012  13 06 09 00             const/16                 v6, 9
00000016  13 07 08 00             const/16                 v7, 8
0000001a  13 08 0a 00             const/16                 v8, 10
0000001e  13 09 0b 00             const/16                 v9, 11
00000022  12 2a                   const/4                  v10, 2
00000024  12 0b                   const/4                  v11, 0
00000026  12 0c                   const/4                  v12, 0
00000028  12 1d                   const/4                  v13, 1
0000002a  2b 0f a3 04 00 00       packed-switch            p1, 1187
00000030  0f 0f                   return                   p1
00000032  00 00                   nop                      
00000034  52 ef 14 00             iget                     p1, p0, I LPCodeVM;.stkidx
00000038  d8 0f 0f fe             add-int/lit8             p1, p1, -2
0000003c  59 ef 14 00             iput                     p1, p0, I LPCodeVM;.stkidx
00000040  54 e0 0d 00             iget-object              v0, p0, [I LPCodeVM;.istk
00000044  44 01 00 0f             aget                     v1, v0, p1
00000048  b0 df                   add-int/2addr            p1, v13
0000004a  44 0f 00 0f             aget                     p1, v0, p1
0000004e  34 f1 03 00             if-lt                    v1, p1, 3
00000052  12 0d                   const/4                  v13, 0
00000054  59 ed 01 00             iput                     v13, p0, I LPCodeVM;.b
00000058  0f 0c                   return                   v12
0000005a  52 ef 14 00             iget                     p1, p0, I LPCodeVM;.stkidx
0000005e  d8 00 0f 01             add-int/lit8             v0, p1, 1
00000062  59 e0 14 00             iput                     v0, p0, I LPCodeVM;.stkidx
00000066  54 e1 0d 00             iget-object              v1, p0, [I LPCodeVM;.istk
0000006a  44 02 01 09             aget                     v2, v1, v9
0000006e  4b 02 01 0f             aput                     v2, v1, p1
00000072  00 00                   nop                      
00000074  d8 0f 00 01             add-int/lit8             p1, v0, 1
00000078  59 ef 14 00             iput                     p1, p0, I LPCodeVM;.stkidx
0000007c  54 e2 10 00             iget-object              v2, p0, [Ljava/lang/Object; LPCodeVM;.lstk
00000080  46 03 02 04             aget-object              v3, v2, v4
00000084  4d 03 02 00             aput-object              v3, v2, v0
00000088  d8 00 0f ff             add-int/lit8             v0, p1, -1
0000008c  d8 03 0f ff             add-int/lit8             v3, p1, -1
00000090  46 03 02 03             aget-object              v3, v2, v3
00000094  b1 df                   sub-int/2addr            p1, v13
00000096  4d 0b 02 0f             aput-object              v11, v2, p1
0000009a  1f 03 07 00             check-cast               v3, [B
0000009e  21 3f                   array-length             p1, v3
000000a0  4b 0f 01 00             aput                     p1, v1, v0
000000a4  0f 0c                   return                   v12
000000a6  52 ef 14 00             iget                     p1, p0, I LPCodeVM;.stkidx
000000aa  b1 df                   sub-int/2addr            p1, v13
000000ac  59 ef 14 00             iput                     p1, p0, I LPCodeVM;.stkidx
000000b0  54 e0 0d 00             iget-object              v0, p0, [I LPCodeVM;.istk
000000b4  44 01 00 0f             aget                     v1, v0, p1
000000b8  4b 01 00 08             aput                     v1, v0, v8
000000bc  00 00                   nop                      
000000be  d8 01 0f 01             add-int/lit8             v1, p1, 1
000000c2  59 e1 14 00             iput                     v1, p0, I LPCodeVM;.stkidx
000000c6  44 02 00 09             aget                     v2, v0, v9
000000ca  4b 02 00 0f             aput                     v2, v0, p1
000000ce  00 00                   nop                      
000000d0  d8 0f 01 01             add-int/lit8             p1, v1, 1
000000d4  59 ef 14 00             iput                     p1, p0, I LPCodeVM;.stkidx
000000d8  4b 05 00 01             aput                     v5, v0, v1
000000dc  0f 0c                   return                   v12
000000de  52 ef 14 00             iget                     p1, p0, I LPCodeVM;.stkidx
000000e2  b1 df                   sub-int/2addr            p1, v13
000000e4  59 ef 14 00             iput                     p1, p0, I LPCodeVM;.stkidx
000000e8  d8 00 0f ff             add-int/lit8             v0, p1, -1
000000ec  54 e1 10 00             iget-object              v1, p0, [Ljava/lang/Object; LPCodeVM;.lstk
000000f0  d8 02 0f ff             add-int/lit8             v2, p1, -1
000000f4  46 02 01 02             aget-object              v2, v1, v2
000000f8  d8 03 0f ff             add-int/lit8             v3, p1, -1
000000fc  4d 0b 01 03             aput-object              v11, v1, v3
00000100  54 e1 0d 00             iget-object              v1, p0, [I LPCodeVM;.istk
00000104  1f 02 07 00             check-cast               v2, [B
00000108  44 0f 01 0f             aget                     p1, v1, p1
0000010c  48 0f 02 0f             aget-byte                p1, v2, p1
00000110  4b 0f 01 00             aput                     p1, v1, v0
00000114  0f 0c                   return                   v12
00000116  52 ef 14 00             iget                     p1, p0, I LPCodeVM;.stkidx
0000011a  b1 df                   sub-int/2addr            p1, v13
0000011c  59 ef 14 00             iput                     p1, p0, I LPCodeVM;.stkidx
00000120  54 e0 0d 00             iget-object              v0, p0, [I LPCodeVM;.istk
00000124  d8 01 0f ff             add-int/lit8             v1, p1, -1
00000128  44 02 00 01             aget                     v2, v0, v1
0000012c  44 03 00 0f             aget                     v3, v0, p1
00000130  b5 32                   and-int/2addr            v2, v3
00000132  4b 02 00 01             aput                     v2, v0, v1
00000136  b1 df                   sub-int/2addr            p1, v13
00000138  59 ef 14 00             iput                     p1, p0, I LPCodeVM;.stkidx
0000013c  44 0f 00 0f             aget                     p1, v0, p1
00000140  4b 0f 00 08             aput                     p1, v0, v8
00000144  0f 0c                   return                   v12
00000146  52 ef 14 00             iget                     p1, p0, I LPCodeVM;.stkidx
0000014a  d8 00 0f 01             add-int/lit8             v0, p1, 1
0000014e  59 e0 14 00             iput                     v0, p0, I LPCodeVM;.stkidx
00000152  54 e1 0d 00             iget-object              v1, p0, [I LPCodeVM;.istk
00000156  44 02 01 06             aget                     v2, v1, v6
0000015a  4b 02 01 0f             aput                     v2, v1, p1
0000015e  b1 d0                   sub-int/2addr            v0, v13
00000160  59 e0 14 00             iput                     v0, p0, I LPCodeVM;.stkidx
00000164  d8 0f 00 ff             add-int/lit8             p1, v0, -1
00000168  54 e2 10 00             iget-object              v2, p0, [Ljava/lang/Object; LPCodeVM;.lstk
0000016c  d8 03 00 ff             add-int/lit8             v3, v0, -1
00000170  46 03 02 03             aget-object              v3, v2, v3
00000174  d8 04 00 ff             add-int/lit8             v4, v0, -1
00000178  4d 0b 02 04             aput-object              v11, v2, v4
0000017c  1f 03 07 00             check-cast               v3, [B
00000180  44 02 01 00             aget                     v2, v1, v0
00000184  48 02 03 02             aget-byte                v2, v3, v2
00000188  4b 02 01 0f             aput                     v2, v1, p1
0000018c  b1 d0                   sub-int/2addr            v0, v13
0000018e  59 e0 14 00             iput                     v0, p0, I LPCodeVM;.stkidx
00000192  d8 0f 00 ff             add-int/lit8             p1, v0, -1
00000196  44 02 01 0f             aget                     v2, v1, p1
0000019a  44 00 01 00             aget                     v0, v1, v0
0000019e  b0 02                   add-int/2addr            v2, v0
000001a0  4b 02 01 0f             aput                     v2, v1, p1
000001a4  0f 0c                   return                   v12
000001a6  52 ef 14 00             iget                     p1, p0, I LPCodeVM;.stkidx
000001aa  b1 df                   sub-int/2addr            p1, v13
000001ac  59 ef 14 00             iput                     p1, p0, I LPCodeVM;.stkidx
000001b0  d8 00 0f ff             add-int/lit8             v0, p1, -1
000001b4  54 e1 10 00             iget-object              v1, p0, [Ljava/lang/Object; LPCodeVM;.lstk
000001b8  d8 03 0f ff             add-int/lit8             v3, p1, -1
000001bc  46 03 01 03             aget-object              v3, v1, v3
000001c0  d8 04 0f ff             add-int/lit8             v4, p1, -1
000001c4  4d 0b 01 04             aput-object              v11, v1, v4
000001c8  54 e4 0d 00             iget-object              v4, p0, [I LPCodeVM;.istk
000001cc  1f 03 07 00             check-cast               v3, [B
000001d0  44 05 04 0f             aget                     v5, v4, p1
000001d4  48 03 03 05             aget-byte                v3, v3, v5
000001d8  4b 03 04 00             aput                     v3, v4, v0
000001dc  00 00                   nop                      
000001de  d8 00 0f 01             add-int/lit8             v0, p1, 1
000001e2  59 e0 14 00             iput                     v0, p0, I LPCodeVM;.stkidx
000001e6  46 00 01 02             aget-object              v0, v1, v2
000001ea  4d 00 01 0f             aput-object              v0, v1, p1
000001ee  0f 0c                   return                   v12
000001f0  52 ef 14 00             iget                     p1, p0, I LPCodeVM;.stkidx
000001f4  d8 00 0f 01             add-int/lit8             v0, p1, 1
000001f8  59 e0 14 00             iput                     v0, p0, I LPCodeVM;.stkidx
000001fc  54 e1 0d 00             iget-object              v1, p0, [I LPCodeVM;.istk
00000200  44 02 01 08             aget                     v2, v1, v8
00000204  4b 02 01 0f             aput                     v2, v1, p1
00000208  d8 00 00 fd             add-int/lit8             v0, v0, -3
0000020c  59 e0 14 00             iput                     v0, p0, I LPCodeVM;.stkidx
00000210  54 ef 10 00             iget-object              p1, p0, [Ljava/lang/Object; LPCodeVM;.lstk
00000214  46 02 0f 00             aget-object              v2, p1, v0
00000218  4d 0b 0f 00             aput-object              v11, p1, v0
0000021c  1f 02 07 00             check-cast               v2, [B
00000220  d8 0f 00 01             add-int/lit8             p1, v0, 1
00000224  44 0f 01 0f             aget                     p1, v1, p1
00000228  b0 a0                   add-int/2addr            v0, v10
0000022a  44 00 01 00             aget                     v0, v1, v0
0000022e  8d 00                   int-to-byte              v0, v0
00000230  4f 00 02 0f             aput-byte                v0, v2, p1
00000234  0f 0c                   return                   v12
00000236  52 ef 14 00             iget                     p1, p0, I LPCodeVM;.stkidx
0000023a  b1 df                   sub-int/2addr            p1, v13
0000023c  59 ef 14 00             iput                     p1, p0, I LPCodeVM;.stkidx
00000240  d8 00 0f ff             add-int/lit8             v0, p1, -1
00000244  54 e1 10 00             iget-object              v1, p0, [Ljava/lang/Object; LPCodeVM;.lstk
00000248  d8 02 0f ff             add-int/lit8             v2, p1, -1
0000024c  46 02 01 02             aget-object              v2, v1, v2
00000250  d8 03 0f ff             add-int/lit8             v3, p1, -1
00000254  4d 0b 01 03             aput-object              v11, v1, v3
00000258  54 e3 0d 00             iget-object              v3, p0, [I LPCodeVM;.istk
0000025c  1f 02 07 00             check-cast               v2, [B
00000260  44 04 03 0f             aget                     v4, v3, p1
00000264  48 02 02 04             aget-byte                v2, v2, v4
00000268  4b 02 03 00             aput                     v2, v3, v0
0000026c  d8 0f 0f fd             add-int/lit8             p1, p1, -3
00000270  59 ef 14 00             iput                     p1, p0, I LPCodeVM;.stkidx
00000274  46 00 01 0f             aget-object              v0, v1, p1
00000278  4d 0b 01 0f             aput-object              v11, v1, p1
0000027c  1f 00 07 00             check-cast               v0, [B
00000280  d8 01 0f 01             add-int/lit8             v1, p1, 1
00000284  44 01 03 01             aget                     v1, v3, v1
00000288  b0 af                   add-int/2addr            p1, v10
0000028a  44 0f 03 0f             aget                     p1, v3, p1
0000028e  8d ff                   int-to-byte              p1, p1
00000290  4f 0f 00 01             aput-byte                p1, v0, v1
00000294  0f 0c                   return                   v12
00000296  52 ef 14 00             iget                     p1, p0, I LPCodeVM;.stkidx
0000029a  d8 00 0f 01             add-int/lit8             v0, p1, 1
0000029e  59 e0 14 00             iput                     v0, p0, I LPCodeVM;.stkidx
000002a2  54 e0 0d 00             iget-object              v0, p0, [I LPCodeVM;.istk
000002a6  44 01 00 07             aget                     v1, v0, v7
000002aa  4b 01 00 0f             aput                     v1, v0, p1
000002ae  0f 0c                   return                   v12
000002b0  52 ef 14 00             iget                     p1, p0, I LPCodeVM;.stkidx
000002b4  d8 00 0f 01             add-int/lit8             v0, p1, 1
000002b8  59 e0 14 00             iput                     v0, p0, I LPCodeVM;.stkidx
000002bc  54 e1 10 00             iget-object              v1, p0, [Ljava/lang/Object; LPCodeVM;.lstk
000002c0  d8 02 00 fe             add-int/lit8             v2, v0, -2
000002c4  46 02 01 02             aget-object              v2, v1, v2
000002c8  d8 03 00 fe             add-int/lit8             v3, v0, -2
000002cc  4d 0b 01 03             aput-object              v11, v1, v3
000002d0  4d 02 01 0f             aput-object              v2, v1, p1
000002d4  54 ef 0d 00             iget-object              p1, p0, [I LPCodeVM;.istk
000002d8  d8 03 00 fe             add-int/lit8             v3, v0, -2
000002dc  d8 04 00 fd             add-int/lit8             v4, v0, -3
000002e0  44 04 0f 04             aget                     v4, p1, v4
000002e4  4b 04 0f 03             aput                     v4, p1, v3
000002e8  b1 50                   sub-int/2addr            v0, v5
000002ea  4d 02 01 00             aput-object              v2, v1, v0
000002ee  0f 0c                   return                   v12
000002f0  52 ef 14 00             iget                     p1, p0, I LPCodeVM;.stkidx
000002f4  d8 00 0f 01             add-int/lit8             v0, p1, 1
000002f8  59 e0 14 00             iput                     v0, p0, I LPCodeVM;.stkidx
000002fc  54 e1 0d 00             iget-object              v1, p0, [I LPCodeVM;.istk
00000300  44 02 01 06             aget                     v2, v1, v6
00000304  4b 02 01 0f             aput                     v2, v1, p1
00000308  b1 d0                   sub-int/2addr            v0, v13
0000030a  59 e0 14 00             iput                     v0, p0, I LPCodeVM;.stkidx
0000030e  d8 0f 00 ff             add-int/lit8             p1, v0, -1
00000312  54 e2 10 00             iget-object              v2, p0, [Ljava/lang/Object; LPCodeVM;.lstk
00000316  d8 03 00 ff             add-int/lit8             v3, v0, -1
0000031a  46 03 02 03             aget-object              v3, v2, v3
0000031e  d8 04 00 ff             add-int/lit8             v4, v0, -1
00000322  4d 0b 02 04             aput-object              v11, v2, v4
00000326  1f 03 07 00             check-cast               v3, [B
0000032a  44 02 01 00             aget                     v2, v1, v0
0000032e  48 02 03 02             aget-byte                v2, v3, v2
00000332  4b 02 01 0f             aput                     v2, v1, p1
00000336  b1 d0                   sub-int/2addr            v0, v13
00000338  59 e0 14 00             iput                     v0, p0, I LPCodeVM;.stkidx
0000033c  44 0f 01 00             aget                     p1, v1, v0
00000340  4b 0f 01 08             aput                     p1, v1, v8
00000344  0f 0c                   return                   v12
00000346  52 ef 14 00             iget                     p1, p0, I LPCodeVM;.stkidx
0000034a  b1 df                   sub-int/2addr            p1, v13
0000034c  59 ef 14 00             iput                     p1, p0, I LPCodeVM;.stkidx
00000350  54 e0 0d 00             iget-object              v0, p0, [I LPCodeVM;.istk
00000354  44 01 00 0f             aget                     v1, v0, p1
00000358  4b 01 00 06             aput                     v1, v0, v6
0000035c  00 00                   nop                      
0000035e  d8 00 0f 01             add-int/lit8             v0, p1, 1
00000362  59 e0 14 00             iput                     v0, p0, I LPCodeVM;.stkidx
00000366  54 e0 10 00             iget-object              v0, p0, [Ljava/lang/Object; LPCodeVM;.lstk
0000036a  46 01 00 02             aget-object              v1, v0, v2
0000036e  4d 01 00 0f             aput-object              v1, v0, p1
00000372  0f 0c                   return                   v12
00000374  52 ef 14 00             iget                     p1, p0, I LPCodeVM;.stkidx
00000378  b1 df                   sub-int/2addr            p1, v13
0000037a  59 ef 14 00             iput                     p1, p0, I LPCodeVM;.stkidx
0000037e  54 e0 0d 00             iget-object              v0, p0, [I LPCodeVM;.istk
00000382  d8 01 0f ff             add-int/lit8             v1, p1, -1
00000386  44 02 00 01             aget                     v2, v0, v1
0000038a  44 0f 00 0f             aget                     p1, v0, p1
0000038e  b5 2f                   and-int/2addr            p1, v2
00000390  4b 0f 00 01             aput                     p1, v0, v1
00000394  0f 0c                   return                   v12
00000396  52 ef 14 00             iget                     p1, p0, I LPCodeVM;.stkidx
0000039a  d8 01 0f 01             add-int/lit8             v1, p1, 1
0000039e  59 e1 14 00             iput                     v1, p0, I LPCodeVM;.stkidx
000003a2  54 e1 0d 00             iget-object              v1, p0, [I LPCodeVM;.istk
000003a6  4b 00 01 0f             aput                     v0, v1, p1
000003aa  0f 0c                   return                   v12
000003ac  52 ef 14 00             iget                     p1, p0, I LPCodeVM;.stkidx
000003b0  b1 df                   sub-int/2addr            p1, v13
000003b2  59 ef 14 00             iput                     p1, p0, I LPCodeVM;.stkidx
000003b6  54 e0 0d 00             iget-object              v0, p0, [I LPCodeVM;.istk
000003ba  d8 01 0f ff             add-int/lit8             v1, p1, -1
000003be  44 02 00 01             aget                     v2, v0, v1
000003c2  44 0f 00 0f             aget                     p1, v0, p1
000003c6  b0 f2                   add-int/2addr            v2, p1
000003c8  4b 02 00 01             aput                     v2, v0, v1
000003cc  0f 0c                   return                   v12
000003ce  52 ef 14 00             iget                     p1, p0, I LPCodeVM;.stkidx
000003d2  d8 00 0f 01             add-int/lit8             v0, p1, 1
000003d6  59 e0 14 00             iput                     v0, p0, I LPCodeVM;.stkidx
000003da  54 e1 0d 00             iget-object              v1, p0, [I LPCodeVM;.istk
000003de  44 02 01 07             aget                     v2, v1, v7
000003e2  4b 02 01 0f             aput                     v2, v1, p1
000003e6  b1 d0                   sub-int/2addr            v0, v13
000003e8  59 e0 14 00             iput                     v0, p0, I LPCodeVM;.stkidx
000003ec  d8 0f 00 ff             add-int/lit8             p1, v0, -1
000003f0  54 e2 10 00             iget-object              v2, p0, [Ljava/lang/Object; LPCodeVM;.lstk
000003f4  d8 03 00 ff             add-int/lit8             v3, v0, -1
000003f8  46 03 02 03             aget-object              v3, v2, v3
000003fc  d8 04 00 ff             add-int/lit8             v4, v0, -1
00000400  4d 0b 02 04             aput-object              v11, v2, v4
00000404  1f 03 07 00             check-cast               v3, [B
00000408  44 00 01 00             aget                     v0, v1, v0
0000040c  48 00 03 00             aget-byte                v0, v3, v0
00000410  4b 00 01 0f             aput                     v0, v1, p1
00000414  0f 0c                   return                   v12
00000416  52 ef 14 00             iget                     p1, p0, I LPCodeVM;.stkidx
0000041a  d8 00 0f 01             add-int/lit8             v0, p1, 1
0000041e  59 e0 14 00             iput                     v0, p0, I LPCodeVM;.stkidx
00000422  54 e0 10 00             iget-object              v0, p0, [Ljava/lang/Object; LPCodeVM;.lstk
00000426  54 e1 08 00             iget-object              v1, p0, Ljava/lang/Object; LPCodeVM;.g
0000042a  4d 01 00 0f             aput-object              v1, v0, p1
0000042e  0f 0c                   return                   v12
00000430  52 ef 13 00             iget                     p1, p0, I LPCodeVM;.peekidx
00000434  d8 00 0f 01             add-int/lit8             v0, p1, 1
00000438  59 e0 13 00             iput                     v0, p0, I LPCodeVM;.peekidx
0000043c  54 e0 10 00             iget-object              v0, p0, [Ljava/lang/Object; LPCodeVM;.lstk
00000440  46 01 00 0f             aget-object              v1, v0, p1
00000444  4d 0b 00 0f             aput-object              v11, v0, p1
00000448  5b e1 0a 00             iput-object              v1, p0, Ljava/lang/Object; LPCodeVM;.i
0000044c  0f 0c                   return                   v12
0000044e  52 ef 14 00             iget                     p1, p0, I LPCodeVM;.stkidx
00000452  d8 00 0f 01             add-int/lit8             v0, p1, 1
00000456  59 e0 14 00             iput                     v0, p0, I LPCodeVM;.stkidx
0000045a  54 e0 10 00             iget-object              v0, p0, [Ljava/lang/Object; LPCodeVM;.lstk
0000045e  46 01 00 02             aget-object              v1, v0, v2
00000462  4d 01 00 0f             aput-object              v1, v0, p1
00000466  0f 0c                   return                   v12
00000468  52 ef 14 00             iget                     p1, p0, I LPCodeVM;.stkidx
0000046c  d8 00 0f 01             add-int/lit8             v0, p1, 1
00000470  59 e0 14 00             iput                     v0, p0, I LPCodeVM;.stkidx
00000474  54 e0 0d 00             iget-object              v0, p0, [I LPCodeVM;.istk
00000478  44 01 00 06             aget                     v1, v0, v6
0000047c  4b 01 00 0f             aput                     v1, v0, p1
00000480  0f 0c                   return                   v12
00000482  52 ef 14 00             iget                     p1, p0, I LPCodeVM;.stkidx
00000486  b1 df                   sub-int/2addr            p1, v13
00000488  59 ef 14 00             iput                     p1, p0, I LPCodeVM;.stkidx
0000048c  54 e0 0d 00             iget-object              v0, p0, [I LPCodeVM;.istk
00000490  44 0f 00 0f             aget                     p1, v0, p1
00000494  4b 0f 00 07             aput                     p1, v0, v7
00000498  0f 0c                   return                   v12
0000049a  52 ef 14 00             iget                     p1, p0, I LPCodeVM;.stkidx
0000049e  d8 01 0f 01             add-int/lit8             v1, p1, 1
000004a2  59 e1 14 00             iput                     v1, p0, I LPCodeVM;.stkidx
000004a6  54 e2 0d 00             iget-object              v2, p0, [I LPCodeVM;.istk
000004aa  4b 00 02 0f             aput                     v0, v2, p1
000004ae  b1 d1                   sub-int/2addr            v1, v13
000004b0  59 e1 14 00             iput                     v1, p0, I LPCodeVM;.stkidx
000004b4  d8 0f 01 ff             add-int/lit8             p1, v1, -1
000004b8  44 00 02 0f             aget                     v0, v2, p1
000004bc  44 01 02 01             aget                     v1, v2, v1
000004c0  b5 10                   and-int/2addr            v0, v1
000004c2  4b 00 02 0f             aput                     v0, v2, p1
000004c6  0f 0c                   return                   v12
000004c8  52 ef 14 00             iget                     p1, p0, I LPCodeVM;.stkidx
000004cc  d8 00 0f 01             add-int/lit8             v0, p1, 1
000004d0  59 e0 14 00             iput                     v0, p0, I LPCodeVM;.stkidx
000004d4  54 e1 0d 00             iget-object              v1, p0, [I LPCodeVM;.istk
000004d8  44 02 01 07             aget                     v2, v1, v7
000004dc  4b 02 01 0f             aput                     v2, v1, p1
000004e0  00 00                   nop                      
000004e2  d8 0f 00 01             add-int/lit8             p1, v0, 1
000004e6  59 ef 14 00             iput                     p1, p0, I LPCodeVM;.stkidx
000004ea  4b 0d 01 00             aput                     v13, v1, v0
000004ee  b1 df                   sub-int/2addr            p1, v13
000004f0  59 ef 14 00             iput                     p1, p0, I LPCodeVM;.stkidx
000004f4  d8 00 0f ff             add-int/lit8             v0, p1, -1
000004f8  44 02 01 00             aget                     v2, v1, v0
000004fc  44 0f 01 0f             aget                     p1, v1, p1
00000500  b0 f2                   add-int/2addr            v2, p1
00000502  4b 02 01 00             aput                     v2, v1, v0
00000506  0f 0c                   return                   v12
00000508  52 ef 14 00             iget                     p1, p0, I LPCodeVM;.stkidx
0000050c  b1 df                   sub-int/2addr            p1, v13
0000050e  59 ef 14 00             iput                     p1, p0, I LPCodeVM;.stkidx
00000512  54 e0 10 00             iget-object              v0, p0, [Ljava/lang/Object; LPCodeVM;.lstk
00000516  4d 0b 00 0f             aput-object              v11, v0, p1
0000051a  0f 0c                   return                   v12
0000051c  52 ef 14 00             iget                     p1, p0, I LPCodeVM;.stkidx
00000520  b1 df                   sub-int/2addr            p1, v13
00000522  59 ef 14 00             iput                     p1, p0, I LPCodeVM;.stkidx
00000526  54 e0 0d 00             iget-object              v0, p0, [I LPCodeVM;.istk
0000052a  44 0f 00 0f             aget                     p1, v0, p1
0000052e  59 ef 01 00             iput                     p1, p0, I LPCodeVM;.b
00000532  0f 0c                   return                   v12
00000534  52 ef 14 00             iget                     p1, p0, I LPCodeVM;.stkidx
00000538  b1 df                   sub-int/2addr            p1, v13
0000053a  59 ef 14 00             iput                     p1, p0, I LPCodeVM;.stkidx
0000053e  54 e0 0d 00             iget-object              v0, p0, [I LPCodeVM;.istk
00000542  44 0f 00 0f             aget                     p1, v0, p1
00000546  39 0f 03 00             if-nez                   p1, 3
0000054a  12 0d                   const/4                  v13, 0
0000054c  59 ed 01 00             iput                     v13, p0, I LPCodeVM;.b
00000550  0f 0c                   return                   v12
00000552  52 ef 14 00             iget                     p1, p0, I LPCodeVM;.stkidx
00000556  b1 df                   sub-int/2addr            p1, v13
00000558  59 ef 14 00             iput                     p1, p0, I LPCodeVM;.stkidx
0000055c  54 e0 0d 00             iget-object              v0, p0, [I LPCodeVM;.istk
00000560  d8 02 0f ff             add-int/lit8             v2, p1, -1
00000564  44 03 00 02             aget                     v3, v0, v2
00000568  44 04 00 0f             aget                     v4, v0, p1
0000056c  b0 43                   add-int/2addr            v3, v4
0000056e  4b 03 00 02             aput                     v3, v0, v2
00000572  00 00                   nop                      
00000574  d8 02 0f 01             add-int/lit8             v2, p1, 1
00000578  59 e2 14 00             iput                     v2, p0, I LPCodeVM;.stkidx
0000057c  d8 03 02 fe             add-int/lit8             v3, v2, -2
00000580  44 03 00 03             aget                     v3, v0, v3
00000584  4b 03 00 0f             aput                     v3, v0, p1
00000588  00 00                   nop                      
0000058a  d8 0f 02 01             add-int/lit8             p1, v2, 1
0000058e  59 ef 14 00             iput                     p1, p0, I LPCodeVM;.stkidx
00000592  4b 01 00 02             aput                     v1, v0, v2
00000596  0f 0c                   return                   v12
00000598  52 ef 14 00             iget                     p1, p0, I LPCodeVM;.stkidx
0000059c  d8 00 0f 01             add-int/lit8             v0, p1, 1
000005a0  59 e0 14 00             iput                     v0, p0, I LPCodeVM;.stkidx
000005a4  54 e0 0d 00             iget-object              v0, p0, [I LPCodeVM;.istk
000005a8  13 01 1f 00             const/16                 v1, 31
000005ac  4b 01 00 0f             aput                     v1, v0, p1
000005b0  0f 0c                   return                   v12
000005b2  52 ef 14 00             iget                     p1, p0, I LPCodeVM;.stkidx
000005b6  d8 00 0f 01             add-int/lit8             v0, p1, 1
000005ba  59 e0 14 00             iput                     v0, p0, I LPCodeVM;.stkidx
000005be  54 e0 0d 00             iget-object              v0, p0, [I LPCodeVM;.istk
000005c2  4b 0d 00 0f             aput                     v13, v0, p1
000005c6  0f 0c                   return                   v12
000005c8  52 ef 14 00             iget                     p1, p0, I LPCodeVM;.stkidx
000005cc  d8 0f 0f fd             add-int/lit8             p1, p1, -3
000005d0  59 ef 14 00             iput                     p1, p0, I LPCodeVM;.stkidx
000005d4  54 e0 10 00             iget-object              v0, p0, [Ljava/lang/Object; LPCodeVM;.lstk
000005d8  46 01 00 0f             aget-object              v1, v0, p1
000005dc  4d 0b 00 0f             aput-object              v11, v0, p1
000005e0  1f 01 07 00             check-cast               v1, [B
000005e4  54 e0 0d 00             iget-object              v0, p0, [I LPCodeVM;.istk
000005e8  d8 02 0f 01             add-int/lit8             v2, p1, 1
000005ec  44 02 00 02             aget                     v2, v0, v2
000005f0  b0 af                   add-int/2addr            p1, v10
000005f2  44 0f 00 0f             aget                     p1, v0, p1
000005f6  8d ff                   int-to-byte              p1, p1
000005f8  4f 0f 01 02             aput-byte                p1, v1, v2
000005fc  44 0f 00 09             aget                     p1, v0, v9
00000600  b0 df                   add-int/2addr            p1, v13
00000602  4b 0f 00 09             aput                     p1, v0, v9
00000606  0f 0c                   return                   v12
00000608  54 ef 0d 00             iget-object              p1, p0, [I LPCodeVM;.istk
0000060c  52 e0 14 00             iget                     v0, p0, I LPCodeVM;.stkidx
00000610  d8 01 00 ff             add-int/lit8             v1, v0, -1
00000614  b1 d0                   sub-int/2addr            v0, v13
00000616  44 00 0f 00             aget                     v0, p1, v0
0000061a  8d 00                   int-to-byte              v0, v0
0000061c  4b 00 0f 01             aput                     v0, p1, v1
00000620  0f 0c                   return                   v12
00000622  52 ef 14 00             iget                     p1, p0, I LPCodeVM;.stkidx
00000626  d8 00 0f 01             add-int/lit8             v0, p1, 1
0000062a  59 e0 14 00             iput                     v0, p0, I LPCodeVM;.stkidx
0000062e  54 e1 0d 00             iget-object              v1, p0, [I LPCodeVM;.istk
00000632  4b 05 01 0f             aput                     v5, v1, p1
00000636  b1 d0                   sub-int/2addr            v0, v13
00000638  59 e0 14 00             iput                     v0, p0, I LPCodeVM;.stkidx
0000063c  d8 0f 00 ff             add-int/lit8             p1, v0, -1
00000640  44 02 01 0f             aget                     v2, v1, p1
00000644  44 03 01 00             aget                     v3, v1, v0
00000648  b0 32                   add-int/2addr            v2, v3
0000064a  4b 02 01 0f             aput                     v2, v1, p1
0000064e  b1 d0                   sub-int/2addr            v0, v13
00000650  59 e0 14 00             iput                     v0, p0, I LPCodeVM;.stkidx
00000654  d8 0f 00 ff             add-int/lit8             p1, v0, -1
00000658  44 02 01 0f             aget                     v2, v1, p1
0000065c  44 00 01 00             aget                     v0, v1, v0
00000660  b7 20                   xor-int/2addr            v0, v2
00000662  4b 00 01 0f             aput                     v0, v1, p1
00000666  0f 0c                   return                   v12
00000668  52 ef 14 00             iget                     p1, p0, I LPCodeVM;.stkidx
0000066c  d8 00 0f 01             add-int/lit8             v0, p1, 1
00000670  59 e0 14 00             iput                     v0, p0, I LPCodeVM;.stkidx
00000674  54 e0 0d 00             iget-object              v0, p0, [I LPCodeVM;.istk
00000678  44 01 00 08             aget                     v1, v0, v8
0000067c  4b 01 00 0f             aput                     v1, v0, p1
00000680  0f 0c                   return                   v12
00000682  52 ef 14 00             iget                     p1, p0, I LPCodeVM;.stkidx
00000686  d8 00 0f 01             add-int/lit8             v0, p1, 1
0000068a  59 e0 14 00             iput                     v0, p0, I LPCodeVM;.stkidx
0000068e  54 e1 10 00             iget-object              v1, p0, [Ljava/lang/Object; LPCodeVM;.lstk
00000692  46 02 01 04             aget-object              v2, v1, v4
00000696  4d 02 01 0f             aput-object              v2, v1, p1
0000069a  00 00                   nop                      
0000069c  d8 0f 00 01             add-int/lit8             p1, v0, 1
000006a0  59 ef 14 00             iput                     p1, p0, I LPCodeVM;.stkidx
000006a4  54 e2 0d 00             iget-object              v2, p0, [I LPCodeVM;.istk
000006a8  44 03 02 09             aget                     v3, v2, v9
000006ac  4b 03 02 00             aput                     v3, v2, v0
000006b0  b1 df                   sub-int/2addr            p1, v13
000006b2  59 ef 14 00             iput                     p1, p0, I LPCodeVM;.stkidx
000006b6  d8 00 0f ff             add-int/lit8             v0, p1, -1
000006ba  d8 03 0f ff             add-int/lit8             v3, p1, -1
000006be  46 03 01 03             aget-object              v3, v1, v3
000006c2  d8 04 0f ff             add-int/lit8             v4, p1, -1
000006c6  4d 0b 01 04             aput-object              v11, v1, v4
000006ca  1f 03 07 00             check-cast               v3, [B
000006ce  44 0f 02 0f             aget                     p1, v2, p1
000006d2  48 0f 03 0f             aget-byte                p1, v3, p1
000006d6  4b 0f 02 00             aput                     p1, v2, v0
000006da  0f 0c                   return                   v12
000006dc  52 ef 14 00             iget                     p1, p0, I LPCodeVM;.stkidx
000006e0  d8 00 0f 01             add-int/lit8             v0, p1, 1
000006e4  59 e0 14 00             iput                     v0, p0, I LPCodeVM;.stkidx
000006e8  54 e1 10 00             iget-object              v1, p0, [Ljava/lang/Object; LPCodeVM;.lstk
000006ec  46 02 01 03             aget-object              v2, v1, v3
000006f0  4d 02 01 0f             aput-object              v2, v1, p1
000006f4  00 00                   nop                      
000006f6  d8 0f 00 01             add-int/lit8             p1, v0, 1
000006fa  59 ef 14 00             iput                     p1, p0, I LPCodeVM;.stkidx
000006fe  54 ef 0d 00             iget-object              p1, p0, [I LPCodeVM;.istk
00000702  44 01 0f 09             aget                     v1, p1, v9
00000706  4b 01 0f 00             aput                     v1, p1, v0
0000070a  0f 0c                   return                   v12
0000070c  54 ef 0d 00             iget-object              p1, p0, [I LPCodeVM;.istk
00000710  44 00 0f 08             aget                     v0, p1, v8
00000714  b0 d0                   add-int/2addr            v0, v13
00000716  4b 00 0f 08             aput                     v0, p1, v8
0000071a  0f 0c                   return                   v12
0000071c  52 ef 14 00             iget                     p1, p0, I LPCodeVM;.stkidx
00000720  d8 00 0f 01             add-int/lit8             v0, p1, 1
00000724  59 e0 14 00             iput                     v0, p0, I LPCodeVM;.stkidx
00000728  54 e0 0d 00             iget-object              v0, p0, [I LPCodeVM;.istk
0000072c  4b 0c 00 0f             aput                     v12, v0, p1
00000730  0f 0c                   return                   v12
00000732  52 ef 14 00             iget                     p1, p0, I LPCodeVM;.stkidx
00000736  d8 00 0f 01             add-int/lit8             v0, p1, 1
0000073a  59 e0 14 00             iput                     v0, p0, I LPCodeVM;.stkidx
0000073e  54 e0 0d 00             iget-object              v0, p0, [I LPCodeVM;.istk
00000742  13 01 62 00             const/16                 v1, 98
00000746  4b 01 00 0f             aput                     v1, v0, p1
0000074a  0f 0c                   return                   v12
0000074c  52 ef 14 00             iget                     p1, p0, I LPCodeVM;.stkidx
00000750  d8 00 0f 01             add-int/lit8             v0, p1, 1
00000754  59 e0 14 00             iput                     v0, p0, I LPCodeVM;.stkidx
00000758  54 e0 0d 00             iget-object              v0, p0, [I LPCodeVM;.istk
0000075c  13 01 5f 00             const/16                 v1, 95
00000760  4b 01 00 0f             aput                     v1, v0, p1
00000764  0f 0c                   return                   v12
00000766  52 ef 14 00             iget                     p1, p0, I LPCodeVM;.stkidx
0000076a  b1 df                   sub-int/2addr            p1, v13
0000076c  59 ef 14 00             iput                     p1, p0, I LPCodeVM;.stkidx
00000770  54 e0 0d 00             iget-object              v0, p0, [I LPCodeVM;.istk
00000774  44 0f 00 0f             aget                     p1, v0, p1
00000778  38 0f 03 00             if-eqz                   p1, 3
0000077c  12 0d                   const/4                  v13, 0
0000077e  59 ed 01 00             iput                     v13, p0, I LPCodeVM;.b
00000782  0f 0c                   return                   v12
00000784  52 ef 14 00             iget                     p1, p0, I LPCodeVM;.stkidx
00000788  d8 00 0f 01             add-int/lit8             v0, p1, 1
0000078c  59 e0 14 00             iput                     v0, p0, I LPCodeVM;.stkidx
00000790  54 e0 0d 00             iget-object              v0, p0, [I LPCodeVM;.istk
00000794  4b 0a 00 0f             aput                     v10, v0, p1
00000798  0f 0c                   return                   v12
0000079a  52 ef 14 00             iget                     p1, p0, I LPCodeVM;.stkidx
0000079e  b1 df                   sub-int/2addr            p1, v13
000007a0  59 ef 14 00             iput                     p1, p0, I LPCodeVM;.stkidx
000007a4  54 e0 0d 00             iget-object              v0, p0, [I LPCodeVM;.istk
000007a8  d8 01 0f ff             add-int/lit8             v1, p1, -1
000007ac  44 02 00 01             aget                     v2, v0, v1
000007b0  44 0f 00 0f             aget                     p1, v0, p1
000007b4  b4 f2                   rem-int/2addr            v2, p1
000007b6  4b 02 00 01             aput                     v2, v0, v1
000007ba  0f 0c                   return                   v12
000007bc  52 ef 13 00             iget                     p1, p0, I LPCodeVM;.peekidx
000007c0  d8 00 0f 01             add-int/lit8             v0, p1, 1
000007c4  59 e0 13 00             iput                     v0, p0, I LPCodeVM;.peekidx
000007c8  54 e0 0d 00             iget-object              v0, p0, [I LPCodeVM;.istk
000007cc  44 0f 00 0f             aget                     p1, v0, p1
000007d0  59 ef 01 00             iput                     p1, p0, I LPCodeVM;.b
000007d4  0f 0c                   return                   v12
000007d6  52 ef 14 00             iget                     p1, p0, I LPCodeVM;.stkidx
000007da  52 e0 02 00             iget                     v0, p0, I LPCodeVM;.c
000007de  b1 0f                   sub-int/2addr            p1, v0
000007e0  59 ef 14 00             iput                     p1, p0, I LPCodeVM;.stkidx
000007e4  59 ef 13 00             iput                     p1, p0, I LPCodeVM;.peekidx
000007e8  0f 0c                   return                   v12
000007ea  52 ef 14 00             iget                     p1, p0, I LPCodeVM;.stkidx
000007ee  d8 00 0f 01             add-int/lit8             v0, p1, 1
000007f2  59 e0 14 00             iput                     v0, p0, I LPCodeVM;.stkidx
000007f6  54 e0 0d 00             iget-object              v0, p0, [I LPCodeVM;.istk
000007fa  4b 01 00 0f             aput                     v1, v0, p1
000007fe  0f 0c                   return                   v12
00000800  52 ef 14 00             iget                     p1, p0, I LPCodeVM;.stkidx
00000804  d8 00 0f 01             add-int/lit8             v0, p1, 1
00000808  59 e0 14 00             iput                     v0, p0, I LPCodeVM;.stkidx
0000080c  54 e1 0d 00             iget-object              v1, p0, [I LPCodeVM;.istk
00000810  13 02 2b 00             const/16                 v2, 43
00000814  4b 02 01 0f             aput                     v2, v1, p1
00000818  b1 d0                   sub-int/2addr            v0, v13
0000081a  59 e0 14 00             iput                     v0, p0, I LPCodeVM;.stkidx
0000081e  d8 0f 00 ff             add-int/lit8             p1, v0, -1
00000822  44 02 01 0f             aget                     v2, v1, p1
00000826  44 03 01 00             aget                     v3, v1, v0
0000082a  b0 32                   add-int/2addr            v2, v3
0000082c  4b 02 01 0f             aput                     v2, v1, p1
00000830  00 00                   nop                      
00000832  d8 0f 00 01             add-int/lit8             p1, v0, 1
00000836  59 ef 14 00             iput                     p1, p0, I LPCodeVM;.stkidx
0000083a  b1 af                   sub-int/2addr            p1, v10
0000083c  44 0f 01 0f             aget                     p1, v1, p1
00000840  4b 0f 01 00             aput                     p1, v1, v0
00000844  0f 0c                   return                   v12
00000846  52 ef 14 00             iget                     p1, p0, I LPCodeVM;.stkidx
0000084a  d8 00 0f 01             add-int/lit8             v0, p1, 1
0000084e  59 e0 14 00             iput                     v0, p0, I LPCodeVM;.stkidx
00000852  54 e0 0d 00             iget-object              v0, p0, [I LPCodeVM;.istk
00000856  52 e1 02 00             iget                     v1, p0, I LPCodeVM;.c
0000085a  4b 01 00 0f             aput                     v1, v0, p1
0000085e  0f 0c                   return                   v12
00000860  52 ef 14 00             iget                     p1, p0, I LPCodeVM;.stkidx
00000864  d8 00 0f 01             add-int/lit8             v0, p1, 1
00000868  59 e0 14 00             iput                     v0, p0, I LPCodeVM;.stkidx
0000086c  54 e0 10 00             iget-object              v0, p0, [Ljava/lang/Object; LPCodeVM;.lstk
00000870  46 01 00 03             aget-object              v1, v0, v3
00000874  4d 01 00 0f             aput-object              v1, v0, p1
00000878  0f 0c                   return                   v12
0000087a  54 ef 10 00             iget-object              p1, p0, [Ljava/lang/Object; LPCodeVM;.lstk
0000087e  52 e0 14 00             iget                     v0, p0, I LPCodeVM;.stkidx
00000882  d8 01 00 ff             add-int/lit8             v1, v0, -1
00000886  46 01 0f 01             aget-object              v1, p1, v1
0000088a  b1 d0                   sub-int/2addr            v0, v13
0000088c  4d 0b 0f 00             aput-object              v11, p1, v0
00000890  5b e1 0a 00             iput-object              v1, p0, Ljava/lang/Object; LPCodeVM;.i
00000894  0f 0c                   return                   v12
00000896  52 ef 14 00             iget                     p1, p0, I LPCodeVM;.stkidx
0000089a  d8 00 0f 01             add-int/lit8             v0, p1, 1
0000089e  59 e0 14 00             iput                     v0, p0, I LPCodeVM;.stkidx
000008a2  54 e1 0d 00             iget-object              v1, p0, [I LPCodeVM;.istk
000008a6  4b 0c 01 0f             aput                     v12, v1, p1
000008aa  b1 d0                   sub-int/2addr            v0, v13
000008ac  59 e0 14 00             iput                     v0, p0, I LPCodeVM;.stkidx
000008b0  44 0f 01 00             aget                     p1, v1, v0
000008b4  4b 0f 01 09             aput                     p1, v1, v9
000008b8  0f 0c                   return                   v12
000008ba  52 ef 14 00             iget                     p1, p0, I LPCodeVM;.stkidx
000008be  b1 df                   sub-int/2addr            p1, v13
000008c0  59 ef 14 00             iput                     p1, p0, I LPCodeVM;.stkidx
000008c4  54 e0 0d 00             iget-object              v0, p0, [I LPCodeVM;.istk
000008c8  44 0f 00 0f             aget                     p1, v0, p1
000008cc  4b 0f 00 06             aput                     p1, v0, v6
000008d0  0f 0c                   return                   v12
000008d2  52 ef 14 00             iget                     p1, p0, I LPCodeVM;.stkidx
000008d6  d8 00 0f 01             add-int/lit8             v0, p1, 1
000008da  59 e0 14 00             iput                     v0, p0, I LPCodeVM;.stkidx
000008de  54 e1 0d 00             iget-object              v1, p0, [I LPCodeVM;.istk
000008e2  4b 0c 01 0f             aput                     v12, v1, p1
000008e6  b1 d0                   sub-int/2addr            v0, v13
000008e8  59 e0 14 00             iput                     v0, p0, I LPCodeVM;.stkidx
000008ec  44 0f 01 00             aget                     p1, v1, v0
000008f0  4b 0f 01 07             aput                     p1, v1, v7
000008f4  00 00                   nop                      
000008f6  d8 0f 00 01             add-int/lit8             p1, v0, 1
000008fa  59 ef 14 00             iput                     p1, p0, I LPCodeVM;.stkidx
000008fe  4b 0c 01 00             aput                     v12, v1, v0
00000902  0f 0c                   return                   v12
00000904  52 ef 14 00             iget                     p1, p0, I LPCodeVM;.stkidx
00000908  b1 df                   sub-int/2addr            p1, v13
0000090a  59 ef 14 00             iput                     p1, p0, I LPCodeVM;.stkidx
0000090e  54 e0 10 00             iget-object              v0, p0, [Ljava/lang/Object; LPCodeVM;.lstk
00000912  46 01 00 0f             aget-object              v1, v0, p1
00000916  4d 0b 00 0f             aput-object              v11, v0, p1
0000091a  4d 01 00 03             aput-object              v1, v0, v3
0000091e  0f 0c                   return                   v12
00000920  52 ef 14 00             iget                     p1, p0, I LPCodeVM;.stkidx
00000924  d8 00 0f 01             add-int/lit8             v0, p1, 1
00000928  59 e0 14 00             iput                     v0, p0, I LPCodeVM;.stkidx
0000092c  54 e1 10 00             iget-object              v1, p0, [Ljava/lang/Object; LPCodeVM;.lstk
00000930  46 02 01 04             aget-object              v2, v1, v4
00000934  4d 02 01 0f             aput-object              v2, v1, p1
00000938  d8 0f 00 ff             add-int/lit8             p1, v0, -1
0000093c  d8 02 00 ff             add-int/lit8             v2, v0, -1
00000940  46 02 01 02             aget-object              v2, v1, v2
00000944  d8 03 00 ff             add-int/lit8             v3, v0, -1
00000948  4d 0b 01 03             aput-object              v11, v1, v3
0000094c  54 e3 0d 00             iget-object              v3, p0, [I LPCodeVM;.istk
00000950  1f 02 07 00             check-cast               v2, [B
00000954  21 22                   array-length             v2, v2
00000956  4b 02 03 0f             aput                     v2, v3, p1
0000095a  d8 0f 00 ff             add-int/lit8             p1, v0, -1
0000095e  b1 d0                   sub-int/2addr            v0, v13
00000960  44 00 03 00             aget                     v0, v3, v0
00000964  23 00 07 00             new-array                v0, v0, [B
00000968  4d 00 01 0f             aput-object              v0, v1, p1
0000096c  0f 0c                   return                   v12
0000096e  00 00                   nop                      
00000970  00 01 37 00 01 00 00 00 
          7b 6d 54 48 36 28 1b 0e 
          eb e0 d6 c9 b8 ad 9e 91 
          84 79 71 59 2c 1f fc ef 
          cf c4 b7 94 85 79 6f 4f 
          38 2c 1f 12 03 f6 d2 c1 
          b6 a5 8e 63 43 36 06 e3 
          be 8e 76 5a 3e 18 04    packed-switch-payload    (size)55 (first/last key)1 
                                [0x47b,0x46d,0x454,0x448,0x436,0x428,0x41b,0x40e,0x3eb,
                                0x3e0,0x3d6,0x3c9,0x3b8,0x3ad,0x39e,0x391,0x384,0x379,
                                0x371,0x359,0x32c,0x31f,0x2fc,0x2ef,0x2cf,0x2c4,0x2b7,
                                0x294,0x285,0x279,0x26f,0x24f,0x238,0x22c,0x21f,0x212,
                                0x203,0x1f6,0x1d2,0x1c1,0x1b6,0x1a5,0x18e,0x163,0x143,
                                0x136,0x106,0xe3,0xbe,0x8e,0x76,0x5a,0x3e,0x18,0x4]


Instruction counter program
Number of different instructions present in the method: 1d
new-array [23] appears: 1 times
rem-int/2addr [b4] appears: 1 times
if-eqz [38] appears: 1 times
xor-int/2addr [b7] appears: 1 times
if-nez [39] appears: 1 times
aput-byte [4f] appears: 3 times
int-to-byte [8d] appears: 4 times
and-int/2addr [b5] appears: 3 times
iput-object [5b] appears: 2 times
array-length [21] appears: 2 times
sub-int/2addr [b1] appears: 26 times
aget-object [46] appears: 18 times
nop [0] appears: f times
if-lt [34] appears: 1 times
aput-object [4d] appears: 1e times
const/16 [13] appears: a times
iget-object [54] appears: 45 times
const/4 [12] appears: b times
aget-byte [48] appears: 7 times
packed-switch [2b] appears: 1 times
packed-switch-payload [100] appears: 1 times
iget [52] appears: 38 times
return [f] appears: 38 times
add-int/lit8 [d8] appears: 60 times
aget [44] appears: 44 times
check-cast [1f] appears: c times
iput [59] appears: 56 times
add-int/2addr [b0] appears: c times
aput [4b] appears: 40 times

Here we have a much bigger method, but even with that only 29 instructions are used, in anycase the disassembler shows the content of the method correctly and using a familiar format for all those who are used to analyzing smali code. We can see the complexity of this method in a graph generated also with Kunai and its Intermmediate Representation (MjolnIR):

PCodeVM exec

Remember that you can download Kunai on its Github repository.

With this we have seen a very brief introduction to the disassembler from Kunai, each one of the instructions contains a different format that you can find in Kunai’s documentation, or directly inside of the header of the instruction.

I hope this set of blogposts become handy for all those who want to start using Kunai for their analysis, and don’t forget to leave your issues in the Github repository!

See you in the next post.