JesusFreke / smali

smali/baksmali
6.32k stars 1.07k forks source link

[Feature] Executing baksmali on an Android device #496

Closed MassyB closed 7 years ago

MassyB commented 7 years ago

Hello, First of all, thank you for the tool you provide, it's really useful. :+1: I'm last year student and the subject of my thesis is 'Android malware detection : a solution on the device' one of the features that the anti-malware looks for is : the API calls. In the PC, I am using baksmali (v2.2) to disassemble the apk to smali files and than pars each smali file (excepte those under the android/* directory) to detect and store method calls.

But, on the device is there any mean to execute the baksmali.jar directly ? How can I do that ? there is a thread on XDA developer forum dealing with this feature https://forum.xda-developers.com/showthread.php?t=904548 But, I didn't understand the process for executing the baksmali jar directly on the device. Thank you.

JesusFreke commented 7 years ago

The process for running baksmali on a device is basically the same as http://stackoverflow.com/questions/10199863/how-to-execute-the-dex-file-in-android-with-command, except that you don't need to compile anything of course, and you just need to pass the baksmali jar to dx, instead of the class file.

You'll need to know the name of the main class in order to perform the last step. For baksmali, that is "org.jf.baksmali.main" for pre-2.2 versions, or "org.jf.baksmali.Main" for 2.2+ versions.

That being said, instead of running baksmali and trying to parse the smali files, I would recommend looking at linking against dexlib2 and reading the dex file directly. You can use it to load a dex file and iterate over all the classes/methods/instructions.

ale5000-git commented 7 years ago

@MassyB: If you search an example, in Tingle I use baksmali directly from a Python script and it work both on the PC and on Android.

MassyB commented 7 years ago

Thank you for your help @JessusFreke: I like the idea of using the dexlib2 library. I searched on stackoverflow :

MassyB commented 7 years ago

@ale5000-git: thank you for the python script. I have thinked about using python for extracting method calls of an APK. But, it's tricky to execute a python script from an android device targeting other APKs. I prefer the Java approach, because it's usable directly by the anti-malware which is also an APK (written in java). The anti-malware is an APK that is installed on a device. in order to classify an APK, the anti-malware must extract the API calls made by that APK. The representation must be in a smali format because most of the research work used smali to represent (suspicious API calls, mapping between API and permission). Behind the scene, the anti-malware is relying on an Machine Learning algorithme (Linear SVM) and the method calls are some of the features describing the data point ( the APK analyzed)

JesusFreke commented 7 years ago

@MassyB You can certainly extract any method calls using dexlib2. e.g. https://gist.github.com/JesusFreke/396458abb2145224e13773ee649f57c5

MassyB commented 7 years ago

When I'm trying to run the jar file for V 2.2b*, I'm getting this error

java.lang.NoClassDefFoundError: java.nio.file.Path
    at com.beust.jcommander.internal.DefaultConverterFactory.<clinit>(DefaultConverterFactory.java:66)
    at com.beust.jcommander.JCommander.<clinit>(JCommander.java:167)
    at org.jf.baksmali.Main.main(Main.java:78)
    at dalvik.system.NativeStart.main(Native Method)

but the V2.1.3 is working

JesusFreke commented 7 years ago

Oh, I think I'll need to take a look at that.

MassyB commented 7 years ago

I've created a helloworld app to test the code: this is the code for the Main Activity

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        PrintMethodInvocations printMethodInvocations = new PrintMethodInvocations();

        DexFile dexFile = null ;
        try{
            dexFile = DexFileFactory.loadDexFile("/data/app/com.example.bartman.helloworldapp-1.apk"
                    , Opcodes.getDefault());

        }catch (IOException ioe){
            ioe.printStackTrace();
        }
        if (dexFile != null){
            printMethodInvocations.printMethodInvocations(dexFile);
        }else
        {
            Log.d("dex_null", "onCreate: dex file is null");
        }

    }

I'm getting en exception on the Opcodes.getDefault(), precisely

FATAL EXCEPTION: main
                  Process: com.example.bartman.dexlib2_helloworld, PID: 7130
                  java.lang.NoClassDefFoundError: com.google.common.collect.Range
                      at org.jf.dexlib2.Opcode.allVersions(Opcode.java:408)
                      at org.jf.dexlib2.Opcode.<init>(Opcode.java:360)
                      at org.jf.dexlib2.Opcode.<clinit>(Opcode.java:44)
                      at java.lang.reflect.Method.invokeNative(Native Method)
                      at java.lang.reflect.Method.invoke(Method.java:515)
                      at java.lang.Enum$1.create(Enum.java:43)
                      at java.lang.Enum$1.create(Enum.java:35)
                      at libcore.util.BasicLruCache.get(BasicLruCache.java:54)
                      at java.lang.Enum.getSharedConstants(Enum.java:209)
                      at java.util.EnumMap.initialization(EnumMap.java:758)
                      at java.util.EnumMap.<init>(EnumMap.java:404)
                      at org.jf.dexlib2.Opcodes.<init>(Opcodes.java:90)
                      at org.jf.dexlib2.Opcodes.forApi(Opcodes.java:59)
                      at org.jf.dexlib2.Opcodes.getDefault(Opcodes.java:73)
                      at com.example.bartman.dexlib2_helloworld.MainActivity.onCreate(MainActivity.java:30)
                      at android.app.Activity.performCreate(Activity.java:5231)
                      at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
                      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2148)
                      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2233)
                      at android.app.ActivityThread.access$800(ActivityThread.java:135)
                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
                      at android.os.Handler.dispatchMessage(Handler.java:102)
                      at android.os.Looper.loop(Looper.java:136)
                      at android.app.ActivityThread.main(ActivityThread.java:5001)
                      at java.lang.reflect.Method.invokeNative(Native Method)
                      at java.lang.reflect.Method.invoke(Method.java:515)
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
                      at dalvik.system.NativeStart.main(Native Method)

thank you in advance and sorry for the not so eloquent previous comment

JesusFreke commented 7 years ago

That's... a less than helpful description of the problem.

ale5000-git commented 7 years ago

@MassyB: Why closing? Is it already fixed?

JesusFreke commented 7 years ago

Just FYI, I know what the problem is with the missing Nio class when trying to run baksmali directly on a device. I'll make sure that that is fixed in the next release.