def _add_stub_class(self, className, superClassName, st ):
        """
        @param className: Name of new class; example: Lcom/test;
        @param superClassName: Name of super class; example: Ljava/lang/Object;
        @param st: Smali tree to save class
        """
        
        stub_class = ClassNode()
        stub_class.set_name("L" + PKG_PREFIX + "/" + className[1:])
        stub_class.add_access("public")
        stub_class.set_super_name(superClassName)

        self.stub_classes[className] = stub_class
        self.class_map[className] = "L" + PKG_PREFIX + "/" + className[1:]

        method = MethodNode()
        method.set_desc("<init>()V")
        method.add_access(["public", "constructor"])
        method.set_registers(1)
#           i1 = InsnNode("invoke-direct {p0}, Ljava/lang/Object;-><init>()V")    #Error! Must not create instance of Object, but of superclass
        i1 = InsnNode("invoke-direct {p0}, "+superClassName+"-><init>()V")
        i2 = InsnNode("return-void")
        method.add_insn([i1, i2])
        stub_class.add_method(method)
        st.add_class(stub_class)
    def __add_stub_inst(self, stub_class, on, m, regs=1):
        segs = m.rsplit("->", 1)

        method = MethodNode()
        method.set_desc(segs[1])
        method.add_para(TypeNode(segs[0]))
        method.add_access(["public", "static"])

        method.set_registers(regs)
        stub_class.add_method(method)

        i = m.find('(')
        self.method_map[m] = "L" + PKG_PREFIX + "/" + segs[0][1:] + "->" + \
                method.get_desc()
    def __add_stub_cons(self, stub_class, m, regs=1):
        segs = m.rsplit("->", 1)
        desc = segs[1].replace("<init>", "droidbox_cons")
        i = desc.find(')')
        desc = desc[:i + 1] + segs[0]
        method = MethodNode()
        method.set_desc(desc)
        method.add_access(["public", "static"])

        method.set_registers(regs)
        stub_class.add_method(method)

        i = m.find('(')
        self.method_map[m] = "L" + PKG_PREFIX + "/" + segs[0][1:] + "->" + \
                method.get_desc()
    def __add_stub_static(self, stub_class, m, regs=1):
        segs = m.rsplit("->", 1)

        method = MethodNode()
        method.set_desc(segs[1])
        method.add_access(["public", "static"])

        para_num = len(method.paras)
        reg_num = method.get_paras_reg_num()
        ri = 1

        method.set_registers(regs)
        stub_class.add_method(method)

        i = m.find('(')
        self.method_map[m] = "L" + PKG_PREFIX + "/" + segs[0][1:] + "->" + \
                method.get_desc()
Esempio n. 5
0
    def add_stub_method(self, on, m, parent_class, parent_method, package):
        #segs = m.split(':', 1)
        #method_type = segs[0]
        #m = segs[1]
        #print on,m
        method_type = METHOD_TYPE_BY_OPCODE[on]
        segs = m.rsplit("->", 1)
        #print on,m,method_type,segs
        #print parent_class.name, segs[0]
        # if package in parent_class.name:
        #     print "removing",parent_class.name,package,segs[0]
        #     self.stub_classes.pop(segs[0],None)
        if self.stub_classes.has_key(segs[0]):
            stub_class = self.stub_classes[segs[0]]
        else:
            stub_class = ClassNode()
            #stub_class.set_name = "Ldroidbox/java/lang/String" for Ljava/lang/String;->format(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String; invoke-static
            stub_class.set_name("L" + PKG_PREFIX + "/" + segs[0][1:])
            stub_class.add_access("public")
            stub_class.set_super_name("Ljava/lang/Object;")

            self.stub_classes[segs[0]] = stub_class
            self.class_map[segs[0]] = "L" + PKG_PREFIX + "/" + segs[0][1:]

            #.method public constructor <init>()V
            #    .registers 1
            #    invoke-direct {p0}, Ljava/lang/Object;-><init>()V
            #    return-void
            #.end method
            method = MethodNode()
            method.set_desc("<init>()V")
            method.add_access(["public", "constructor"])
            method.set_registers(1)
            i1 = InsnNode("invoke-direct {p0}, Ljava/lang/Object;-><init>()V")
            i2 = InsnNode("return-void")
            method.add_insn([i1, i2])
            stub_class.add_method(method)
        method_name = segs[1][:segs[1].find("(")]
        #print stub_class.name,method_name,method_type,parent_class.name
        if method_type == "constructor":
            self.__add_stub_cons2(stub_class, m, parent_class, parent_method)
        elif method_type == "instance":
            self.__add_stub_inst(stub_class, on, m, parent_class,
                                 parent_method)
        elif method_type == "static":
            self.__add_stub_static(stub_class, m, parent_class, parent_method)
