radare2/shlr/www/old/index.html
pancake 1c93e8a727 Better webui, fix segfault in ag, add agj for json graphs
More work on the webui
New 'agj' command to get function graphs in json
Fix segfault in 'ag' command
'agv' now launches the internal http server
Initial refactoring for RAnalHint integration into RCore
Add basic mime-type support in the http server
Enhace the graph view style
2013-01-24 03:48:24 +01:00

596 lines
17 KiB
HTML

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>r2wUI</title>
<!--
<meta content="yes" name="apple-mobile-web-app-capable" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
-->
<link rel=Stylesheet href="style.css" type="text/css" />
<meta name="viewport" content="width=340px, initial-scale=1" />
<script src="script.js"></script>
<script>
function Ajax (method, uri, body, fn) {
var x = new XMLHttpRequest ();
x.open (method, uri, false);
x.setRequestHeader ('Accept', 'text/plain');
x.onreadystatechange = function (y) {
if (x.status == 200) {
if (fn) fn (x.responseText);
} else alert ("ajax "+x.status)
}
x.send (body);
}
function cmd(c, cb) {
Ajax ('GET', "/cmd/"+c, '', function (x) {
if (cb) cb (x);
else {
x = filter_asm (x);
document.getElementById ('output').innerHTML = x;
}
});
}
function hi(reg) {
css ('a.rcx', 'background-color', 'yellow');
}
function about() { cmd ("?V", function (version) { alert ("r2w v"+version); }); }
function panel_functions_load() {
Ajax ('GET', "/cmd/afl", '', function (x) {
var arr = x.split ("\n");
x = ''
for (var i in arr) {
var line = arr[i].replace (/\s+/g,' ').split (' ');
var addr = line[0];
var name = line[3];
if (!addr) continue;
x += "<a onclick=\"cmd('pdr@"+addr+"')\">"+addr+"</a> "+name+"\n";
}
popup_show ("Functions", x);
document.getElementById('output').innerHTML = x;
});
}
var debug_mode = false;
function runcmd(x) {
popup_hide ();
cmd (x, function() { cmd (display)});
}
function setmode (x) {
popup_hide();
display = x;
if (backward) display = "pd";
switch (x) {
case "pd": x = "b 128;"+x; break;
case "px": x = "b 512;"+x; break;
}
if (debug_mode && x=='pd')
x = ".dr*;dr=;"+x;
display = x
cmd (x);
window.scrollTo (0,0);
}
function runprompt (t, c) {
popup_hide ();
var msg = prompt (t);
if (msg) cmd ('"'+c+msg+'"', function (x) {cmd (display);});
}
function toggle(x) {
popup_hide();
display = "pd";
cmd ("e "+x, function (y) {
var b = y.indexOf ("true")!=-1? "false": "true";
cmd ("e "+x+"=" + b, function (z) { cmd ("pd"); });
});
}
var nl = "<br />";
var nl2 = "<br /><br />";
function show_popup_about () {
var txt =
"<a href='/enyo/'>Try new UI</a> (<a href='/enyo/two'>two panels</a>)<br />"+
"<a href='/d3/'>Try call graph d3</a><br />"+
"<table class='popup_content'><tr><td valign=top>"+
"Display"+
"<hr size=1/>"+
"<a href=\"javascript:setmode('pd')\" />pd</a>"+
"&nbsp;"+
"<a href=\"javascript:setmode('pdf')\" />pdf</a>"+
"&nbsp;"+
"<a href=\"javascript:setmode('px')\" />px</a>"+
"&nbsp;"+
"<a href=\"javascript:setmode('pxw')\" />pxw</a>"+
"&nbsp;"+
"<a href=\"javascript:setmode('afi $$;pdf');\">afi</a>"+
"<br /><br />"+
"Listings"+
"<hr size=1/>"+
"<a href=\"javascript:setmode('i',1)\" />file info</a><br />"+
"<a href=\"javascript:setmode('isq',1)\" />symbols</a><br />"+
"<a href=\"javascript:setmode('iiq',1)\" />imports</a><br />"+
"<a href=\"javascript:setmode('afl',1)\" />functions</a><br />"+
"<a href=\"javascript:setmode('izq',1)\" />strings</a><br />"+
"<br />"+
"Flags"+
"<hr size=1/>"+
"<a href=\"javascript:setmode('fs',1)\" />flagspaces</a><br />"+
"<a href=\"javascript:setmode('f',1)\" />flags</a><br />"+
"<a href=\"javascript:runprompt('Flag','f ')\" />set flag</a><br />"+
"<a href=\"javascript:runprompt('Flag','f-')\" />unset flag</a><br />"+
"</td><td valign=top>"+
"Places"+
"<hr size=1/>"+
"<a href=\"javascript:popup_hide();setmode('pd');seek('entry0')\" />entry0</a>&nbsp;"+
"<a href=\"javascript:popup_hide();setmode('pd');seek('main')\" />main</a><br />"+
"<br />"+
"Toggles"+
"<hr size=1/>"+
"<a href=\"javascript:toggle('asm.offset')\" />asm.offset</a><br />"+
"<a href=\"javascript:toggle('asm.lines')\" />asm.lines</a><br />"+
"<a href=\"javascript:toggle('asm.pseudo')\" />asm.pseudo</a><br />"+
"<a href=\"javascript:toggle('asm.bytes')\" />asm.bytes</a><br />"+
"<a href=\"javascript:toggle('cfg.bigendian')\" />cfg.bigendian</a><br />"+
"&nbsp;"+
"<br />"+
"Actions"+
"<hr size=1/>"+
"<a href=\"javascript:runprompt('Comment','CC ')\" />set comment</a><br />"+
"<a href=\"javascript:runprompt('Rename function','afr ')\" />rename function</a><br />"+
"<a href=\"javascript:runcmd('af')\" />analyze function</a><br />"+
"<a href=\"javascript:runcmd('aa');\">full analyze</a><br />"+
"<a href=\"javascript:runcmd('ap');\">analyze preludes</a><br />"+
"<a href=\"/graph/\">function graph</a>"+nl2+
"&nbsp;"+
"</td></tr></table>"+
"";
popup_show ("", txt);
}
function handleKeyPress(e, form) {
var key = e.keyCode || e.which;
if (key==13) {
input_activate ();
}
}
var seekindex = 0;
var seekhistory = [];
function seek_undo() {
seekindex--;
seekhistory[seekhistory.length-1] = x;
}
function seek_redo() {
seekindex++;
if (seekindex>=seekhistory.length) {
seekindex--;
return;
}
seek (seekhistory[seekindex]);
}
function seek_do(x) {
seekindex++;
seekhistory[seekhistory.length] = x;
}
function seek(x,back) {
seek_do (x)
next_curoff = prev_curoff = x;
if (display[0] != 'p')
setmode('pd');
cmd ("s "+x, function (x) {
if (display[0]=='f') display="pd";
cmd (display);
window.scrollTo (0,0);
});
}
var prev_curoff = 0;
var prev_lastoff = 0;
var next_curoff = 0;
var next_lastoff = 0;
var backward = false;
var display = "pd";
function less () {
var oldoff = document.body.scrollHeight;
backward = true;
cmd ("b", function (block) {
cmd ("s "+prev_curoff+"-"+block+";"+display, function (x) {
x = filter_asm (x);
var body = document.getElementById ('output').innerHTML;
document.getElementById ('output').innerHTML = x + body;
var newoff = document.body.scrollHeight;
var d= newoff-oldoff;
document.body.scrollTop =d;
});
});
}
function hasmore(x) {
var a = document.getElementById ("more");
var b = document.getElementById ("less");
if (x) {
a.style.visibility=b.style.visibility="visible";
} else {
a.style.visibility=b.style.visibility="hidden";
}
}
function more () {
backward = false;
cmd ("?v $l @ "+next_lastoff, function (oplen) {
if (display == "px") oplen = 16;
cmd (display+" @ "+next_lastoff+"+"+oplen, function (x) {
x = filter_asm (x);
document.getElementById('output').innerHTML += x;
});
});
}
function filter_asm(x) {
var curoff = backward? prev_curoff: next_curoff;;
var lastoff = backward? prev_lastoff: next_lastoff;;
var lines = x.split (/\n/g);
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) {
lastoff = a[0].replace (/:/g, "");
break;
}
}
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";
}
x = z;
} 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];
if (!space) continue;
z += row[0]+ " "+mark+" <a href=\"javascript:runcmd('fs "+
space+"')\">"+space+"</a>\n";
}
x = z;
} else {
}
} else
if (display[0] == "i") {
hasmore (false);
if (display[1]) {
var z = "";
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++) {
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];
}
z += addr+ " "+name+"\n";
}
x = z;
}
} else hasmore (true);
function haveDisasm(x) {
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:red>function:</span>");
x = x.replace (/;(\s+)/g, ";");
x = x.replace (/;(.*)/g, "// <span style='color:yellow'>$1</span>");
x = x.replace (/(bl|call)/g, "<b style='color:green'>call</b>");
x = x.replace (/(jmp|bne|beq|jnz|jae|jge|jbe|jg|je|jl|jz|jb|ja|jne)/g, "<b style='color:green'>$1</b>");
x = x.replace (/(dword|qword|word|byte|movzx|movsxd|cmovz|mov\ |lea\ )/g, "<b style='color:yellow'>$1</b>");
x = x.replace (/(hlt|leave|retn|ret)/g, "<b style='color:red'>$1</b>");
x = x.replace (/(add|sub|mul|div|shl|shr|and|not|xor|inc|dec|sar|sal)/g, "<b style='color:orange'>$1</b>");
x = x.replace (/(push|pop)/g, "<b style='color:magenta'>$1</b>");
x = x.replace (/(test|cmp)/g, "<b style='color:green'>$1</b>");
x = x.replace (/nop/g, "<b style='color:blue'>nop</b>");
x = x.replace (/(sym|fcn|imp|loc).(.*)/g, "<a href='javascript:seek(\"$1.$2\")'>$1.$2</a>");
}
x = x.replace (/0x([a-zA-Z0-9]*)/g, "<a href='javascript:seek(\"0x$1\")'>0x$1</a>");
// registers
if (backward) {
prev_curoff = curoff;
prev_lastoff = lastoff;
} else {
next_curoff = curoff;
next_lastoff = lastoff;
if (!prev_curoff)
prev_curoff = next_curoff;
}
return x;
}
function input_activate () {
var txt = document.getElementById('input').value;
//if (txt.length == 0) show_popup_commands (); else
if (txt.length == 0) show_popup_about (); else
Ajax ('GET', '/cmd/'+txt, '', function (x) {
x = filter_asm (x);
document.getElementById('output').innerHTML = x;
document.getElementById('input').value = '';
if (x=="") cmd (display);
});
}
function css(selector, property, value) {
for (var i=0; i<document.styleSheets.length; i++) {
try {
document.styleSheets[i].insertRule (
selector+ ' {'+property+':'+value+'}',
document.styleSheets[i].cssRules.length);
} catch (err) {
try {
document.styleSheets[i].addRule(
selector, property+':'+value);
} catch(err) {}
}
}
}
/* probably unnecesary */
window.onorientationchange = function() {
var header = document.getElementById ('header');
var orientation = window.orientation;
switch (orientation) {
case 0:
css ('.header', 'width', '220px');
css ('input', 'width', '190px');
css ('.console', 'width', '320px');
document.body.setAttribute ("class","portrait");
break;
case -90:
case 90:
css ('.header', 'width', '480');
css ('input', 'width', '360');
css ('.console', 'width', '470');
document.body.setAttribute("class","landscape");
break;
}
}
function popup_hide () {
var p = document.getElementById ("popup");
var b = document.getElementById ("popup_background");
p.style.visibility="hidden";
b.style.visibility="hidden";
}
function popup_show (title, body) {
var p = document.getElementById ("popup");
var t = document.getElementById ("popup_title");
var c = document.getElementById ("popup_content");
var b = document.getElementById ("popup_background");
if (title)
t.innerHTML = title;
if (body) {
var top = document.body.scrollTop+10;
var left = document.body.scrollLeft+10;
c.innerHTML = body;
p.style.visibility =
b.style.visibility = "visible";
//c.style.top = top; /* XXX doesnt works */
css ('.popup', 'top', top+"px"); //'220px');
css ('.popup', 'left', left+"px"); //'220px');
}
b.height = 100;
}
function menubar_display() {
/*
var m = document.getElementById('menubar');
var w = window.innerWidth;
if (w<800) {
m.style.top = 26;
m.style.left = 12;
}
*/
}
function toggle_editor() {
var x = document.getElementById('x');
var e = document.getElementById('editor');
var et = document.getElementById('editor_textarea');
var em = document.getElementById('editor_menu');
if (et.style.visibility == "hidden") {
e.style.width = 300;
et.style.visibility = em.style.visibility="visible";
x.innerHTML = "&gt;";
} else {
et.style.visibility = em.style.visibility="hidden";
e.style.visibility = em.style.visibility="hidden";
x.innerHTML = "&lt;";
}
}
function notepad_run() {
var t = document.getElementById ('editor_textarea').value;
cmd (t.replace (/\n/g, ';'), function (out) {
document.getElementById ('editor_textarea').value = out;
});
}
function notepad_assemble () {
var t = document.getElementById ('editor_textarea').value;
cmd ("\"pa "+t.replace (/\n/g, ';')+"\"", function (out) {
document.getElementById ('editor_textarea').value = out;
});
}
var console2_toggle_var = false;
function console2_toggle () {
var m = document.getElementById('menubar');
var c = document.getElementById('console');
var c2 = document.getElementById('console2');
var b2 = document.getElementById('console2_body');
console2_toggle_var = !console2_toggle_var;
if (console2_toggle_var) {
b2.style.visibility="visible";
m.style.visibility="visible";
c.style.left = 400;
c2.style.width = 400;
} else {
b2.style.visibility="hidden";
m.style.visibility="hidden";
c.style.left = 20;
c2.style.width = 20;
}
}
function notepad_disassemble () {
var t = document.getElementById ('editor_textarea').value;
cmd ("pi@b:"+t.replace (/\n/g, ''), function (out) {
document.getElementById ('editor_textarea').value = out;
});
}
function notepad_clear() {
document.getElementById ('editor_textarea').value = '';
}
function init() {
var input = document.getElementById ('input');
input.addEventListener ("activate", function (x) {
input_activate();
}, false);
cmd (display);
menubar_display ();
r2.config_get ("cfg.debug", function(x) {
debug_mode = true;
});
}
var r2 = {
'analyze': function () { runcmd ('af'); },
'entry': function () { runcmd ('s entry0'); },
'step': function () { runcmd ('ds;.dr*'); },
'continue': function () { runcmd ('dc;.dr*'); },
'step_over': function () { runcmd ('dso;.dr*'); },
'hexdump': function () { setmode ("px"); },
'disasm': function () { setmode ('pd'); },
'incode': function (x) { setmode ('pc'+x); },
'main': function () { runcmd ('s main'); },
'config_get': function (x,y) { cmd ('e '+x, y); },
'config_set': function (x) { runcmd ('s entry0'); }
}
</script>
</head>
<body id="body" onload="init()">
<div class=popup_background id="popup_background" style="visibility:hidden"></div>
<div id="editor" class="editor" style="visibility:hidden">
<table style="background-color:black">
<tr><td>
<div id="editor_menu">
<a title="execute selected text" href="javascript:notepad_run()">run</a>
<a title="assemble selected text" href="javascript:notepad_assemble()">asm</a>
<a title="disassemble selected text" href="javascript:notepad_disassemble()">dis</a>
<a title="clear textarea" href="javascript:notepad_clear()">clr</a>
</div>
</td></tr></table>
<textarea id="editor_textarea" class="editor_textarea" style="visibility:hidden">
</textarea>
</div>
<div id="popup" style="visibility:hidden">
<table class=popup>
<tr>
<td style="text-align:left; width:100%">
<div class=popup_title id="popup_title"></div>
</td><td style="text-align:right">
<input type="button" class="button" value="x" onclick="popup_hide()">
</td>
</tr>
<tr>
<td colspan=2 valign="top" style="light">
<div class="popup_content" id="popup_content"> </div>
</td>
</tr>
</table>
</div>
<div style="position:fixed; top:0px;left:0px;width:100%;height:28px;background-color:black;border:0px;color:black;z-index:0"> . </div>
<div>
<a href="javascript:seek_undo()">&lt;</a>
<a href="javascript:seek_redo()">&gt;</a>
</div>
<div style="position:fixed; top:0px;left:0px;background-color:black;border:0px">
<table class=header>
<tr><td style="text-align:left;vertical-align:top">
<a href="javascript:show_popup_about ()"><img border=0 src="rlogo2.png" /></a>
</td><td align="right" style="width:100%">
<input autocapitalize="off" style="width:100%" onkeypress="handleKeyPress(event)" id="input">
</td></tr>
</table>
</div>
<div id="console2" class="console2">
<table style="height:100%">
<tr><td valign="top">
&nbsp;<a href="javascript:console2_toggle()">]</a>
<br />
&nbsp;<a href="javascript:toggle_editor()">[</a>
</td><td width="100%" valign="top">
<div id="menubar" style="visibility:hidden;color:white;">
cmds:
<a href="javascript:r2.hexdump()">x</a>
<a href="javascript:r2.disasm()">pd</a>
<a href="javascript:r2.incode()">pc</a>
|
<a href="javascript:r2.entry()">entry</a>
<a href="javascript:r2.main()">main</a>
<a href="javascript:r2.analyze()">a</a>
|
<a href="javascript:r2.break()">db</a>
<a href="javascript:r2.step()">ds</a>
<a href="javascript:r2.step_over()">dso</a>
<a href="javascript:r2.continue()">dc</a>
</div>
<textarea class="editor_textarea" id="console2_body" style="visibility:hidden">
...
</textarea>
</td></tr>
</table>
</div>
<div onresize="menubar_display()" id="console" class="console" style="top:45px !important; position:absolute;z-index:-99">
<div id="less" class="scroller" onclick="less()"> &nbsp;&nbsp;^^^
&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; ^^^
&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; ^^^
</div>
<p id="output"></p>
<div id="more" class="scroller" onclick="more()"> &nbsp;&nbsp;vvv
&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; vvv
&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; vvv
</div>
<br /> <br />
</div>
</body>
</html>