I have separately decompiled apk to smali/dalvik and to java classes. As apk is not obfuscated java code is pretty good to read and I can pretty easily see corresponding smali code. So far I was able to do successfully:

  • modify code for checking license file (change comparison for year)
  • add logging to some basic data. Logger function was already in apk to I just call it and everything works fine. I use adb to read logs.

What I was trying to add next was to add logging for byte array. Why? Because this apk connects to Bluetooth device from which it receives the data. I wanted to know what data it receives. As I didn't know how to do that this is what I did:

I've made simple Android app with static function which gets byte array and returns string (copied some snipped). It was using BigInteger. Then I compiled it and decompiled using apktool.

    .method public static ByteArrayToString([B)Ljava/lang/String;
    .locals 2
    .param p0, "data"    # [B

    .line 16
    new-instance v0, Ljava/math/BigInteger;

    const/4 v1, 0x1

    invoke-direct {v0, v1, p0}, Ljava/math/BigInteger;-><init>(I[B)V

    const/16 v1, 0x10

    invoke-virtual {v0, v1}, Ljava/math/BigInteger;->toString(I)Ljava/lang/String;

    move-result-object v0

    .line 17
    .local v0, "hexaString":Ljava/lang/String;
    return-object v0
    .end method

I copied that whole function to my decompiled apk (the same class from which I wanted to call it/log data) and called that function.

    invoke-static {v0}, Lxx/xxxx/xxxxx/xx/xxxx/xxxxxx;->ByteArrayToString([B)Ljava/lang/String;
    const-string v5, ":: MY RAW DATA: "
    invoke-static {v5}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
    move-result-object v4
    invoke-static {v4}, Lorg/apache/log4j/helpers/LogLog;->debug(Ljava/lang/String;)V

Unfortunately it didn't work. Application compiled succesfully, it installed and lunched without a crash. However it didn't connect to my bluetooth device (bluetooth communication is essential).

So here are some questions (edited):

  • Is my approach correct?
  • What may be the reason for application not to work with bluetooth anymore?
  • Where should I put additional logic? Is the same class OK?
  • What about importing? For example in my new logic I had to import java.math.BigInteger; Will my function has this import somehow embedded in its logic?
  • Is there any better approach than mine?


I've solved my initial problem, now I'm trying to figure out the rest. Answers are:

  • Yes, my approach is correct and it works. I just used wrong log function (as it was mentioned in comment below).

  • Probably using this function (instead of adding new method) is sufficient:

invoke-static {v0}, Ljava/util/Arrays;->toString([B)Ljava/lang/String;
  • Strangely my problems with discovering Bluetooth devices has been solved by enabling GPS. Not 100% sure, but looks that way. I also saw this in logs:
BluetoothUtils: packagename is xx.xxxxx.xxxx ,and its permission is false

1 Answer 1


I think your approach is generally correct. You probably can't connect to the Bluetooth because your additional code throws an exception somewhere. The best idea would be to check it during dynamic analysis. You can do it using for example Android Studio and smalidea plugin.

As far as I see you don't store the result of your ByteArrayToString function call. You also pass only one parameter to the android.util.Log.d function (in your case v5) but it actually requires two parameters.

You can hook and intercept functions in android applications using for example dynamic instrumentation. Good tool for this purpose is named frida. Thanks to this tool you can hook various functions and change the behavior during runtime (for example add logging feature) without repacking the application. You don't need to mess with smali code, instead you can just use their easy JavaScript API.

If you are interested in the Bluetooth data logging there is even better way. You can use bulit-in Android function called Bluetooth HCI snoop log. You can enable it in developer options on your phone. After you enable the option all the bluetooth communication made between those devices will be recorded and saved onto internal storage. You can later copy the btsnoop_hci.log and possibly all files with the .cfa extension to further examination. Those files can be loaded into for example popular program named WireShark and inspected similar to PCAP files.

  • Thanks you for your input. I mixed up two functions, one accepts 1 parameter and the other one 2. Also - strangely my problem with bluetooth fixed itself when I enabled GPS. However I'm not 100% sure if that's the case. In logs I there's this: "BluetoothUtils: packagename is xx.xxxxx.xxxx ,and its permission is false". I found also my old code (I've been trying to solve this problem of mine few years back) and I used "invoke-static {v0}, Ljava/util/Arrays;->toString([B)Ljava/lang/String;" and it should work also.
    – matt
    May 22, 2020 at 21:10
  • Well, the new log looks strange, but according to the GPS, since some time Android may require the "Get location" permission if the app uses Bluetooth. Maybe you denied the permission in the repacked app, so the bluetooth didn't work, and now after turning GPS on the app displayed some sort of monit and obtained necessary permissions. It is just theory. Also if you need the logging feature only to capture bluetooth patckets, I highly recommend to use the Bluetooth HCI snoop log without modifying smali code. Wireshark and static analyse of the .apk may be enough to understand the logic.
    – morsisko
    May 22, 2020 at 21:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.