Esempio n. 6
0
    def add_stub_method(self, on, m):
        #segs = m.split(':', 1)
        #method_type = segs[0]
        #m = segs[1]
        method_type = METHOD_TYPE_BY_OPCODE[on]
        segs = m.rsplit("->", 1)

        if self.stub_classes.has_key(segs[0]):
            stub_class = self.stub_classes[segs[0]]
        else:
            stub_class = ClassNode()
            stub_class.set_name("L" + PKG_PREFIX + "/" + segs[0][1:])
            stub_class.add_access("public")
            stub_class.set_super_name("Ljava/lang/Object;")

            self.stub_classes[segs[0]] = stub_class
            self.class_map[segs[0]] = "L" + PKG_PREFIX + "/" + segs[0][1:]

            #.method public constructor <init>()V
            #    .registers 1
            #    invoke-direct {p0}, Ljava/lang/Object;-><init>()V
            #    return-void
            #.end method
            method = MethodNode()
            method.set_desc("<init>()V")
            method.add_access(["public", "constructor"])
            method.set_registers(1)
            i1 = InsnNode("invoke-direct {p0}, Ljava/lang/Object;-><init>()V")
            i2 = InsnNode("return-void")
            method.add_insn([i1, i2])
            stub_class.add_method(method)

        method_name = segs[1][:segs[1].find("(")]
        if method_type == "constructor":
            self.__add_stub_cons2(stub_class, m)
        elif method_type == "instance":
            self.__add_stub_inst(stub_class, on, m)
        elif method_type == "static":
            self.__add_stub_static(stub_class, m)
