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.
Related
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)
I am trying to debug a Nativescript app for Android and I have noticed that it no longer prints Syntax errors with their corresponding line and col. numbers, not even console.log statements. How can I enable this feature again? The command I use to launch the app is tns run android. I am using Nativescript version 2.5.2. The VSCode plugin doesn't work either as it ignores any breakpoint I place, and also the console doesn't show any errors. What can I do?
Edit:
It appears that only console.error() statements get printed.
After tinkering a lot with different kinds of constructions and by researching more into how Nativescript relates to regular browser JS, I found out that the problem lies in the use of Promises, which in case of errors defer the execution to the catch() method, but unlike any other regular programming language, "unhandled" rejected results within promises won't raise any kind of exception; which means that, basically, for any promise you invoke in your code, you should have a chained catch() method call so you effectively catch any errors your promises might produce. This also applies to promises which involve navigation, where stuff gets a lot trickier: You might think the next view (say, view.js) will have a call stack on its own and produce an unhandled exception at code that's not even inside a promise in there, but that's not the case: An exception produced at view.js will get captured by the catch() method of the promise within which you started the navigation, and any subsequent promises must have their own catch() method calls because errors won't get bubbled up to the previous view. I can think of many other troublesome constructions but I hope the important bit stays clear: always chain a catch call on any and all promises.
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
I'm working on a collage project about security in Android. One part of the project attempts to capture and log all API function called by the selected APK. This can't be done with a external programs so in the project we are working with the Android source code to modify the ROM.
At the present time we only have two possible solutions:
DVM JNI Bridge
The API is Java code so, obviously, the Dalvik Virtual Machine needs a bridge to execute JNI code. The function which handle all cases is dvmCallJNIMethod(const u4* args, JValue* pResult, const Method* method, Thread* self). In this function we can get the name and the class of the called function.
This function can log all the JNI code executed, which includes API calls. But there is no easy way to distinct between private calls and API calls. And, if we wanted to execute some code depending on the risk of the API call executed, we would have to create a huge and inefficient switch.
API Framework
another solution To log all API calls is creating a new interface for the framework. With a new logging class and a simple inheritance should be easy to log all calls and add a risk parameter. But it would mean changing a lot of code. Also, Java code has worst performance than C, so it might not be the most efficient way.
More over, we would like to ask you a few questions about Android DVM and the API.
1.Which is exactly the call flow between DVM and the API?
2.Could be the DVM monitor a good idea to log the calls?
3.Which role have the shared libraries in all of this?
4.Are all API calls really Java code?
Thanks for your time.
I am new to RenderScript and still have not so good idea on blocking/non-blocking nature of the calls from Java layer. The general question is: which situations block the code and allow RenderScript to finish. Particularly:
From Java I invoked a kernel using forEach_kernel() and that was not blocking - I had to add an extra Allocation.copyTo() so that I could use the result. Was there another way?
I read somewhere that if there are 2 kernels then calling second will block until the first one will finish. What conditions result in this - maybe only when working on the same allocation?
Will the invokable functions block a) each other, b) kernel? Particularly, I have a custom initializer invokable function which I need to prepare some data which will be later used by the kernel. This preparation might take some time so I would like to know if it is dangerous to call in Java script.invoke_somefunc() and then immediately call script.forEach_kernel()?
1) You could use rs.finish() to make sure you wait for the kernel to finish. Kernel execution is indeed asynchronous in RS.
2) We only allow one kernel to execute at a time (ignoring ScriptGroup, where you have a DAG of kernels, and thus maybe some additional room for optimizations). In this case, your second kernel won't start running until the first kernel completes.
3) Invokable functions (i.e. things you run with invoke_*() from Java) are not asynchronous. You will block until they complete on the Java side. Thus, they will block each other, or kernels. If you have a kernel followed by an invoke, you will asynchronously start the kernel, but the invoke won't begin until the kernel finishes. You will then be waiting for the invoke to finish as well.
One more detail. If your initializer doesn't require parameters, you can put it in an actual "void init(void)" function. Those get run once when the ScriptC is created.
My experiments showed that even though the functions are invoked asynchronously on Java level, they are executed one after another in RenderScript. So basically having:
script.invoke_somefunc();
script.forEach_kernel();
alloc.copyTo(); // or rs.finish();
will return immediately from first 2 lines but on RenderScript level kernel will not start until somefunc is finished. This was not so obvious from the documentation. The third line will block until everything is finished.