Search for used and unused functions - android

Assumptions
I have an application with a very large number of screens.
I see the application for the first time so I don't know it
I have a method that connects to the Web Service and I don't know if it is actually used.
Is there any way to check (without running the application) whether the method is actually used in the application?

In Android Studio, you can easily find if a method is used or not.
Right click on the method > "Find usage"

Put a breakpoint on method and start debugging to know whether control
transfers to that method.
Put Log statements inside method to know whether they are executed.
Not recommended: Use Toast messages.

If I understand you, you're looking for "dead code", right ?
You can use Android Lint then: Analyze > Inspect Code...
In the results, Java part I think, you will find Declaration redundancy which will point you the dead code of the project (or the analyzed package)

Related

How does Xposed Framework hook methods in Android

I am going through Xposed framework in Android. Specifically reading blog - http://d3adend.org/blog/?p=589 for potential countermeasures and have couple of question on those line.
So when we hook a method using Xposed , framework makes that method as native and executes the code it wants to hook. So how is that in stacktrace original method is called?
com.example.hookdetection.DoStuff->getSecret //This one
de.robv.android.xposed.XposedBridge->invokeOriginalMethodNative
de.robv.android.xposed.XposedBridge->handleHookedMethod
com.example.hookdetection.DoStuff->getSecret //This one again
com.example.hookdetection.MainActivity->onCreate
android.app.Activity->performCreate
android.app.Instrumentation->callActivityOnCreate
android.app.ActivityThread->performLaunchActivity
android.app.ActivityThread->handleLaunchActivity
android.app.ActivityThread->access$800
android.app.ActivityThread$H->handleMessage
android.os.Handler->dispatchMessage
android.os.Looper->loop
android.app.ActivityThread->main
java.lang.reflect.Method->invokeNative
java.lang.reflect.Method->invoke
com.android.internal.os.ZygoteInit$MethodAndArgsCaller->run
com.android.internal.os.ZygoteInit->main
de.robv.android.xposed.XposedBridge->main
dalvik.system.NativeStart->main
Also why does it come twice in the stacktrace. I want to understand the order in which they are executed.
Is the actual method even run? Since the hooked method code executes it would not ideally execute the original method code. So how can we possible add a stracktrace detection mechanism in the same method knowing it would be replaced.
Xposed inner workings aren't easy to understand if you aren't comfortable with low level code and android kernel. To make it short, when you open an app on your Android device, there is a master process called Zygote that will spawn it as its child process.
The purpose of Xposed is to be able to control Zygote and detect whenever a process is about to be spawned, so that someone is able to hook methods by replacing their definitions before any calls are made to them.
You have a lot of control by using Xposed, you can replace the entire method body, so the original code never get called or you can use beforeCall and afterCall hooks which is basically an usage of the trampoline technique (A C++ example below)
As you can see when a method is called it doesn't directly go to the original code but to an injected code block where someone can do anything he wants (Dump, Change parameters, etc) then it will jump back to the genuine code. You can also do this after the genuine code, so you get the method output. Xposed implements this by using beforeHookedMethod and afterHookedMethod.
Adding a stacktrace detection mechanism won't help at all. You will call Java methods to get the actual stacktrace. It can be defeated easily by hooking the getStacktrace method, saving a valid genuine stacktrace, then when ever getStackTrace is called and contains Xposed methods, return the previously saved genuine stacktrace.
Your best bet is to rely on Native code to detect it, but even then any determined and experimented hacker with full device control can manage to defeat it eventually.
To add to above points when you call XposedHelpers.findAndHookMethod the callback can either be -
XC_MethodHook : Callback class for method hooks. Usually, anonymous subclasses of this class are created which override beforeHookedMethod(XC_MethodHook.MethodHookParam) and/or afterHookedMethod(XC_MethodHook.MethodHookParam).
XC_MethodReplacement : A special case of XC_MethodHook which completely replaces the original method.
1st one just provides you the hooks to execute methods before and after original method where as 2nd one replaces it completely. Eg - Xposed example on github
Couple of posts I have written -
Creating a new Xposed module in Android
Installing Xposed Framework on Android devices

Modifying Dalvik Virtual Machine to intercept methods of Application code

In my current implementation, I can only intercept the Method_Entry event of the some Class initialization methods, including:
*.<init> or *.<cinit>
* stands for any Class
All the methods written in Java applications are missing.
Currently, I have inserted "fprintf()" in the following places:
stack.cpp: dvmCallMethod()
stack.cpp: dvmCallMethodV()
stack.cpp: dvmCallMethodA()
stack.cpp: dvmInvokeMethod()
Interp.cpp: dvmInterpret()
Mterp.cpp: dvmMterpStd()
When these places of DVM are executed, I will print a message in my log file. However, only the Class initialization functions has triggered my println() code. In other words, it looks like that the execution of application methods does not go through the above places of DVM. I don't know which part of DVM is responsible for method execution of applications. Can anyone give me a clue?
The easiest way to figure out how things work is to look at how the method profiling works. Profiling adds an entry to a log file every time a method is called. The key file is dalvik/vm/Profile.h, which defines macros like TRACE_METHOD_ENTER. (In gingerbread, this was all you needed to look for. The situation changed quite a bit in ICS, when the interaction between debugging, profiling, and JIT compilation got reworked. And KitKat added the "sampling" profiler into the mix. So it's a bit more twisty now, and there are some other functions to be aware of, like dvmFastMethodTraceEnter().)
The entry points you've identified in your question are for reflection and calls in and out of native code. Calls between interpreted code are handled by updating the stack and program counter, and just continuing to loop through the interpreter. You can see this at line 3928 in the portable interpreter.
The non-obvious part is the FINISH() macro, defined on line 415. This calls into dvmCheckBefore(), line 1692 in Interp.cpp. This function checks the subMode field to see if there is anything interesting to do; you can find the various meanings in the definition, line 50 in InterpState.h. In short, flags are used for various profiling, debugging, and JIT compilation features.
You can see a subMode check on line 3916 in the portable interpreter, in the method invocation handling. It calls into dvmReportInvoke(), over in Interp.cpp, which invokes the TRACE_METHOD_ENTER macro.
If you're just trying to have something happen every time any method is invoked, you should probably just wire it into the profiling system, as that's already doing what you want. If you don't need the method profiling features, just replace them with your code.

I have been making an app for which I want to maintain a private call log for all my calls. Can someone please help me out with this

How do I access call log for android?
found this but this gives me an access to my existing call log. I want to make private call log in which some specified numbers will be handled.
A "private call log" is simply a list (or ListView activity).
You can use the same layouts and fonts as the "default" android app, but remember that each carrier and manufacturer re-brands the call logs on almost every phone.
So you just need to make your own. You can monitor call logs and remove them if you don't want them duplicated in both logs. See this post:
Delete call log in android for particular number

Do I really need to add the com.facebook.Settings.publishInstallAsync() method to all of my Activities?

I'm currently trying to make the mobile ads with facebook work for my android app.
I did all of the steps required, except the one where I need to add the method:
com.facebook.Settings.publishInstallAsync();
to all of my activities in the onResume() method.
My questions is - do I really have to put this method in ALL of my activities, and if yes - why?
I'm concerned that if I do so - my app will run slower.
Maybe if I put it in the first Launching activity only, it will still work?
Thanks :)
That method, as the name implies, runs on a different thread, so unless your app is very resource constrained, should not affect the performance. It will also handle tracking repeat calls to prevent multiple installs being reported, so once it reports on first install, it won't report again.

Global initialization in Android

I'm writing some library code distributed as a jar file that developers will need to initialize with an application id before using. Initialization is just a function call, like
MyLibrary.initialize("16ea53b");
The tricky thing is that I am not sure how to instruct developers to make this initialization call. At first I thought a single static initializer block in the main activity would be the easiest way to do it. The problem is a user could enter the application through some other activity or intent, and the main activity would not be loaded. Is there a general way to ensure that a line of code is run at the application's startup regardless of how the application was started?
The initialize call is idempotent so I could just tell people to make this initialization call in every place it could be used, but that would be bothersome.
One easy way is to save something in SharedPrefences when your library code is initialized. And then, wherever you deem important, you can check for this value, and continue if it exists or prompt for initialization or anything (error messages etc). This will also allow your developers to not have to initialize more than once.
Be sure to provide the developers an API to reset this value.
Also, here is a good talk on API design that may help you, by Joshua Bloch.
This sounds like a problem that can be resolved by extending creating a class that extends Application and placing it there, which is global for the entire Application.

Categories

Resources