Esempio n. 7
0
    def __add_stub_static(self, stub_class, m):
        segs = m.rsplit("->", 1)

        method = MethodNode()
        method.set_desc(segs[1])
        method.add_access(["public", "static"])

        para_num = len(method.paras)
        reg_num = method.get_paras_reg_num()
        ri = 1

        if reg_num <= 5:
            i = "invoke-static {%s}, %s" % \
                    (", ".join(["p%d" % k for k in range(reg_num)]), m)
        else:
            i = "invoke-static/range {p0 .. p%d}, %s" % (reg_num - 1, m) 

        method.add_insn(InsnNode(i)) 

        if not method.ret.void:
            if method.ret.basic and method.ret.dim == 0:
                if method.ret.words == 1:
                    method.add_insn(InsnNode("move-result v1"))
                    ri += 1
                else:
                    method.add_insn(InsnNode("move-result-wide v1"))
                    ri += 2
            else:
                method.add_insn(InsnNode("move-result-object v1"))
                ri += 1

        method.add_insn(InsnNode("new-instance \
v%d, Ljava/lang/StringBuilder;" % ri))
        method.add_insn(InsnNode("invoke-direct \
{v%d}, Ljava/lang/StringBuilder;-><init>()V" % ri))

        method.add_insn(InsnNode("const-string v%d,\"%s(\"" % \
                                 (ri + 1, m.split('(', 1)[0])))
        append_i = InsnNode("invoke-virtual \
{v%d, v%d}, Ljava/lang/StringBuilder;->\
append(Ljava/lang/String;)Ljava/lang/StringBuilder;" % \
                            (ri, ri + 1))
        method.add_insn(append_i)
        
        # print parameters
        pi = 0
        for k in range(0, para_num):
            p = method.paras[k]
            method.add_insn(InsnNode("const-string v%d, \"%s=\"" % (ri + 1,
                                     p.get_desc())))
            method.add_insn(append_i)

            if p.basic and p.dim == 0:
                if p.words == 1:
                    method.add_insn(InsnNode("invoke-static {p%d}, \
Ljava/lang/String;->valueOf(%s)Ljava/lang/String;" % \
                                             (pi, p.get_desc())))
                    pi += 1
                else:
                    method.add_insn(InsnNode("invoke-static \
{p%d, p%d}, Ljava/lang/String;->valueOf(%s)Ljava/lang/String;" % \
                        (pi, pi + 1, p.get_desc())))
                    pi += 2
                method.add_insn(InsnNode("move-result-object v%d" % (ri + 1)))
                method.add_insn(append_i)
            else:
                method.add_insn(InsnNode("invoke-static {p%d}, \
Ldroidbox/apimonitor/Helper;->toString(Ljava/lang/Object;)Ljava/lang/String;" % (pi, )))
                pi += 1
                method.add_insn(InsnNode("move-result-object v%d" % (ri + 1)))
                method.add_insn(append_i)

            if k < para_num - 1:
                method.add_insn(InsnNode("const-string v%d, \" | \"" % \
                                         (ri + 1)))
                method.add_insn(append_i)

        method.add_insn(InsnNode("const-string v%d, \")\"" % (ri + 1)))
        method.add_insn(append_i)

        # print return value
        p = method.ret
        if p.void:
            method.add_insn(InsnNode("const-string v%d, \"%s\"" % (ri + 1,
                                     p.get_desc())))
            method.add_insn(append_i)
        else:
            method.add_insn(InsnNode("const-string v%d, \"%s=\"" % (ri + 1,
                                     p.get_desc())))
            method.add_insn(append_i)
            if p.basic and p.dim == 0:
                if p.words == 1:
                    method.add_insn(InsnNode("invoke-static {v1}, \
Ljava/lang/String;->valueOf(%s)Ljava/lang/String;" % \
                                             p.get_desc()))
                else:
                    method.add_insn(InsnNode("invoke-static \
{v1, v2}, Ljava/lang/String;->valueOf(%s)Ljava/lang/String;" % \
                                             p.get_desc()))
                method.add_insn(InsnNode("move-result-object v%d" % (ri + 1)))
                method.add_insn(append_i)
            else:
                method.add_insn(InsnNode("invoke-static {v1}, \
Ldroidbox/apimonitor/Helper;->toString(Ljava/lang/Object;)Ljava/lang/String;"))
                method.add_insn(InsnNode("move-result-object v%d" % (ri + 1)))
                method.add_insn(append_i)

        method.add_insn(InsnNode("invoke-virtual {v%d}, \
Ljava/lang/StringBuilder;->toString()Ljava/lang/String;" % ri))
        method.add_insn(InsnNode("move-result-object v%d" % (ri + 1)))
        method.add_insn(InsnNode("invoke-static {v%d}, \
Ldroidbox/apimonitor/Helper;->log(Ljava/lang/String;)V" % \
                                 (ri + 1, )))
        if not method.ret.void:
            if method.ret.basic and method.ret.dim == 0:
                if method.ret.words == 1:
                    method.add_insn(InsnNode("return v1"))
                else:
                    method.add_insn(InsnNode("return-wide v1"))
            else:
                method.add_insn(InsnNode("return-object v1"))
        else:
            method.add_insn(InsnNode("return-void"))

        start = LabelNode(":droidbox_try_start", 0)
        end = LabelNode(":droidbox_try_end", 1)
        index = len(method.insns)
        ret = LabelNode(":droidbox_return", index - 1)
        handler = LabelNode(":droidbox_handler", index)
        line = ".catch Ljava/lang/Exception; {:droidbox_try_start .. \
:droidbox_try_end} :droidbox_handler"
        TryNode(line, start, end, handler)
        method.add_label([start, end, ret, handler])

        method.add_insn(InsnNode("move-exception v0"))
        method.add_insn(InsnNode("invoke-virtual {v0}, \
Ljava/lang/Exception;->printStackTrace()V"))
        if not method.ret.void:
            if method.ret.basic and method.ret.dim == 0:
                if method.ret.words == 1:
                    method.add_insn(InsnNode("const/4 v1, 0x0"))
                else:
                    method.add_insn(InsnNode("const-wide/16 v1, 0x0"))
            else:
                method.add_insn(InsnNode("const/4 v1, 0x0"))
        method.add_insn(InsnNode("goto :droidbox_return"))

        method.set_registers(reg_num + ri + 2)
        stub_class.add_method(method)

        i = m.find('(')
        self.method_map[m] = "L" + PKG_PREFIX + "/" + segs[0][1:] + "->" + \
                method.get_desc()
Esempio n. 8
0
    def __add_stub_cons2(self, stub_class, m):
        segs = m.rsplit("->", 1)
        desc = segs[1].replace("<init>", "droidbox_cons")
        i = desc.find(')')
        desc = desc[:i + 1] + 'V'
        method = MethodNode()
        method.set_desc(desc)
        method.add_access(["public", "static"])

        para_num = len(method.paras)
        reg_num = method.get_paras_reg_num()
        ri = 0

        method.add_insn(InsnNode("new-instance \
v%d, Ljava/lang/StringBuilder;" % ri))
        method.add_insn(InsnNode("invoke-direct \
{v%d}, Ljava/lang/StringBuilder;-><init>()V" % ri))

        method.add_insn(InsnNode("const-string v%d,\"%s(\"" % \
                                 (ri + 1, m.split('(', 1)[0])))
        append_i = InsnNode("invoke-virtual \
{v%d, v%d}, Ljava/lang/StringBuilder;->\
append(Ljava/lang/String;)Ljava/lang/StringBuilder;" % \
                            (ri, ri + 1))
        method.add_insn(append_i)
        
        # print parameters
        pi = 0
        for k in range(0, para_num):
            p = method.paras[k]
            method.add_insn(InsnNode("const-string v%d, \"%s=\"" % (ri + 1,
                                     p.get_desc())))
            method.add_insn(append_i)

            if p.basic and p.dim == 0:
                if p.words == 1:
                    method.add_insn(InsnNode("invoke-static {p%d}, \
Ljava/lang/String;->valueOf(%s)Ljava/lang/String;" % \
                                             (pi, p.get_desc())))
                    pi += 1
                else:
                    method.add_insn(InsnNode("invoke-static \
{p%d, p%d}, Ljava/lang/String;->valueOf(%s)Ljava/lang/String;" % \
                        (pi, pi + 1, p.get_desc())))
                    pi += 2
                method.add_insn(InsnNode("move-result-object v%d" % (ri + 1)))
                method.add_insn(append_i)
            else:
                method.add_insn(InsnNode("invoke-static {p%d}, \
Ldroidbox/apimonitor/Helper;->toString(Ljava/lang/Object;)Ljava/lang/String;" % (pi, )))
                pi += 1
                method.add_insn(InsnNode("move-result-object v%d" % (ri + 1)))
                method.add_insn(append_i)

            if k < para_num - 1:
                method.add_insn(InsnNode("const-string v%d, \" | \"" % \
                                         (ri + 1)))
                method.add_insn(append_i)

        method.add_insn(InsnNode("const-string v%d, \")\"" % (ri + 1)))
        method.add_insn(append_i)

        # print return value
        p = method.ret
        if p.void:
            method.add_insn(InsnNode("const-string v%d, \"%s\"" % (ri + 1,
                                     p.get_desc())))
            method.add_insn(append_i)
        else:
            method.add_insn(InsnNode("const-string v%d, \"%s=\"" % (ri + 1,
                                     p.get_desc())))
            method.add_insn(append_i)
            if p.basic and p.dim == 0:
                if p.words == 1:
                    method.add_insn(InsnNode("invoke-static {v1}, \
Ljava/lang/String;->valueOf(%s)Ljava/lang/String;" % \
                                             p.get_desc()))
                else:
                    method.add_insn(InsnNode("invoke-static \
{v1, v2}, Ljava/lang/String;->valueOf(%s)Ljava/lang/String;" % \
                                             p.get_desc()))
                method.add_insn(InsnNode("move-result-object v%d" % (ri + 1)))
                method.add_insn(append_i)
            else:
                method.add_insn(InsnNode("invoke-static {v1}, \
Ldroidbox/apimonitor/Helper;->toString(Ljava/lang/Object;)Ljava/lang/String;"))
                method.add_insn(InsnNode("move-result-object v%d" % (ri + 1)))
                method.add_insn(append_i)

        method.add_insn(InsnNode("invoke-virtual {v%d}, \
Ljava/lang/StringBuilder;->toString()Ljava/lang/String;" % ri))
        method.add_insn(InsnNode("move-result-object v%d" % (ri + 1)))
        method.add_insn(InsnNode("invoke-static {v%d}, \
Ldroidbox/apimonitor/Helper;->log(Ljava/lang/String;)V" % \
                                 (ri + 1, )))
        if not method.ret.void:
            if method.ret.basic and method.ret.dim == 0:
                if method.ret.words == 1:
                    method.add_insn(InsnNode("return v1"))
                else:
                    method.add_insn(InsnNode("return-wide v1"))
            else:
                method.add_insn(InsnNode("return-object v1"))
        else:
            method.add_insn(InsnNode("return-void"))

        method.set_registers(reg_num + ri + 2)
        stub_class.add_method(method)

        i = m.find('(')
        self.method_map[m] = "L" + PKG_PREFIX + "/" + segs[0][1:] + "->" + \
                method.get_desc()