rollback frida 'Java.registerClass'
This commit is contained in:
parent
6ee51c13d6
commit
30c1abe1ea
7 changed files with 154 additions and 10 deletions
1
frida/.gitignore
vendored
1
frida/.gitignore
vendored
|
|
@ -1,4 +1,3 @@
|
||||||
__pycache__
|
__pycache__
|
||||||
dist
|
dist
|
||||||
theseus_frida/StackConsumer.dex.b64
|
|
||||||
consumer/build
|
consumer/build
|
||||||
|
|
|
||||||
|
|
@ -2,3 +2,25 @@
|
||||||
|
|
||||||
Collect runtime information about reflection operation done by en application to feed them to the patcher.
|
Collect runtime information about reflection operation done by en application to feed them to the patcher.
|
||||||
|
|
||||||
|
|
||||||
|
# Modifying StackConsumer.java
|
||||||
|
|
||||||
|
The Frida hook uses a Java class to collect the stack information. If you modify it, before building/installing the python package, you need to build regenerate the base64 encoded class used by frida:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
|
||||||
|
# If the default values do not match, set the variables:
|
||||||
|
#
|
||||||
|
# JAVAC: path to the java compiler
|
||||||
|
# ANDROID_SDK: path to the android sdk
|
||||||
|
# VERSION: Android SDK version to use
|
||||||
|
# D8: path to the d8 executable
|
||||||
|
# ANDROID_JAR: path to the android.jar file to link
|
||||||
|
# BUILD_F: build folder (will be delated if exist)
|
||||||
|
# OUT_FILE: the file where to put the b64 of the compiled dex
|
||||||
|
|
||||||
|
bash consumer/build.sh
|
||||||
|
|
||||||
|
# Then you can build the package / install it
|
||||||
|
poetry build # / poetry install / pip install .
|
||||||
|
```
|
||||||
|
|
|
||||||
29
frida/consumer/StackConsumer.java
Normal file
29
frida/consumer/StackConsumer.java
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
package theseus.android;
|
||||||
|
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.lang.StackWalker.StackFrame;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
class StackConsumer implements Consumer<StackFrame> {
|
||||||
|
|
||||||
|
public ArrayList<StackFrame> stack;
|
||||||
|
|
||||||
|
public StackConsumer() {
|
||||||
|
this.stack = new ArrayList<StackFrame>();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(StackFrame frame) {
|
||||||
|
stack.add(frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
public StackFrame[] getStack() {
|
||||||
|
return this.stack.toArray(new StackFrame[] {});
|
||||||
|
}
|
||||||
|
|
||||||
|
public Function<? super Stream<StackWalker.StackFrame>, StackFrame[]> walkNFrame(int n) {
|
||||||
|
return s -> { s.limit(n).forEach(this); return this.getStack(); };
|
||||||
|
}
|
||||||
|
}
|
||||||
32
frida/consumer/build.sh
Normal file
32
frida/consumer/build.sh
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
|
||||||
|
JAVAC="${JAVAC:-/usr/lib/jvm/java-17-openjdk/bin/javac}"
|
||||||
|
ANDROID_SDK="${ANDROID_SDK:-${HOME}/Android/Sdk/}"
|
||||||
|
VERSION="${VERSION:-34.0.0}"
|
||||||
|
D8="${D8:-${ANDROID_SDK}/build-tools/${VERSION}/d8}"
|
||||||
|
VERSION_B="${VERSION_B:-$(echo "${VERSION}" | sed 's/\..*//')}"
|
||||||
|
ANDROID_JAR="${ANDROID_JAR:-${ANDROID_SDK}/platforms/android-${VERSION_B}/android.jar}"
|
||||||
|
|
||||||
|
FOLDER=$(dirname "$(realpath $0)")
|
||||||
|
BUILD_F="${BUILD_F:-${FOLDER}/build}"
|
||||||
|
OUT_FILE="${OUT_FILE:-${FOLDER}/../theseus_frida/StackConsumer.dex.b64}"
|
||||||
|
|
||||||
|
echo "JAVAC = ${JAVAC}"
|
||||||
|
echo "ANDROID_SDK = ${ANDROID_SDK}"
|
||||||
|
echo "VERSION = ${VERSION}"
|
||||||
|
echo "D8 = ${D8}"
|
||||||
|
# echo "VERSION_B = ${VERSION_B}"
|
||||||
|
echo "ANDROID_JAR = ${ANDROID_JAR}"
|
||||||
|
echo "BUILD_F = ${BUILD_F}"
|
||||||
|
echo "OUT_FILE = ${OUT_FILE}"
|
||||||
|
|
||||||
|
rm -r "${BUILD_F}"
|
||||||
|
mkdir "${BUILD_F}"
|
||||||
|
|
||||||
|
"${JAVAC}" -Xlint -d "${BUILD_F}" -classpath "${ANDROID_JAR}" "${FOLDER}/StackConsumer.java"
|
||||||
|
|
||||||
|
mkdir "${BUILD_F}/classes"
|
||||||
|
"${D8}" --classpath "${ANDROID_JAR}" "${BUILD_F}/theseus/android/StackConsumer.class" --output "${BUILD_F}/classes"
|
||||||
|
|
||||||
|
base64 "${BUILD_F}/classes/classes.dex" > "${OUT_FILE}"
|
||||||
49
frida/theseus_frida/StackConsumer.dex.b64
Normal file
49
frida/theseus_frida/StackConsumer.dex.b64
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
ZGV4CjAzNQBSwVrBo2GZnSIiXXnINXUzvz6Ai4dYk7LgCgAAcAAAAHhWNBIAAAAAAAAAABwKAAA5
|
||||||
|
AAAAcAAAABEAAABUAQAAEQAAAJgBAAADAAAAZAIAABUAAAB8AgAAAgAAACQDAAB8BwAAZAMAAG4F
|
||||||
|
AACABQAAkgUAALoFAAC/BQAAwgUAAMoFAADOBQAA0wUAAOcFAADqBQAA7QUAAPAFAAD0BQAA+QUA
|
||||||
|
AP0FAAABBgAABwYAAAwGAAArBgAAPwYAAGMGAAB6BgAAkQYAALQGAADTBgAA8gYAABUHAAA0BwAA
|
||||||
|
UwcAAG4HAACJBwAAxAcAAOUHAAD5BwAA/AcAAAAIAAAFCAAACAgAAAwIAAAhCAAARggAAE4IAABT
|
||||||
|
CAAAXAgAAGMIAABsCAAAcQgAAHYIAAB/CAAAiQgAAJ4IAAClCAAArAgAALUIAAC8CAAAyAgAAAkA
|
||||||
|
AAAKAAAAEgAAABMAAAAUAAAAFQAAABcAAAAYAAAAGgAAABsAAAAdAAAAHwAAACAAAAAiAAAAJQAA
|
||||||
|
ACcAAAAoAAAADwAAAAMAAAAcBQAADwAAAAcAAAAUBQAAEQAAAAcAAAAkBQAADAAAAAkAAAAsBQAA
|
||||||
|
DwAAAAkAAAAMBQAAEQAAAAkAAAA0BQAADgAAAAoAAAA8BQAAIgAAAA0AAAAAAAAAIwAAAA0AAAAc
|
||||||
|
BQAAIwAAAA0AAABEBQAAIwAAAA0AAAAUBQAAJAAAAA0AAABMBQAAJgAAAA4AAAAcBQAADwAAAA8A
|
||||||
|
AABUBQAACwAAABAAAAAAAAAADQAAABAAAABcBQAAEAAAABAAAABkBQAACwAMAC4AAAALAAAALwAA
|
||||||
|
AAwABQA0AAAAAwAHAAUAAAAFAAcABQAAAAUADAAqAAAABQANADUAAAAGAAIAAAAAAAgABQAAAAAA
|
||||||
|
CAAFAAEAAAAKAAoAMAAAAAoABgAzAAAACwALAAUAAAALAAQAKwAAAAsAAAAsAAAACwAEAC0AAAAM
|
||||||
|
ABAAAgAAAAwABwAFAAAADAAIACkAAAAMAAkAKQAAAAwAAQArAAAADAAOADEAAAAMAA8AMgAAAAwA
|
||||||
|
AwA3AAAACwAAABEQAAADAAAADAUAAAgAAAAAAAAAlgkAAAAAAAAMAAAAAAAAAAMAAAAUBQAAIQAA
|
||||||
|
APwJAAC0CQAAAAAAAAQAAgADAAAAAAAAAAsAAABUIAAAUiEBAB8DCgBxMA0AEAMMAxEDAAACAAIA
|
||||||
|
AgAAAAAAAAAFAAAAcSAFABAADAERAQAAAgACAAIAAAAAAAAABQAAAHEgBgAQAAwBEQEAAAMAAwAB
|
||||||
|
AAAAAAAAAAgAAABwEAAAAABbAQAAWQIBAA4AAwADAAMAAAAAAAAABQAAAHAwEwAQAgwAEQAAAAMA
|
||||||
|
AQACAAAA7AQAAAwAAABUIAIAEgEjERAAbiADABAADAAfABAAEQAFAAMAAwAAAPAEAAANAAAAgTBy
|
||||||
|
MAgABAEMA3IgBwAjAG4QEgACAAwDEQMAAAIAAgACAAAAAAAAAAUAAABxIAQAEAAMAREBAAADAAIA
|
||||||
|
AwAAAPYEAAAGAAAAIgALAHAwCQAQAhEAAgABAAEAAAD7BAAACwAAAHAQAAABACIABQBwEAEAAABb
|
||||||
|
EAIADgAAAAIAAgACAAAAAQUAAAYAAAAfAQQAbiAQABAADgADAAIAAgAAAAYFAAAGAAAAVBACAG4g
|
||||||
|
AgAgAA4AFwAOABsCAAAOABsBAA4ADQAOPHgACQEADgATAQAOWgABAAAACQAAAAEAAAAHAAAAAQAA
|
||||||
|
AAMAAAACAAAABwAHAAEAAAAAAAAAAgAAAAkACQABAAAAAQAAAAEAAAAEAAAAAgAAAAwAAAABAAAA
|
||||||
|
DwAAAAIAAAAAAAoAAwAAAAwAAAAKABAkZGVmYXVsdCRhbmRUaGVuABAkZGVmYXVsdCRjb21wb3Nl
|
||||||
|
ACYkcjgkbGFtYmRhJFpYZWVGQm9YWU03d2VwZjhsSjNzcnh6YnRlbwADKEkpAAEtAAY8aW5pdD4A
|
||||||
|
Aj47AAM+O1sAEkQ4JCRTeW50aGV0aWNDbGFzcwABSQABSgABTAACTEkAA0xJTAACTEoAAkxMAARM
|
||||||
|
TElMAANMTEwAHUxkYWx2aWsvYW5ub3RhdGlvbi9TaWduYXR1cmU7ABJMamF2YS9sYW5nL09iamVj
|
||||||
|
dDsAIkxqYXZhL2xhbmcvU3RhY2tXYWxrZXIkU3RhY2tGcmFtZTsAFUxqYXZhL3V0aWwvQXJyYXlM
|
||||||
|
aXN0OwAVTGphdmEvdXRpbC9BcnJheUxpc3Q8ACFMamF2YS91dGlsL2Z1bmN0aW9uL0NvbnN1bWVy
|
||||||
|
JC1DQzsAHUxqYXZhL3V0aWwvZnVuY3Rpb24vQ29uc3VtZXI7AB1MamF2YS91dGlsL2Z1bmN0aW9u
|
||||||
|
L0NvbnN1bWVyPAAhTGphdmEvdXRpbC9mdW5jdGlvbi9GdW5jdGlvbiQtQ0M7AB1MamF2YS91dGls
|
||||||
|
L2Z1bmN0aW9uL0Z1bmN0aW9uOwAdTGphdmEvdXRpbC9mdW5jdGlvbi9GdW5jdGlvbjwAGUxqYXZh
|
||||||
|
L3V0aWwvc3RyZWFtL1N0cmVhbTsAGUxqYXZhL3V0aWwvc3RyZWFtL1N0cmVhbTwAOUx0aGVzZXVz
|
||||||
|
L2FuZHJvaWQvU3RhY2tDb25zdW1lciQkRXh0ZXJuYWxTeW50aGV0aWNMYW1iZGEwOwAfTHRoZXNl
|
||||||
|
dXMvYW5kcm9pZC9TdGFja0NvbnN1bWVyOwASU3RhY2tDb25zdW1lci5qYXZhAAFWAAJWTAADVkxJ
|
||||||
|
AAFaAAJaTAATW0xqYXZhL2xhbmcvT2JqZWN0OwAjW0xqYXZhL2xhbmcvU3RhY2tXYWxrZXIkU3Rh
|
||||||
|
Y2tGcmFtZTsABmFjY2VwdAADYWRkAAdhbmRUaGVuAAVhcHBseQAHY29tcG9zZQADZiQwAANmJDEA
|
||||||
|
B2ZvckVhY2gACGdldFN0YWNrABNsYW1iZGEkd2Fsa05GcmFtZSQwAAVsaW1pdAAFc3RhY2sAB3Rv
|
||||||
|
QXJyYXkABXZhbHVlAAp3YWxrTkZyYW1lAJsBfn5EOHsiYmFja2VuZCI6ImRleCIsImNvbXBpbGF0
|
||||||
|
aW9uLW1vZGUiOiJkZWJ1ZyIsImhhcy1jaGVja3N1bXMiOmZhbHNlLCJtaW4tYXBpIjoxLCJzaGEt
|
||||||
|
MSI6ImZhY2VkZjQxYmJkMjhiNTYzZDFlOWUwOWM1ZjcyZDdjNWNhNTk4ZDUiLCJ2ZXJzaW9uIjoi
|
||||||
|
OC4yLjItZGV2In0AAgIBNhwIFwMXHBcEFx4XFBcHFxQXBgICATYcAxcWFxQXBgICATYcBBcTFxkX
|
||||||
|
FBcGAAIBAwCRIAGRIAmBoATEBwqBIIwHARHkBgGBIKgHAAEDBQIBDYkg5AcBgYAEjAkFgiCoCA/B
|
||||||
|
ILQJAQHQCQGBINQIAQGACAIB8AgAAAAAAQAAAGYJAAABAAAAfAkAAAEAAACICQAA9AkAAAEAAAAB
|
||||||
|
AAAAAAAAAAIAAADsCQAAFAAAAOQJAAAQAAAAAAAAAAEAAAAAAAAAAQAAADkAAABwAAAAAgAAABEA
|
||||||
|
AABUAQAAAwAAABEAAACYAQAABAAAAAMAAABkAgAABQAAABUAAAB8AgAABgAAAAIAAAAkAwAAASAA
|
||||||
|
AAwAAABkAwAAAyAAAAYAAADsBAAAARAAAAwAAAAMBQAAAiAAADkAAABuBQAABCAAAAMAAABmCQAA
|
||||||
|
ACAAAAIAAACWCQAAAxAAAAQAAADgCQAABiAAAAEAAAD8CQAAABAAAAEAAAAcCgAA
|
||||||
|
|
@ -21,6 +21,7 @@ from loguru import logger # type: ignore
|
||||||
logger.remove() # remove androguard logs
|
logger.remove() # remove androguard logs
|
||||||
|
|
||||||
FRIDA_SCRIPT = Path(__file__).parent / "hook.js"
|
FRIDA_SCRIPT = Path(__file__).parent / "hook.js"
|
||||||
|
STACK_CONSUMER_B64 = Path(__file__).parent / "StackConsumer.dex.b64"
|
||||||
FRIDA_SERVER_BIN = Path(__file__).parent / "frida-server-16.7.4-android-x86_64.xz"
|
FRIDA_SERVER_BIN = Path(__file__).parent / "frida-server-16.7.4-android-x86_64.xz"
|
||||||
FRIDA_SERVER_ANDROID_PATH = "/data/local/tmp/frida-server"
|
FRIDA_SERVER_ANDROID_PATH = "/data/local/tmp/frida-server"
|
||||||
|
|
||||||
|
|
@ -347,6 +348,11 @@ def collect_runtime(
|
||||||
|
|
||||||
with FRIDA_SCRIPT.open("r") as file:
|
with FRIDA_SCRIPT.open("r") as file:
|
||||||
jsscript = file.read()
|
jsscript = file.read()
|
||||||
|
with STACK_CONSUMER_B64.open("r") as file:
|
||||||
|
jsscript = jsscript.replace(
|
||||||
|
"<PYTHON REPLACE StackConsumer.dex.b64>",
|
||||||
|
file.read().replace("\n", "").strip(),
|
||||||
|
)
|
||||||
|
|
||||||
pid = device.spawn([app])
|
pid = device.spawn([app])
|
||||||
session = device.attach(pid)
|
session = device.attach(pid)
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,8 @@ function dump_classloaders() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ----- Frida Native Class Loading -----
|
||||||
|
* Broken, for some ineffable frida-android reason.
|
||||||
function registerStackConsumer() {
|
function registerStackConsumer() {
|
||||||
const Consumer = Java.use('java.util.function.Consumer');
|
const Consumer = Java.use('java.util.function.Consumer');
|
||||||
const Method = Java.use('java.lang.reflect.Method');
|
const Method = Java.use('java.lang.reflect.Method');
|
||||||
|
|
@ -91,6 +93,19 @@ function registerStackConsumer() {
|
||||||
console.log(Object.keys(spec.methods));
|
console.log(Object.keys(spec.methods));
|
||||||
return Java.registerClass(spec);
|
return Java.registerClass(spec);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
// ----- InMemoryDexClassLoader class loading -----
|
||||||
|
function registerStackConsumer() {
|
||||||
|
const InMemoryDexClassLoader = Java.use("dalvik.system.InMemoryDexClassLoader");
|
||||||
|
const ByteBuffer = Java.use("java.nio.ByteBuffer");
|
||||||
|
const Base64 = Java.use("android.util.Base64");
|
||||||
|
let myClassLoader = InMemoryDexClassLoader.$new(
|
||||||
|
ByteBuffer.wrap(Base64.decode("<PYTHON REPLACE StackConsumer.dex.b64>", Base64.DEFAULT.value)),
|
||||||
|
null,
|
||||||
|
);
|
||||||
|
return Java.ClassFactory.get(myClassLoader).use("theseus.android.StackConsumer");
|
||||||
|
}
|
||||||
|
|
||||||
// recv('dump-class-loaders', function onMessage(msg) {dump_classloaders()});
|
// recv('dump-class-loaders', function onMessage(msg) {dump_classloaders()});
|
||||||
|
|
||||||
|
|
@ -108,9 +123,8 @@ Java.perform(() => {
|
||||||
const StackWalkerOptionsShowReflect = StackWalkerOptions.valueOf("SHOW_REFLECT_FRAMES");
|
const StackWalkerOptionsShowReflect = StackWalkerOptions.valueOf("SHOW_REFLECT_FRAMES");
|
||||||
const StackWalkerOptionsRetainClassReference = StackWalkerOptions.valueOf("RETAIN_CLASS_REFERENCE");
|
const StackWalkerOptionsRetainClassReference = StackWalkerOptions.valueOf("RETAIN_CLASS_REFERENCE");
|
||||||
const StackFrame = Java.use('java.lang.StackWalker$StackFrame');
|
const StackFrame = Java.use('java.lang.StackWalker$StackFrame');
|
||||||
const Base64 = Java.use("android.util.Base64");
|
|
||||||
const InMemoryDexClassLoader = Java.use("dalvik.system.InMemoryDexClassLoader");
|
|
||||||
const ByteBuffer = Java.use("java.nio.ByteBuffer");
|
const ByteBuffer = Java.use("java.nio.ByteBuffer");
|
||||||
|
const Base64 = Java.use("android.util.Base64");
|
||||||
const Method = Java.use("java.lang.reflect.Method");
|
const Method = Java.use("java.lang.reflect.Method");
|
||||||
const Class = Java.use("java.lang.Class");
|
const Class = Java.use("java.lang.Class");
|
||||||
const Constructor = Java.use("java.lang.reflect.Constructor");
|
const Constructor = Java.use("java.lang.reflect.Constructor");
|
||||||
|
|
@ -122,13 +136,6 @@ Java.perform(() => {
|
||||||
const System = Java.use('java.lang.System');
|
const System = Java.use('java.lang.System');
|
||||||
const Arrays = Java.use('java.util.Arrays');
|
const Arrays = Java.use('java.util.Arrays');
|
||||||
|
|
||||||
/*
|
|
||||||
const myClassLoader = InMemoryDexClassLoader.$new(
|
|
||||||
ByteBuffer.wrap(Base64.decode("<PYTHON REPLACE StackConsumer.dex.b64>", Base64.DEFAULT.value)),
|
|
||||||
null
|
|
||||||
);
|
|
||||||
const StackConsumer = Java.ClassFactory.get(myClassLoader).use("theseus.android.StackConsumer");
|
|
||||||
*/
|
|
||||||
const StackConsumer = registerStackConsumer();
|
const StackConsumer = registerStackConsumer();
|
||||||
|
|
||||||
const get_stack = function () {
|
const get_stack = function () {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue