enjarify 8.6 0.0 L5 Python Enjarify is a tool for translating Dalvik bytecode to equivalent Java bytecode. This allows Java analysis tools to analyze Android applications.

Overview

Note: This repository may be out of date. Future development will occur at https://github.com/Storyyeller/enjarify.

Introduction

Enjarify is a tool for translating Dalvik bytecode to equivalent Java bytecode. This allows Java analysis tools to analyze Android applications.

Usage and installation

Enjarify is a pure python 3 application, so you can just git clone and run it. To run it directly, assuming you are in the top directory of the repository, you can just do

python3 -O -m enjarify.main yourapp.apk

For normal use, you'll probably want to use the wrapper scripts and set it up on your path.

Linux

For convenience, a wrapper shell script is provided, enjarify.sh. This will try to use Pypy if available, since it is faster than CPython. If you want to be able to call Enjarify from anywhere, you can create a symlink from somewhere on your PATH, such as ~/bin. To do this, assuming you are inside the top level of the repository,

ln -s "$PWD/enjarify.sh" ~/bin/enjarify

Windows

A wrapper batch script, enjarify.bat, is provided. To be able to call it from anywhere, just add the root directory of the repository to your PATH. The batch script will always invoke python3 as interpreter. If you want to use pypy, just edit the script.

Usage

Assuming you set up the script on your path correctly, you can call it from anywhere by just typing enjarify, e.g.

enjarify yourapp.apk

The most basic form of usage is to just specify an apk file or dex file as input. If you specify a multidex apk, Enjarify will automatically translate all of the dex files and output the results in a single combined jar. If you specify a dex file, only that dex file will be translated. E.g. assuming you manually extracted the dex files you could do

enjarify classes2.dex

The default output file is [inputname]-enjarify.jar in the current directory. To specify the filename for the output explicitly, pass the -o or --output option.

enjarify yourapp.apk -o yourapp.jar

By default, Enjarify will refuse to overwrite the output file if it already exists. To overwrite the output, pass the -f or --force option.

Why not dex2jar?

Dex2jar is an older tool that also tries to translate Dalvik to Java bytecode. It works reasonable well most of the time, but a lot of obscure features or edge cases will cause it to fail or even silently produce incorrect results. By contrast, Enjarify is designed to work in as many cases as possible, even for code where Dex2jar would fail. Among other things, Enjarify correctly handles unicode class names, constants used as multiple types, implicit casts, exception handlers jumping into normal control flow, classes that reference too many constants, very long methods, exception handlers after a catchall handler, and static initial values of the wrong type.

Limitations

Enjarify does not currently translate optional metadata such as sourcefile attributes, line numbers, and annotations.

Enjarify tries hard to successfully translate as many classes as possible, but there are some potential cases where it is simply not possible due to limitations in Android, Java, or both. Luckily, this only happens in contrived circumstances, so it shouldn't be a problem in practice.

Performance tips

PyPy is much faster than CPython. To install PyPy, see http://pypy.org/. Make sure you get PyPy3 rather than regular PyPy. The Linux wrapper script will automatically use the command pypy3 if available. On Windows, you'll need to edit the wrapper script yourself.

By default, Enjarify runs optimizations on the bytecode which make it more readable for humans (copy propagation, unused value removal, etc.). If you don't need this, you can speed things up by disabling the optimizations with the --fast option. Note that in the very rare case where a class is too big to fit in a classfile without optimization, Enjarify will automatically retry it with all optimizations enabled, so this option does not affect the number of classes that are successfully translated.

Disclaimer

This is not an official Google product (experimental or otherwise), it is just code that happens to be owned by Google.

Comments
  • python3 test regression (test2)

    python3 test regression (test2)

    Hi, I'm a package maintainer and while building enjarify in a CI to early catch problems I have detected that the test2 is failing. Python version: 3.5.2 commit: 2a94b403259e9e432fbd9607926db50286de6bc5 log:

    ==> Starting check()...
    running test test1
    running test test2
    Traceback (most recent call last):
      File "/usr/lib/python3.5/runpy.py", line 184, in _run_module_as_main
        "__main__", mod_spec)
      File "/usr/lib/python3.5/runpy.py", line 85, in _run_code
        exec(code, run_globals)
      File "/build/enjarify-git/src/enjarify-git/enjarify/runtests.py", line 46, in <module>
        executeTest('test{}'.format(i), opts)
      File "/build/enjarify-git/src/enjarify-git/enjarify/runtests.py", line 40, in executeTest
        assert result == expected
    AssertionError
    ==> ERROR: A failure occurred in check().
        Aborting...
    ==> ERROR: Build failed
    
    opened by anthraxx 13
  • struct.error: 'H' format requires 0 <= number <= 65535

    struct.error: 'H' format requires 0 <= number <= 65535

    Traceback:

    com/rise/app/wallet/application/RisingApp.class Traceback (most recent call last):
      File "~/Programs/enjarify/enjarify/main.py", line 38, in translate
        class_data = writeclass.toClassFile(cls, opts)
      File "~/Programs/enjarify/enjarify/jvm/writeclass.py", line 116, in toClassFile
        pool, rest_stream = classFileAfterPool(cls, opts=opts)
      File "~/Programs/enjarify/enjarify/jvm/writeclass.py", line 100, in classFileAfterPool
        writeMethods(pool, stream, cls.data.methods, opts=opts)
      File "~/Programs/enjarify/enjarify/jvm/writeclass.py", line 65, in writeMethods
        code_attrs = writebytecode.finishCodeAttrs(pool, code_irs, opts=opts)
      File "~/Programs/enjarify/enjarify/jvm/writebytecode.py", line 75, in finishCodeAttrs
        return {irdata.method: writeCodeAttributeTail(pool, irdata, opts=opts) for irdata in code_irs}
      File "~/Programs/enjarify/enjarify/jvm/writebytecode.py", line 75, in <dictcomp>
        return {irdata.method: writeCodeAttributeTail(pool, irdata, opts=opts) for irdata in code_irs}
      File "~/Programs/enjarify/enjarify/jvm/writebytecode.py", line 80, in writeCodeAttributeTail
        bytecode, excepts = jumps.createBytecode(irdata)
      File "~/Programs/enjarify/enjarify/jvm/optimization/jumps.py", line 84, in createBytecode
        packed_excepts.append(struct.pack('>HHHH', s_off, e_off, h_off, c))
    struct.error: 'H' format requires 0 <= number <= 65535
    

    Looks like s_off, e_off and h_off can be greater than 65k when a DEX file is large enough.

    I tried the following fix and it worked:

        try:
            packed_excepts.append(struct.pack('>HHHH', s_off, e_off, h_off, c))
        except struct.error:
            packed_excepts.append(struct.pack('>IIIH', s_off, e_off, h_off, c))
    
    opened by balidani 8
  • No module named enjarify.main

    No module named enjarify.main

    It didn't works. Just show log:

    Using python3 as Python interperter ./enjarify/enjarify.sh: line 39: realpath: command not found /usr/local/bin/python3: No module named enjarify.main

    opened by quanghd 6
  • PyPy3 speed

    PyPy3 speed

    I got this results running latest enjarify with latest PyPy3 with Python 3.5 support (hashtests.py using range 10 ):

    pypy3 -m enjarify.hashtests  21,44s user 0,11s system 99% cpu 21,552 total
    
    python3.5 -m enjarify.hashtests  73,71s user 0,37s system 99% cpu 1:14,09 total
    

    So there's ~3.4x speed improvement

    opened by Yardanico 5
  • add ACC_SUPER flag to non-interface class so super.someMethod can be correctly handled

    add ACC_SUPER flag to non-interface class so super.someMethod can be correctly handled

    There are an notable problem which been fixed in dex2jar previously: Many converted class lost ACC_SUPER flag which cause super.someMethod() go to non-existent abstract method (throw error).

    When android's dx utility convert java class to dex, it discards ACC_SUPER flag of class, so enjarify should restore it when convert back to jar.

    The full modification of dex2jar is here https://github.com/pxb1988/dex2jar/blob/master/dex-translator/src/main/java/com/googlecode/d2j/dex/Dex2Asm.java#L91

    According to jvm's spec, interface should not have ACC_SUPER flag.

    opened by jjqq2013 5
  • git tag for packaging

    git tag for packaging

    Hey,

    any chance to get a git tag to make it easier to package this great tool? That would be amazing! :smile:

    If yes, then it would be gorgeous if you sometimes create a new tag :yum:

    cheers anthraxx

    opened by anthraxx 5
  • fail cases

    fail cases

    Hi,

    I used enjarify to covert some commercial apks into jar files. I found it work well on most cases. However, I still find some fail cases, especially when involving some expection sentences. And many fail cases also fails with the use of dex2jar.

    So I would like to know what the reason of it is. And what the main advantage of enjarify is. Does it use some unique methods or just consider some special cases?

    Thanks for your help! : )

    opened by Sophiexuer 5
  • PyPy3 Issue

    PyPy3 Issue

    For some reason when using pypy3-2.4.0-win32 and BCV I get this exception: Traceback (most recent call last): File "C:\Users\null.Bytecode-Viewer\enjarify_2\enjarify-master\enjarify\main.py", line 75, in main outfile = open(outname, mode=('wb' if args.force else 'xb')) ValueError: invalid mode: xb

    During handling of the above exception, another exception occurred:

    Traceback (most recent call last): File "H:\Programs\pypy3-2.4.0-win32\lib-python\3\runpy.py", line 161, in _run_module_as_main "main", fname, loader, pkg_name) File "H:\Programs\pypy3-2.4.0-win32\lib-python\3\runpy.py", line 74, in _run_code exec(code, run_globals) File "C:\Users\null.Bytecode-Viewer\enjarify_2\enjarify-master\enjarify\main.py", line 94, in main() File "C:\Users\null.Bytecode-Viewer\enjarify_2\enjarify-master\enjarify\main.py", line 76, in main except FileExistsError: NameError: global name 'FileExistsError' is not defined

    However with Python 3.4 it works fine, this is on Windows 7.

    Is there maybe something I messed up on with BCV? If that's the case sorry for opening a ticket here, I just wasn't sure because Python 3.4 works perfectly fine, whereas PyPy3 doesn't.

    opened by Konloch 5
  • s390x: array index out of range

    s390x: array index out of range

    When running enjarify on s390x it fails with the following error:

    Traceback (most recent call last):
      File "/usr/lib/python3.5/runpy.py", line 193, in _run_module_as_main
        "__main__", mod_spec)
      File "/usr/lib/python3.5/runpy.py", line 85, in _run_code
        exec(code, run_globals)
      File "/usr/lib/python3/dist-packages/enjarify/main.py", line 107, in <module>
        main()
      File "/usr/lib/python3/dist-packages/enjarify/main.py", line 97, in main
        translate(data, opts=opts, classes=classes, errors=errors)
      File "/usr/lib/python3/dist-packages/enjarify/main.py", line 27, in translate
        dex = parsedex.DexFile(data)
      File "/usr/lib/python3/dist-packages/enjarify/parsedex.py", line 258, in __init__
        self.classes.append(DexClass(self, defs.off, i))
      File "/usr/lib/python3/dist-packages/enjarify/parsedex.py", line 205, in __init__
        self.name = dex.clsType(words[0])
      File "/usr/lib/python3/dist-packages/enjarify/parsedex.py", line 274, in clsType
        desc = self.type(i)
      File "/usr/lib/python3/dist-packages/enjarify/parsedex.py", line 270, in type
        return self.string(self.u32s[self.type_ids.off//4 + i])
    IndexError: array index out of range
    

    The dex file used is available here: https://anonscm.debian.org/git/reproducible/diffoscope.git/tree/tests/data/test1.dex

    opened by reinerh 4
  • add debug.py for debugger to avoid relative import error in main.py

    add debug.py for debugger to avoid relative import error in main.py

    I think the following problem i'v met is very common for other users, no matter which python debugger used.

    For example, I am using PyCharm to debug enjarify, i set main.py as startup script, see following picture: pycharm debugger settings

    but main.py went error at:

    from . import parsedex
    

    Error message:

    /usr/local/Cellar/pypy3/2.4.0/libexec/bin/pypy "/Applications/PyCharm CE.app/Contents/helpers/pydev/pydevd.py" --multiproc --qt-support --client 127.0.0.1 --port 50129 --file /Users/q/Documents/enjarify/enjarify/main.py /tmp/a.apk -o /tmp/a.jar -f
    pydev debugger: process 2139 is connecting
    
    Connected to pydev debugger (build 143.1919)
    Traceback (most recent call last):
      File "/Applications/PyCharm CE.app/Contents/helpers/pydev/pydevd.py", line 2411, in <module>
        globals = debugger.run(setup['file'], None, None, is_module)
      File "/Applications/PyCharm CE.app/Contents/helpers/pydev/pydevd.py", line 1802, in run
        launch(file, globals, locals)  # execute the script
      File "/Applications/PyCharm CE.app/Contents/helpers/pydev/_pydev_imps/_pydev_execfile.py", line 18, in execfile
        exec(compile(contents+"\n", file, 'exec'), glob, loc)
      File "/Users/q/Documents/enjarify/enjarify/main.py", line 17, in <module>
        from . import parsedex
    ValueError: Attempted relative import in non-package
    
    Process finished with exit code 1
    

    The reason is i invoke main.py as file mode, not as package mode. To invoke main.py as package mode, i must specify following option to replace main.py in command line

    -m enjarify.main
    

    The easiest way to solve this problem is change main.py

    from enjarify import parsedex
    

    But I do not want to change source file,

    so i tried following debug config: pycharm debugger settings specify package mode

    but this way still does not works, just exit silently. The command line have both --module and --file option which seems can not be controlled by settings and maybe cause problem.

    /usr/local/Cellar/pypy3/2.4.0/libexec/bin/pypy "/Applications/PyCharm CE.app/Contents/helpers/pydev/pydevd.py" --multiproc --module --qt-support --client 127.0.0.1 --port 50274 --file enjarify.main /tmp/a.apk -o /tmp/a.jar -f
    pydev debugger: process 2205 is connecting
    
    Connected to pydev debugger (build 143.1919)
    
    Process finished with exit code 0
    

    The main.py:main is not executed because the __name__ is not "__main__" at this time.

    __name__is_not_main

    I have no way to make debugger works without modifying main.py.

    So, what about add a launcher script for debugger? no more modification later. debug.py

    import enjarify.main
    
    enjarify.main.main()
    
    debug py

    So debugger normally calls main.py:main for me.

    Any better idea is welcome.

    opened by jjqq2013 4
  • Use Python launcher instead of python3

    Use Python launcher instead of python3

    Currently enjarify.bat calls python3, but Python installer doesn't install python3.exe. According to PEP 397, the preferred way is to use Python launcher.

    opened by FranklinYu 3
  • struct.error: unpack str size too short for format

    struct.error: unpack str size too short for format

    I get the following error while using enjarify with pypy3:

    struct.error: unpack str size too short for format

    Using python3 fixes the issue. Also, the script will not use python because python -c "print(range)" returns "<built-in function range>", not "<class 'range'>".

    opened by jaredrummler 3
  • missing convenient python object cache generation/distribution (+ possible filesystem cluttering on uninstall)

    missing convenient python object cache generation/distribution (+ possible filesystem cluttering on uninstall)

    Hey :smile:

    I wanted to report a small problem and suggest a possible solution. The problem is that when the .py files are distributed into the filesystem from a package (f.e. under /usr/lib/enjarify or /usr/share/enjarify) by just copying them over, then no python caching files are created. One problem arises if anyone executes enjarify as root (yes that shouldn't be the case but why not) then python will create those cache object files for all python modules that are imported somewhere within your module. If anyone uninstalls your package afterwards, then the filesystem is left in a cluttered state as the generated object files are not tracked and remain. Additionally there may also be a small performance improvement if python cache object files are distributed.

    One possible solution would be to use python setuptools and create a setup.py that will distribute your python module files into f.e. /usr/lib/python3.5/site-packages/enjarify, which will also take care to create the cache entries if the -O1 parameter is passed when calling the setup.py. You could still have your enjarify.sh script that checks for all your favorite python interpreters.

    What do you think about this idea? If you need feedback or something like that, feel free... i try to help where i can :smile:

    opened by anthraxx 2
  • No module named 'enjarify'

    No module named 'enjarify'

    I used the python-3.5.0-embed-amd64.zip to excute,because no 'python3' command in it, so edited the second line in 'enjarify.bat' file------'python -O -m enjarify.main %*' and the result is below: ...\python-3.5.0-embed-amd64\python.exe: Error while finding spec for 'enjarify.main' (<class 'ImportError'>: No module named 'enjarify')

    20151027132317

    opened by liboLiao 5
  • Python 2.7 Support

    Python 2.7 Support

    Any ways to get a Python 2.7 friendly enjarify? I would love to integrate it with https://github.com/ajinabraham/Mobile-Security-Framework-MobSF as an alternative to Dex2Jar.

    opened by ajinabraham 1
  • Missing Java Annotations

    Missing Java Annotations

    I was dealing with an app using Retrofit (Java Annotations play an important role in that library). Enjarify seemed to work smoothly, but when I opened output .jar frustrating things came out. I can't find any Java Annotation that should have applied to methods. Unluckily I‘m not good at python so have no idea. Is enjarify planned to support Java Annotations?

    opened by silverdragon727 6
Releases(1.0.3)
Owner
Google
Google ❤️ Open Source
Google
A runtime mobile application analysis toolkit with a Web GUI, powered by Frida, written in Python.

___ ___ / | \ ____ __ __ ______ ____ / ~ \/ _ \| | \/ ___// __ \ \ Y ( <_> )

NCC Group Plc 1.2k Dec 21, 2022
A program analysis tool to find cryptographic misuse in Java and Android.

A program analysis tool to find cryptographic misuse in Java and Android.

null 92 Dec 15, 2022
Analyze any Android/Java based app or game

ClassyShark Introduction ClassyShark is a standalone binary inspection tool for Android developers. It can reliably browse any Android executable and

Google 7.2k Jan 3, 2023
Java bytecode obfuscator created by x4e.

Binscure Java bytecode obfuscator created by x4e. Usage First, create a config file, (example config here). When you have a config file, run binscure

null 35 Nov 22, 2022
A Program Analysis Toolkit for Android

PATDroid PATDroid is a collection of tools and data structures for analyzing Android applications and the system itself. We intend to build it as a co

Mingyuan Xia 103 Dec 10, 2022
Android Malware (Analysis | Scoring) System

An Obfuscation-Neglect Android Malware Scoring System Quark-Engine is also bundled with Kali Linux, BlackArch. A trust-worthy, practical tool that's r

Quark-Engine 999 Dec 20, 2022
Appshark is a static taint analysis platform to scan vulnerabilities in an Android app.

Document Index 1.overview 2.startup 3.how to write rules 4.how to find compliance problems use appshark 5.a path traversal game 6.argument 7.engine co

Bytedance Inc. 998 Jan 7, 2023
CLI tool for decompiling Android apps to Java. It does resources! It does Java! Its real easy!

Easy-as-pie Android Decompiler Why One stop shop I got pretty tired of decompiling Android apps with a bunch of steps that I had to remember all the t

Alex Davis 619 Dec 27, 2022
Find Security Bugs is the SpotBugs plugin for security audits of Java web applications

The SpotBugs plugin for security audits of Java web applications and Android applications. (Also work with Kotlin, Groovy and Scala projects)

OWASP Find Security Bugs 2k Jan 6, 2023
XDROID is android all in one hack tools

XDROID XDroid Android HackingTools Legal Disclamer: The author does not hold any responsibility for the bad use of this tool, remember this is only fo

Davlix 16 May 9, 2022
Android Applications Permission Scanner

An Android Application Scanner built using Java on Android Studio. It basically scans all the applications and lets you know if any application is using your camera or microphone. If it does then it tells you to use that application for some time so that it could track it and let you know if there is any privacy concern

Sameet Asadullah 3 Aug 18, 2022
BlackDex is an Android unpack tool, it supports Android 5.0~12 and need not rely to any environment. BlackDex can run on any Android mobile phones or emulators, you can unpack APK File in several seconds.

BlackDex is an Android unpack tool, it supports Android 5.0~12 and need not rely to any environment. BlackDex can run on any Android mobile phones or emulators, you can unpack APK File in several seconds.

null 4.3k Jan 2, 2023
A tool translate a apk file to stantard android project include so hook api and il2cpp c++ scaffolding when apk is a unity il2cpp game. Write code on a apk file elegantly.

FakerAndroid (FakerAndroid.jar or FakerAndroid-AS) A tool translate a apk file to stantard android project include so hook api and il2cpp c++ scaffold

null 231 Dec 29, 2022
A simple text encryption/decryption password based GUI+CLI tool

ZeText: Zero disk exposition texts This is a simple text encryption/decryption password based GUI+CLI tool, allowing to enter, edit and decrypt files

sergeych 0 Dec 21, 2021
Signal Protocol library for Java/Android

Overview A ratcheting forward secrecy protocol that works in synchronous and asynchronous messaging environments. PreKeys This protocol uses a concept

Signal 1.8k Dec 24, 2022
Grab’n Run, a simple and effective Java Library for Android projects to secure dynamic code loading.

Grab’n Run, a simple and effective Java Library for Android projects to secure dynamic code loading.

Luca Falsina 418 Dec 29, 2022
A Java ePub reader and parser framework for Android.

FolioReader-Android is an EPUB reader written in Java and Kotlin. Features Custom Fonts Custom Text Size Themes / Day mode / Night mode Text Highlight

FolioReader 2.1k Jan 3, 2023
CRYLOGGER: Detecting Crypto Misuses for Android and Java Apps Dynamically

CRYLOGGER: Detecting Crypto Misuses for Android and Java Apps Dynamically

Luca Piccolboni 139 Dec 12, 2022
Appdbg - make it possible to run android dex file in original Java Virtual Machine

Appdbg - make it possible to run android dex file in original Java Virtual Machine

null 137 Dec 20, 2022