Fix r2.js to be used from duktape

This commit is contained in:
pancake 2014-10-23 04:45:01 +02:00
parent e43f0622fe
commit 8ec5e4ae94
2 changed files with 210 additions and 157 deletions

View File

@ -127,11 +127,13 @@ static char *getstr(const char *src) {
*pat++ = 0;
int i, rep = atoi (src+1);
int len = strlen (pat);
char *buf = malloc (rep);
for(i=0;i<rep;i++) {
buf[i] = pat[i%len];
if (rep>0) {
char *buf = malloc (rep);
for(i=0;i<rep;i++) {
buf[i] = pat[i%len];
}
return buf;
}
return buf;
}
// slurp file
return r_file_slurp (src+1, NULL);
@ -551,8 +553,8 @@ R_API int r_run_start(RRunProfile *p) {
eprintf ("rarun2: %s: file not found\n", p->_program);
return 1;
}
// close all non-tty fds
{ int i; for (i=3; i<9999; i++) close (i); }
// XXX HACK close all non-tty fds
{ int i; for (i=3; i<10; i++) close (i); }
// TODO: use posix_spawn
exit (execv (p->_program, (char* const*)p->_args));
}

View File

@ -8,46 +8,48 @@ var next_curoff = 0;
var next_lastoff = 0;
var prev_curoff = 0;
var prev_lastoff = 0;
var r2cmd = false;
var hascmd = false;
// async helper
function asyncLoop(iterations, func, callback) {
var index = 0;
var done = false;
var loop = {
next: function() {
if (done) {
return;
}
var index = 0;
var done = false;
var loop = {
next: function() {
if (done) {
return;
}
if (index < iterations) {
index++;
func(loop);
if (index < iterations) {
index++;
func(loop);
} else {
done = true;
callback();
}
},
} else {
done = true;
callback();
}
},
iteration: function() {
return index - 1;
},
iteration: function() {
return index - 1;
},
break: function() {
done = true;
callback();
}
};
loop.next();
return loop;
break: function() {
done = true;
callback();
}
};
loop.next();
return loop;
}
if (typeof (module) !== 'undefined') {
module.exports = function(r) {
if (typeof (r) == 'function')
r2cmd = r;
else r2cmd = r.cmd;
if (typeof (r) == 'function') {
hascmd = r;
} else {
hascmd = r.cmd;
}
return r2;
}
}
@ -55,24 +57,30 @@ if (typeof (module) !== 'undefined') {
r2.plugin = function() {
console.error ("r2.plugin is not available in this environment");
}
try { if (r2plugin) r2.plugin = r2plugin } catch(e) { }
try {
if (r2plugin) {
r2.plugin = r2plugin
}
} catch ( e ) {}
r2.root = ""; // prefix path
/* helpers */
function dump(obj) {
var x = "";
for (var a in obj) x += a+"\n";
if (typeof ('alert') != 'undefined')
for (var a in obj) x += a + "\n";
if (typeof ('alert') != 'undefined') {
alert (x);
else console.log (x);
} else {
console.log (x);
}
}
r2.analOp = function (addr, cb) {
r2.cmd ("aoj 1 @ "+addr, function (txt) {
r2.analOp = function(addr, cb) {
r2.cmd ("aoj 1 @ " + addr, function(txt) {
try {
cb(JSON.parse (txt)[0]);
} catch (e) {
} catch ( e ) {
console.error (e)
cb (txt);
}
@ -82,114 +90,125 @@ r2.analOp = function (addr, cb) {
function objtostr(obj) {
var str = "";
for (var a in obj)
str += a+": "+obj[a] + ",\n";
str += a + ": " + obj[a] + ",\n";
return str;
}
function Ajax (method, uri, body, fn) {
function Ajax(method, uri, body, fn) {
if (typeof (XMLHttpRequest) == "undefined")
return false;
var x = new XMLHttpRequest ();
if (!x)
return false;
x.open (method, uri, false);
x.setRequestHeader ('Accept', 'text/plain');
x.setRequestHeader ('Accept', 'text/html');
x.setRequestHeader ("Content-Type", "application/x-ww-form-urlencoded; charset=UTF-8");
x.onreadystatechange = function (y) {
x.onreadystatechange = function(y) {
if (x.status == 200) {
if (fn) fn (x.responseText);
} else console.error ("ajax "+x.status)
if (fn) {
fn (x.responseText);
}
} else {
console.error ("ajax " + x.status)
}
}
x.send (body);
return true;
}
r2.assemble = function (offset, opcode, fn) {
var off = offset? "@"+offset:'';
r2.cmd ('"pa '+opcode+'"'+off, fn);
r2.assemble = function(offset, opcode, fn) {
var off = offset ? "@" + offset : '';
r2.cmd ('"pa ' + opcode + '"' + off, fn);
}
r2.disassemble = function (offset, bytes, fn) {
var off = offset? "@"+offset:'';
var str = 'pi @b:'+bytes+off;
r2.disassemble = function(offset, bytes, fn) {
var off = offset ? "@" + offset : '';
var str = 'pi @b:' + bytes + off;
r2.cmd (str, fn);
}
r2.get_hexdump = function (offset, length, cb) {
r2.cmd ("px "+length+"@"+offset, cb);
r2.get_hexdump = function(offset, length, cb) {
r2.cmd ("px " + length + "@" + offset, cb);
}
r2.get_disasm = function (offset, length, cb) {
r2.get_disasm = function(offset, length, cb) {
// TODO: honor offset and length
r2.cmd ("pD "+length+"@"+offset, cb);
r2.cmd ("pD " + length + "@" + offset, cb);
}
r2.Config = function (k, v, fn) {
r2.Config = function(k, v, fn) {
if (typeof v == 'function' || !v) { // get
r2.cmd ("e "+k, fn || v);
r2.cmd ("e " + k, fn || v);
} else { // set
r2.cmd ("e "+k+"="+v, fn);
r2.cmd ("e " + k + "=" + v, fn);
}
return r2;
}
r2.set_flag_space = function (ns, fn) {
r2.cmd ("fs "+ns, fn);
r2.set_flag_space = function(ns, fn) {
r2.cmd ("fs " + ns, fn);
}
r2.get_flags = function (fn) {
r2.cmd ("fj", function (x) {
fn (x? JSON.parse (x): []);
r2.get_flags = function(fn) {
r2.cmd ("fj", function(x) {
fn (x ? JSON.parse (x) : []);
});
}
r2.get_opcodes = function (off, n, cb) {
r2.cmd ("pdj @"+off+"!"+n, function (json) {
r2.get_opcodes = function(off, n, cb) {
r2.cmd ("pdj @" + off + "!" + n, function(json) {
cb (JSON.parse (json));
});
}
r2.get_bytes = function (off, n, cb) {
r2.cmd ("pcj @"+off+"!"+n, function (json) {
r2.get_bytes = function(off, n, cb) {
r2.cmd ("pcj @" + off + "!" + n, function(json) {
cb (JSON.parse (json));
});
}
r2.get_info = function (cb) {
r2.cmd ("ij", function (json) {
r2.get_info = function(cb) {
r2.cmd ("ij", function(json) {
cb (JSON.parse (json));
});
}
r2.bin_relocs = function (cb) {
r2.cmd ("irj", function (json) {
r2.bin_relocs = function(cb) {
r2.cmd ("irj", function(json) {
cb (JSON.parse (json));
});
}
r2.bin_imports = function (cb) {
r2.cmd ("iij", function (json) {
r2.bin_imports = function(cb) {
r2.cmd ("iij", function(json) {
cb (JSON.parse (json));
});
}
r2.bin_symbols = function (cb) {
r2.cmd ("isj", function (json) {
r2.bin_symbols = function(cb) {
r2.cmd ("isj", function(json) {
cb (JSON.parse (json));
});
}
r2.bin_sections = function (cb) {
r2.cmd ("iSj", function (json) {
r2.bin_sections = function(cb) {
r2.cmd ("iSj", function(json) {
cb (JSON.parse (json));
});
}
r2.cmds = function (cmds, cb) {
if (cmds.length==0) return;
r2.cmds = function(cmds, cb) {
if (cmds.length == 0) return;
var cmd = cmds[0];
cmds = cmds.splice (1);
function lala () {
function lala() {
if (cmd == undefined || cmds.length == 0) {
return;
}
cmd = cmds[0];
cmds = cmds.splice (1);
r2.cmd (cmd, lala);
if (cb) cb ();
if (cb) {
cb ();
}
return;
}
r2.cmd (cmd, lala);
@ -197,119 +216,145 @@ r2.cmds = function (cmds, cb) {
function _internal_cmd(c, cb) {
if (r2cmd) {
hascmd = r2cmd;
}
if (hascmd) {
// TODO: use setTimeout for async?
return r2cmd (c, cb);
if (typeof (r2plugin) != "undefined") {
// duktape
cb (r2cmd(c));
} else {
// node
return hascmd (c, cb);
}
} else {
Ajax ('GET', r2.root+"/cmd/"+encodeURI (c), '',
function (x) { if (cb) cb (x); });
Ajax ('GET', r2.root + "/cmd/" + encodeURI (c), '', function(x) {
if (cb) {
cb (x);
}
});
}
}
r2.cmd = function (c, cb) {
r2.cmd = function(c, cb) {
if (Array.isArray (c)) {
var res = [];
var idx = 0;
asyncLoop (c.length, function(loop) {
_internal_cmd (c[idx], function(result) {
idx = loop.iteration();
res[idx] = result.replace(/\n$/,"");
res[idx] = result.replace(/\n$/, "");
idx++;
loop.next ();
});
}, function() {
// all iterations done
cb (res);
});
// all iterations done
cb (res);
});
} else {
_internal_cmd (c, cb);
}
}
r2.cmdj = function (c, cb) {
r2.cmdj = function(c, cb) {
r2.cmd (c, function(x) {
try {
cb (JSON.parse(x));
} catch(e) {
cb (null);
}
});
}
r2.alive = function (cb) {
r2.cmd ("b", function (o) {
var ret = false;
if (o && o.length () > 0)
ret = true;
if (cb) cb (o);
try {
cb (JSON.parse(x));
} catch ( e ) {
cb (null);
}
});
}
r2.getTextLogger = function (obj) {
if (typeof (obj) != "object")
r2.alive = function(cb) {
r2.cmd ("b", function(o) {
var ret = false;
if (o && o.length () > 0) {
ret = true;
}
if (cb) {
cb (o);
}
});
}
r2.getTextLogger = function(obj) {
if (typeof (obj) != "object") {
obj = {};
}
obj.last = 0;
obj.events = {};
obj.interval = null;
r2.cmd ("Tl", function (x) {
r2.cmd ("Tl", function(x) {
obj.last = +x;
});
obj.load = function (cb) {
r2.cmd ("Tj "+(obj.last+1), function (ret) {
if (cb) cb (JSON.parse (ret));
obj.load = function(cb) {
r2.cmd ("Tj " + (obj.last + 1), function(ret) {
if (cb) {
cb (JSON.parse (ret));
}
});
}
obj.clear = function (cb) {
obj.clear = function(cb) {
// XXX: fix l-N
r2.cmd ("T-", cb); //+obj.last, cb);
}
obj.send = function (msg, cb) {
r2.cmd ("T "+msg, cb);
obj.send = function(msg, cb) {
r2.cmd ("T " + msg, cb);
}
obj.refresh = function (cb) {
obj.load (function (ret) {
obj.refresh = function(cb) {
obj.load (function(ret) {
//obj.last = 0;
for (var i = 0; i< ret.length; i++) {
for (var i = 0; i < ret.length; i++) {
var message = ret[i];
obj.events["message"] ({
"id": message[0],
"text": message[1]
});
if (message[0] > obj.last)
if (message[0] > obj.last) {
obj.last = message[0];
}
}
if (cb) {
cb ();
}
if (cb) cb ();
});
}
obj.autorefresh = function (n) {
obj.autorefresh = function(n) {
if (!n) {
if (obj.interval)
if (obj.interval) {
obj.interval.stop ();
}
return;
}
function to() {
obj.refresh (function () {
obj.refresh (function() {
//obj.clear ();
});
setTimeout (to, n*1000);
setTimeout (to, n * 1000);
return true;
}
obj.interval = setTimeout (to, n*1000);
obj.interval = setTimeout (to, n * 1000);
}
obj.on = function (ev, cb) {
obj.on = function(ev, cb) {
obj.events[ev] = cb;
return obj;
}
return obj;
}
r2.filter_asm = function (x, display) {
var curoff = backward? prev_curoff: next_curoff;;
var lastoff = backward? prev_lastoff: next_lastoff;;
r2.filter_asm = function(x, display) {
var curoff = backward ? prev_curoff : next_curoff;
;
var lastoff = backward ? prev_lastoff : next_lastoff;
;
var lines = x.split (/\n/g);
r2.cmd ("s", function (x) { curoff = x; });
for (var i=lines.length-1;i>0;i--) {
r2.cmd ("s", function(x) {
curoff = x;
});
for (var i = lines.length - 1; i > 0; i--) {
var a = lines[i].match (/0x([a-fA-F0-9]+)/);
if (a && a.length>0) {
if (a && a.length > 0) {
lastoff = a[0].replace (/:/g, "");
break;
}
@ -317,55 +362,59 @@ r2.filter_asm = function (x, display) {
if (display == "afl") {
//hasmore (false);
var z = "";
for (var i=0;i<lines.length;i++) {
var row = lines[i].replace (/\ +/g," ").split (/ /g);
z += row[0]+ " "+row[3]+"\n";
for (var i = 0; i < lines.length; i++) {
var row = lines[i].replace (/\ +/g, " ").split (/ /g);
z += row[0] + " " + row[3] + "\n";
}
x = z;
} else
if (display[0] == 'f') {
} else if (display[0] == 'f') {
//hasmore (false);
if (display[1] == 's') {
var z = "";
for (var i=0; i<lines.length; i++) {
var row = lines[i].replace (/\ +/g," ").split (/ /g);
var mark = row[1]=='*'? '*': ' ';
var space = row[2]? row[2]: row[1];
for (var i = 0; i < lines.length; i++) {
var row = lines[i].replace (/\ +/g, " ").split (/ /g);
var mark = row[1] == '*' ? '*' : ' ';
var space = row[2] ? row[2] : row[1];
if (!space) continue;
z += row[0]+ " "+mark+" <a href=\"javascript:runcmd('fs "+
space+"')\">"+space+"</a>\n";
z += row[0] + " " + mark + " <a href=\"javascript:runcmd('fs " +
space + "')\">" + space + "</a>\n";
}
x = z;
} else {
}
} else
if (display[0] == "i") {
} else if (display[0] == "i") {
//hasmore (false);
if (display[1]) {
var z = "";
for (var i=0;i<lines.length;i++) {
for (var i = 0; i < lines.length; i++) {
var elems = lines[i].split (/ /g);
var name = "";
var addr = "";
for (var j=0;j<elems.length;j++) {
for (var j = 0; j < elems.length; j++) {
var kv = elems[j].split (/=/);
if (kv[0] == "addr") addr = kv[1];
if (kv[0] == "name") name = kv[1];
if (kv[0] == "string") name = kv[1];
if (kv[0] == "addr") {
addr = kv[1];
}
if (kv[0] == "name") {
name = kv[1];
}
if (kv[0] == "string") {
name = kv[1];
}
}
z += addr+ " "+name+"\n";
z += addr + " " + name + "\n";
}
x = z;
}
} //else hasmore (true);
function haveDisasm(x) {
if (x[0]=='p' && x[1]=='d') return true;
if (x[0] == 'p' && x[1] == 'd') return true;
if (x.indexOf (";pd") != -1) return true;
return false;
}
if (haveDisasm (display)) {
x = x.replace (/function:/g,"<span style=color:green>function:</span>");
x = x.replace (/function:/g, "<span style=color:green>function:</span>");
x = x.replace (/;(\s+)/g, ";");
x = x.replace (/;(.*)/g, "// <span style='color:#209020'>$1</span>");
x = x.replace (/(bl|goto|call)/g, "<b style='color:green'>call</b>");
@ -380,15 +429,17 @@ r2.filter_asm = function (x, display) {
x = x.replace (/(sym|fcn|str|imp|loc).([^:<(\\\/ \|)\->]+)/g, "<a href='javascript:r2ui.seek(\"$1.$2\")'>$1.$2</a>");
}
x = x.replace (/0x([a-zA-Z0-9]+)/g, "<a href='javascript:r2ui.seek(\"0x$1\")'>0x$1</a>");
// registers
// registers
if (backward) {
prev_curoff = curoff;
prev_lastoff = lastoff;
} else {
next_curoff = curoff;
next_lastoff = lastoff;
if (!prev_curoff)
if (!prev_curoff) {
prev_curoff = next_curoff;
}
}
return x;
}