Skip to content

Instantly share code, notes, and snippets.

@sudhackar
Last active January 21, 2024 00:52
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sudhackar/ad9c15851f274b3248ef1645abee9ae8 to your computer and use it in GitHub Desktop.
Save sudhackar/ad9c15851f274b3248ef1645abee9ae8 to your computer and use it in GitHub Desktop.
ida python and idc
from z3 import *
# https://reverseengineering.stackexchange.com/questions/30303/z3-is-unable-to-predict-the-operand
v7 = [123,456,789,987,654,321]
v6 = [92,29,380,2,497,296]
arrl = 14
argv1 = [BitVec(f'a{i}', 32) for i in range(arrl)]
solver = Solver()
v18 = BitVecVal(0x7fffffff, 32)
for i in range(arrl):
solver.add(argv1[i] < 128)
solver.add(argv1[i] > 32)
v18 += i*argv1[i]
for i in range(6):
solver.add(URem(v18, v7[i]) == v6[i])
print(solver.check())
print("".join(map(chr,[solver.model()[argv1[i]].as_long() for i in range(arrl)])))
from idautils import *
from idc import *
from ida_hexrays import *
from ida_kernwin import *
from idaapi import *
flag = ["[missing]" for i in range(256)]
def process_constraints(cfunc) :
class arr_conv(ctree_visitor_t):
def __init__(self, cfunc):
ctree_visitor_t.__init__(self, CV_FAST)
self.cfunc = cfunc
def visit_expr(self, i):
if i.op == cot_eq:
if i.x.op == cot_idx and i.y.op == cot_num:
idx = i.x.y.numval()
val = chr(i.y.numval())
flag[idx] = val
return 0
a = arr_conv(cfunc)
a.apply_to(cfunc.body, None)
for segea in Segments():
for funcea in Functions(segea, get_segm_end(segea)):
fname = get_func_name(funcea)
if fname[0] == 'f' and fname[1].isdigit() and len(list(XrefsTo(funcea))) > 0:
pt = idc.parse_decl("int %s(char f[256])" % fname, idc.PT_SILENT)
idc.apply_type(funcea, pt)
process_constraints(decompile(funcea))
print("".join(flag))
setImmediate(function () {
var base;
var modules = Process.enumerateModules();
modules.forEach((i) => {
// console.log(i.name);
if (i.name === "chall") {
base = i.base;
}
});
console.log(base);
var tohook = base.add(0x10A7);
var comphook = base.add(0x1214);
var data = base.add(0x4038);
Interceptor.attach(tohook,
function (args) {
var i = this.context.rdx;
var op = (i >> 24) & 0xff;
var arg1 = (i >> 12) & 0xfff;
var arg2 = i & 0xfff;
console.log(this.context.rax);
if (op == 0xd6) {
var d1 = data.add(Number(arg1 * 4)).readU32();
var d2 = data.add(Number(arg2 * 4)).readU32();
console.log(`mov data[${arg1}], data[${arg2}] : ${d1} : ${d2}`);
}
else if (op == 0xd5) {
var d1 = data.add(Number(arg1 * 4)).readU32();
console.log(`data[${arg1}] = getchar() : ${d1}`);
}
else if (op == 0xd8) {
var d1 = data.add(Number(arg1 * 4)).readU32();
console.log(`mov data[${arg1}], ${arg2} : ${d1}`);
}
else if (op == 0xf6) {
var d1 = data.add(Number(arg1 * 4)).readU32();
console.log(`putchar(data[${arg1}])`);
}
else if (op == 0x18) {
var d1 = data.add(Number(arg1 * 4)).readU32();
var d2 = data.add(Number(arg2 * 4)).readU32();
console.log(`xor data[${arg1}], data[${arg2}] : ${d1} : ${d2}`);
}
else if (op == 0x69) {
var d1 = data.add(Number(arg1 * 4)).readU32();
console.log(`if !data[${arg1}] jmp ip+${arg2} : ${d1}`);
}
else if (op == 0xa6) {
console.log(`jmp ${arg1}`);
}
else if (op == 0x16) {
var d1 = data.add(Number(arg1 * 4)).readU32();
var d2 = data.add(Number(arg2 * 4)).readU32();
console.log(`add data[${arg1}], data[${arg2}] : ${d1} : ${d2}`);
}
else if (op == 0x17) {
var d1 = data.add(Number(arg1 * 4)).readU32();
var d2 = data.add(Number(arg2 * 4)).readU32();
console.log(`sub data[${arg1}], data[${arg2}] : ${d1} : ${d2}`);
}
else {
console.log(`${op} ${arg1} ${arg2}`);
}
}
);
Interceptor.attach(comphook,
function (args) {
var readat = ptr(Number(Number(this.context.rax * 4) + Number(this.context.rbp)));
console.log(readat, readat.readU32());
}
);
});
from miasm.analysis.dse import DSEPathConstraint
from miasm.analysis.machine import Machine
from miasm.analysis.sandbox import Sandbox_Linux_x86_64
from miasm.core.utils import int_to_byte
from miasm.expression.expression import *
from miasm.os_dep.win_api_x86_32 import get_win_str_a
parser = Sandbox_Linux_x86_64.parser()
parser.add_argument("--f", default="/tmp/ctf-bin", required=False)
options = parser.parse_args()
solution = "........."
options.mimic_env = True
options.command_line = [solution]
sb = Sandbox_Linux_x86_64(options.f, options, globals())
sb.jitter.init_run(sb.entry_point)
machine = Machine("x86_64")
dse = DSEPathConstraint(
machine, produce_solution=DSEPathConstraint.PRODUCE_SOLUTION_BRANCH_COV)
dse.attach(sb.jitter)
dse.update_state_from_concrete()
strln = ExprId("strln", 64)
z3_strln = dse.z3_trans.from_expr(strln)
dse.cur_solver.add(0 < z3_strln)
dse.cur_solver.add(z3_strln < 10)
expr_map = dict()
str_ptr = 0
class FinishOn(Exception):
def __init__(self, string):
self.string = string
super(FinishOn, self).__init__()
def xxx___libc_start_main_symb(dse):
regs = dse.ir_arch.arch.regs
top_stack = dse.eval_expr(regs.RSP)
main_addr = dse.eval_expr(regs.RDI)
argc = dse.eval_expr(regs.RSI)
argv = dse.eval_expr(regs.RDX)
hlt_addr = ExprInt(sb.CALL_FINISH_ADDR, 64)
dse.update_state({
ExprMem(top_stack, 64): hlt_addr,
regs.RDI: argc,
regs.RSI: argv,
dse.ir_arch.IRDst: main_addr,
dse.ir_arch.pc: main_addr,
})
def xxx_exit_symb(dse):
raise FinishOn("Fail")
def xxx_puts_symb(dse):
string = get_win_str_a(dse.jitter, dse.jitter.cpu.RDI)
raise FinishOn(string)
def xxx_strlen_symb(dse):
global str_ptr
regs = dse.ir_arch.arch.regs
ptr = dse.eval_expr(regs.RDI)
str_ptr = int(ptr)
ret_addr = ExprInt(dse.jitter.get_stack_arg(0), regs.RIP.size)
ret_value = strln
update = {}
for i, content in enumerate(curr):
addr = dse.symb.expr_simp(ptr + ExprInt(i, ptr.size))
expr_map[i] = ExprId("C_%d" % (i), 8)
# print("Setting {}".format(expr_map[i]))
# if content > 0x30:
# print("Fixing {}:{}".format(i,content))
# dse.cur_solver.add(dse.z3_trans.from_expr(expr_map[i]) == content)
# update[ExprMem(addr, 8)] = ExprInt(content, 8)
# dse.symb.mem_write(ExprMem(addr, 8), ExprInt(content, 8))
# else:
dse.cur_solver.add(0x2f < dse.z3_trans.from_expr(expr_map[i]))
update[ExprMem(addr, 8)] = expr_map[i]
dse.update_state({
regs.RSP: dse.eval_expr(regs.RSP + ExprInt(8, regs.RSP.size)),
dse.ir_arch.IRDst: ret_addr,
regs.RIP: ret_addr,
regs.RAX: ret_value,
})
dse.update_state(update)
dse.add_lib_handler(sb.libs, globals())
snapshot = dse.take_snapshot()
found = False
curr = b""
todo = set([b""])
while todo:
flag = todo.pop()
curr = flag
dse.restore_snapshot(snapshot, keep_known_solutions=True)
if str_ptr:
print("Already {}".format(sb.jitter.vm.get_mem(int(str_ptr), 9)))
for idx, content in enumerate(curr):
currb = sb.jitter.vm.get_mem(int(str_ptr) + idx, 1)
# print((currb, content))
if currb == b'.' and content > 0x30:
sb.jitter.vm.set_mem(int(str_ptr) + idx, bytes([content]))
print("Done {}".format(sb.jitter.vm.get_mem(int(str_ptr), 9)))
try:
sb.run()
except FinishOn as finish_info:
print(finish_info.string)
if "Level Unlocked" in finish_info.string:
found = True
break
for sol_ident, model in viewitems(dse.new_solutions):
candidate = []
# print((sol_ident, model))
ln = max(model.eval(dse.z3_trans.from_expr(strln)).as_long(), 9)
for i in range(ln):
try:
candidate.append(int_to_byte(model.eval(
dse.z3_trans.from_expr(expr_map[i])).as_long()))
except (KeyError, AttributeError) as _:
candidate.append(b"\x00")
# print(candidate)
todo.add(b"".join(candidate))
import angr
p = angr.Project('no_flo_f51e2f24345e094cd2080b7b690f69fb')
even = 0x4006c6
avoid = (0x40071d, 0x400710, 0x40077a, 0x40076d, 0x4007d7, 0x4007ca, 0x400834, 0x400827, 0x400894, 0x400887, 0x4008f4, 0x4008e7, 0x400950, 0x400943, 0x4009a8, 0x40099b, 0x400a09, 0x4009fc, 0x400a6f, 0x400a62, 0x400ac7, 0x400aba, 0x400b24, 0x400b17, 0x400b81, 0x400b74, 0x400bd9, 0x400bcc, 0x400c31, 0x400c24, 0x400c8e, 0x400c81, 0x400ce6, 0x400cd9, 0x400d3e, 0x400d31, 0x400d96, 0x400d89, 0x400df2, 0x400de5, 0x400e4a, 0x400e3d, 0x400ea0, 0x400e96, 0x400eeb, 0x400ee1)
flag_addr = 0x1000
state = p.factory.blank_state(addr=even)
state.regs.rdi = flag_addr
for i in range(16):
state.mem[flag_addr + i*4].dword = state.solver.BVS('c', 32)
ex = p.factory.simulation_manager(state)
ex.explore(find=0x400f17, avoid=avoid)
s = ""
for i in range(16):
s += chr(ex.found[0].solver.eval(ex.found[0].memory.load(flag_addr + i*4, 1)))
s += "*"
print(s)
import sark
f_addr = 0x004006C6
f = sark.Function(f_addr)
for line in f.lines:
# print line.disasm
if line.insn.mnem == "mov":
if len(line.insn.operands) ==2 and line.insn.operands[0].reg == "r8d" and line.insn.operands[1].value == 0:
code_block = sark.CodeBlock(line._ea)
code_block.color = 0x00ff0000
print hex(code_block.start_ea),
for i in line.xrefs_to:
code_block = sark.CodeBlock(i.frm)
code_block.color = 0x000000ff
print hex(code_block.start_ea),
import angr
import claripy
# https://reverseengineering.stackexchange.com/questions/30303/z3-is-unable-to-predict-the-operand
b = open("shellcode", "rb").read()
assert(b[0xc4]==0xc3)
p = angr.project.load_shellcode(b[:0xc5],arch="amd64")
opts = {angr.options.ZERO_FILL_UNCONSTRAINED_MEMORY,angr.options.ZERO_FILL_UNCONSTRAINED_REGISTERS}
s = p.factory.blank_state(add_options=opts)
arg1 = claripy.BVS("arg1", 8*14)
flag_addr = 0x1000
s.memory.store(flag_addr, arg1)
s.regs.rdi = flag_addr
s.regs.rsi = 14
s.regs.rbp = 0x2000
s.regs.rsp = 0x2000
pg = p.factory.simulation_manager(s)
out = pg.explore(find=0xbe)
print(out.found)
solved = out.found[0]
print(solved.solver.eval(arg1, cast_to=bytes))
import angr
# dump the rwx region from gdb
p = angr.Project("/tmp/dump", main_opts={'backend': 'blob', 'arch': 'amd64'})
start_n = [0x7f4b4a0a8a7f, 0x7f4b4a0a8b23, 0x7f4b4a0a8bc7, 0x7f4b4a0a8c6b, 0x7f4b4a0a8d0f, 0x7f4b4a0a94a2, 0x7f4b4a0a9546, 0x7f4b4a0a95ea, 0x7f4b4a0a968e, 0x7f4b4a0a9732, 0x7f4b4a0a9ec3, 0x7f4b4a0a9f67, 0x7f4b4a0aa00b, 0x7f4b4a0aa0af, 0x7f4b4a0aa153, 0x7f4b4a0aa8ec, 0x7f4b4a0aa990, 0x7f4b4a0aaa34, 0x7f4b4a0aaad8, 0x7f4b4a0aab7c, 0x7f4b4a0ab311, 0x7f4b4a0ab3b5, 0x7f4b4a0ab459, 0x7f4b4a0ab4fd, 0x7f4b4a0ab5a1, 0x7f4b4a0abd3a, 0x7f4b4a0abdde, 0x7f4b4a0abe82, 0x7f4b4a0abf26, 0x7f4b4a0abfca, 0x7f4b4a0ac75f, 0x7f4b4a0ac803, 0x7f4b4a0ac8a7, 0x7f4b4a0ac94b, 0x7f4b4a0ac9ef, 0x7f4b4a0ad186, 0x7f4b4a0ad22a, 0x7f4b4a0ad2ce, 0x7f4b4a0ad372, 0x7f4b4a0ad416, 0x7f4b4a0adba5, 0x7f4b4a0adc49, 0x7f4b4a0adced, 0x7f4b4a0add91, 0x7f4b4a0ade35, 0x7f4b4a0ae5ca, 0x7f4b4a0ae66e, 0x7f4b4a0ae712, 0x7f4b4a0ae7b6, 0x7f4b4a0ae85a, 0x7f4b4a0aeff7, 0x7f4b4a0af09b, 0x7f4b4a0af13f, 0x7f4b4a0af1e3, 0x7f4b4a0af287, 0x7f4b4a0afa22, 0x7f4b4a0afac6, 0x7f4b4a0afb6a, 0x7f4b4a0afc0e, 0x7f4b4a0afcb2, 0x7f4b4a0b0449, 0x7f4b4a0b04ed, 0x7f4b4a0b0591, 0x7f4b4a0b0635, 0x7f4b4a0b06d9, 0x7f4b4a0b0e72, 0x7f4b4a0b0f16, 0x7f4b4a0b0fba, 0x7f4b4a0b105e, 0x7f4b4a0b1102, 0x7f4b4a0b1897, 0x7f4b4a0b193b, 0x7f4b4a0b19df, 0x7f4b4a0b1a83, 0x7f4b4a0b1b27, 0x7f4b4a0b22be, 0x7f4b4a0b2362, 0x7f4b4a0b2406, 0x7f4b4a0b24aa, 0x7f4b4a0b254e, 0x7f4b4a0b2ce3, 0x7f4b4a0b2d87, 0x7f4b4a0b2e2b, 0x7f4b4a0b2ecf, 0x7f4b4a0b2f73, 0x7f4b4a0b3706, 0x7f4b4a0b37aa, 0x7f4b4a0b384e, 0x7f4b4a0b38f2, 0x7f4b4a0b3996, 0x7f4b4a0b412f, 0x7f4b4a0b41d3, 0x7f4b4a0b4277, 0x7f4b4a0b431b, 0x7f4b4a0b43bf, 0x7f4b4a0b4b54, 0x7f4b4a0b4bf8, 0x7f4b4a0b4c9c, 0x7f4b4a0b4d40, 0x7f4b4a0b4de4, 0x7f4b4a0b557b, 0x7f4b4a0b561f, 0x7f4b4a0b56c3, 0x7f4b4a0b5767, 0x7f4b4a0b580b, 0x7f4b4a0b5fa4, 0x7f4b4a0b6048, 0x7f4b4a0b60ec, 0x7f4b4a0b6190, 0x7f4b4a0b6234, 0x7f4b4a0b69cb, 0x7f4b4a0b6a6f, 0x7f4b4a0b6b13, 0x7f4b4a0b6bb7, 0x7f4b4a0b6c5b, 0x7f4b4a0b73f0, 0x7f4b4a0b7494, 0x7f4b4a0b7538, 0x7f4b4a0b75dc, 0x7f4b4a0b7680, 0x7f4b4a0b7e15, 0x7f4b4a0b7eb9, 0x7f4b4a0b7f5d, 0x7f4b4a0b8001, 0x7f4b4a0b80a5, 0x7f4b4a0b883c, 0x7f4b4a0b88e0, 0x7f4b4a0b8984, 0x7f4b4a0b8a28, 0x7f4b4a0b8acc, 0x7f4b4a0b925f, 0x7f4b4a0b9303, 0x7f4b4a0b93a7, 0x7f4b4a0b944b, 0x7f4b4a0b94ef, 0x7f4b4a0b9c88, 0x7f4b4a0b9d2c, 0x7f4b4a0b9dd0, 0x7f4b4a0b9e74, 0x7f4b4a0b9f18, 0x7f4b4a0ba6ab, 0x7f4b4a0ba74f, 0x7f4b4a0ba7f3, 0x7f4b4a0ba897, 0x7f4b4a0ba93b, 0x7f4b4a0bb0d4, 0x7f4b4a0bb178, 0x7f4b4a0bb21c, 0x7f4b4a0bb2c0, 0x7f4b4a0bb364, 0x7f4b4a0bbafb, 0x7f4b4a0bbb9f, 0x7f4b4a0bbc43, 0x7f4b4a0bbce7, 0x7f4b4a0bbd8b, 0x7f4b4a0bc522, 0x7f4b4a0bc5c6, 0x7f4b4a0bc66a, 0x7f4b4a0bc70e, 0x7f4b4a0bc7b2, 0x7f4b4a0bcf47, 0x7f4b4a0bcfeb, 0x7f4b4a0bd08f, 0x7f4b4a0bd133, 0x7f4b4a0bd1d7, 0x7f4b4a0bd96a, 0x7f4b4a0bda0e]
base = 0x7f4b4a09d000
end_n = [0x7f4b4a0a8ae7, 0x7f4b4a0a8b8b, 0x7f4b4a0a8c2f, 0x7f4b4a0a8cd3, 0x7f4b4a0a8d77, 0x7f4b4a0a950a, 0x7f4b4a0a95ae, 0x7f4b4a0a9652, 0x7f4b4a0a96f6, 0x7f4b4a0a979a, 0x7f4b4a0a9f2b, 0x7f4b4a0a9fcf, 0x7f4b4a0aa073, 0x7f4b4a0aa117, 0x7f4b4a0aa1bb, 0x7f4b4a0aa954, 0x7f4b4a0aa9f8, 0x7f4b4a0aaa9c, 0x7f4b4a0aab40, 0x7f4b4a0aabe4, 0x7f4b4a0ab379, 0x7f4b4a0ab41d, 0x7f4b4a0ab4c1, 0x7f4b4a0ab565, 0x7f4b4a0ab609, 0x7f4b4a0abda2, 0x7f4b4a0abe46, 0x7f4b4a0abeea, 0x7f4b4a0abf8e, 0x7f4b4a0ac032, 0x7f4b4a0ac7c7, 0x7f4b4a0ac86b, 0x7f4b4a0ac90f, 0x7f4b4a0ac9b3, 0x7f4b4a0aca57, 0x7f4b4a0ad1ee, 0x7f4b4a0ad292, 0x7f4b4a0ad336, 0x7f4b4a0ad3da, 0x7f4b4a0ad47e, 0x7f4b4a0adc0d, 0x7f4b4a0adcb1, 0x7f4b4a0add55, 0x7f4b4a0addf9, 0x7f4b4a0ade9d, 0x7f4b4a0ae632, 0x7f4b4a0ae6d6, 0x7f4b4a0ae77a, 0x7f4b4a0ae81e, 0x7f4b4a0ae8c2, 0x7f4b4a0af05f, 0x7f4b4a0af103, 0x7f4b4a0af1a7, 0x7f4b4a0af24b, 0x7f4b4a0af2ef, 0x7f4b4a0afa8a, 0x7f4b4a0afb2e, 0x7f4b4a0afbd2, 0x7f4b4a0afc76, 0x7f4b4a0afd1a, 0x7f4b4a0b04b1, 0x7f4b4a0b0555, 0x7f4b4a0b05f9, 0x7f4b4a0b069d, 0x7f4b4a0b0741, 0x7f4b4a0b0eda, 0x7f4b4a0b0f7e, 0x7f4b4a0b1022, 0x7f4b4a0b10c6, 0x7f4b4a0b116a, 0x7f4b4a0b18ff, 0x7f4b4a0b19a3, 0x7f4b4a0b1a47, 0x7f4b4a0b1aeb, 0x7f4b4a0b1b8f, 0x7f4b4a0b2326, 0x7f4b4a0b23ca, 0x7f4b4a0b246e, 0x7f4b4a0b2512, 0x7f4b4a0b25b6, 0x7f4b4a0b2d4b, 0x7f4b4a0b2def, 0x7f4b4a0b2e93, 0x7f4b4a0b2f37, 0x7f4b4a0b2fdb, 0x7f4b4a0b376e, 0x7f4b4a0b3812, 0x7f4b4a0b38b6, 0x7f4b4a0b395a, 0x7f4b4a0b39fe, 0x7f4b4a0b4197, 0x7f4b4a0b423b, 0x7f4b4a0b42df, 0x7f4b4a0b4383, 0x7f4b4a0b4427, 0x7f4b4a0b4bbc, 0x7f4b4a0b4c60, 0x7f4b4a0b4d04, 0x7f4b4a0b4da8, 0x7f4b4a0b4e4c, 0x7f4b4a0b55e3, 0x7f4b4a0b5687, 0x7f4b4a0b572b, 0x7f4b4a0b57cf, 0x7f4b4a0b5873, 0x7f4b4a0b600c, 0x7f4b4a0b60b0, 0x7f4b4a0b6154, 0x7f4b4a0b61f8, 0x7f4b4a0b629c, 0x7f4b4a0b6a33, 0x7f4b4a0b6ad7, 0x7f4b4a0b6b7b, 0x7f4b4a0b6c1f, 0x7f4b4a0b6cc3, 0x7f4b4a0b7458, 0x7f4b4a0b74fc, 0x7f4b4a0b75a0, 0x7f4b4a0b7644, 0x7f4b4a0b76e8, 0x7f4b4a0b7e7d, 0x7f4b4a0b7f21, 0x7f4b4a0b7fc5, 0x7f4b4a0b8069, 0x7f4b4a0b810d, 0x7f4b4a0b88a4, 0x7f4b4a0b8948, 0x7f4b4a0b89ec, 0x7f4b4a0b8a90, 0x7f4b4a0b8b34, 0x7f4b4a0b92c7, 0x7f4b4a0b936b, 0x7f4b4a0b940f, 0x7f4b4a0b94b3, 0x7f4b4a0b9557, 0x7f4b4a0b9cf0, 0x7f4b4a0b9d94, 0x7f4b4a0b9e38, 0x7f4b4a0b9edc, 0x7f4b4a0b9f80, 0x7f4b4a0ba713, 0x7f4b4a0ba7b7, 0x7f4b4a0ba85b, 0x7f4b4a0ba8ff, 0x7f4b4a0ba9a3, 0x7f4b4a0bb13c, 0x7f4b4a0bb1e0, 0x7f4b4a0bb284, 0x7f4b4a0bb328, 0x7f4b4a0bb3cc, 0x7f4b4a0bbb63, 0x7f4b4a0bbc07, 0x7f4b4a0bbcab, 0x7f4b4a0bbd4f, 0x7f4b4a0bbdf3, 0x7f4b4a0bc58a, 0x7f4b4a0bc62e, 0x7f4b4a0bc6d2, 0x7f4b4a0bc776, 0x7f4b4a0bc81a, 0x7f4b4a0bcfaf, 0x7f4b4a0bd053, 0x7f4b4a0bd0f7, 0x7f4b4a0bd19b, 0x7f4b4a0bd23f, 0x7f4b4a0bd9d2, 0x7f4b4a0bda76]
start = [i-base-0x17 for i in start_n]
end = [i-base+0x13 for i in end_n]
avoid = [i-base+0xc for i in end_n]
def return_two(ex, idx):
return chr(ex.found[0].solver.eval(ex.found[0].memory.load(flag_addr+idx, 1)))+chr(ex.found[0].solver.eval(ex.found[0].memory.load(flag_addr+idx+1, 1)))
s = ""
# each check involves 2 contiguous bytes -> length 334/2
for i in range(167):
state = p.factory.blank_state(addr=start[i])
flag_addr = 0x1000
for ii in range(i*2, i*2+2):
state.mem[flag_addr + ii].byte = state.solver.BVS('c', 8)
state.memory.store(0x2000, 0x1000+i*2, endness='Iend_LE')
state.memory.store(state.regs.rbp - 0x58, 0x2000, endness='Iend_LE')
ex = p.factory.simulation_manager(state)
ex.explore(find=end[i], avoid=avoid[i])
# raw_input()
s += return_two(ex, i*2)
print(i)
print(s)
size_code = 0x2236f
def decrypt_code(start_idx, key, ln):
for i in xrange(ln):
PatchByte(start_idx+i, key^Byte(start_idx+i))
def scan_start(start_idx):
i = start_idx
while Byte(i) != 0x74 or Byte(i+1) != 0x5:
i += 1
if i > size_code:
return (-1, -1, -1)
code_start = i + 7
key = Byte(code_start) ^ 0x55
length = Dword(i+3)
return (code_start, key, length)
start_addr = 0
code_start, key, length = scan_start(start_addr)
print "%x:%x:%x" % (code_start, key, length)
decrypt_code(code_start, key, length)
MakeCode(code_start)
# raw_input()
while code_start > 0 and code_start < size_code:
code_start, key, length = scan_start(code_start)
print "%x:%x:%x" % (code_start, key, length)
if code_start + length > size_code:
break
decrypt_code(code_start, key, length)
MakeCode(code_start)
#include "pin.H"
#include <fstream>
#include <stdio.h>
using namespace std;
KNOB<string> KnobOutputFile(KNOB_MODE_WRITEONCE, "pintool", "o", "pin.out",
"specify output file name");
ofstream outFile;
ADDRINT l, h;
VOID log_ret(CONTEXT *ctx) {
PIN_REGISTER regval, regval1;
PIN_GetContextRegval(ctx, REG_RAX, reinterpret_cast<UINT8 *>(&regval));
PIN_GetContextRegval(ctx, REG_RIP, reinterpret_cast<UINT8 *>(&regval1));
outFile << std::hex << regval1.qword[0] << " : returns " << regval.qword[0]
<< endl;
}
VOID log_call(CONTEXT *ctx) {
PIN_REGISTER regval, regval1;
PIN_GetContextRegval(ctx, REG_RAX, reinterpret_cast<UINT8 *>(&regval));
PIN_GetContextRegval(ctx, REG_RIP, reinterpret_cast<UINT8 *>(&regval1));
outFile << std::hex << regval.qword[0] << " called from "
<< regval1.qword[0] << endl;
}
VOID callback_instruction(INS ins, VOID *v) {
if (INS_IsRet(ins)) {
INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)log_ret, IARG_CONTEXT,
IARG_END);
}
if (INS_IsCall(ins)) {
if (INS_IsIndirectBranchOrCall(ins) &&
INS_OperandReg(ins, 0) == REG_RAX)
INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)log_call, IARG_CONTEXT,
IARG_END);
}
// outFile << std::hex << INS_Address(ins) << " : " << INS_Disassemble(ins)
// << endl;
}
VOID fini(INT32 code, VOID *v) { outFile.close(); }
int main(int argc, char *argv[]) {
if (PIN_Init(argc, argv)) {
perror("init");
return 0;
}
outFile.open(KnobOutputFile.Value().c_str());
INS_AddInstrumentFunction(callback_instruction, 0);
PIN_AddFiniFunction(fini, 0);
PIN_StartProgram();
return 0;
}
#include "pin.H"
#include <fstream>
#include <stdio.h>
using namespace std;
KNOB<string> KnobOutputFile(KNOB_MODE_WRITEONCE, "pintool", "o", "pin.out",
"specify output file name");
ofstream outFile;
char flag[0x90];
VOID fix_jump(CONTEXT *ctx, bool zf) {
PIN_REGISTER regval;
PIN_GetContextRegval(ctx, REG_CL, reinterpret_cast<UINT8 *>(&regval));
regval.byte[0] = 1;
PIN_SetContextRegval(ctx, REG_CL, reinterpret_cast<UINT8 *>(&regval));
PIN_ExecuteAt(ctx);
}
VOID callback_instruction(INS ins, VOID *v) {
bool toset = false;
if (INS_Opcode(ins) == XED_ICLASS_AND && INS_OperandReg(ins, 0) == REG_CL &&
INS_OperandIsImmediate(ins, 1)) {
INS nxt = INS_Next(ins);
INS prev = INS_Prev(ins);
toset |= INS_Opcode(prev) == XED_ICLASS_NOT;
while (INS_Opcode(prev) != XED_ICLASS_MOV) {
prev = INS_Prev(prev);
toset |= INS_Opcode(prev) == XED_ICLASS_NOT;
}
if (INS_Valid(nxt) && INS_Valid(prev)) {
if (INS_Opcode(prev) == XED_ICLASS_MOV &&
INS_OperandReg(prev, 0) == REG_CL &&
INS_MemoryBaseReg(prev) == REG_RAX &&
INS_Opcode(nxt) == XED_ICLASS_JECXZ) {
int idx = INS_OperandMemoryDisplacement(prev, 1);
// bool toset = INS_Opcode(nxt) == XED_ICLASS_JECXZ;
// outFile << hex << idx << ":" << (INS_OperandImmediate(ins, 1)
// & 0xff) << ":" << toset << endl;
if (!toset)
flag[idx] |= (INS_OperandImmediate(ins, 1) & 0xff);
INS_InsertCall(ins, IPOINT_AFTER, (AFUNPTR)fix_jump,
IARG_CONTEXT, IARG_BOOL, toset, IARG_END);
}
}
}
}
VOID fini(INT32 code, VOID *v) {
outFile << flag << endl;
outFile.close();
}
int main(int argc, char *argv[]) {
if (PIN_Init(argc, argv)) {
perror("init");
return 0;
}
outFile.open(KnobOutputFile.Value().c_str());
INS_AddInstrumentFunction(callback_instruction, 0);
PIN_AddFiniFunction(fini, 0);
PIN_StartProgram();
return 0;
}
#include <idc.idc>
extern nxt_idx;
extern len_code;
static FindKeyNext(start_idx){
auto i = start_idx;
while(i <= len_code){
if (Byte(i) == 0xad && Byte(i+4) == 0xad)
break;
i = i + 1;
}
return i+Byte(i-4);
}
static DecryptCode(start_idx, key, ln){
auto i;
msg("%x:%x:%x\n", start_idx, key, ln);
for(i = 0; i < ln; i=i+1){
if(start_idx+i >= len_code){
print("Fail!");
break;
}
PatchDword(start_idx+(i*4), ~(key^Dword(start_idx+(i*4))));
}
}
static main(){
nxt_idx = 0x0000000006B2020;
len_code = nxt_idx + 0x2890B;
auto ln, key, idx, cnt = 0;
MakeCode(nxt_idx);
while(nxt_idx < len_code){
idx = FindKeyNext(nxt_idx);
if (idx >= len_code){
print("Done?");
break;
}
MakeCode(idx+8);
MakeDword(idx);
MakeDword(idx+4);
ln = Dword(idx);
key = Dword(idx+0x4);
PatchDword(idx, 1);
PatchDword(idx+4, 0);
nxt_idx = idx + 8;
if (nxt_idx+ln > len_code){
print("Breaks?");
break;
}
cnt = cnt + 1;
DecryptCode(nxt_idx, key, ln);
}
}
#include "pin.H"
#include <fstream>
#include <stdio.h>
using namespace std;
KNOB<string> KnobOutputFile(KNOB_MODE_WRITEONCE, "pintool", "o", "pin.out",
"specify output file name");
ofstream outFile;
char flag[0x90];
unsigned int zf_mask = 1 << 6;
VOID fix_jump(CONTEXT *ctx, bool zf) {
PIN_REGISTER regval;
PIN_GetContextRegval(ctx, REG_EFLAGS, reinterpret_cast<UINT8 *>(&regval));
if (!zf) {
regval.byte[0] |= zf_mask;
} else {
regval.byte[0] &= (~zf_mask);
}
PIN_SetContextRegval(ctx, REG_EFLAGS, reinterpret_cast<UINT8 *>(&regval));
PIN_ExecuteAt(ctx);
}
VOID callback_instruction(INS ins, VOID *v) {
if (INS_Opcode(ins) == XED_ICLASS_AND && INS_OperandReg(ins, 0) == REG_AL &&
INS_OperandIsImmediate(ins, 1)) {
INS nxt = INS_Next(ins);
INS prev = INS_Prev(ins);
if (INS_Valid(nxt) && INS_Valid(prev)) {
if (INS_Opcode(prev) == XED_ICLASS_MOV &&
INS_OperandReg(prev, 0) == REG_AL &&
INS_MemoryBaseReg(prev) == REG_RAX) {
int idx = INS_OperandMemoryDisplacement(prev, 1);
bool toset = INS_Opcode(nxt) == XED_ICLASS_JZ;
if (toset)
flag[idx] |= (INS_OperandImmediate(ins, 1) & 0xff);
INS_InsertCall(ins, IPOINT_AFTER, (AFUNPTR)fix_jump,
IARG_CONTEXT, IARG_BOOL, toset, IARG_END);
}
}
}
}
VOID fini(INT32 code, VOID *v) {
outFile << flag << endl;
outFile.close();
}
int main(int argc, char *argv[]) {
if (PIN_Init(argc, argv)) {
perror("init");
return 0;
}
outFile.open(KnobOutputFile.Value().c_str());
INS_AddInstrumentFunction(callback_instruction, 0);
PIN_AddFiniFunction(fini, 0);
PIN_StartProgram();
return 0;
}
#include <idc.idc>
extern nxt_idx;
extern len_code;
static FindKeyNext(start_idx){
auto i = start_idx;
while(i <= len_code){
if (Byte(i) == 0xad && Byte(i+4) == 0xad)
break;
i = i + 1;
}
return i+Byte(i-4);
}
static DecryptCode(start_idx, key, ln){
auto i;
msg("%x:%x:%x\n", start_idx, key, ln);
for(i = 0; i < ln; i=i+1){
if(start_idx+i >= len_code){
print("Fail!");
break;
}
PatchDword(start_idx+(i*4), key^Dword(start_idx+(i*4)));
}
}
static main(){
nxt_idx = 0x601310;
len_code = nxt_idx + 0x24C8D;
auto ln, key, idx, cnt = 0;
MakeCode(nxt_idx);
while(nxt_idx < len_code){
idx = FindKeyNext(nxt_idx);
if (idx >= len_code){
print("Done?");
break;
}
MakeCode(idx+8);
MakeDword(idx);
MakeDword(idx+4);
ln = Dword(idx);
key = Dword(idx+0x4);
PatchDword(idx, 1);
PatchDword(idx+4, 0);
nxt_idx = idx + 8;
if (nxt_idx+ln > len_code){
print("Breaks?");
break;
}
cnt = cnt + 1;
DecryptCode(nxt_idx, key, ln);
}
}
import struct
nxt_idx = 0x601310
len_code = nxt_idx + 0x24C8D
MakeCode(nxt_idx)
def find_key_next(start_idx):
i = start_idx
while True:
if Byte(i) == 0xad and Byte(i+4) == 0xad:
break
i+=1
return i+Byte(i-4)
def decrypt_code(start_idx, key, ln):
for i in xrange(ln):
if start_idx+i >= len_code:
print "Fail!"
break
PatchDword(start_idx+(i*4), key^Dword(start_idx+(i*4)))
print "decrypted"
cnt = 0
while nxt_idx < len_code:
idx = find_key_next(nxt_idx)
print hex(idx)
if idx >= len_code:
print "Done?"
break
MakeCode(idx+8)
MakeDword(idx)
print "length at %x" % (idx)
MakeDword(idx+4)
print "key at %x" % (idx+0x4)
ln = Dword(idx)
key = Dword(idx+0x4)
nxt_idx = idx+8
print cnt, hex(nxt_idx), hex(ln), hex(key)
if nxt_idx+ln > len_code:
print "Breaks?"
break
cnt+=1
decrypt_code(nxt_idx, key, ln)
@sudhackar
Copy link
Author

Pintool to call and instrument a function in a statically linked binary : https://gist.github.com/sudhackar/3fd44806e9edc73897156c1432f777ba

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment