对神器objection的分析,学习一下frida的代码写法和大佬的思路

下方的大标题是objection的目录信息

android

lib

libjava.ts

warpJavaPerform(包装perform)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// all Java calls need to be wrapped in a Java.perform().
// this helper just wraps that into a Promise that the
// rpc export will sniff and resolve before returning
// the result when its ready.
export const wrapJavaPerform = (fn: any): Promise<any> => {
return new Promise((resolve, reject) => {
Java.perform(() => {
try {
resolve(fn());
} catch (e) {
reject(e);
}
});
});
};

可以看到这里用Promise对Perform进行了包装。返回值是new了一个新的Promise,俩参数分别是作为异步的成功或者失败的分支。如果perform操作成功就会调用resolve来异步的执行fn()函数,如果发生了异常就会调用reject来捕获这个异常。所以这个包装实际上就是普通的perform执行,只不过加上了异步和异步捕获异常

此处的Promise是Javascript的异步编程里的知识点。JavaScript学习笔记里面写了

getApplicationContext(获取应用的上下文)

1
2
3
4
5
6
export const getApplicationContext = (): any => {
const ActivityThread = Java.use("android.app.ActivityThread");
const currentApplication = ActivityThread.currentApplication();

return currentApplication.getApplicationContext();
};

可以看到这里用到了Java的android.app.ActivityThread类,调用该类的currentApplication方法来获得当前的应用,然后用当前应用的方法getApplicationContext来获取上下文

R(和apk的R.id差不多)

1
2
3
4
5
6
export const R = (name: string, type: string): any => {
const context = getApplicationContext();
// https://github.com/bitpay/android-sdk/issues/14#issue-202495610
return context.getResources().getIdentifier(name, type, context.getPackageName());
};

模仿apk的R.id,首先获取一下应用的上下文,然后返回当前资源对应的标识符

image-20230121002712772

如图,getIdentifier是返回给定资源名字的标识符。和apk的通过资源的id找对应资源的操作差不多

未完待续。。