radare/radare2-webui

View on GitHub
www/old/index.html

Summary

Maintainability
Test Coverage
<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>