Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
oleavr committed Sep 5, 2018
0 parents commit 2143b9a
Show file tree
Hide file tree
Showing 7 changed files with 226 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/bin/
/ext/
46 changes: 46 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
HOST_TRIPLET_PREFIX := arm-linux-androideabi-

CC := $(HOST_TRIPLET_PREFIX)clang
CFLAGS := -DANDROID -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 -mthumb -Os -Wall -fPIC -ffunction-sections -fdata-sections
LDFLAGS := -fuse-ld=gold -Wl,--fix-cortex-a8 -Wl,--icf=safe -Wl,--gc-sections -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now
STRIP := $(HOST_TRIPLET_PREFIX)strip --strip-all

frida_version := 12.1.2
frida_os_arch := android-arm
FRIDA_CORE_DEVKIT_URL := https://github.com/frida/frida/releases/download/$(frida_version)/frida-core-devkit-$(frida_version)-$(frida_os_arch).tar.xz
FRIDA_GUM_DEVKIT_URL := https://github.com/frida/frida/releases/download/$(frida_version)/frida-gum-devkit-$(frida_version)-$(frida_os_arch).tar.xz

all: bin/inject bin/agent.so bin/victim

deploy: bin/inject bin/agent.so bin/victim
adb shell "rm -rf /data/local/tmp/android-inject-example"
adb push bin/* /data/local/tmp/android-inject-example

bin/inject: inject.c ext/frida-core/.stamp
@mkdir -p $(@D)
$(CC) -Wl,-pie $(CFLAGS) -I./ext/frida-core inject.c -o $@ -L./ext/frida-core -lfrida-core $(LDFLAGS)
$(STRIP) $@

bin/agent.so: agent.c ext/frida-gum/.stamp
@mkdir -p $(@D)
$(CC) -shared $(CFLAGS) -I./ext/frida-gum agent.c -o $@ -L./ext/frida-gum -lfrida-gum -Wl,--version-script,agent.version $(LDFLAGS)
$(STRIP) $@

bin/victim: victim.c
@mkdir -p $(@D)
$(CC) -Wl,-pie $(CFLAGS) victim.c -o $@ $(LDFLAGS)
$(STRIP) $@

ext/frida-core/.stamp:
@mkdir -p $(@D)
@rm -f $(@D)/*
curl -Ls $(FRIDA_CORE_DEVKIT_URL) | xz -d | tar -C $(@D) -xf -
@touch $@

ext/frida-gum/.stamp:
@mkdir -p $(@D)
@rm -f $(@D)/*
curl -Ls $(FRIDA_GUM_DEVKIT_URL) | xz -d | tar -C $(@D) -xf -
@touch $@

.PHONY: all deploy
57 changes: 57 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# android-inject-custom

Example showing how to use Frida for standalone injection of a custom
payload. The payload is a .so that uses Gum, Frida's low-level instrumentation
library, to hook `open()` and print the arguments on `stderr` every time it's
called. The payload could be any shared library as long as it exports a function
with the name that you specify when calling `inject_library_file_sync()`.

In our example we named it `example_agent_main`. This function will also be
passed a string of data, which you can use for application-specific purposes.

Note that only the build system is Android-specific, so this example is
easily portable to all other OSes supported by Frida.

# Prerequisites

- Android NDK r17b
- Rooted Android device

# Preparing the build environment

```sh
$ $ANDROID_NDK_ROOT/build/tools/make_standalone_toolchain.py \
--arch arm \
--api 14 \
--stl=libc++ \
--install-dir=./ext/toolchain
$ export PATH=$(pwd)/ext/toolchain/bin:$PATH
```

# Running

```sh
$ make
```

This will build the injector, the payload, and an example program you
can inject the payload into to easily observe the results.

Next copy the `bin/` directory somewhere on your Android device, and in one
terminal adb shell into your device and launch the `victim` binary:

```sh
$ ./victim
Victim running with PID 1303
```

Then in another terminal change directory to where the `inject` binary
is and run it:

```sh
$ ./inject 1303
$
```

You should now see a message printed by the `victim` process every time
`open()` is called.
43 changes: 43 additions & 0 deletions agent.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#include <fcntl.h>
#include <frida-gum.h>

static int replacement_open (const char * path, int oflag, ...);

void
example_agent_main (const gchar * data, gboolean * stay_resident)
{
GumInterceptor * interceptor;

/* We don't want to our library to be unloaded after we return. */
*stay_resident = TRUE;

gum_init_embedded ();

g_printerr ("example_agent_main()\n");

interceptor = gum_interceptor_obtain ();

/* Transactions are optional but improve performance with multiple hooks. */
gum_interceptor_begin_transaction (interceptor);

gum_interceptor_replace_function (interceptor,
(gpointer) gum_module_find_export_by_name (NULL, "open"), replacement_open, NULL);
/*
* ^
* |
* This is using replace_function(), but there's also attach_listener() which
* can be used to hook functions without any knowledge of argument types,
* calling convention, etc. It can even be used to put a probe in the middle
* of a function.
*/

gum_interceptor_end_transaction (interceptor);
}

static int
replacement_open (const char * path, int oflag, ...)
{
g_printerr ("open(\"%s\", 0x%x)\n", path, oflag);

return open (path, oflag);
}
7 changes: 7 additions & 0 deletions agent.version
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
EXAMPLE_AGENT_1.0 {
global:
example_agent_main;

local:
*;
};
47 changes: 47 additions & 0 deletions inject.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#include <frida-core.h>
#include <stdio.h>
#include <stdlib.h>

int
main (int argc, char * argv[])
{
int result = 0;
FridaInjector * injector;
int pid;
GError * error;
guint id;

if (argc != 2)
goto bad_usage;

pid = atoi (argv[1]);
if (pid <= 0)
goto bad_usage;

frida_init ();

injector = frida_injector_new ();

error = NULL;
id = frida_injector_inject_library_file_sync (injector, pid, "./agent.so", "example_agent_main", "example data", &error);
if (error != NULL)
{
fprintf (stderr, "%s\n", error->message);
g_error_free (error);

result = 1;
}

frida_injector_close_sync (injector);
g_object_unref (injector);

frida_deinit ();

return result;

bad_usage:
{
fprintf (stderr, "Usage: %s <pid>\n", argv[0]);
return 1;
}
}
24 changes: 24 additions & 0 deletions victim.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>

int
main (int argc, char * argv[])
{
printf ("Victim running with PID %d\n", getpid ());

while (1)
{
int fd;

fd = open ("/etc/hosts", O_RDONLY);
if (fd != -1)
close (fd);

fd = open ("/etc/passwd", O_RDONLY);
if (fd != -1)
close (fd);

sleep (1);
}
}

0 comments on commit 2143b9a

Please sign in to comment.