Run Frida hooks on system_server without a client - android

I am using Frida and I want to hook a system_server method but without having the Frida client running on my computer. I want the entire thing to be on the device. I will have to gather the data while I am going about my day (possibly without any network connectivity either). I know about frida-gadget but frida-gadget looks under /data/app/<APP_NAME>/lib for its config file, and system_server has no such (writable) directory. Is there any workaround for this? I would of course also consider non-frida solutions.

Download frida-inject from https://github.com/frida/frida/releases , push & chmod on device
./frida-inject -p `pidof system_server` -s /data/local/tmp/script.js --runtime=v8
Other CLI options # https://github.com/frida/frida-core/blob/master/inject/inject.vala#L12
Edit:
For gadget you will need to repack ( & sign ) the apk with frida-gadget.so and somehow load the gadget to the memory.
The approach I use is to find the c'tor of the welcome-activity and insert the smali code that uses java.lang.System.loadLibrary to load the so.
The is how I find the activity
$ aapt dump badging $APK | grep "launchable-activity:" | grep -Po "(?<=name=').*?(?=')"
aapt is part of android sdk
You will need to increment local variables.. and handle if it's static c'tor ( or not ) but mostly this is the smali
const-string v0, "frida-gadget"
invoke-static {v0}, Ljava/lang/System;->loadLibrary(Ljava/lang/String;)V

Related

Android Init startup - Ueventd and watchdogd

I'm a beginner and I'm trying to understand the Kernel-Android interface.
In the system/core/init/init.c, the initial part has the following code.
if (!strcmp(basename(argv[0]), "ueventd"))
return ueventd_main(argc, argv);
if (!strcmp(basename(argv[0]), "watchdogd"))
return watchdogd_main(argc, argv);
This is followed by the parsing of the board specific init.rc files.
The ueventd_main parses the board specific uevent.rc files.
The watchdogd_main tries to set the timeout & then keeps writing an empty character to the /dev/watchdog in an infinite loop.
In the book 'Embedded Android' by Karim Yaghmour, it is mentioned as,
One of the first things init does is check whether it was invoked as
ueventd. init includes an implementation of the udev hotplug events
handler. Because this code is compiled within init’s own code, init
checks the command-line that was used to invoke it, and if it was
invoked through the /sbin/ueventd symbolic link to /init, then init
immediately runs as ueventd.
My questions are
1) I believe that the arguments to this main function are received from kernel bootcmd parameters "init=". Am I right?
2) Under what scenario one would invoke an init to be run only as ueventd or watchdogd?
3) What do they mean by symbolically linked to /init?
1) I believe that the arguments to this main function are received
from kernel bootcmd parameters "init=". Am I right?
No, not bootcmd arguments. argv[0] is the name of the executable being launched.
If you look at the Android.mk for init, you will see:
# Create symlinks.
LOCAL_POST_INSTALL_CMD := $(hide) mkdir -p $(TARGET_ROOT_OUT)/sbin; \
ln -sf ../init $(TARGET_ROOT_OUT)/sbin/ueventd; \
ln -sf ../init $(TARGET_ROOT_OUT)/sbin/watchdogd
Here you can see that two extra symbolic links are created, both pointing to init. These will be included in the final Android boot image in /sbin/
2) Under what scenario one would invoke an init to be run only as
ueventd or watchdogd?
In init.rc, you can see:
## Daemon processes to be run by init.
##
service ueventd /sbin/ueventd
class core
critical
seclabel u:r:ueventd:s0
shutdown critical
This is declaring the service ueventd and specifying a path to the ueventd path. So when the ueventd service is started, it will the the init executable but the argv[0] argument will be ueventd.
watchdogd is done the same way.
So it is the same executable called with three different names init, ueventd, or watchdogd. Depending on which name it is called with, one of three different code paths are executed (as in the code you referenced).
This is often done when different commands are substantially the same in implementation. On my Ubuntu system:
$ ls -l /usr/bin/unxz
lrwxrwxrwx 1 root root 2 Oct 3 11:04 /usr/bin/unxz -> xz
You can see that unxz is linked to xz
From the man page for xz: unxz is equivalent to xz --decompress.
So here, there was only one executable, but depending on which executable name is used to launch it, the behavior is different.
3) What do they mean by symbolically linked to /init?
Answered in previous two answers.

How to run malloDroid script?

