Coder Social home page Coder Social logo

androguard / androguard Goto Github PK

View Code? Open in Web Editor NEW
5.0K 240.0 1.0K 98.22 MB

Reverse engineering and pentesting for Android applications

License: Apache License 2.0

Python 86.75% JavaScript 10.38% Java 2.87%
android dalvik reverse-engineering dex odex pentesting

androguard's People

Contributors

1orenz0 avatar adesnos avatar bernhl avatar danielgf3 avatar dweinstein avatar ehrenb avatar eighthave avatar enkelli avatar erev0s avatar hallucino avatar hugovk avatar jochasinga avatar krnick avatar ksg97031 avatar leonid-s-usov avatar lircyn avatar lorinwu avatar loydjayme25 avatar marcograss avatar martinthoma avatar nlachfr avatar reox avatar ryu-s-r avatar saidelike1 avatar shuxin avatar subho007 avatar supercilex avatar totoag avatar ylarod avatar zyrikby avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

androguard's Issues

Unpack error when loading classes.dex

Hi,

I got the following error when trying to load a dex file:

error: unpack requires a string argument of length 20

And the sample dex can be found at:

http://expirebox.com/download/d692213bf6e4b289f55005c601242952.html

Regression: androrisk.py is broken

commit 37e3c3b adds regression:

$ androrisk.py --help
  File "/usr/lib/python-exec/python2.7/androrisk.py", line 59
SyntaxError: Non-ASCII character '\xef' in file /usr/lib/python-exec/python2.7/androrisk.py on line 59, but no encoding declared; see http://www.python.org/peps/pep-0263.html for details
$ python --version
Python 2.7.7

commit aa5ad78 works fine.

AttributeError: 'TryBlock' object has no attribute 'visit_cond'

i have a QQ.apk
my code like:
TEST = "./QQ.apk"
de = decompile.DvMachine(TEST)
start = time.clock()
de.process()
end = time.clock()
print end-start

the full log is:
de.process()
File "build\bdist.win-amd64\egg\androguard\decompiler\dad\decompile.py", line 401, in process
File "build\bdist.win-amd64\egg\androguard\decompiler\dad\decompile.py", line 251, in process
File "build\bdist.win-amd64\egg\androguard\decompiler\dad\decompile.py", line 242, in process_method
File "build\bdist.win-amd64\egg\androguard\decompiler\dad\decompile.py", line 168, in process
File "build\bdist.win-amd64\egg\androguard\decompiler\dad\writer.py", line 187, in write_method
File "build\bdist.win-amd64\egg\androguard\decompiler\dad\writer.py", line 203, in visit_node
File "build\bdist.win-amd64\egg\androguard\decompiler\dad\basic_blocks.py", line 72, in visit
File "build\bdist.win-amd64\egg\androguard\decompiler\dad\writer.py", line 381, in visit_statement_node
File "build\bdist.win-amd64\egg\androguard\decompiler\dad\writer.py", line 203, in visit_node
File "build\bdist.win-amd64\egg\androguard\decompiler\dad\basic_blocks.py", line 241, in visit
File "build\bdist.win-amd64\egg\androguard\decompiler\dad\writer.py", line 240, in visit_loop_node
AttributeError: 'TryBlock' object has no attribute 'visit_cond'

Consider removing psyco support

http://psyco.sourceforge.net/

News
12 March 2012
    Psyco is unmaintained and dead. Please look at PyPy for the state-of-the-art in JIT compilers for Python.
$ grep psyco -i androguard/core/bytecode.py -a3
class _Bytecode(object):
    def __init__(self, buff):
        try:
            import psyco
            psyco.full()
        except ImportError:
            pass

issue when run androdd.py

Hi all, I get the following error when i run androdd.py :

Traceback (most recent call last):
  File "androdd.py", line 242, in <module>
    main(options, arguments)
  File "androdd.py", line 226, in main
    a = Androguard([options.input])
NameError: global name 'Androguard' is not defined

IOError when running androdd.py

When running androdd.py -i app-debug.apk -o tmp on Windows I get following error:

Traceback (most recent call last):
  File "E:\TestAndroid\androguard-2.0\androdd.py", line 218, in <module>
    main(options, arguments)
  File "E:\TestAndroid\androguard-2.0\androdd.py", line 203, in main
    export_apps_to_format(options.input, a, options.output, options.limit, options.jar, options.decompiler, options.format)
  File "E:\TestAndroid\androguard-2.0\androdd.py", line 195, in export_apps_to_format
    with open(filename + ".ag", "w") as fd:
IOError: [Errno 22] invalid mode ('w') or filename: 'tmp/android/support/v4/BuildConfig/<init>--V.ag'

incomplete get_operands

Hi, is it normal that instruction.get_operands() doesn't give me the same registers as instruction.get_output()?

Example to better explain:

If i execute print instruction.get_output() I get:

v0 ... v7, Landroid/database/sqlite/SQLiteDatabase;->query(Ljava/lang/String; [Ljava/lang/String; Ljava/lang/String; [Ljava/lang/String; Ljava/lang/String; Ljava/lang/String; Ljava/lang/String;)Landroid/database/Cursor; 

If I execute print instruction.get_operands() I get:

[(0, 0), (0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (0, 6), (256, 420, 'Landroid/database/sqlite/SQLiteDatabase;->query(Ljava/lang/String; [Ljava/lang/String; Ljava/lang/String; [Ljava/lang/String; Ljava/lang/String; Ljava/lang/String; Ljava/lang/String;)Landroid/database/Cursor;')]

The result of get_output() ranges from v0 to v7, while the result of get_operands() ranges from (0, 0) to (0, 6). Maybe I'm wrong, but I expected get_operands() to range from (0, 0) to (0, 7).

The instruction type in this example is <class 'androguard.core.bytecodes.dvm.Instruction3rc'>

Thanks

Invalid uleb128 decoding, idx_diffs for Encoded*

Some elements are not read correctly, causing *Invalid objects to be created for them. Sounds like a decoding issue, but after doing some digging I couldn't find the cause. Btw, the biggest values are 32b full of 1s.

Dexdump has no issues reading that file.

Example APK is hosted on http://tepr.in/~tpr/temp/androguard_broken.apk . Here's an excerpt from androlyze shell for that file.

In [11]: for i in d.get_classes():
for x in i.get_methods():
print "idx: %i" % x.get_method_idx_diff()
....:
idx: 4
idx: 5
idx: 7
idx: 4294967292
idx: 1
idx: 4294967293
idx: 1
idx: 10
idx: 13
idx: 1
idx: 3
idx: 4294967295
idx: 4294967295
idx: 18
idx: 19
idx: 20
idx: 21
idx: 22
idx: 23
idx: 24

androidd.py has error pydot.InvocationException: -11

When i decompile a apk, an error happens. I try two times. It always stops at Dump Lcbd; h ()Z ... jpg ... Exception list below. Is thers some solutions? Hope your help.

Dump Lcbd; h ()Z ... jpg ...
Traceback (most recent call last):
  File "/Users/victor/Documents/develop/github/v_androguard/androdd.py", line 218, in <module>
    main(options, arguments)
  File "/Users/victor/Documents/develop/github/v_androguard/androdd.py", line 203, in main
    export_apps_to_format(options.input, a, options.output, options.limit, options.jar, options.decompiler, options.format)
  File "/Users/victor/Documents/develop/github/v_androguard/androdd.py", line 180, in export_apps_to_format
    method2format(filename + "." + format, format, None, buff)
  File "/Users/victor/Documents/develop/github/v_androguard/androguard/core/bytecode.py", line 360, in method2format
    getattr(d, "write_" + _format.lower())(output)
  File "/usr/local/lib/python2.7/site-packages/pydot.py", line 1602, in <lambda>
    lambda path, f=frmt, prog=self.prog : self.write(path, format=f, prog=prog))
  File "/usr/local/lib/python2.7/site-packages/pydot.py", line 1696, in write
    dot_fd.write(self.create(prog, format))
  File "/usr/local/lib/python2.7/site-packages/pydot.py", line 1796, in create
    status, stderr_output) )
