运行环境
这里以winmine扫雷程序为例,加载的文件是info.js,运行环境从默认的QJS改为了V8。
JavaScript代码函数:
进程(Process)
// 进程(Process)
function showProcessInfo() {
console.log("Process.id:\t\t", Process.id);
console.log("Process.getCurrentThreadId():\t", Process.getCurrentThreadId());
console.log("Process.arch:\t\t", Process.arch);
console.log("Process.platform:\t", Process.platform);
console.log("Process.pageSize:\t", Process.pageSize);
console.log("Process.pointerSize:\t", Process.pointerSize);
console.log("Process.codeSigningPolicy:\t", Process.codeSigningPolicy);
console.log("Process.getCurrentDir():\t", Process.getCurrentDir());
console.log("Process.getHomeDir():\t", Process.getHomeDir());
console.log("Process.getTmpDir():\t", Process.getTmpDir());
let threads = Process.enumerateThreads();
for (const iterator of threads) {
console.log(JSON.stringify(iterator));
}
let modules = Process.enumerateModules();
for (const iterator of modules) {
console.log(JSON.stringify(iterator));
}
let ranges = Process.enumerateRanges("rwx");
for (const iterator of ranges) {
console.log(JSON.stringify(iterator));
}
// let mallocRanges = Process.enumerateMallocRanges();
// for (const iterator of mallocRanges) {
// console.log(JSON.stringify(iterator));
// }
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
Thread(线程)
Module(模块)
// Module(模块)
function showModuleInfo() {
let module = Process.getModuleByName("winmine.exe");
// let module = Process.getModuleByName("user32.dll");
// module = Process.getModuleByName("Kernel32.dll");
console.log("module", JSON.stringify(module, null, 4));
for (const iterator of module.enumerateImports()) {
console.log(JSON.stringify(iterator));
}
for (const iterator of module.enumerateExports()) {
console.log(JSON.stringify(iterator));
}
for (const iterator of module.enumerateSymbols()) {
console.log(JSON.stringify(iterator));
}
// enumerateRanges
for (const iterator of module.enumerateRanges("r--")) {
console.log(JSON.stringify(iterator));
}
// {"type":"function","name":"lstrlenW","address":"0x7630e0b0"}
let p = module.findExportByName("lstrlenW");
console.log(p);
let p1 = Module.load("DBGHELP.DLL");
console.log(JSON.stringify(p1));
for (const iterator of p1.enumerateExports()) {
console.log(JSON.stringify(iterator));
}
for (const iterator of p1.enumerateImports()) {
console.log(JSON.stringify(iterator));
}
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
内存
function showMemory() {
let module = Process.getModuleByName("winmine.exe");
// Memory.scan(module.base, module.size, pattern, {
Memory.scan(module.base, module.size, "04 ?? ?1 ?0", {
onMatch: (address, size) => {
console.log("onMatch", size, address, address.sub(module.base));
},
onError: (reason) => {
console.log(reason);
},
onComplete: () => {
console.log("Scan Complete!");
}
});
// let matches = Memory.scanSync(module.base, module.size, pattern);
let matches = Memory.scanSync(module.base, module.size, "04 ?? ?1 ?0");
for (const iterator of matches) {
console.log(JSON.stringify(iterator));
}
let m1 = Memory.alloc(Process.pageSize);
console.log("protect", JSON.stringify(Process.getRangeByAddress(m1)));
Memory.protect(m1, Process.pageSize, "r-x");
console.log("protect", JSON.stringify(Process.getRangeByAddress(m1)));
let lpText = Memory.allocUtf16String("This is a string!");
let lpCaption = Memory.allocUtf16String("Caption");
// WinApi.MessageBox(p, lpText, lpCaption, 0x00000001);
let m2 = Memory.alloc(Process.pageSize);
console.log("m2", m2);
let address = Module.getExportByName("User32.dll", "MessageBoxW");
Memory.patchCode(m2, Process.pageSize, (code) => {
// console.log("code", code);
let asm = new X86Writer(code);
asm.putPushU32(0x00000001);
asm.putPushU32(lpCaption.toUInt32());
asm.putPushU32(lpText.toUInt32());
// asm.putPushU32(p.toUInt32());
asm.putPushU32(0);
asm.putCallAddress(address);
asm.putRet();
asm.flush();
});
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
拦截器
拦截器Interceptor用于在运行时拦截和修改函数调用, 一个入口函数onEnter,一个出口函数onLeave。通过Frida Interceptor,你可以监视并修改应用程序中特定函数的行为,比如修改函数的参数、返回值等。
// 拦截器
function showInterceptorInfo() {
let address = Module.getExportByName("User32.dll", "DispatchMessageW");
Interceptor.attach(address, {
onEnter(args) {
console.log(JSON.stringify(this.context));
console.log(args[0]);
console.log(args[1]);
console.log(args[2]);
console.log(args[3]);
console.log(args[4]);
console.log(args[5]);
let msg = args[0];
console.log("hwnd", msg.readPointer());
console.log("message", msg.add(4).readPointer());
console.log("wParam", msg.add(8).readPointer());
console.log("lParam", msg.add(12).readPointer());
console.log("pt", msg.add(20).readPointer());
console.log("lPrivate", msg.add(24).readPointer());
}
});
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
function injectMessage(){
// 获取MessageBoxA地址
const funcAddr = Module.findExportByName('user32.dll', 'MessageBoxW')
// hook MessageBoxA
Interceptor.attach(funcAddr, {
// 进入函数前打印第一个参数(从0开始计算,第0个参数为句柄)
onEnter(args) {
send("HOOK MessageBoxA args[1] = " + args[1].readUtf16String())
send("HOOK MessageBoxA args[2] = " + args[2].readUtf16String())
console.log("end");
}
});
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
汇编代码
// 显示汇编代码
function showAsm(start, length) {
for (let index = 0; index < length; index++) {
let inst = Instruction.parse(start);
// console.log(JSON.stringify(inst));
let byteArray = start.readByteArray(inst.size);
let byteCode = Array.prototype.slice.call(new Uint8Array(byteArray));
let mCode = byteCode.map(x => x.toString(16).padStart(2, "0")).join(" ").toUpperCase();
console.log(inst.address.toString().toUpperCase().replace("0X", "0x"), mCode.padEnd(14, " "), "\t", inst.toString().toUpperCase().replace("0X", "0x"));
start = inst.next;
if (start.readU32() == 0) break;
}
}
// 测试功能函数封装(snippets)
function testSnippets() {
let address = Module.getExportByName("User32.dll", "MessageBoxW");
console.log(address);
showAsm(address, 10);
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
相关链接
https://frida.re/docs/examples/javascript/ https://frida.re/docs/javascript-api/