mirror of https://github.com/geohot/qira
add which and address highlighting regex
This commit is contained in:
parent
400ceda6cf
commit
f7258901e3
|
@ -25,7 +25,7 @@ if __name__ == '__main__':
|
|||
|
||||
is_qira_running = 1
|
||||
try:
|
||||
socket.create_connection(('127.0.0.1', qira_webserver.QIRA_PORT))
|
||||
socket.create_connection(('127.0.0.1', qira_webserver.QIRA_WEB_PORT))
|
||||
if args.server:
|
||||
raise Exception("can't run as server if QIRA is already running")
|
||||
except:
|
||||
|
|
|
@ -262,7 +262,7 @@ def get_hacked_depth_map(flow):
|
|||
for (address, length, clnum, ins) in flow:
|
||||
if address in return_stack:
|
||||
return_stack = return_stack[0:return_stack.index(address)]
|
||||
if ins[0:5] == "call ":
|
||||
if ins[0:5] == "call " or ins[0:6] == "callq ":
|
||||
return_stack.append(address+length)
|
||||
#print return_stack
|
||||
ret.append(len(return_stack))
|
||||
|
@ -289,6 +289,9 @@ def analyze(trace, program):
|
|||
dmap = get_hacked_depth_map(flow)
|
||||
maxd = max(dmap)
|
||||
|
||||
if maxd == 0:
|
||||
return None
|
||||
|
||||
#print dmap
|
||||
#print maxclnum, maxd
|
||||
|
||||
|
|
|
@ -12,6 +12,19 @@ ARMREGS = (['R0','R1','R2','R3','R4','R5','R6','R7','R8','R9','R10','R11','R12',
|
|||
X86REGS = (['EAX', 'ECX', 'EDX', 'EBX', 'ESP', 'EBP', 'ESI', 'EDI', 'EIP'], 4, False)
|
||||
X64REGS = (['RAX', 'RCX', 'RDX', 'RBX', 'RSP', 'RBP', 'RSI', 'RDI', 'RIP'], 8, False)
|
||||
|
||||
|
||||
def which(prog):
|
||||
import subprocess
|
||||
cmd = ["which", prog]
|
||||
p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
|
||||
res = p.stdout.readlines()
|
||||
if len(res) == 0:
|
||||
# fallback mode, look for the binary straight up
|
||||
if os.path.isfile(prog):
|
||||
return os.path.realpath(prog)
|
||||
raise Exception("binary not found")
|
||||
return os.path.realpath(res[0].strip())
|
||||
|
||||
# things that don't cross the fork
|
||||
class Program:
|
||||
def __init__(self, prog, args):
|
||||
|
@ -21,13 +34,17 @@ class Program:
|
|||
except:
|
||||
pass
|
||||
|
||||
# call which to match the behavior of strace and gdb
|
||||
self.program = which(prog)
|
||||
self.args = args
|
||||
|
||||
# bring this back
|
||||
if prog != "/tmp/qira_binary":
|
||||
if self.program != "/tmp/qira_binary":
|
||||
try:
|
||||
os.unlink("/tmp/qira_binary")
|
||||
except:
|
||||
pass
|
||||
os.symlink(os.path.realpath(prog), "/tmp/qira_binary")
|
||||
os.symlink(os.path.realpath(self.program), "/tmp/qira_binary")
|
||||
|
||||
# defaultargs for qira binary
|
||||
self.defaultargs = ["-strace", "-D", "/dev/null", "-d", "in_asm", "-singlestep"]
|
||||
|
@ -35,12 +52,8 @@ class Program:
|
|||
# pmaps is global, but updated by the traces
|
||||
self.instructions = {}
|
||||
|
||||
self.program = prog
|
||||
self.args = args
|
||||
|
||||
# get file type
|
||||
#self.fb = qira_binary.file_binary(prog)
|
||||
self.fb = struct.unpack("H", open(prog).read(0x18)[0x12:0x14])[0] # e_machine
|
||||
self.fb = struct.unpack("H", open(self.program).read(0x18)[0x12:0x14])[0] # e_machine
|
||||
qemu_dir = os.path.dirname(os.path.realpath(__file__))+"/../qemu/"
|
||||
|
||||
def use_lib(arch):
|
||||
|
@ -50,7 +63,7 @@ class Program:
|
|||
print "**** set QEMU_LD_PREFIX to",os.environ['QEMU_LD_PREFIX']
|
||||
|
||||
if self.fb == 0x28:
|
||||
progdat = open(prog).read(0x800)
|
||||
progdat = open(self.program).read(0x800)
|
||||
if '/lib/ld-linux.so.3' in progdat:
|
||||
use_lib('armel')
|
||||
elif '/lib/ld-linux-armhf.so.3' in progdat:
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
qira-0.5.tar.xz
|
|
@ -0,0 +1,10 @@
|
|||
#include <stdio.h>
|
||||
|
||||
int main() {
|
||||
char *a = malloc(0x100);
|
||||
char *b = malloc(0x100);
|
||||
memset(a, 0, 0x400);
|
||||
//read(0, a, 0x100);
|
||||
free(b);
|
||||
}
|
||||
|
|
@ -15,6 +15,26 @@ function get_data_type(v) {
|
|||
else return "data"+a;
|
||||
}
|
||||
|
||||
function highlight_addresses(a) {
|
||||
// no XSS :)
|
||||
var d = UI.toHTML(a);
|
||||
var re = /0x[0123456789abcdef]+/g;
|
||||
var m = d.match(re);
|
||||
if (m !== null) {
|
||||
m = m.filter(function (v,i,a) { return a.indexOf (v) == i });
|
||||
m.map(function(a) {
|
||||
var cl = get_data_type(a);
|
||||
if (cl == "") return;
|
||||
d = d.replace(a, "<span class='h"+cl+"'>"+a+"</span>");
|
||||
});
|
||||
}
|
||||
return new Handlebars.SafeString(d);
|
||||
}
|
||||
|
||||
function fhex(a) {
|
||||
return parseInt(a, 16);
|
||||
}
|
||||
|
||||
function hex(a) {
|
||||
if (a == undefined) {
|
||||
return "";
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
stream = io.connect(STREAM_URL);
|
||||
|
||||
|
||||
Template.controls.clnum = function() {
|
||||
return Session.get("clnum");
|
||||
};
|
||||
|
@ -25,10 +24,10 @@ Template.controls.events = {
|
|||
Session.set("forknum", parseInt(e.target.value));
|
||||
},
|
||||
'change #control_iaddr': function(e) {
|
||||
Session.set("iaddr", parseInt(e.target.value, 16));
|
||||
Session.set("iaddr", fhex(e.target.value));
|
||||
},
|
||||
'change #control_daddr': function(e) {
|
||||
update_dview(parseInt(e.target.value, 16));
|
||||
update_dview(fhex(e.target.value));
|
||||
},
|
||||
'click #control_fork': function(e) {
|
||||
var clnum = Session.get("clnum");
|
||||
|
@ -56,6 +55,19 @@ window.onkeydown = function(e) {
|
|||
}
|
||||
};
|
||||
|
||||
$(document).ready(function() {
|
||||
$('body').on('click', '.hdatamemory', function(e) {
|
||||
update_dview(fhex(e.target.innerHTML));
|
||||
});
|
||||
$('body').on('click', '.hdatainstruction', function(e) {
|
||||
update_dview(fhex(e.target.innerHTML));
|
||||
});
|
||||
$('body').on('contextmenu', '.hdatainstruction', function(e) {
|
||||
Session.set("iaddr", fhex(e.target.innerHTML));
|
||||
return false;
|
||||
});
|
||||
});
|
||||
|
||||
// don't pull the window
|
||||
//window.onmousewheel = function() { return false; }
|
||||
|
||||
|
|
|
@ -42,6 +42,8 @@ Template.idump.events({
|
|||
}
|
||||
});
|
||||
|
||||
Template.idump.instruction = function() { return highlight_addresses(this.instruction); }
|
||||
|
||||
// ** should move these to idump.js **
|
||||
|
||||
stream.on('instructions', function(msg) {
|
||||
|
|
|
@ -131,6 +131,9 @@ stream.on('registers', function(msg) {
|
|||
var tsize = msg[0]['size'];
|
||||
if (tsize > 0) PTRSIZE = tsize;
|
||||
UI.insert(UI.renderWithData(Template.regviewer, {regs: msg}), $('#regviewer')[0]);
|
||||
|
||||
// hack to display the change editor on x86 only
|
||||
if (msg[0]['name']=="EAX") $('#changeeditor').show();
|
||||
});
|
||||
|
||||
// events, add the editing here
|
||||
|
|
|
@ -24,3 +24,5 @@ Template.strace.events({
|
|||
},
|
||||
});
|
||||
|
||||
Template.strace.sc = function() { return highlight_addresses(this.sc); }
|
||||
|
||||
|
|
|
@ -128,6 +128,7 @@ body {
|
|||
height: 180px;
|
||||
width: 200px;
|
||||
padding: 10px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.changeedit {
|
||||
|
@ -184,6 +185,14 @@ body {
|
|||
color: #888800;
|
||||
}
|
||||
|
||||
.hdatainstruction {
|
||||
color: #CC0000;
|
||||
}
|
||||
|
||||
.hdatamemory {
|
||||
color: #888800;
|
||||
}
|
||||
|
||||
.reg {
|
||||
display: inline-block;
|
||||
width: 200px;
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
<script type="text/javascript" src="/client/regmem.js"></script>
|
||||
<script type="text/javascript" src="/client/vtimeline.js"></script>
|
||||
<script type="text/javascript" src="/client/strace.js"></script>
|
||||
<script type="text/javascript" src="/client/changeeditor.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
if (typeof Package === 'undefined' ||
|
||||
|
|
|
@ -5,10 +5,13 @@ UI.body.contentParts.push(UI.Component.extend({render: (function() {
|
|||
id: "onlypanel"
|
||||
}, "\n", HTML.DIV({
|
||||
id: "controls"
|
||||
}, "\n", Spacebars.include(self.lookupTemplate("controls")), "\n"), "\n", HTML.DIV({
|
||||
}, "\n", Spacebars.include(self.lookupTemplate("controls")), "\n"), "\n\n", HTML.DIV("\n\n", HTML.DIV({
|
||||
"class": "panelthing",
|
||||
id: "changeeditor"
|
||||
}, "\n", Spacebars.include(self.lookupTemplate("changeeditor")), "\n"), "\n\n", HTML.DIV({
|
||||
"class": "panelthing",
|
||||
id: "idump"
|
||||
}, "\n", Spacebars.include(self.lookupTemplate("idump")), "\n"), HTML.Raw('\n<div class="panelthing" id="regviewer">\n</div>\n'), HTML.DIV({
|
||||
}, "\n", Spacebars.include(self.lookupTemplate("idump")), "\n"), "\n"), HTML.Raw('\n\n<div class="panelthing" id="regviewer">\n</div>\n'), HTML.DIV({
|
||||
"class": "panelthing",
|
||||
id: "datachanges"
|
||||
}, "\n", Spacebars.include(self.lookupTemplate("datachanges")), "\n"), "\n", HTML.DIV({
|
||||
|
@ -76,6 +79,33 @@ Template.__define__("strace", (function() {
|
|||
}));
|
||||
}));
|
||||
|
||||
Template.__define__("changeeditor", (function() {
|
||||
var self = this;
|
||||
var template = this;
|
||||
return [ HTML.Raw('<input id="changeadd" type="button" value="Add Change">\n<input id="changeclear" type="button" value="Clear">\n'), HTML.DIV({
|
||||
id: "pending"
|
||||
}, "\n", Spacebars.include(self.lookupTemplate("pending")), "\n") ];
|
||||
}));
|
||||
|
||||
Template.__define__("pending", (function() {
|
||||
var self = this;
|
||||
var template = this;
|
||||
return HTML.TABLE("\n", UI.Each(function() {
|
||||
return Spacebars.call(self.lookup("pending"));
|
||||
}, UI.block(function() {
|
||||
var self = this;
|
||||
return [ "\n", HTML.TR("\n", HTML.TD(function() {
|
||||
return Spacebars.mustache(self.lookup("daddr"));
|
||||
}), HTML.TD("="), "\n", HTML.INPUT({
|
||||
spellcheck: "false",
|
||||
"class": "changeedit",
|
||||
value: function() {
|
||||
return Spacebars.mustache(self.lookup("ddata"));
|
||||
}
|
||||
}), "\n"), "\n" ];
|
||||
})), "\n");
|
||||
}));
|
||||
|
||||
Template.__define__("idump", (function() {
|
||||
var self = this;
|
||||
var template = this;
|
||||
|
@ -114,12 +144,16 @@ Template.__define__("regviewer", (function() {
|
|||
"class": [ "reg ", function() {
|
||||
return Spacebars.mustache(self.lookup("regactions"));
|
||||
} ]
|
||||
}, "\n ", function() {
|
||||
}, "\n ", HTML.SPAN({
|
||||
"class": "register"
|
||||
}, function() {
|
||||
return Spacebars.mustache(self.lookup("name"));
|
||||
}, ": ", HTML.SPAN({
|
||||
"class": function() {
|
||||
}, ": "), HTML.SPAN({
|
||||
"class": [ function() {
|
||||
return Spacebars.mustache(self.lookup("datatype"));
|
||||
}
|
||||
}, " ", function() {
|
||||
return Spacebars.mustache(self.lookup("isselected"));
|
||||
} ]
|
||||
}, function() {
|
||||
return Spacebars.mustache(self.lookup("hexvalue"));
|
||||
}), "\n "), "\n" ];
|
||||
|
|
Loading…
Reference in New Issue