pydot.InvocationException: Program terminated with status: -11. stderr follows: []

missing security checks

Variables are often used without having been properly controlled if they are None.
This raise Exceptions.
I have fixed this bugs in the writer.py file where a crash was generated when analyzing optimezed APK.
Please find below the patched file:

import logging
from struct import unpack
from androguard.decompiler.dad.util import get_type
from androguard.decompiler.dad.opcode_ins import Op
from androguard.decompiler.dad.instruction import (Constant, ThisParam,
                                                   BinaryExpression,
                                                   BaseClass,
                                                   InstanceExpression,
                                                   NewInstance,
                                                   Variable,
                                                   BinaryCompExpression)

logger = logging.getLogger('dad.writer')

class Writer(object):
    def **init**(self, graph, method):
        self.graph = graph
        self.method = method
        self.visited_nodes = set()
        self.ind = 4
        self.buffer = []
        self.buffer2 = []
        self.loop_follow = [None]
        self.if_follow = [None]
        self.switch_follow = [None]
        self.latch_node = [None]
        self.try_follow = [None]
        self.next_case = None
        self.skip = False
        self.need_break = True

def __str__(self):
    return ''.join(self.buffer)

def str_ext(self):
    return self.buffer2

def inc_ind(self, i=1):
    self.ind += (4 * i)

def dec_ind(self, i=1):
    self.ind -= (4 * i)

def space(self):
    if self.skip:
        self.skip = False
        return ''
    return ' ' * self.ind

def write_ind(self):
    if self.skip:
        self.skip = False
    else:
        self.write(self.space())
        self.write_ext(('INDENTATION', self.space()))

def write(self, s, data=None):
    self.buffer.append(s)
    # old method, still used
    # TODO: clean?
    if data:
        self.buffer2.append((data, s))

# at minimum, we have t as a tuple of the form:
# (TYPE_STR, MY_STR) such as ('THIS', 'this')
# where the 2nd field is the actual generated source code
# We can have more fields, for example:
# ('METHOD', 'sendToServer', 'this -> sendToServer', <androguard.decompiler.dad.instruction.ThisParam>)
def write_ext(self, t):
    if not isinstance(t, tuple):
        raise "Error in write_ext: %s not a tuple" % str(t)
    self.buffer2.append(t)

def end_ins(self):
    self.write(';\n')
    self.write_ext(('END_INSTRUCTION', ';\n'))

def write_ind_visit_end(self, lhs, s, rhs=None, data=None):
    self.write_ind()
    lhs.visit(self)
    self.write(s)
    self.write_ext(('TODO_4343', s, data))
    if rhs is not None:
        rhs.visit(self)
    self.end_ins()

#TODO: prefer this class as write_ind_visit_end that should be deprecated
# at the end
def write_ind_visit_end_ext(self, lhs, before, s, after, rhs=None,
                            data=None, subsection='UNKNOWN_SUBSECTION'):
    self.write_ind()
    lhs.visit(self)
    self.write(before + s + after)
    self.write_ext(('BEFORE', before))
    self.write_ext((subsection, s, data))
    self.write_ext(('AFTER', after))
    if rhs is not None:
        rhs.visit(self)
    self.end_ins()

def write_inplace_if_possible(self, lhs, rhs):
    if isinstance(rhs, BinaryExpression) and lhs == rhs.var_map[rhs.arg1]:
        exp_rhs = rhs.var_map[rhs.arg2]
        if rhs.op in '+-' and isinstance(exp_rhs, Constant) and\
                              exp_rhs.get_int_value() == 1:
            return self.write_ind_visit_end(lhs, rhs.op * 2, data=rhs)
        return self.write_ind_visit_end(
            lhs, ' %s= ' % rhs.op, exp_rhs, data=rhs)
    return self.write_ind_visit_end(lhs, ' = ', rhs, data=rhs)

def visit_ins(self, ins):
    ins.visit(self)

def write_method(self):
    acc = []
    if self.method is None :
        return
    access = self.method.access
    if not access is None :
        return
    self.constructor = False
    for modifier in access:
        if modifier == 'constructor':
            self.constructor = True
            continue
        acc.append(modifier)
    self.write('\n%s' % self.space())
    self.write_ext(('NEWLINE', '\n%s' % (self.space())))
    if acc:
        self.write('%s ' % ' '.join(acc))
        self.write_ext(('PROTOTYPE_ACCESS', '%s ' % ' '.join(acc)))
    if self.constructor:
        name = get_type(self.method.cls_name).split('.')[-1]
        self.write(name)
        self.write_ext(('NAME_METHOD_PROTOTYPE', '%s' % name, self.method))
    else:
        self.write(
            '%s %s' % (get_type(self.method.type), self.method.name))
        self.write_ext(
            ('PROTOTYPE_TYPE', '%s' % get_type(self.method.type)))
        self.write_ext(('SPACE', ' '))
        self.write_ext(
            ('NAME_METHOD_PROTOTYPE',
            '%s' % self.method.name, self.method))
    params = self.method.lparams
    if 'static' not in access:
        params = params[1:]
    proto = ''
    self.write_ext(('PARENTHESIS_START', '('))
    if self.method.params_type:
        proto = ', '.join(['%s p%s' % (get_type(p_type), param) for
                    p_type, param in zip(self.method.params_type, params)])
        first = True
        for p_type, param in zip(self.method.params_type, params):
            if not first:
                self.write_ext(('COMMA', ', '))
            else:
                first = False
            self.write_ext(('ARG_TYPE', '%s' % get_type(p_type)))
            self.write_ext(('SPACE', ' '))
            self.write_ext(
                ('NAME_ARG', 'p%s' % param, p_type, self.method))
    self.write_ext(('PARENTHESIS_END', ')'))
    self.write('(%s)' % proto)
    if self.graph is None:
        self.write(';\n')
        self.write_ext(('METHOD_END_NO_CONTENT', ';\n'))
        return
    self.write('\n%s{\n' % self.space())
    self.write_ext(('METHOD_START', '\n%s{\n' % self.space()))
    self.inc_ind()
    self.visit_node(self.graph.entry)
    self.dec_ind()
    self.write('%s}\n' % self.space())
    self.write_ext(('METHOD_END', '%s}\n' % self.space()))

