Skip to content

Commit

Permalink
Add argument parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
0x8008135 committed Sep 4, 2020
1 parent 2d03a3a commit 071f351
Show file tree
Hide file tree
Showing 3 changed files with 150 additions and 2,918 deletions.
279 changes: 150 additions & 129 deletions diffosaurus.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import time
from tqdm import tqdm
from wasabi import color
import argparse

debug = False
old_c = ''
Expand Down Expand Up @@ -132,133 +133,153 @@ def print_regs(regs_dbg,regs_esl):
old_c = c


logo="\n\
@@\n\
@██@\n\
@ @████@\n\
@█@ @███████@\n\
@███@ @█████████@\n\
@█████@ @███████████@ @ @ @\n\
@@ @███████@ @█████████████@ @█@@ @█@@ @█@@\n\
@██@ @█████████@@███████████████@████@███████@███████@@@@@@@@\n\
@████@███████████@██████████████████████████████@@@@@@\n\
@ @██████@███████████████████████████████████@@@@@@\n\
@@@ @██████████████████████████████████████@@@@\n\
███@@ @███████████████████████████████████@@@\n\
████@███@@█████████████████████████@@██████@@\n\
███████████████████████████████@@@███████@\n\
██████████████████@@@@@@@@@@@█████████@\n\
████ ████ ████ █████\n\
███ ████ ███ █████\n\
███ ████ ███ █████\n\
███ ████ ███ █████\n\
███ ████ ███ █████\n\
@@@ @@@@ @@@ @@@@@ \n\
\n"

banner="\
____ _ __ __ \n\
| _ \(_)/ _|/ _| ___ ___ __ _ _ _ _ __ _ _ ___ \n\
| | | | | |_| |_ / _ \/ __|/ _` | | | | '__| | | / __| \n\
| |_| | | _| _| (_) \__ \ (_| | |_| | | | |_| \__ \ \n\
|____/|_|_| |_| \___/|___/\__,_|\__,_|_| \__,_|___/ \n\
\n\
"

print("".join(color(x, fg=16, bg="red") if x == "@" else x for x in logo))
print("".join(color(x[0:25], fg=16, bg="red")+x[25:]+"\n" for x in banner.split("\n")))

debug_file="./binaries/aes_thumb"

#DEBUG
subprocess.Popen(args=["qemu-arm","-singlestep","-g","1234",debug_file])

r2_dbg=r2pipe.open("gdb://127.0.0.1:1234", flags=["-e bin.baddr=0x10000","-e dbg.exe.path="+debug_file,"-D gdb-multiarch", "-d"])

r2_dbg.cmd("e io.cache=true")
r2_dbg.cmd("e asm.arch=arm")
r2_dbg.cmd("e asm.bits=16")
r2_dbg.cmd("e dbg.bpinmaps=0")

#ESIL
r2_esl=r2pipe.open(debug_file)
r2_esl.cmd("e io.cache=true")
r2_esl.cmd("e asm.arch=arm")
r2_esl.cmd("e asm.bits=16")
r2_esl.cmd("aei")
r2_esl.cmd("aeim")
r2_esl.cmd("aeip")

esl_old_instr=""
dbg_old_instr=""

registers = filter_registers()

# Copy stack ARM specific
sp = int(get_debug_registers()['sp'],0)
print(hex(sp))
sp_start = sp & 0xfffff000
sp_end = sp + 0x1000
chunk=16

for x in tqdm(range(sp_start,sp_end,chunk)):
a=r2_dbg.cmd(f'"p8 {chunk}" @{hex(x)}')
r2_esl.cmd(f'"wx {a.strip()}" @{hex(x)}')

#print(r2_dbg.cmd(f'"p8 0x100" @{hex(sp+0x100)}'))
#print(r2_esl.cmd(f'"p8 0x100" @{hex(sp+0x100)}'))


# sync regs before start
reg_t2e_sync() #target > esil

while True:
print("ESIL:")
print(f"[--] {esl_old_instr}")
esl_old_instr=r2_esl.cmd('pdt 1 @pc')
print(f"[PC] {esl_old_instr}")
print("DEBUG:")
print(f"[--] {dbg_old_instr}")
dbg_old_instr=r2_dbg.cmd('pdt 1 @pc')
print(f"[PC] {dbg_old_instr}")
print_regs(get_debug_registers(),get_esil_registers())
esl_old_instr=r2_esl.cmd('pdt 1 @pc')
dbg_old_instr=r2_dbg.cmd('pdt 1 @pc')
time.sleep(0.25)
r2_esl.cmd("aes")
r2_dbg.cmd("ds")
#print("\n\n\n")
cls()
#print("\x1B[2J")
def print_logo():
logo="\n\
@@\n\
@██@\n\
@ @████@\n\
@█@ @███████@\n\
@███@ @█████████@\n\
@█████@ @███████████@ @ @ @\n\
@@ @███████@ @█████████████@ @█@@ @█@@ @█@@\n\
@██@ @█████████@@███████████████@████@███████@███████@@@@@@@@\n\
@████@███████████@██████████████████████████████@@@@@@\n\
@ @██████@███████████████████████████████████@@@@@@\n\
@@@ @██████████████████████████████████████@@@@\n\
███@@ @███████████████████████████████████@@@\n\
████@███@@█████████████████████████@@██████@@\n\
███████████████████████████████@@@███████@\n\
██████████████████@@@@@@@@@@@█████████@\n\
████ ████ ████ █████\n\
███ ████ ███ █████\n\
███ ████ ███ █████\n\
███ ████ ███ █████\n\
███ ████ ███ █████\n\
@@@ @@@@ @@@ @@@@@ \n\
\n"

r2_esl.quit()
r2_dbg.quit()


#EXAMPLE for tests
#tests = [
# "MOV r1,#1;asrs r1, r1, #1;asrs r1, r1, #1",
# "MOV r1,#1;RSB r1,#1280;RSB r1,#1280",
# "MOV r1,#16;cmp r1, #16;cmp r1, #1",
# "SUB r1,8;asrs r1, r1, #2;asrs r1, r1, #2",
# "MOV r1,#0x0;SUBS r1,#1;SUBS r1,#1",
# "MOV r1,#0xffffffff;ADDS r1,#1",
# "MOV r1,#0xffffffff;MOV r3,#0xffffffff;ADCS r1, r3;ADCS r1, r3;ADCS r1,r3",
# "MOV r1,#0x90000000;MOV r3,#0x80000000;ADCS r1, r3;ADCS r1, r3;ADCS r1,r3",
# "loop:;MOV r1,#0x80000000;LSRS r1,r2;ADD r2,1;CMP R2,#31;BLT loop",
# "loop:;MOV r1,1;LSLS r1,r2;ADD r2,1;CMP R2,#31;BLT loop"
#]
#
#for x in tests:
# #Target ESIL
# sram = "0x20000000"
# sp = "0x20000400"
# fp = "0x0"
# r2_esl=r2pipe.open("-")
# r2_esl.cmd("e asm.arch=arm;e asm.bits=16")
# r2_esl.cmd("aei;aeim;aeip")
# r2_esl.cmd(f"omb. {sram}")
# r2_esl.cmd(f"aro;ar pc={sram};ar sp={sp};ar fp={fp}")
# r2_esl.cmd(f"ar lr=0xffffffff")
# r2_esl.cmd(f"s {sram}")
# r2_esl.cmd(f"\"wa {x} ;MOV r5,1\"")
banner="\
____ _ __ __ \n\
| _ \(_)/ _|/ _| ___ ___ __ _ _ _ _ __ _ _ ___ \n\
| | | | | |_| |_ / _ \/ __|/ _` | | | | '__| | | / __| \n\
| |_| | | _| _| (_) \__ \ (_| | |_| | | | |_| \__ \ \n\
|____/|_|_| |_| \___/|___/\__,_|\__,_|_| \__,_|___/ \n\
\n"

print("".join(color(x, fg=16, bg="red") if x == "@" else x for x in logo))
print("".join(color(x[0:25], fg=16, bg="red")+x[25:]+"\n" for x in banner.split("\n")))


if __name__ == '__main__':
print_logo()
parser = argparse.ArgumentParser(description="Diffosaurus - ESIL differential analysis\n\n\
[Examples]\n\
File mode: python diffosaurus.py -m f -f ./binaries/aes_thumb -qp 1234 -qb qemu-arm -da 0x1000 -D gdb-multiarch -a arm -b 16\n\
Test mode: python diffosaurus.py -m t -t \"MOV r1,#1;asrs r1, r1, #1;asrs r1, r1, #1\" -D gdb-multiarch -a arm -b 16 -dp 3333\n\n")
parser.add_argument("-m", "--mode", dest="mode", action="store", required=True, help="Mode Selection [f]ile/[t]est")
parser.add_argument("-f", "--file", dest="dbg_file", action="store", default="-", help="File to analyse")
parser.add_argument("-t", "--test", dest="test", action="store", help="Assembly to test (wa <assembly>")
parser.add_argument("-qb", "--qbin", dest="qb", action="store", help="Qemu binary (e.g. qemu-arm)")
parser.add_argument("-qp", "--qport", dest="qp", action="store", default="1234", help="Qemu port (default = %(default)s)")
parser.add_argument("-dh", "--dhost", dest="dbg_host", action="store", default="localhost", help="Debugger hostname/ip (default = %(default)s)")
parser.add_argument("-dp", "--dport", dest="dbg_port", action="store", default="1234", help="Debugger port (default = %(default)s)")
parser.add_argument("-D", "--dback", dest="dbg_backend", action="store", required=True, default="gdb-multiarch", help="Debugger backend (e.g. gdb-multiarch)")
parser.add_argument("-da", "--dbadd", dest="dbg_baddr", action="store", help="File base address (e bin.baddr)")
parser.add_argument("-a", "--arch", dest="arch", action="store", required=True, help="Architecture (e asm.arch")
parser.add_argument("-b", "--bits", dest="bits", action="store", required=True, help="Architecture bits (e asm.bits)")

