Skip to content

Commit

Permalink
Fix #143 - Initial implementation of \iz and \izj
Browse files Browse the repository at this point in the history
  • Loading branch information
trufae committed Jul 1, 2019
1 parent cf4acba commit 2872357
Show file tree
Hide file tree
Showing 2 changed files with 129 additions and 5 deletions.
52 changes: 47 additions & 5 deletions src/agent/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const path = require('path');
const config = require('./config');
const io = require('./io');
const isObjC = require('./isobjc');
const strings = require('./strings');

let Gcwd = '/';

Expand Down Expand Up @@ -184,6 +185,8 @@ const commandHandlers = {
'icj': listClassesJson,
'ip': listProtocols,
'ipj': listProtocolsJson,
'iz': listStrings,
'izj': listStringsJson,
'dd': listFileDescriptors,
'ddj': listFileDescriptorsJson,
'dd-': closeFileDescriptors,
Expand Down Expand Up @@ -835,7 +838,7 @@ async function dumpInfoJson () {
const ActivityThread = Java.use('android.app.ActivityThread');
const app = ActivityThread.currentApplication();
if (app !== null) {
const ctx = app.getApplicationContext()
const ctx = app.getApplicationContext();
if (ctx !== null) {
res.dataDir = ctx.getDataDir().getAbsolutePath();
res.codeCacheDir = ctx.getCodeCacheDir().getAbsolutePath();
Expand Down Expand Up @@ -1523,6 +1526,45 @@ function listFileDescriptorsJson (args) {
}
}

function listStringsJson (args) {
if (!args || args.length !== 1) {
args = [ offset ];
}
const base = ptr(args[0]);
const currentRange = Process.findRangeByAddress(base);
if (currentRange) {
const options = { base: base }; // filter for urls?
const length = Math.min(currentRange.size, 1024*1024*128);
const block = 1024*1024; // 512KB
if (length !== currentRange.size) {
const curSize = currentRange.size / (1024 * 1024);
console.error('Warning: this range is too big ('+curSize+'MB), truncated to ' + length / (1024*1024) + 'MB');
}
try {
let res = [];
console.log('Reading ' + (length/(1024*1024)) + 'MB ...');
for (let i = 0; i < length; i += block) {
const addr = currentRange.base.add(i);
const bytes = addr.readCString(block);
const blockResults = strings(bytes.split('').map(_ => _.charCodeAt(0)), options);
res.push(...blockResults);
}
return res;
} catch (e) {
console.log(e.message);
}
}
throw new Error('Memory not mapped here');
}

function listStrings (args) {
if (!args || args.length !== 1) {
args = [ ptr(offset) ];
}
const base = ptr(args[0]);
return listStringsJson(args).map(({ base, text }) => padPointer(base) + ` "${text}"`).join('\n');
}

function listProtocolsJson (args) {
if (args.length === 0) {
return Object.keys(ObjC.protocols);
Expand Down Expand Up @@ -1581,9 +1623,9 @@ function listMemoryRangesHere (args) {
if (args.length !== 1) {
args = [ ptr(offset) ];
}
const addr = +args[0];
const addr = ptr(args[0]);
return listMemoryRangesJson()
.filter(({ base, size }) => (addr >= +base && addr < (+base + size)))
.filter(({ base, size }) => (addr.compare(base) >= 0 && addr.compare(base.add(size)) < 0))
.map(({ base, size, protection, file }) =>
[
padPointer(base),
Expand Down Expand Up @@ -1992,8 +2034,8 @@ function getEnv () {
const result = [];
let envp = Memory.readPointer(Module.findExportByName(null, 'environ'));
let env;
while (!envp.isNull() && !(env = Memory.readPointer(envp)).isNull()) {
result.push(Memory.readCString(env));
while (!envp.isNull() && !(env = envp.readPointer()).isNull()) {
result.push(env.readCString());
envp = envp.add(Process.pointerSize);
}
return result;
Expand Down
82 changes: 82 additions & 0 deletions src/agent/strings.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
function isPrintable (ch) {
return (ch >= 32 && ch <= 126);
}

function parseOptions (options) {
const opts = {
minLength: 15,
maxLength: 128,
filter: false,
urls: false,
base: 0
};
if (typeof options === 'object') {
for (let key of Object.keys(options)) {
opts[key] = options[key];
}
}
return opts;
}

function parseStrings (data, options) {
const opt = parseOptions(options);
const strs = [];
let str = '';
let off = 0;
let cur = 0;
data.forEach(ch => {
if (isPrintable(ch)) {
if (str === '') {
cur = off;
}
str += String.fromCharCode(ch);
} else {
if (str.length > opt.minLength && str.length < opt.maxLength) {
let valid = true;
if (opt.filter && !isValidString(str)) {
valid = false;
}
if (opt.urls && !isValidURL(str)) {
valid = false;
}
if (valid) {
strs.push({ base: opt.base.add(cur), text: str });
}
}
str = '';
}
off++;
});
return strs;
}

function isValidString (s) {
if (s.indexOf('://') !== -1) {
return false;
}
if (+s) {
return false;
}
const invalidChars = '<\\)?@)>{~}^()=/!-"*:]%\';` $';
for (let ic of invalidChars) {
if (s.indexOf(ic) !== -1) {
return false;
}
}
return true;
}

function isValidURL (s) {
if (s.indexOf('://') === -1) {
return false;
}
const invalidChars = '<\\)?)>{~}^()=!-"*]\'` $';
for (let ic of invalidChars) {
if (s.indexOf(ic) !== -1) {
return false;
}
}
return true;
}

module.exports = parseStrings;

0 comments on commit 2872357

Please sign in to comment.