def visit_node(self, node):
    if node in (self.if_follow[-1], self.switch_follow[-1],
                self.loop_follow[-1], self.latch_node[-1],
                self.try_follow[-1]):
        return
    if not node.type.is_return and node in self.visited_nodes:
        return
    if self.visited_nodes is None :
        return
    self.visited_nodes.add(node)
    if node.var_to_declare is None :
        return
    for var in node.var_to_declare:
        var.visit_decl(self)
        var.declared = True
    node.visit(self)

def visit_loop_node(self, loop):
    if loop is None :
        return
    follow = loop.follow['loop']
    if follow is None and not loop.looptype.is_endless:
        logger.error('Loop has no follow !')
    if loop.looptype.is_pretest:
        if loop.true is follow:
            loop.neg()
            loop.true, loop.false = loop.false, loop.true
        self.write('%swhile (' % self.space())
        self.write_ext(('WHILE', '%swhile (' % self.space()))
        loop.visit_cond(self)
        self.write(') {\n')
        self.write_ext(('WHILE_START', ') {\n'))
    elif loop.looptype.is_posttest:
        self.write('%sdo {\n' % self.space())
        self.write_ext(('DO', '%sdo {\n' % self.space()))
        self.latch_node.append(loop.latch)
    elif loop.looptype.is_endless:
        self.write('%swhile(true) {\n' % self.space())
        self.write_ext(('WHILE_TRUE', '%swhile(true) {\n' % self.space()))
    self.inc_ind()
    self.loop_follow.append(follow)
    if loop.looptype.is_pretest:
        self.visit_node(loop.true)
    else:
        self.visit_node(loop.cond)
    self.loop_follow.pop()
    self.dec_ind()
    if loop.looptype.is_pretest:
        self.write('%s}\n' % self.space())
        self.write_ext(('END_PRETEST', '%s}\n' % self.space()))
    elif loop.looptype.is_posttest:
        self.latch_node.pop()
        self.write('%s} while(' % self.space())
        self.write_ext(('WHILE_POSTTEST', '%s} while(' % self.space()))
        loop.latch.visit_cond(self)
        self.write(');\n')
        self.write_ext(('POSTTEST_END', ');\n'))
    else:
        self.inc_ind()
        self.visit_node(loop.latch)
        self.dec_ind()
        self.write('%s}\n' % self.space())
        self.write_ext(('END_LOOP', '%s}\n' % self.space()))
    if follow is not None:
        self.visit_node(follow)

def visit_cond_node(self, cond):
    if cond is None :
        return
    follow = cond.follow['if']
    if cond.false is cond.true:
        self.write('%s// Both branches of the condition point to the same'
                   ' code.\n' % self.space())
        self.write_ext(
            ('COMMENT_ERROR_MSG',
             '%s// Both branches of the condition point to the same'
             ' code.\n' % self.space()))
        self.write('%s// if (' % self.space())
        self.write_ext(('COMMENT_IF', '%s// if (' % self.space()))
        cond.visit_cond(self)
        self.write(') {\n')
        self.write_ext(('COMMENT_COND_END', ') {\n'))
        self.inc_ind()
        self.visit_node(cond.true)
        self.dec_ind()
        self.write('%s// }\n' % self.space(), data="COMMENT_IF_COND_END")
        return
    if cond.false is self.loop_follow[-1]:
        cond.neg()
        cond.true, cond.false = cond.false, cond.true
    if self.loop_follow[-1] in (cond.true, cond.false):
        self.write('%sif (' % self.space(), data="IF_2")
        cond.visit_cond(self)
        self.write(') {\n', data="IF_TRUE_2")
        self.inc_ind()
        self.write('%sbreak;\n' % self.space(), data="BREAK")
        self.dec_ind()
        self.write('%s}\n' % self.space(), data="IF_END_2")
        self.visit_node(cond.false)
    elif follow is not None:
        if cond.true in (follow, self.next_case) or\
                                            cond.num > cond.true.num:
                         # or cond.true.num > cond.false.num:
            cond.neg()
            cond.true, cond.false = cond.false, cond.true
        self.if_follow.append(follow)
        if cond.true:  # in self.visited_nodes:
            self.write('%sif (' % self.space(), data="IF")
            cond.visit_cond(self)
            self.write(') {\n', data="IF_TRUE")
            self.inc_ind()
            self.visit_node(cond.true)
            self.dec_ind()
        is_else = not (follow in (cond.true, cond.false))
        if is_else and not cond.false in self.visited_nodes:
            self.write('%s} else {\n' % self.space(), data="IF_FALSE")
            self.inc_ind()
            self.visit_node(cond.false)
            self.dec_ind()
        self.if_follow.pop()
        self.write('%s}\n' % self.space(), data="IF_END")
        self.visit_node(follow)
    else:
        self.write('%sif (' % self.space(), data="IF_3")
        cond.visit_cond(self)
        self.write(') {\n', data="IF_COND_3")
        self.inc_ind()
        self.visit_node(cond.true)
        self.dec_ind()
        self.write('%s} else {\n' % self.space(), data="ELSE_3")
        self.inc_ind()
        self.visit_node(cond.false)
        self.dec_ind()
        self.write('%s}\n' % self.space(), data="IF_END_3")

def visit_short_circuit_condition(self, nnot, aand, cond1, cond2):
    if nnot:
        cond1.neg()
    self.write('(', data="TODO24")
    cond1.visit_cond(self)
    self.write(') %s (' % ['||', '&&'][aand], data="TODO25")
    cond2.visit_cond(self)
    self.write(')', data="TODO26")

def visit_switch_node(self, switch):
    if switch is None:
        return
    lins = switch.get_ins()
    if lins is not None :
       for ins in lins[:-1]:
            self.visit_ins(ins)
    switch_ins = switch.get_ins()[-1]
    if switch_ins is not None :
        self.visit_ins(switch_ins)
    self.write('%sswitch (' % self.space(), data="SWITCH")
    self.write(') {\n', data="SWITCH_END")
    follow = switch.follow['switch']
    if follow is not None :
        self.switch_follow.append(follow)
    cases = switch.cases
    default = switch.default
    if cases is not None :
        for i, node in enumerate(cases):
            if node in self.visited_nodes:
                continue
            self.inc_ind()
            for case in switch.node_to_case[node]:
                self.write(
                    '%scase %d:\n' % (self.space(), case), data="CASE_XX")
            if i + 1 < len(cases):
                self.next_case = cases[i + 1]
            else:
                self.next_case = None
            if node is default:
                self.write('%sdefault:\n' % self.space(), data="CASE_DEFAULT")
                default = None
            self.inc_ind()
            self.visit_node(node)
            if self.need_break:
                self.write('%sbreak;\n' % self.space(), data="CASE_BREAK")
            else:
                self.need_break = True
            self.dec_ind(2)
    if default not in (None, follow):
        self.inc_ind()
        self.write('%sdefault:\n' % self.space(), data="CASE_DEFAULT_2")
        self.inc_ind()
        self.visit_node(default)
        self.dec_ind(2)
    self.write('%s}\n' % self.space(), data="CASE_END")
    self.switch_follow.pop()
    if follow is not None :        
        self.visit_node(follow)

def visit_statement_node(self, stmt):
    if stmt is None :
        return
    sucs = self.graph.sucs(stmt)
    instruction = stmt.get_ins()
    if instruction is not None :
        for i in instruction:
            self.visit_ins(i)
    if len(sucs) == 1:
        if sucs[0] is self.loop_follow[-1]:
            self.write('%sbreak;\n' % self.space(), data="BREAK_2")
        elif sucs[0] is self.next_case:
            self.need_break = False
        else:
            self.visit_node(sucs[0])

def visit_try_node(self, try_node):
    if try_node is None :
        return
    self.write('%stry {\n' % self.space(), data="TRY_START")
    self.inc_ind()
    if try_follow is not None and try_node is not None :
        self.try_follow.append(try_node.follow)
    self.visit_node(try_node.try_start)
    self.dec_ind()
    self.write('%s}' % self.space(), data="TRY_START_END")
    if try_node.catch is not None :
        for catch in try_node.catch:
            self.visit_node(catch)
    self.write('\n', data="NEWLINE_END_TRY")
    self.visit_node(self.try_follow.pop())

def visit_catch_node(self, catch_node):
    if catch_node is None :
        return
    self.write(' catch (', data="CATCH")
    catch_node.visit_exception(self)
    self.write(') {\n', data="CATCH_START")
    self.inc_ind()
    self.visit_node(catch_node.catch_start)
    self.dec_ind()
    self.write('%s}' % self.space(), data="CATCH_END")

def visit_return_node(self, ret):
    if ret is None :
        return
    self.need_break = False
    instruction = ret.get_ins()
    if instruction is None :
        return
    for ins in instruction:
        self.visit_ins(ins)

def visit_throw_node(self, throw):
    if throw is None :
        return
    instruction = throw.get_ins()
    if instruction is None :
        return
    for ins in instruction:
        self.visit_ins(ins)

def visit_decl(self, var):
    if var is None :
        return
    if not var.declared:
        var_type = var.get_type() or 'unknownType'
        self.write('%s%s v%s' % (
            self.space(), get_type(var_type),
            var.name), data="DECLARATION")
        self.end_ins()

def visit_constant(self, cst):
    if cst is None :
        return
    if isinstance(cst, basestring):
        return self.write(string(cst), data="CONSTANT_STRING")
    self.write('%r' % cst, data="CONSTANT_INTEGER")  # INTEGER or also others?

def visit_base_class(self, cls, data=None):n
    self.write(cls)
    self.write_ext(('NAME_BASE_CLASS', cls, data))

def visit_variable(self, var):
    if var is None :
        return
    var_type = var.get_type() or 'unknownType'
    if not var.declared:
        self.write('%s ' % get_type(var_type))
        self.write_ext(
            ('VARIABLE_TYPE', '%s' % get_type(var_type), var_type))
        self.write_ext(('SPACE', ' '))
        var.declared = True
    self.write('v%s' % var.name)
    self.write_ext(('NAME_VARIABLE', 'v%s' % var.name, var, var_type))

def visit_param(self, param, data=None):
    self.write('p%s' % param)
    self.write_ext(('NAME_PARAM', 'p%s' % param, data))

def visit_this(self):
    self.write('this', data="THIS")

def visit_assign(self, lhs, rhs):
    if lhs is not None:
        return self.write_inplace_if_possible(lhs, rhs)
    self.write_ind()
    rhs.visit(self)
    if not self.skip:
        self.end_ins()

def visit_move_result(self, lhs, rhs):
    self.write_ind_visit_end(lhs, ' = ', rhs)

def visit_move(self, lhs, rhs):
    if lhs is not rhs:
        self.write_inplace_if_possible(lhs, rhs)

def visit_astore(self, array, index, rhs, data=None):
    self.write_ind()
    if array is not None :
        array.visit(self)
    self.write('[', data=("ASTORE_START", data))
    if index is not None :
        index.visit(self)
    self.write('] = ', data="ASTORE_END")
    if rhs is not None :
        rhs.visit(self)
    self.end_ins()

def visit_put_static(self, cls, name, rhs):
    self.write_ind()
    self.write('%s.%s = ' % (cls, name), data="STATIC_PUT")
    if rhs is not None :
        rhs.visit(self)
    self.end_ins()

def visit_put_instance(self, lhs, name, rhs, data=None):
    self.write_ind_visit_end_ext(
        lhs, '.', '%s' % name, ' = ', rhs,
        data=data, subsection='NAME_CLASS_ASSIGNMENT')

def visit_new(self, atype, data=None):
    self.write('new %s' % get_type(atype))
    self.write_ext(('NEW', 'new '))
    self.write_ext(
        ('NAME_CLASS_NEW', '%s' % get_type(atype), data.type, data))

def visit_invoke(self, name, base, ptype, rtype, args, invokeInstr=None):
    if isinstance(base, ThisParam):
        if name == '<init>' and self.constructor and len(args) == 0:
            self.skip = True
            return
    if base is not None :
        base.visit(self)
    if name != '<init>':
        if isinstance(base, BaseClass):
            call_name = "%s -> %s" % (base.cls, name)
        elif isinstance(base, InstanceExpression):
            call_name = "%s -> %s" % (base.ftype, name)
        elif hasattr(base, "base") and hasattr(base, "var_map"):
            base2base = base
            while True:
                base2base = base2base.var_map[base2base.base]
                if isinstance(base2base, NewInstance):
                    call_name = "%s -> %s" % (base2base.type, name)
                    break
                elif (hasattr(base2base, "base") and
                      hasattr(base2base, "var_map")):
                    continue
                else:
                    call_name = "UNKNOWN_TODO"
                    break
        elif isinstance(base, ThisParam):
            call_name = "this -> %s" % name
        elif isinstance(base, Variable):
            call_name = "%s -> %s" % (base.type, name)
        else:
            call_name = "UNKNOWN_TODO2"
        self.write('.%s' % name)
        self.write_ext(('INVOKE', '.'))
        self.write_ext(
            ('NAME_METHOD_INVOKE',
             '%s' % name, call_name, ptype, rtype, base, invokeInstr))
    self.write('(', data="PARAM_START")
    comma = False
    if args is not None :
        for arg in args:
            if comma:
                self.write(', ', data="PARAM_SEPARATOR")
            comma = True
            arg.visit(self)
    self.write(')', data="PARAM_END")

def visit_return_void(self):
    self.write_ind()
    self.write('return', data="RETURN")
    self.end_ins()

def visit_return(self, arg):
    self.write_ind()
    self.write('return ', data="RETURN")
    if arg is not None :
        arg.visit(self)
    self.end_ins()

def visit_nop(self):
    pass

def visit_switch(self, arg):
    if arg is not None :
        arg.visit(self)

def visit_check_cast(self, arg, atype):
    self.write('((%s) ' % atype, data="CHECKCAST")
    if arg is not None :
        arg.visit(self)
    self.write(')')

def visit_aload(self, array, index):
    if array is not None :
        array.visit(self)
    self.write('[', data="ALOAD_START")
    if index is not None :
        index.visit(self)
    self.write(']', data="ALOAD_END")

def visit_alength(self, array):
    if array is not None :
        array.visit(self)
    self.write('.length', data="ARRAY_LENGTH")

def visit_new_array(self, atype, size):
    self.write('new %s[' % get_type(atype[1:]), data="NEW_ARRAY")
    if size is not None :
        size.visit(self)
    self.write(']', data="NEW_ARRAY_END")

def visit_filled_new_array(self, atype, size, args):
    self.write('new %s {' % get_type(atype), data="NEW_ARRAY_FILLED")
    if args is not None :
        for idx, arg in enumerate(args):
            arg.visit(self)
            if idx + 1 < len(args):
                self.write(', ', data="COMMA")
    self.write('})', data="NEW_ARRAY_FILLED_END")

def visit_fill_array(self, array, value):
    self.write_ind() 
    if array is not None :
        array.visit(self)
    if value is None :
        return
    self.write(' = {', data="ARRAY_FILLED")
    data = value.get_data()
    tab = []
    elem_size = value.element_width
    if elem_size == 4:
        for i in range(0, value.size * 4, 4):
            tab.append('%s' % unpack('i', data[i:i + 4])[0])
    else:  # FIXME: other cases
        for i in range(value.size):
            tab.append('%s' % unpack('b', data[i])[0])
    self.write(', '.join(tab), data="COMMA")
    self.write('}', data="ARRAY_FILLED_END")
    self.end_ins()

def visit_move_exception(self, var, data=None):
    if var is None :
        return
    var.declared = True
    var_type = var.get_type() or 'unknownType'
    self.write('%s v%s' % (get_type(var_type), var.name))
    self.write_ext(
        ('EXCEPTION_TYPE', '%s' % get_type(var_type), data.type))
    self.write_ext(('SPACE', ' '))
    self.write_ext(
        ('NAME_CLASS_EXCEPTION', 'v%s' % var.value(), data.type, data))

def visit_monitor_enter(self, ref):
    self.write_ind()
    self.write('synchronized(', data="SYNCHRONIZED")
    if ref is None :
        ref.visit(self)
    self.write(') {\n', data="SYNCHRONIZED_END")
    self.inc_ind()

#COMMENT: ADDED ref.visit(self).it was missed
def visit_monitor_exit(self, ref):
    self.dec_ind()
    self.write_ind()
    if ref is not None :
        ref.visit(self)
    self.write('}\n', data="MONITOR_EXIT")

def visit_throw(self, ref):
    self.write_ind()
    self.write('throw ', data="THROW")
    if ref is not None :
        ref.visit(self)
    self.end_ins()

def visit_binary_expression(self, op, arg1, arg2):
    self.write('(', data="BINARY_EXPRESSION_START")
    if arg1 is not None:
        arg1.visit(self)
    self.write(' %s ' % op, data="TODO58")
    if arg2 is not None :
        arg2.visit(self)
    self.write(')', data="BINARY_EXPRESSION_END")

def visit_unary_expression(self, op, arg):
    self.write('(%s ' % op, data="UNARY_EXPRESSION_START")
    if arg is not None :
        arg.visit(self)
    self.write(')', data="UNARY_EXPRESSION_END")

def visit_cast(self, op, arg):
    self.write('(%s ' % op, data="CAST_START")
    if arg is not None :
        arg.visit(self)
    self.write(')', data="CAST_END")

def visit_cond_expression(self, op, arg1, arg2):
    if arg1 is not None :
        arg1.visit(self)
    self.write(' %s ' % op, data="COND_EXPRESSION")
    if arg2 is not None :
        arg2.visit(self)

def visit_condz_expression(self, op, arg):
    if arg is None :
        return
    if isinstance(arg, BinaryCompExpression):
        arg.op = op
        return arg.visit(self)
    atype = arg.get_type()
    if atype == 'Z':
        if op == Op.EQUAL:
            self.write('!', data="NEGATE")
        arg.visit(self)
    else:
        arg.visit(self)
        if atype in 'VBSCIJFD':
            self.write(' %s 0' % op, data="TODO64")
        else:
            self.write(' %s null' % op, data="TODO65")

def visit_get_instance(self, arg, name, data=None):
    if arg is not None :
        arg.visit(self)
    self.write('.%s' % name)
    self.write_ext(('GET_INSTANCE', '.'))
    self.write_ext(('NAME_CLASS_INSTANCE', '%s' % name, data))

def visit_get_static(self, cls, name):
    self.write('%s.%s' % (cls, name), data="GET_STATIC")


