1. Process
1.1 Process.id
当前附加进程的 pid
。
function main() {
Java.perform(() => {
console.log("process pid = " + Process.id);
});
}
setImmediate(main);
1.2 Process.enumerateModules()
枚举已加载的 so
。
function main() {
Java.perform(() => {
var Modules = Process.enumerateModules();
for (let i = 0; i < Modules.length; i++) {
const Module = Modules[i];
console.log(JSON.stringify(Module));
}
});
}
setImmediate(main);
1.3 查找 so
1.3.1 Process.getModuleByName(name)
根据 name
查找 so
,找不到则抛异常。
function main() {
Java.perform(() => {
var libc = Process.getModuleByName("libc.so");
console.log(JSON.stringify(libc, null, 2));
});
}
setImmediate(main);
1.3.2 Process.findModuleByName(name)
根据 name
查找 so
,找不到则返回 null
。
function main() {
Java.perform(() => {
var libc = Process.findModuleByName("libc.so");
console.log(JSON.stringify(libc, null, 2))
});
}
setImmediate(main);
2. Module
2.1 属性
- name,模块名
- base,基地址,类型为
NativePointer
- size,字节大小
- path,完整文件系统路径
function main() {
Java.perform(() => {
var libc = Module.load('libc.so');
console.log("libc 属性:");
console.log("\tname: " + libc.name);
console.log("\tbase: " + libc.base);
console.log("\tsize: " + libc.size);
console.log("\tpath: " + libc.path);
});
}
setImmediate(main);
2.2 常用 API
2.2.1 Module.load(path)
加载指定的 so
文件,如果无法加载会抛异常。
function main() {
Java.perform(() => {
var libc = Module.load('libc.so');
console.log(JSON.stringify(libc, null, 2));
});
}
setImmediate(main);
2.2.2 Module.enumerateImports()
枚举 so
文件所有的 Import
库函数。
function main() {
Java.perform(() => {
var libc = Module.load("libc.so");
var Imports = libc.enumerateImports();
for (let i = 0; i < Imports.length; i++) {
console.log(JSON.stringify(Imports[i], null, 2));
}
});
}
setImmediate(main);
2.2.3 Module.enumerateExports()
枚举 so
文件所有的 Export
库函数
function main() {
Java.perform(() => {
var libc = Module.load("libc.so");
var Exports = libc.enumerateExports();
for (let i = 0; i < Exports.length; i++) {
console.log(JSON.stringify(Exports[i], null, 2));
}
});
}
setImmediate(main);
2.2.4 Module.ensureInitialized(name)
确保 so
文件初始化。
function main() {
Java.perform(() => {
Module.ensureInitialized("libc.so")
});
}
setImmediate(main);
2.2.5 获取 so 文件基地址
2.2.5.1 Module.getBaseAddress(name)
获取 so
文件基地址,找不到则抛异常。
function main() {
Java.perform(() => {
var libcBaseAddress = Module.getBaseAddress('libc.so');
console.log("libc.so 基地址为 " + libcBaseAddress);
});
}
setImmediate(main);
2.2.5.2 Module.findBaseAddress(name)
获取 so
文件基地址,找不到返回 null
。
function main() {
Java.perform(() => {
var libcBaseAddress = Module.findBaseAddress('libc.so');
console.log("libc.so 基地址为 " + libcBaseAddress);
});
}
setImmediate(main);
2.2.6 查找 Export 库函数
2.2.6.1 Module.getExportByName(moduleName, exportName)
查找 so
文件的库函数,找不到抛异常。
function main() {
Java.perform(() => {
var ioctlBaseAddress = Module.getExportByName("libc.so", "ioctl");
console.log("函数 ioctl 的基地址为 " + ioctlBaseAddress);
});
}
setImmediate(main);
2.2.6.2 Module.findExportByName(moduleName, exportName)
查找 so
文件的库函数,找不到抛返回 null
。
function main() {
Java.perform(() => {
var ioctlBaseAddress = Module.findExportByName("libc.so", "ioctl");
console.log("函数 ioctl 的基地址为 " + ioctlBaseAddress);
});
}
# 3. Memory
## 3.1 内存检索
### 3.1.1 Memory.scan(address, size, pattern, callbacks)
同步检索内存,查找匹配的字节序列的基地址及大小。
```js
function main() {
Java.perform(() => {
Memory.scan(libc.base, libc.size, pattern, {
onMatch(address, size) {
console.log("匹配到字节序列,地址为 " + address);
},
onError(reason) {
console.log("内存检索失败,原因为 " + reason);
},
onComplete() {
}
});
});
}
setImmediate(main);
3.1.2 Memory.scanSync(address, size, pattern)
异步检索内存,查找匹配的字节序列的基地址及大小。
function main() {
Java.perform(() => {
var libc = Process.findModuleByName("libc.so");
var memoryArray = Memory.scanSync(libc.base, libc.size, "00 ?8 4d ?? 00");
for (let i = 0; i < memoryArray.length; i++) {
console.log("匹配到字节序列,地址为 " + memoryArray[i].address);
}
});
}
setImmediate(main);
3.2 内存分配
3.2.1 Memory.alloc(size, options)
在附加进程的堆内存上申请大小为 size
的内存空间,如果此内存在 js
里没有对其使用时会自动释放。
function main() {
Java.perform(() => {
var allocMemoryAddress = Memory.alloc(4);
console.log("动态分配内存基地址为 " + allocMemoryAddress);
});
}
setImmediate(main);
3.2.2 Memory.allocUtf8String(str)
在附加进程的堆内存上申请大小能存放 str
的内存空间,如果此内存在 js
里没有对其使用时会自动释放。
function main() {
Java.perform(() => {
var allocMemoryAddress = Memory.allocUtf8String("Hello, Frida!");
console.log(hexdump(allocMemoryAddress, {offset:0, length:"Hello, Frida!".length}));
});
}
setImmediate(main);
3.3 Memory.copy(dst, src, size)
进行内存复制。
function main() {
Java.perform(() => {
var allocMemoryAddress = Memory.alloc(4);
Memory.copy(allocMemoryAddress, libc.base, 4);
console.log(hexdump(allocMemoryAddress, { length: 4, offset: 0 }));
});
}
setImmediate(main);
4. Interceptor
5. Java
5.1 Java.perform(fn)
确保当前线程连接到虚拟机并调用函数 fn
。
5.2 Java.available
指定当前进程是否已加载虚拟机。
function main() {
Java.perform(() => {
console.log("Java.available = " + Java.available);
});
}
setImmediate(main);
5.3 Java.androidVersion
获取 android
版本。
function main() {
Java.perform(() => {
console.log("Java.androidVersion = " + Java.androidVersion);
});
}
setImmediate(main);
5.4 枚举已加载的类
5.4.1 Java.enumerateLoadedClasses(callbacks)
异步枚举已加载的类。
function main() {
Java.perform(() => {
Java.enumerateLoadedClasses({
onMatch(name, handle) {
console.log("class name is " + name);
},
onComplete() {
}
})
});
}
setImmediate(main);
5.4.2 Java.enumerateLoadedClassesSync()
Java.enumerateLoadedClassesSync()
,同步枚举已加载的类。
function main() {
Java.perform(() => {
var classNames = Java.enumerateLoadedClassesSync()
for (let i = 0; i < classNames.length; i++) {
console.log("class name is " + classNames[i]);
}
});
}
setImmediate(main);
5.5 枚举类加载器
5.5.1 Java.enumerateClassLoaders(callbacks)
异步枚举类加载器。
function main() {
Java.perform(() => {
Java.enumerateClassLoaders({
onMatch(loader) {
console.log(loader.getClass());
},
onComplete() {
}
});
});
}
setImmediate(main);
5.5.2 Java.enumerateClassLoadersSync()
同步枚举类加载器。
function main() {
Java.perform(() => {
var classLoaders = Java.enumerateClassLoadersSync();
for (let i = 0; i < classLoaders.length; i++) {
console.log(classLoaders[i].getClass());
}
});
}
setImmediate(main);
5.6 Java.enumerateMethods(query)
枚举满足 query
规则的函数。query
格式为 class!method
,可以通过 /
添加参数,比如 class!method/isu
。
- i,忽略大小写
- s,包含方法签名
- u,只匹配用户定义类,忽略系统类
function main() {
Java.perform(() => {
var methods = Java.enumerateMethods("*!get*/isu");
console.log(JSON.stringify(methods, null, 2));
});
}
setImmediate(main);
5.7 Java.use(className)
通过类的完全限定名获取包装器,可以通过调用 $new
来实例化对象。
function main() {
Java.perform(() => {
var JString = Java.use('java.lang.String');
var str = JString.$new("Hello, Frida!");
});
}
setImmediate(main);
5.8 Java.choose(className, callbacks)
在堆内存中找类的实例。
function main() {
Java.perform(() => {
Java.choose("android.app.ActivityThread", {
onMatch: function (instance) {
console.log(instance.currentApplication());
},
onComplete() {
}
});
});
}
setImmediate(main);
5.9 Java.cast(handle, kclass)
进行类型转换,将指定数据强制转换成所需类型。
function main() {
Java.perform(() => {
var JObject = Java.use("java.lang.Object");
var JString = Java.use("java.lang.String");
var str = JString.$new("Hello, Frida!");
var objStr = Java.cast(str, JObject);
});
}
setImmediate(main);
5.10 Java.array(type, elements)
创建数组。
function main() {
Java.perform(() => {
var JString = Java.use("java.lang.String");
var JStringArray = Java.array("java.lang.String", [JString.$new("Hello"), JString.$new("Frida")]);
for (let i = 0; i < JStringArray.length; i++) {
console.log(JStringArray[i]);
}
});
}
setImmediate(main);
5.11 Java.registerClass(spec)
动态注册一个 Java
类。
function main() {
Java.perform(() => {
Java.registerClass({
name: "com.smile.gifmaker.DynamicClass",
fields: {
str: "java.lang.String"
},
methods: {
getStr: {
returnType: 'java.lang.String',
implementation() {
return str;
}
},
setStr: {
returnType: 'void',
argumentTypes: ['java.lang.String'],
implementation(text) {
str = text;
}
}
}
})
var instance = Java.use("com.smile.gifmaker.DynamicClass").$new()
instance.setStr("Hello, Frida!");
console.log(instance.getStr());
}
}
setImmediate(main);
5.12 Java.openClassFile(filePath)
打开 dex
文件。
function main() {
Java.perform(() => {
var dexFile = Java.openClassFile('/data/data/com.ppdai.frida/classes.dex');
dexFile.load();
var classNames = dexFile.getClassNames();
for (let i = 0; i < classNames.length; i++) {
console.log(classNames[i]);
}
});
}
setImmediate(main);
5.13 获取 JNIEnv
5.13.1 Java.vm.getEnv()
获取 JNIEnv
对象,若当前线程未附加到 VM
,则抛异常。
function main() {
Java.perform(() => {
var JNIEnv = Java.vm.getEnv();
});
}
setImmediate(main);
5.13.2 Java.vm.tryGetEnv()
尝试获取 JNIEnv
对象,若当前线程未附加到 VM
,则返回 null
。
function main() {
Java.perform(() => {
var JNIEnv = Java.vm.tryGetEnv();
});
}
setImmediate(main);