2014-08-05 13:14:03 +04:00
#!/usr/bin/env python2.7
2019-03-24 00:49:07 +03:00
from __future__ import print_function
2014-07-23 04:37:06 +04:00
import os
2014-08-10 23:21:26 +04:00
import sys
2014-07-31 19:20:12 +04:00
basedir = os . path . dirname ( os . path . realpath ( __file__ ) )
2014-07-23 04:37:06 +04:00
import argparse
2014-08-04 22:51:14 +04:00
import ipaddr
2014-07-23 04:37:06 +04:00
import socket
import threading
import time
2014-07-31 01:01:44 +04:00
import qira_config
2014-07-23 04:37:06 +04:00
import qira_socat
import qira_program
import qira_webserver
if __name__ == ' __main__ ' :
2014-07-31 01:01:44 +04:00
# define arguments
2014-07-29 01:08:10 +04:00
parser = argparse . ArgumentParser ( description = ' Analyze binary. Like " qira /bin/ls / " ' )
2014-07-23 04:37:06 +04:00
parser . add_argument ( ' -s ' , " --server " , help = " bind on port 4000. like socat " , action = " store_true " )
2014-07-25 07:38:01 +04:00
parser . add_argument ( ' -t ' , " --tracelibraries " , help = " trace into all libraries " , action = " store_true " )
2014-07-23 04:37:06 +04:00
parser . add_argument ( ' binary ' , help = " path to the binary " )
parser . add_argument ( ' args ' , nargs = ' * ' , help = " arguments to the binary " )
2014-08-20 11:47:32 +04:00
parser . add_argument ( " --gate-trace " , metavar = " ADDRESS " , help = " don ' t start tracing until this address is hit " )
2014-07-31 03:24:34 +04:00
parser . add_argument ( " --flush-cache " , help = " flush all QIRA caches " , action = " store_true " )
2014-08-21 06:00:51 +04:00
parser . add_argument ( " --pin " , help = " use pin as the backend, requires ./pin_build.sh " , action = " store_true " )
2015-03-17 07:32:03 +03:00
parser . add_argument ( " --host " , metavar = " HOST " , help = " listen address for web interface and socat. " + qira_config . HOST + " by default " , default = qira_config . HOST )
2014-08-21 06:00:51 +04:00
parser . add_argument ( " --web-port " , metavar = " PORT " , help = " listen port for web interface. 3002 by default " , type = int , default = qira_config . WEB_PORT )
parser . add_argument ( " --socat-port " , metavar = " PORT " , help = " listen port for socat. 4000 by default " , type = int , default = qira_config . SOCAT_PORT )
2015-08-28 01:55:14 +03:00
parser . add_argument ( ' -S ' , ' --static ' , help = " enable static2 " , action = " store_true " )
2022-07-03 00:00:14 +03:00
parser . add_argument ( ' --no-run ' , help = " don ' t run the program " , action = " store_true " )
parser . add_argument ( ' --no-delete-runs ' , help = " don ' t clear the logs " , action = " store_true " )
2014-09-12 22:11:14 +04:00
#capstone flag in qira_config for now
2014-07-31 01:01:44 +04:00
2014-08-20 11:43:51 +04:00
# parse arguments, first try
args , unknown = parser . parse_known_args ( )
# hack to allow arguments to be passed to the analyzed program
sys . argv . insert ( sys . argv . index ( args . binary ) , " -- " )
# parse args, second try
2014-07-23 04:37:06 +04:00
args = parser . parse_args ( )
2014-08-04 22:51:14 +04:00
# validate arguments
if args . web_port < 1 or args . web_port > 65535 :
raise Exception ( " --web-port must be a valid port number (1-65535) " )
2015-12-06 20:36:08 +03:00
if args . socat_port < 1 or args . socat_port > 65534 :
raise Exception ( " --socat-port must be a valid port number (1-65534) " )
2014-08-04 22:51:14 +04:00
try :
2014-09-08 02:31:56 +04:00
args . host = ipaddr . IPAddress ( args . host ) . exploded
2014-08-04 22:51:14 +04:00
except ValueError :
raise Exception ( " --web-host must be a valid IPv4/IPv6 address " )
# handle arguments
2014-09-13 18:40:02 +04:00
if sys . platform == " darwin " :
2019-03-24 00:49:07 +03:00
print ( " *** running on darwin, defaulting to --pin " )
2014-09-13 18:40:02 +04:00
qira_config . USE_PIN = True
else :
qira_config . USE_PIN = args . pin
2014-09-08 02:31:56 +04:00
qira_config . HOST = args . host
2014-08-04 22:51:14 +04:00
qira_config . WEB_PORT = args . web_port
2014-08-20 11:43:51 +04:00
qira_config . SOCAT_PORT = args . socat_port
qira_config . FORK_PORT = args . socat_port + 1
2015-08-11 11:25:31 +03:00
2014-07-31 01:01:44 +04:00
if args . tracelibraries :
qira_config . TRACE_LIBRARIES = True
2015-08-27 11:19:35 +03:00
2015-08-28 01:55:14 +03:00
if args . static :
2019-03-24 00:49:07 +03:00
print ( " *** using static " )
2015-08-27 11:19:35 +03:00
qira_config . WITH_STATIC = True
2014-07-31 03:24:34 +04:00
if args . flush_cache :
2019-03-24 00:49:07 +03:00
print ( " *** flushing caches " )
2014-07-31 03:24:34 +04:00
os . system ( " rm -rfv /tmp/qira* " )
2014-07-23 04:37:06 +04:00
2014-08-20 11:01:30 +04:00
# qemu args from command line
qemu_args = [ ]
if args . gate_trace != None :
qemu_args . append ( " -gatetrace " )
qemu_args . append ( args . gate_trace )
2014-07-23 04:37:06 +04:00
# creates the file symlink, program is constant through server run
2014-08-20 11:01:30 +04:00
program = qira_program . Program ( args . binary , args . args , qemu_args )
2014-07-23 04:37:06 +04:00
is_qira_running = 1
try :
2014-08-04 22:51:14 +04:00
socket . create_connection ( ( ' 127.0.0.1 ' , qira_config . WEB_PORT ) )
2014-07-23 04:37:06 +04:00
if args . server :
raise Exception ( " can ' t run as server if QIRA is already running " )
except :
is_qira_running = 0
2019-03-24 00:49:07 +03:00
print ( " no qira server found, starting it " )
2022-07-03 00:00:14 +03:00
program . clear ( not args . no_delete_runs )
2014-07-23 04:37:06 +04:00
# start the binary runner
2014-11-23 00:00:33 +03:00
if args . server :
qira_socat . start_bindserver ( program , qira_config . SOCAT_PORT , - 1 , 1 , True )
else :
2022-07-03 00:00:14 +03:00
if not args . no_run :
print ( " **** running " , program . program )
program . execqira ( shouldfork = not is_qira_running )
2014-07-23 04:37:06 +04:00
if not is_qira_running :
# start the http server
2014-07-25 08:34:10 +04:00
qira_webserver . run_server ( args , program )
2014-07-23 04:37:06 +04:00