def string(s):
    if s is None :
        return
    ret = ['"']
    for c in s.decode('utf8'):
        if c >= ' ' and c < '\x7f':
            if c == "'" or c == '"' or c == '\':
                ret.append('\')
            ret.append(c)
            continue
        elif c <= '\x7f':
            if c in ('\r', '\n', '\t'):
                ret.append(c.encode('unicode-escape'))
                continue
        i = ord(c)
        ret.append('\u')
        ret.append('%x' % (i >> 12))
        ret.append('%x' % ((i >> 8) & 0x0f))
        ret.append('%x' % ((i >> 4) & 0x0f))
        ret.append('%x' % (i & 0x0f))
    ret.append('"')
    return ''.join(ret).encode('utf8')

andromercury.py is obsolete and broken

andromercury.py is using from merc.lib.common import Session , https://code.google.com/p/androguard/wiki/Installation suggests downloading it from http://labs.mwrinfosecurity.com/tools/2012/03/16/mercury/downloads/ , but this link redirects to https://www.mwrinfosecurity.com/products/drozer/community-edition/

Seems upstream renamed mercury to drozer and most likely did a lot other changes to it, so http://androguard.blogspot.fr/2012/03/androguard-mercury.html is obsolete too.

Killed message? Fresh installation

I have a fresh installation of androguard and I'm trying to test androsim/diff.py andthe only msg I get is "Killed".

Any idea what might be possibly wrong? I downloaded Santoku linux and it works there, so I don't know why I can't make it work on my machine. It's fresh Ubuntu 14.04. I also tried to use https://github.com/QKaiser/santoku-vm but I had to fix some dependencies to provision 80% of that instance, but even with that Androguard should work fine.

I'm at point where I can compile it correctly correctly, but still it doesn't work :(

HOME and other documentation wiki pages

i noticed that the wiki home page is not updated to point back to github.

can i volunteer to make that update? and after i am done i will submit a pull request. just to make sure nobody else is doing likewise.

thanks.

missing security checks in apk.py

In some optimzed apk xml[i] can be None. If not handled, this raises an exception.
The code to handle this case has been added:
def get_element(self, tag_name, attribute):
"""
Return element in xml files which match with the tag name and the specific attribute

        :param tag_name: specify the tag name
        :type tag_name: string
        :param attribute: specify the attribute
        :type attribute: string

        :rtype: string
    """
    for i in self.xml:
        if self.xml[i] is None :
            continue
        tag = self.xml[i].getElementsByTagName(tag_name)
        if tag is None :
            return None
        for item in tag:
            value = item.getAttributeNS(NS_ANDROID_URI, attribute)

            if len(value) > 0:
                return value
    return None

androxgmml.py: options '-e' and '-f' are broken

androxgmml.py works fine only if none of '-e' and '-f' options are used:

$ androxgmml.py -i /tmp/Torch.apk -o /tmp/androxgmml_Torch_t1.xgmml
$ androxgmml.py -i /tmp/Torch.apk -o /tmp/androxgmml_Torch_t2.xgmml -e
Traceback (most recent call last):
  File "/usr/lib/python-exec/python2.7/androxgmml.py", line 274, in <module>
    main(options, arguments)
  File "/usr/lib/python-exec/python2.7/androxgmml.py", line 262, in main
    export_apps_to_xgmml( options.input, options.output, options.functions, options.externals )
  File "/usr/lib/python-exec/python2.7/androxgmml.py", line 256, in export_apps_to_xgmml
    export_xgmml_efcg(vm, x, fd)
  File "/usr/lib/python-exec/python2.7/androxgmml.py", line 191, in export_xgmml_efcg
    if j.get_method().get_class_name() in classes and m.get_info() not in classes:
AttributeError: 'PathP' object has no attribute 'get_method'
$ androxgmml.py -i /tmp/Torch.apk -o /tmp/androxgmml_Torch_t3.xgmml -f
Traceback (most recent call last):
  File "/usr/lib/python-exec/python2.7/androxgmml.py", line 274, in <module>
    main(options, arguments)
  File "/usr/lib/python-exec/python2.7/androxgmml.py", line 262, in main
    export_apps_to_xgmml( options.input, options.output, options.functions, options.externals )
  File "/usr/lib/python-exec/python2.7/androxgmml.py", line 253, in export_apps_to_xgmml
    export_xgmml_fcg(vm, x, fd)
  File "/usr/lib/python-exec/python2.7/androxgmml.py", line 153, in export_xgmml_fcg
    if j.get_method().get_class_name() in classes and m.get_info() in classes:
AttributeError: 'PathP' object has no attribute 'get_method'

Bug: TypeError: argument of type 'NoneType' is not iterable in core/bytecodes/apk.py

Hey,

With some APK, I got this crash:

  File "build/bdist.linux-x86_64/egg/androguard/core/bytecodes/apk.py", line 205, in __init__
  File "build/bdist.linux-x86_64/egg/androguard/core/bytecodes/apk.py", line 295, in get_files_types
  File "build/bdist.linux-x86_64/egg/androguard/core/bytecodes/apk.py", line 308, in _patch_magic
TypeError: argument of type 'NoneType' is not iterable

When I call:

apk = APK(apkFile)

The bug occurs here at line 308 in the core/bytecodes/apk.py file:

 307     def _patch_magic(self, buffer, orig):
 308         if ("Zip" in orig) or ("DBase" in orig):

I tried to return None if "orig" is None and it seems to be working but I'm not sure about the side effect.

 307     def _patch_magic(self, buffer, orig):
 308         if orig is None:
 309             return orig
 310         if ("Zip" in orig) or ("DBase" in orig):

Cheers,

apkviewer.py: AttributeError: 'DalvikVMFormat' object has no attribute 'dotbuff'

$ apkviewer.py -i /tmp/Torch.apk -o /tmp/apkviewer_Torch_t1
...
<androguard.core.data.data.File object at 0x2b8cfcedd50>
net/cactii/flash2/FlashDevice
<androguard.core.analysis.analysis.DVMBasicBlock object at 0x2b8cfdb6d90> 1 None
Traceback (most recent call last):
  File "/usr/lib/python-exec/python2.7/apkviewer.py", line 97, in <module>
    main(options, arguments)
  File "/usr/lib/python-exec/python2.7/apkviewer.py", line 83, in main
    buff = dd.export_dex_to_gml()
  File "/usr/lib64/python2.7/site-packages/androguard/core/data/data.py", line 101, in export_dex_to_gml
    return self.dex_data.export_to_gml()
  File "/usr/lib64/python2.7/site-packages/androguard/core/data/data.py", line 242, in export_to_gml
    buff_nodes += self.add_node( i, id_i )
  File "/usr/lib64/python2.7/site-packages/androguard/core/data/data.py", line 166, in add_node
    c_label = "%x %s\n" % (idx, self.vm.dotbuff(ins, idx))
AttributeError: 'DalvikVMFormat' object has no attribute 'dotbuff'

killed

andro
why i am getting killed as output?

libmagic broken on mac

After installing libmagic with

brew install libmagic

androguard fails with the following traceback:

RROR: 'module' object has no attribute 'open'
Traceback (most recent call last):
  File "/Users/nils/uni/android_security/workspace/androlyze_stuff/androlyze/androlyze/analyze/AnalyzeUtil.py", line 64, in open_apk
    eandro_apk = EAndroApk(apk_or_path)
  File "/Users/nils/uni/android_security/workspace/androlyze_stuff/androlyze/androlyze/model/android/apk/EAndroApk.py", line 29, in __init__
    APK.__init__(self, *args, **kwargs)
  File "/Users/nils/uni/android_security/workspace/androlyze_stuff/androlyze/androguard/androguard/core/bytecodes/apk.py", line 222, in __init__
    self.get_files_types()
  File "/Users/nils/uni/android_security/workspace/androlyze_stuff/androlyze/androguard/androguard/core/bytecodes/apk.py", line 339, in get_files_types
    ms = magic.open(magic.MAGIC_NONE)
AttributeError: 'module' object has no attribute 'open'

Install error: andromercury.py does not exist

While running 'python setup.py install' I got this error

error: file '/usr/src/androguard/andromercury.py' does not exist

Taking a careful look, it seems like andromercury.py is still listed in setup.py but it was removed from the root directory. Not sure if it was meant to be removed or just an error in committing.

androaxml error "not well-formed (invalid token)"

Imported from: https://code.google.com/p/androguard/issues/detail?id=163

What steps will reproduce the problem?

  1. .\androaxml.py -i eu.chainfire.firepaper.fivehundredpx.xml -o out.xml

What is the expected output? What do you see instead?
expected: unpacked xml file.
but was: xml.parsers.expat.ExpatError: not well-formed (invalid token): line 5, column 0

What version of the product are you using? On what operating system?
Androaxml version 1.9 with python 2.7.7 on windows 7

Please provide any additional information below.
aapt tool from android-4.4W perfectly dumps xml tree.
aapt version: Android Asset Packaging Tool, v0.2
run: >aapt.exe dump xmltree eu.chainfire.fire
paper.fivehundredpx.apk AndroidManifest.xml

Packed AndroidManifest.xml and whole apk:
https://github.com/xkrt/misc/blob/master/issue_attaches/eu.chainfire.firepaper.fivehundredpx.xml
https://github.com/xkrt/misc/blob/master/issue_attaches/eu.chainfire.firepaper.fivehundredpx.apk

Update documentation

Currently the documentation on the old Google Code site is marked as deprecated. Are there any plans to import it into the github wiki, or update it?

How to find out in which method a string is used?

I would like to find out how to detect a method in an application where a particular string is used? E.g., it is common to specify content provider by a string. So I would like to know in which method the string is used.

AnalyzeAPK Fails with "AttributeError: 'dict' object has no attribute 'AOSP_PERMISSIONS'"

Trying to analyze an app as follows:

androlyze.py -s
Androlyze version 3.0

In [1]: a,d,dx = AnalyzeAPK("../com.whatsapp.apk")

AttributeError Traceback (most recent call last)
/Library/Python/2.7/site-packages/androguard-3.0-py2.7.egg/EGG-INFO/scripts/androlyze.py in ()
----> 1 a,d,dx = AnalyzeAPK("../com.whatsapp.apk")

/Library/Python/2.7/site-packages/androguard-3.0-py2.7.egg/androguard/misc.pyc in AnalyzeAPK(filename, raw, decompiler)
55 androconf.debug("APK ...")
56 a = APK(filename, raw)
---> 57 d, dx = AnalyzeDex(a.get_dex(), raw=True, decompiler=decompiler)
58 return a, d, dx
59

/Library/Python/2.7/site-packages/androguard-3.0-py2.7.egg/androguard/misc.pyc in AnalyzeDex(filename, raw, decompiler)
84
85 androconf.debug("GVMAnalysis ...")
---> 86 gx = GVMAnalysis(dx, None)
87
88 d.set_vmanalysis(dx)

/Library/Python/2.7/site-packages/androguard-3.0-py2.7.egg/androguard/core/analysis/ganalysis.pyc in init(self, vmx, apk)
3206 # j.get_class_name(), j.get_name(), j.get_descriptor())
3207
-> 3208 list_permissions = self.vmx.get_permissions([])
3209 for x in list_permissions:
3210 for j in list_permissions[x]:

/Library/Python/2.7/site-packages/androguard-3.0-py2.7.egg/androguard/core/analysis/analysis.pyc in get_permissions(self, permissions_needed)
1967 permissions = {}
1968
-> 1969 permissions.update( self.get_tainted_packages().get_permissions( permissions_needed ) )
1970 permissions.update( self.get_tainted_variables().get_permissions( permissions_needed ) )
1971

/Library/Python/2.7/site-packages/androguard-3.0-py2.7.egg/androguard/core/analysis/analysis.pyc in get_permissions(self, permissions_needed)
1174 pn = set(permissions_needed)
1175 if permissions_needed == []:
-> 1176 pn = set(self.AOSP_PERMISSIONS_MODULE.AOSP_PERMISSIONS.keys())
1177
1178 classes = self.__vm.get_classes_names()

AttributeError: 'dict' object has no attribute 'AOSP_PERMISSIONS'

In [2]:

Tried other APKs with same result. Thoughts?

Versioning

Hi,

I suggest that we create a clean release branch and start merging master there once it is stabilized. Over the couple of last days master was quite unstable, and that is the only branch people are checking out. Also, we need to bump up the version. WDYT?

What has replaced AndroguardS?

I was using this class for a lot of functionality in my own tool and I noticed after pulling today, that the androgen file is no longer available.

sublime text 2 plugin not working on os x yosemite

I copied the plugins/ag-st folder to ~/Library/Application Support/Sublime Text 2/Packages,
then I found the keymap is

{
      "keys": ["ctrl+f5"],
      "command": "ag"
}

but it's not working when I open an apk file in st2 and click ctrl+f5 :(

System: OS X Yosemite 10.10.2
Sublime Text 2 version 2.0.2, build 2221
androguard version: 2.0

I can use ag command from my shell, and androlyze.py is also working.

I found that in ST2, Tools -> Packages -> Androguard -> View Strings is gray.

Am I missing something? Or ST2 plugin is only available for Androguard 1.9??

(Incorrect) relative path in androguard/core/androconf.py

Hi,

The path to permission files is hardcoded, and when running scripts from the root directory looks for them from a wrong place. Basically this small patch fixes it for me, but isn't obviously a great fix. Just adding it here before I forget about it.

diff --git a/androguard/core/androconf.py b/androguard/core/androconf.py
index 842661d..43eb722 100644
--- a/androguard/core/androconf.py
+++ b/androguard/core/androconf.py
@@ -102,7 +102,7 @@ CONF = {
"LAZY_ANALYSIS": False,
"MAGIC_PATH_FILE": None,

  • "PATH_TO_API_SPECIFIC_RESOURCE_MODULES" : "../androguard/core/api_specific_resources",
  • "PATH_TO_API_SPECIFIC_RESOURCE_MODULES" : "androguard/core/api_specific_resources",
    "DEFAULT_API" : 19,
    }

ipython

Hey,
i am receiving an error message: module not found
from IPython.terminal.embed import InteractiveShellEmbed

I already checked out every solution on google nothing helps. I just can get androguard 1.5 running but not 2.0

Decoding resources is broken

I am trying to use androguard on Inbox by Google which is located at https://play.google.com/store/apps/details?id=com.google.android.apps.inbox&hl=en

At first for getting the resource objects I am using:

aobj = apks.get_android_resources()

where the variable apks is defined as apks = apk.APK('com.google.android.apps.inbox.apk')

Package name is defined as packagename = apks.get_package()

application name in hex as defined in manifest file which we get by

appnamehex = "0x" + apks.get_android_manifest_xml().getElementsByTagName("application")[0].getAttribute("android:label")[1:]

now to get the id, I am using

aobj.get_id(packagename, int(appnamehex, 0))[1]

Which produces the following warning

WARNING: list index out of range
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/site-packages/androguard/core/bytecodes/apk.py", line 1416, in get_resource_dimen
    return [ate.get_value(), "%s%s" % (complexToFloat(ate.key.get_data()), DIMENSION_UNITS[ate.key.get_data() & COMPLEX_UNIT_MASK])]
IndexError: list index out of range

And then I get a None type return, What does this warning means? This is working for all other kind of APK which I have tried out with.

I think there is a bug in the ate.get_value()

'VMAnalysis' object has no attribute '_VMAnalysis__vm'

If you create VMAnalysis object:

a = apk.APK( TEST )
vm = DalvikVMFormat(a.get_dex())
vmx = VMAnalysis(vm)

you will get the following error:

Traceback (most recent call last):
  File "/home/yury/PROJECTS/ANDROGUARD/androguard/demos/apk_format_3.py", line 21, in <module>
    vmx = VMAnalysis(vm)
  File "/home/yury/PROJECTS/ANDROGUARD/androguard/androguard/core/analysis/analysis.py", line 1886, in __init__
    for i in self.__vm.get_all_fields():
AttributeError: 'VMAnalysis' object has no attribute '_VMAnalysis__vm'

Status of networkx and pygments dependencies

Since commit d4770c4 CHANGELOG has - remove useless dependencies (networkx, pygments line, but these dependencies are still used and required.

apkviewer.py does not work if networkx is not installed:

$ apkviewer.py --help
Traceback (most recent call last):
  File "/usr/lib/python-exec/python2.7/apkviewer.py", line 25, in <module>
    from androguard.core.data import data
  File "/usr/lib64/python2.7/site-packages/androguard/core/data/data.py", line 18, in <module>
    from networkx import DiGraph
ImportError: No module named networkx
$ grep -e networkx -e DiGraph -c androguard/core/analysis/ganalysis.py androguard/core/data/data.py
androguard/core/analysis/ganalysis.py:85
androguard/core/data/data.py:2

androdd.py still tries to open pygments python module (checked via strace)

$ grep -i pygments -c androguard/decompiler/decompiler.py
15

Negative resource id in result

My source code is like:

from androguard.misc import *
a, d, dx = AnalyzeAPK(APKFile)
a.show()

But output of a.show() contains negative resource id:

    res/raw/bdgethtmltag.js Unknown -9ea23b
    res/raw/bdtiebarcss.js Unknown 33810998
    res/raw/bdtiebarjs.js Unknown -156d68f3

How can I convert these to correct res id?

Instruction 21h seems to have a wrong implementation

Hi,
I saw this flaw with the const/high16 opcode (and fixed it at least for DAD), but as i tried to fix it in DAD and also in the decompiler i found out that the instruction it self is not implemented correctly.
The instruction basically moves a 16bit value into the high part of a register, there are two versions: const/high16 and const-wide/high16, where the first one uses 32bit registers and the second 64bit.
In the current implementation only the 16bit value is returned in the opcode.BBBB variable.
A quick fix would be to just fix the value by shifting it 16 or 48 bytes in opcode.BBBB but then the name of BBBB should also be BBBB0000 and BBBB000000000000.

The fix is easy but i have no idea what else would break if you shift the value inside BBBB by the right value or if everything gets even worse if you rename it? discuss now ;)

"list index out of range" in dvm.py

I got a IndexError when trying to decompile a dex file.

The Traceback info is as follows:

WARNING: unknown string item @ 41242
Traceback (most recent call last):
  File "build/bdist.linux-x86_64/egg/androguard/core/bytecodes/dvm.py", line 7011, in get_string
    off = self.__manage_item[ "TYPE_STRING_ID_ITEM" ][idx].get_string_data_off()
IndexError: list index out of range

androguard and android-21

Looks like there is an issue with androguard and android-21. Specifically the get_android_resources() function seems to be having an issue parsing the resources.arsc file successfully. We discovered issue on some internal builds and I'm going to try to recreate a simple apk to demonstrate, but wanted to go ahead and create issue in case anyone has any ideas.

androsign.py Segmentation Fault

When i run a androsign.py i got an segmentation fault of elsim library. I did some tracing and found out that the problem is in "androguard/elsim/elsim/elsign/libelsign/elsign.cc"
in function: PyObject entropy(PyObject *self, PyObject args)
The problem was in uninitialized local variables (which is my opinion is very bad taste) here:

PyObject *entropy(PyObject *self, PyObject* args)
{
    char *input; size_t input_size;
    // FIX: char *input = NULL; size_t input_size = 0;

    int ok = PyArg_ParseTuple( args, "s#", &input, &input_size );
    if(!ok) return PyInt_FromLong(-1);

    double value = entropy( input, input_size );

    return PyFloat_FromDouble( value );
}

So, initializing them to NULL and 0 fixed the problem, seems like PyArg_ParseTuple doesn't allocate memory if it got a non NULL pointer. I don't know how to commit a changes so please fix it.

UTF-8 problem

Hi, I have a problem if UTF-8 encode.
I save the source code in a file, than in the screen show:


UnicodeEncodeError Traceback (most recent call last)
/.../androguard/androlyze.py in ()
3 if method.get_code() == None:
4 continue
----> 5 print(method.get_class_name(), method.get_name(), method.get_descriptor(), file=f)
6 ms = decompile.DvMethod(mx)
7 ms.process()

UnicodeEncodeError: 'ascii' codec can't encode character u'\u02cb' in position 1: ordinal not in range(128)

the apk is: https://play.google.com/store/apps/details?id=com.itau&hl=pt_BR

dvm.save() is broken

I tried running crackme_dexlabs_patch.py from the demos folder and I get the following error

File "crackme_dexlabs_patch.py", line 59, in
new_dex = vm.save()
File "/home/android/androguard/androguard/core/bytecodes/dvm.py", line 7445, in save
length = i.get_length()
File "/home/android/androguard/androguard/core/bytecodes/dvm.py", line 512, in get_length
return len(self.get_raw())
File "/home/android/androguard/androguard/core/bytecodes/dvm.py", line 509, in get_raw
return self.get_obj()
File "/home/android/androguard/androguard/core/bytecodes/dvm.py", line 505, in get_obj
pack("=I", self.data_size) +
struct.error: integer out of range for 'I' format code

Appreciate any help in this regard.

Thanks,
Palani.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.