135 lines
3.4 KiB
JavaScript
135 lines
3.4 KiB
JavaScript
#!/usr/bin/env node
|
|
// Work in progress
|
|
// TBD how to show diff.. use git or just git style
|
|
const fs = require('fs');
|
|
const frida = require('frida');
|
|
|
|
const APP_ID = process.argv[2];
|
|
|
|
const source = `
|
|
Java.perform(function() {
|
|
|
|
var openedfile = "";
|
|
var data = {
|
|
"file": "",
|
|
"content": []
|
|
};
|
|
var isOpen = false;
|
|
var index = 0;
|
|
|
|
var fos = Java.use('java.io.FileOutputStream');
|
|
|
|
var fos_construct_2 = fos.$init.overload('java.lang.String');
|
|
var fos_construct_3 = fos.$init.overload('java.io.File');
|
|
var fos_construct_4 = fos.$init.overload('java.lang.String', 'boolean');
|
|
var fos_construct_5 = fos.$init.overload('java.io.File', 'boolean');
|
|
|
|
var fos_write_1 = fos.write.overload('[B', 'int', 'int');
|
|
|
|
var fos_close = fos.close;
|
|
|
|
function dump(data) {
|
|
console.log("Got " + data["content"].length + " bytes!");
|
|
var tmp_name = openedfile.split("/");
|
|
tmp_name = tmp_name[tmp_name.length - 1];
|
|
data["file"] = tmp_name;
|
|
send(data);
|
|
data["content"] = [];
|
|
index = 0;
|
|
}
|
|
|
|
fos_construct_2.implementation = function(file) {
|
|
var filename = file;
|
|
if (openedfile != filename) {
|
|
openedfile = filename;
|
|
console.log("File opened for write " + filename);
|
|
isOpen = true;
|
|
}
|
|
return fos_construct_2.call(this, file);
|
|
}
|
|
|
|
fos_construct_3.implementation = function(file) {
|
|
var filename = file.getAbsolutePath();
|
|
if (openedfile != filename) {
|
|
openedfile = filename;
|
|
console.log("File opened for write " + filename);
|
|
isOpen = true;
|
|
}
|
|
return fos_construct_3.call(this, file);
|
|
}
|
|
|
|
fos_construct_4.implementation = function(file, true_false) {
|
|
var filename = file;
|
|
if (openedfile != filename) {
|
|
openedfile = filename;
|
|
console.log("File opened for write " + filename);
|
|
isOpen = true;
|
|
}
|
|
return fos_construct_4.call(this, file, true_false);
|
|
}
|
|
|
|
fos_construct_5.implementation = function(file, true_false) {
|
|
var filename = file.getAbsolutePath();
|
|
if (openedfile != filename) {
|
|
openedfile = filename;
|
|
console.log("File opened for write " + filename);
|
|
isOpen = true;
|
|
}
|
|
return fos_construct_5.call(this, file, true_false);
|
|
}
|
|
|
|
fos_write_1.implementation = function(arr, offset, length) {
|
|
var i = 0;
|
|
for (i = offset; i < length; i = i + 1) {
|
|
data["content"][index] = arr[i];
|
|
index = index + 1;
|
|
}
|
|
return fos_write_1.call(this, arr, offset, length);
|
|
}
|
|
|
|
fos_close.implementation = function() {
|
|
dump(data);
|
|
return fos_close.call(this);
|
|
}
|
|
|
|
});
|
|
`;
|
|
|
|
function stop() { // cleanup, TODO add session.detach ?
|
|
if (script !== null) {
|
|
script.unload().then(() => {
|
|
script = null;
|
|
console.log('[!] Script unloaded');
|
|
}).catch(console.error);
|
|
}
|
|
}
|
|
|
|
async function Main() {
|
|
|
|
let device = await frida.getUsbDevice();
|
|
let pid = await device.spawn([APP_ID]);
|
|
let session = await device.attach(pid);
|
|
let script = await session.createScript(source);
|
|
|
|
script.message.connect(msg => {
|
|
if (msg['type'] === 'send') {
|
|
let payload = msg['payload'];
|
|
if (typeof payload === 'object') {
|
|
console.log('[D]', payload['file'], '\n\n', payload['content']);
|
|
}
|
|
} else {
|
|
console.error('[!]', msg, '\n', msg['stack']);
|
|
}
|
|
});
|
|
|
|
await script.load();
|
|
await device.resume(pid);
|
|
|
|
process.stdin.resume(); // keep process running
|
|
process.on('SIGTERM', stop);
|
|
process.on('SIGINT', stop);
|
|
console.log('...');
|
|
}
|
|
|
|
Main().catch(console.error);
|