result = parser.parse_args()

esl_old_instr = ""
dbg_old_instr = ""

if (result.mode == 't'):
sram = input("Enter SRAM location (e.g. 0x20000000): ")
sp = input("Enter SP location (e.g. 0x20000100): ")

# ESIL
r2_esl = r2pipe.open("-")
r2_esl.cmd("e io.cache=true")
r2_esl.cmd("e asm.arch=" + result.arch)
r2_esl.cmd("e asm.bits=" + result.bits)
r2_esl.cmd("aei")
r2_esl.cmd("aeim")
r2_esl.cmd("aeip")
r2_esl.cmd(f"omb. {sram}")
r2_esl.cmd(f"aro;ar PC={sram};ar SP={sp};")
r2_esl.cmd(f"s {sram}")
r2_esl.cmd(f"\"wa {result.test}\"")

# DEBUG
r2_dbg=r2pipe.open("gdb://"+result.dbg_host+":"+ result.dbg_port, flags=["-D "+ result.dbg_backend])
r2_dbg.cmd("e dbg.bpinmaps=0")
r2_dbg.cmd("e asm.arch=" + result.arch)
r2_dbg.cmd("e asm.bits=" + result.bits)
r2_dbg.cmd(f"dr PC={sram};dr SP={sp};")
r2_dbg.cmd(f"s {sram}")
r2_dbg.cmd(f"\"wa {result.test}\"")

registers = filter_registers()

# sync regs before start
#reg_e2t_sync() #esil > target
else:
# ESIL
r2_esl = r2pipe.open(result.dbg_file)
r2_esl.cmd("e io.cache=true")
r2_esl.cmd("e asm.arch=" + result.arch)
r2_esl.cmd("e asm.bits=" + result.bits)
r2_esl.cmd("aei")
r2_esl.cmd("aeim")
r2_esl.cmd("aeip")

# QEMU
if (result.qb):
subprocess.Popen(args=[result.qb,"-singlestep","-g", result.qp, result.dbg_file])

dbg_flags = ["-e dbg.exe.path=" + result.dbg_file,"-D "+ result.dbg_backend, "-d"]

if (result.dbg_baddr):
dbg_flags = ["-e bin.baddr=" + result.dbg_baddr] + dbg_flags

# DEBUG
r2_dbg=r2pipe.open("gdb://" + result.dbg_host + ":" + result.dbg_port, flags=dbg_flags)
r2_dbg.cmd("e io.cache=true")
r2_dbg.cmd("e dbg.bpinmaps=0")
r2_dbg.cmd("e asm.arch=" + result.arch)
r2_dbg.cmd("e asm.bits=" + result.bits)

registers = filter_registers()

# stack copy qemu arm
if ( result.arch.lower() == "arm" and result.qb ):
sp = int(get_debug_registers()['sp'],0)
sp_start = sp & 0xfffff000
sp_end = sp + 0x1000
chunk=16

for x in tqdm(range(sp_start,sp_end,chunk)):
a=r2_dbg.cmd(f'"p8 {chunk}" @{hex(x)}')
r2_esl.cmd(f'"wx {a.strip()}" @{hex(x)}')

# sync regs before start
#reg_t2e_sync() #target > esil

while True:
print("ESIL:")
print(f"[--] {esl_old_instr}")
esl_old_instr=r2_esl.cmd('pdt 1 @pc')
print(f"[PC] {esl_old_instr}")
print("DEBUG:")
print(f"[--] {dbg_old_instr}")
dbg_old_instr=r2_dbg.cmd('pdt 1 @pc')
print(f"[PC] {dbg_old_instr}")
print_regs(get_debug_registers(),get_esil_registers())
esl_old_instr=r2_esl.cmd('pdt 1 @pc')
dbg_old_instr=r2_dbg.cmd('pdt 1 @pc')
r2_esl.cmd("aes")
r2_dbg.cmd("ds")
print("\n\n\n")

r2_esl.quit()
r2_dbg.quit()
Loading

0 comments on commit 071f351

Please sign in to comment.