I want to check SSL verification in my application. I downloaded on my santoku malloDroid.py and try use it (of course earlier I have read that script is an extansion of Androguard). I simply run mallo app: ./malloroid.py -f test.apk and i got import error that there is no androguard module. How to run malloDroid script to verify ssl?
In order to use MalloDroid, you need to have AndroGuard. Setting up Androguard is quite straight forward. Read more about installation here .
Once you have Androguard set up along with the proper environment variables, you can use Mallodroid as follows :
./mallodroid.py -f test.apk -x
This will most likely work!

Libgit2 running on Android unable to perform clone operation - returns "failed to set permissions" error

I have just built Libgit2 (v0.20.0) for Android (target SDK version 18, debugging on a rooted device running Cyanogenmod 10.1.2, Android 4.2.2) and a simple function like getting the version number of Libgit2 works fine through the JNI. But when I use the git_clone function it stops right after the objects/info folder is created and returns this error:
Error -1 cloning repository - Failed to set permissions on '/storage/sdcard0/it/ptt/.git/objects/info': Operation not permitted
I have given the application the WRITE_EXTERNAL_STORAGE permission but I guess it still can't chmod unless owner of the file. When I use adb shell to check out the permission mode of the info folder I get:
d---rwxr-x system sdcard_rw 2014-05-15 09:31 info
And by using pwd.h functions I get the username that the c code (that is calling git_clone) is under to be u0_a92. How am I suppose to get pass this I suppose very Android related issue? Is there a simple way to stop Libgit2 from calling p_chmod or can I give it permissions to do so?
I ended up defining p_chmod as a method always returning true to get passed the error. In the bash script I use to build libgit2 I inserted the following lines that leaves the source files in an unmodified condition after building for android:
LIBGIT2_POSIX_PATH="$LIBGIT2_SOURCE_PATH/src/posix.h"
LIBGIT2_POSIX_BACKUP_PATH="$LIBGIT2_SOURCE_PATH/src/posix_original.h"
printf "#include \"always_success.h\"\nint always_success() { return 0; }" > "$LIBGIT2_SOURCE_PATH/src/always_success.c"
printf "int always_success();" > "$LIBGIT2_SOURCE_PATH/src/always_success.h"
cp $LIBGIT2_POSIX_PATH "$LIBGIT2_POSIX_BACKUP_PATH"
sed -i "s/^#define\sp_chmod(p, m).*$/#include \"always_success.h\"\n#define p_chmod(p, m) always_success()\nextern int always_success();\n/" $LIBGIT2_POSIX_PATH
# run the build process with cmake ...
# restore chmod manipulated source header
mv $LIBGIT2_POSIX_BACKUP_PATH $LIBGIT2_POSIX_PATH
There is probably a cleaner way to solve this but at least now I dont get that error anymore. Thanks to Carlos for his help!
UPDATE
Running adb shell mount | grep sdcard I could see that the sdcard which I am trying to clone the repository into uses the vfat file system which according to this forum thread doesn't support unix-style permissions.

Android Ethernet and Wi-Fi at the same time

I have a small TV box device running Android. Whenever I bring up the Wi-Fi interface, the Ethernet interface is disconnected. If I then bring up the Ethernet device, the Wi-Fi interface.
I have tried various methods including using the command line to manually bring up the interfaces and the same issue occurs.
I want to be able to connect to the Wi-Fi and have it as my default gateway but then also be connected to the Ethernet port to route certain traffic over that interface.
Obviously this is possible to do in Linux so there must be a way... does anybody know what it is that is tearing down the interfaces when the other is initiated...
This is a restriction in Android. It purposely only allows one connection to be up at a time and has a handler in the 'ConnectivityServices.java' file that tears down a 'non-preferred' network when a network with a priority is enabled. This is also what brings wifi up and tears down cellular data connections when in range of a recognised hotspot...
Just in case anybody ever needs this, here is what I did :
Download the AOSP source code for the version of Android on the device.
Edit the 'ConnectivityServices.java' file accordingly. I basically just commented out the command in the failover command in the connection change handler. I don't have the source code in front of me so message me if you need to know what I did here...
Anyway, then build the AOSP source code on your machine.
Once completed, grab the 'services.jar' file in the /dexclasses/ directory that has been created.
Extract it using WinRAR then copy the 'classes.dex' file out of the .jar file to a separate directory.
Use this to extract the classes.dex : https://code.google.com/p/smali/
Grab the 'ConnectivityServices.smali' file and keep it safe.
From the device
Go onto the device you wish to enable both network interfaces on and copy the /system/framework/services.jar file to a PC. Extract it using WinRAR then copy the 'classes.dex' file out of the .jar file to a separate directory.
Use the Java Smali command to extract the classes.dex.
Take the ConnectivityServices.smali file from the AOSP and put it in the directly you have just extracted using the classes.dex on the device. Might be a good idea to make a backup of the original ConnectivityServices.smali file before overwriting it.
Then simple repackage the classes.dex file using the baksmali command.
Copy the classes.dex file into the original services.jar file using winRAR. Again, take a backup of the original but then overwrite it in the .jar file.
Then simply put the new services.jar file back on the device in the /system/framework/ directory.
Then reboot - it will take longer than normal to boot up on the first time.
There is a simpler way, which doesn't require you to build AOSP matching your device. You can simply modify smali-decompiled code and recompile it. Use https://github.com/android/platform_frameworks_base/blob/master/services/java/com/android/server/ConnectivityService.java for comparizon.
Something along this lines:
adb pull /system/framework/services.jar
cp services.jar services.jar.bak
unzip services.jar classes.dex
java -jar baksmali.jar classes.dex
Edit out/com/android/server/ConnectivityService.smali in handleConnect(), so that this will be the result:
// if this is a default net and other default is running
// kill the one not preferred
if (false && mNetConfigs[newNetType].isDefault()) {
if (mActiveDefaultNetwork != -1 && mActiveDefaultNetwork != newNetType) { ...
I made the following change:
aget-object v5, v5, v1
invoke-virtual {v5}, Landroid/net/NetworkConfig;->isDefault()Z
move-result v5
#if-eqz v5, :cond_a6 # changed to unconditional jump
goto :cond_a6
Recompile, repack, push. Then reboot and test.
java -jar smali.jar -o classes.dex out
zip services.jar classes.dex
adb push services.jar /system/framework/services.jar
So I also found out how to do it on CM12.1
Just change this line over here
https://github.com/CyanogenMod/android_frameworks_base/blob/e49d5ea0858a765c22d8aa96cc660d4708a413fb/services/core/java/com/android/server/ConnectivityService.java#L4264
or in smali replace the line before .line 4266
with goto :cond_1b1

Android apitrace failed to run

I would like to use the apitrace project on android. I followed the instructions from the readme file.
But get no trace where created.
I run this command
adb shell TRACE_FILE=/data/test.trace LD_PRELOAD=/data/egltrace.so am start -n APP_NAME
How can I make it work?
I tried following the instructions in Dalvik.markdown of the original distribution of apitrace, but without success.
The instructions say to set two properties: wrap._process_name_ and debug.apitrace.procname. The former has to be set, according to those instructions, to LD_PRELOAD=/data/egltrace.so. When launching the application I still wouldn't get any trace generated nor any apitrace-related message in the logcat.
I had more success by putting the LD_PRELOAD instruction in a script and using that as the wrapper. This is the script that I use, called /data/apitrace.sh:
LD_PRELOAD=/data/egltrace.so exec $#
You can also set the TRACE_FILE environment variable to specify the path to which the trace file should be written to. Otherwise it will be _/data/app_process.trace_. For example:
TRACE_FILE=/data/apitraces/mytrace.trace LD_PRELOAD=/data/egltrace.so exec $#
I believe apitrace takes care of adding numbers to the filename to prevent overwriting existing ones. So you'll have mytrace.trace, mytrace.1.trace, and so on.
So with this script in place I set the properties like so:
adb shell setprop wrap._process_name_ /data/apitrace.sh
adb shell setprop debug.apitrace.procname _process_name_
And then I launch the application. I see in the logcat something like the following:
I/dalvikvm( 5980): Exec: /system/bin/sh -c /data/apitrace.sh /system/bin/app_process /system/bin --application '--nice-name=_process_name_' com.android.internal.os.WrapperInit 25 17 'android.app.ActivityThread'
D/apitrace( 5991): apitrace: loaded
D/apitrace( 5991): apitrace[5991]: enabled for _process_name_
D/apitrace( 5991): apitrace: tracing to /data/app_process.trace
I'm using CyanogenMod 10.1.3, which is based on Android 4.2.2.

Categories

Resources