Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

debug/wrappers: Link wrapper code directly to apkenv

Instead of compiling the wrappers as separate units, built them
into the main binary and use the functions directly as data (with
the data fields found by the first occurence of 0xFFFFFFFF, which
is not a valid ARM instruction).
  • Loading branch information...
commit 6fc5bde4a67ec935ff99b22466a07b3b091fd6bd 1 parent 4f050c0
Thomas Perl authored
55 debug/wrappers.c
View
@@ -30,6 +30,7 @@
#include "wrappers.h"
#include "../compat/hooks.h"
#include "../apkenv.h"
+#include "wrappers/wrapper_code.h"
#include <stdio.h>
#include <stdlib.h>
@@ -115,14 +116,27 @@ const char *msg_thumb_injection = "called injected THUMB wrapper";
#define IS_T32(hi16) \
(((hi16) & 0xe000) == 0xe000 && ((hi16) & 0x1800))
+static size_t
+get_wrapper_code_size(void *wrapper)
+{
+ // Find first occurence of 0xFFFFFFFF in the code object,
+ // which is the placeholder for the attached data words
+ uint32_t *ptr = wrapper;
+ while (*ptr != 0xFFFFFFFF) {
+ ptr++;
+ }
+ return ((void *)ptr - (void *)wrapper);
+}
+
void *create_wrapper(char *symbol, void *function, int wrapper_type)
{
- int helper = 0;
- int wrapper_size = 0;
+ size_t wrapper_size = 0;
+ void *wrapper_code = NULL;
void *wrapper_addr = NULL;
+ int helper = 0;
const char *msg = NULL;
-
+
switch(wrapper_type)
{
case WRAPPER_LATEHOOK:
@@ -151,41 +165,31 @@ void *create_wrapper(char *symbol, void *function, int wrapper_type)
switch(wrapper_type)
{
case WRAPPER_LATEHOOK:
- wrapper_size =
-#include "wrappers/wrapper_GENERIC.size"
- * sizeof(uint32_t);
+ wrapper_code = wrapper_code_generic;
msg = msg_latehook;
break;
case WRAPPER_UNHOOKED:
- wrapper_size =
-#include "wrappers/wrapper_GENERIC.size"
- * sizeof(uint32_t);
+ wrapper_code = wrapper_code_generic;
msg = msg_unhooked;
break;
case WRAPPER_DYNHOOK:
- wrapper_size =
-#include "wrappers/wrapper_GENERIC.size"
- * sizeof(uint32_t);
+ wrapper_code = wrapper_code_generic;
msg = msg_dynhook;
break;
case WRAPPER_ARM_INJECTION:
- wrapper_size =
-#include "wrappers/wrapper_ARM.size"
- * sizeof(uint32_t); // 32-Bit
+ wrapper_code = wrapper_code_arm;
msg = msg_arm_injection;
break;
-#ifndef FREMANTLE
case WRAPPER_THUMB_INJECTION:
- wrapper_size =
-#include "wrappers/wrapper_THUMB.size"
- * sizeof(uint16_t); // 16-Bit
+ wrapper_code = wrapper_code_thumb;
msg = msg_thumb_injection;
break;
-#endif /* FREMANTLE */
default:
assert(NULL == "ERROR: invalid wrapper type!\n");
}
-
+
+ wrapper_size = get_wrapper_code_size(wrapper_code);
+
// 4 additional longs for data storage, see below
wrapper_size += 4 * sizeof(uint32_t);
@@ -204,19 +208,22 @@ void *create_wrapper(char *symbol, void *function, int wrapper_type)
// this variable is used to determine how many operations we need to copy from the thumb code
int thumb_fifth_nop = 0;
+ memcpy(wrapper_addr, wrapper_code, wrapper_size);
+
+ // Helper = offset of data fields in wrapper_addr (interpreted as int32_t)
+ helper = wrapper_size / sizeof(uint32_t) - 4;
+
switch(wrapper_type)
{
case WRAPPER_LATEHOOK:
case WRAPPER_UNHOOKED:
case WRAPPER_DYNHOOK:
-#include "wrappers/wrapper_GENERIC.instructions"
((int32_t*)wrapper_addr)[helper++] = (uint32_t)symbol;
((int32_t*)wrapper_addr)[helper++] = (uint32_t)function;
((int32_t*)wrapper_addr)[helper++] = (uint32_t)trace_callback;
((int32_t*)wrapper_addr)[helper++] = (uint32_t)msg;
break;
case WRAPPER_ARM_INJECTION:
-#include "wrappers/wrapper_ARM.instructions"
// relocate the first 2 instructions
// this is EXPERIMENTAL! it works in many cases because of how
// ARM methods are layout in ASM.
@@ -244,7 +251,6 @@ void *create_wrapper(char *symbol, void *function, int wrapper_type)
function = (void*)((char*)function - 1);
// fix wrapper addr (tell the processor this is THUMB code)
wrapper_addr = (void*)((char*)wrapper_addr + 1);
-#include "wrappers/wrapper_THUMB.instructions"
thumb_fifth_nop = IS_T32(*((int16_t*)function + 4)) && (
(!IS_T32(*((int16_t*)function)) && !IS_T32(*((int16_t*)function + 1)) && !IS_T32(*((int16_t*)function + 3))) ||
(!IS_T32(*((int16_t*)function)) && IS_T32(*((int16_t*)function + 1)) ) ||
@@ -292,6 +298,7 @@ void *create_wrapper(char *symbol, void *function, int wrapper_type)
((int16_t*)wrapper_addr)[helper++] = ((uint32_t)msg) >> 16;
break;
default:
+ assert(0);
break;
};
8 debug/wrappers/wrapper_code.h
View
@@ -0,0 +1,8 @@
+#ifndef WRAPPER_CODE_H
+#define WRAPPER_CODE_H
+
+void wrapper_code_generic() __attribute__((naked,noinline));
+void wrapper_code_arm() __attribute__((naked,noinline));
+void wrapper_code_thumb() __attribute__((naked,noinline));
+
+#endif /* WRAPPER_CODE_H */
15 debug/wrappers/wrapper_ARM.c → debug/wrappers/wrapper_code_arm.c
View
@@ -1,5 +1,7 @@
-static void dummy_f() __attribute__((naked,noinline));
-static void dummy_f()
+#include "wrapper_code.h"
+
+void
+wrapper_code_arm()
{
asm volatile(
// don't use any labels within the code because our *.o to code converter will stop at the first label
@@ -29,10 +31,9 @@ static void dummy_f()
// necessary and this is easier
// dummy instructions, this is where we locate our pointers
- "name: mov r0, r0\n" // name of function to call
- "fun: mov r0, r0\n" // function to call (actually the pointer to the third instruction)
- "tc: mov r0, r0\n" // address of trace_callback
- "str: mov r0, #0\n" // the string being printed in trace_callback
+ "name: .word 0xFFFFFFFF\n" // name of function to call
+ "fun: .word 0xFFFFFFFF\n" // function to call (actually the pointer to the third instruction)
+ "tc: .word 0xFFFFFFFF\n" // address of trace_callback
+ "str: .word 0xFFFFFFFF\n" // the string being printed in trace_callback
);
}
-
15 debug/wrappers/wrapper_GENERIC.c → debug/wrappers/wrapper_code_generic_arm.c
View
@@ -1,5 +1,7 @@
-static void dummy_f() __attribute__((naked,noinline));
-static void dummy_f()
+#include "wrapper_code.h"
+
+void
+wrapper_code_generic()
{
// we can never use r0-r11, neither the stack
asm volatile(
@@ -21,10 +23,9 @@ static void dummy_f()
// necessary and this is easier
// dummy instructions, this is where we locate our pointers
- "name: mov r0, #0\n" // name of function to call
- "fun: mov r0, #0\n" // function to call
- "tc: mov r0, #0\n" // address of trace_callback
- "str: mov r0, #0\n" // the string being printed in trace_callback
+ "name: .word 0xFFFFFFFF\n" // name of function to call
+ "fun: .word 0xFFFFFFFF\n" // function to call
+ "tc: .word 0xFFFFFFFF\n" // address of trace_callback
+ "str: .word 0xFFFFFFFF\n" // the string being printed in trace_callback
);
}
-
19 debug/wrappers/wrapper_THUMB.c → debug/wrappers/wrapper_code_thumb.c
View
@@ -1,5 +1,7 @@
-static void dummy_f() __attribute__((naked,noinline));
-static void dummy_f()
+#include "wrapper_code.h"
+
+void
+wrapper_code_thumb()
{
// the thumb wrapper does not work yet
asm volatile(
@@ -35,14 +37,9 @@ static void dummy_f()
// necessary and this is easier
// dummy instructions, this is where we locate our pointers
- "name: mov r0, r0\n" // name of function to call
- "mov r0, r0\n"
- "fun: mov r0, r0\n" // function to call (actually the pointer to the third instruction)
- "mov r0, r0\n"
- "tc: mov r0, r0\n" // address of print_fun_name
- "mov r0, r0\n"
- "str: mov r0, r0\n" // the string being printed in trace_callback
- "mov r0, r0\n"
+ "name: .word 0xFFFFFFFF\n" // name of function to call
+ "fun: .word 0xFFFFFFFF\n" // function to call (actually the pointer to the third instruction)
+ "tc: .word 0xFFFFFFFF\n" // address of print_fun_name
+ "str: .word 0xFFFFFFFF\n" // the string being printed in trace_callback
);
}
-
42 makefile
View
@@ -21,11 +21,7 @@ IMAGELIB_SOURCES=$(wildcard imagelib/*.c)
DEBUG_SOURCES=$(wildcard debug/*.c)
# debug wrappers
-WRAPPER_INJECT_ARM_SOURCE=debug/wrappers/wrapper_ARM.c
-WRAPPER_INJECT_THUMB_SOURCE=debug/wrappers/wrapper_THUMB.c
-WRAPPER_INJECT_GENERIC_SOURCE=debug/wrappers/wrapper_GENERIC.c
-WRAPPER_INJECT_SOURCES=$(WRAPPER_INJECT_ARM_SOURCE) $(WRAPPER_INJECT_THUMB_SOURCE) $(WRAPPER_INJECT_GENERIC_SOURCE)
-WRAPPER_INJECT_TARGETS=$(patsubst %.c,%.instructions,$(WRAPPER_INJECT_SOURCES))
+WRAPPER_SOURCES=$(wildcard debug/wrappers/*.c)
TARGET = apkenv
@@ -88,7 +84,15 @@ else
CFLAGS += -O2 -DLINKER_DEBUG=0
endif
-all: $(WRAPPER_INJECT_TARGETS) $(TARGET) $(MODULES)
+all: $(TARGET) $(MODULES)
+
+debug/wrappers/%_thumb.o: debug/wrappers/%_thumb.c
+ @echo -e "\tCC (TH)\t$@"
+ @$(CC) -mthumb -O0 -c -o $@ $<
+
+debug/wrappers/%_arm.o: debug/wrappers/%_arm.c
+ @echo -e "\tCC\t$@"
+ @$(CC) -marm -O0 -c -o $@ $<
%.o: %.c
@echo -e "\tCC\t$@"
@@ -106,30 +110,6 @@ strip:
@echo -e "\tSTRIP"
@strip $(TARGET) $(MODULES)
-$(patsubst %.c,%.instructions,$(WRAPPER_INJECT_ARM_SOURCE)): $(WRAPPER_INJECT_ARM_SOURCE)
- @echo -e "\tCC_W\t$<"
- @$(CC) -marm -Wno-unused-function -O0 -c -o $(patsubst %.c,%.o,$<) $<
- @echo -e "\tDEC\t$(patsubst %.c,%.o,$<)"
- @$(OBJDUMP) -d $(patsubst %.c,%.o,$<) | ./tools/extract_wrapper_code.sh | ./tools/to_code_arm.sh > $(patsubst %.c,%.instructions,$<)
- @echo -e "\tSIZE\t$(patsubst %.c,%.instructions,$<)"
- @wc -l $(patsubst %.c,%.instructions,$<) | awk '{print $$1}' > $(patsubst %.c,%.size,$<)
-
-$(patsubst %.c,%.instructions,$(WRAPPER_INJECT_THUMB_SOURCE)): $(WRAPPER_INJECT_THUMB_SOURCE)
- @echo -e "\tCC_W\t$<"
- @$(CC) -mthumb -Wno-unused-function -O0 -c -o $(patsubst %.c,%.o,$<) $<
- @echo -e "\tDEC\t$(patsubst %.c,%.o,$<)"
- @$(OBJDUMP) -d $(patsubst %.c,%.o,$<) | ./tools/extract_wrapper_code.sh | ./tools/to_code_thumb.sh > $(patsubst %.c,%.instructions,$<)
- @echo -e "\tSIZE\t$(patsubst %.c,%.instructions,$<)"
- @wc -l $(patsubst %.c,%.instructions,$<) | awk '{print $$1}' > $(patsubst %.c,%.size,$<)
-
-$(patsubst %.c,%.instructions,$(WRAPPER_INJECT_GENERIC_SOURCE)): $(WRAPPER_INJECT_GENERIC_SOURCE)
- @echo -e "\tCC_W\t$<"
- @$(CC) -marm -Wno-unused-function -O0 -c -o $(patsubst %.c,%.o,$<) $<
- @echo -e "\tDEC\t$(patsubst %.c,%.o,$<)"
- @$(OBJDUMP) -d $(patsubst %.c,%.o,$<) | ./tools/extract_wrapper_code.sh | ./tools/to_code_arm.sh > $(patsubst %.c,%.instructions,$<)
- @echo -e "\tSIZE\t$(patsubst %.c,%.instructions,$<)"
- @wc -l $(patsubst %.c,%.instructions,$<) | awk '{print $$1}' > $(patsubst %.c,%.size,$<)
-
install: $(TARGET) $(MODULES)
@echo -e "\tMKDIR"
@mkdir -p $(DESTDIR)$(PREFIX)/{modules,bionic}
@@ -154,7 +134,7 @@ endif
clean:
@echo -e "\tCLEAN"
- @rm -rf $(TARGET) $(OBJS) $(MODULES) $(WRAPPER_INJECT_TARGETS) $(patsubst %.c,%.o, $(WRAPPER_INJECT_SOURCES)) $(patsubst %.c,%.size, $(WRAPPER_INJECT_SOURCES))
+ @rm -rf $(TARGET) $(OBJS) $(MODULES)
.DEFAULT: all
.PHONY: strip install clean
1  tools/extract_wrapper_code.sh
View
@@ -1 +0,0 @@
-awk '/ 0:/ {do_print=1} NF==0 {do_print=0} do_print==1 {print}'
2  tools/to_code_arm.sh
View
@@ -1,2 +0,0 @@
-#!/bin/sh
-awk '{ print "((int32_t*)wrapper_addr)[helper++] = 0x"$2"; // "$3" "$4" "$5" "$6" "$7" "$8" "$9" "$10" "$11}' -
23 tools/to_code_thumb.sh
View
@@ -1,23 +0,0 @@
-#!/bin/sh
-
-while read line
-do
- opstart=2;
- opend=2;
- line=( $line );
- if [[ "${line[2]}" =~ "^[0-9a-f]+$" ]]; then
- opend=3;
- fi
- echo -ne "((int16_t*)wrapper_addr)[helper++] = 0x"${line[1]}";"
- echo -ne " // "
- for i in `seq $opend ${#line[@]}`
- do
- echo -ne "${line[$i]} "
- done
- if [[ $opend -eq 2 ]]; then
- echo -ne "\n"
- else
- echo -ne "\n((int16_t*)wrapper_addr)[helper++] = 0x"${line[2]}"; // above command continued\n"
- fi
-done
-
Please sign in to comment.
Something went wrong with that request. Please try again.