-
-
Save sudhackar/ad9c15851f274b3248ef1645abee9ae8 to your computer and use it in GitHub Desktop.
ida python and idc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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)]))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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()); | |
} | |
); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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)) | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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), | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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 *>(®val)); | |
PIN_GetContextRegval(ctx, REG_RIP, reinterpret_cast<UINT8 *>(®val1)); | |
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 *>(®val)); | |
PIN_GetContextRegval(ctx, REG_RIP, reinterpret_cast<UINT8 *>(®val1)); | |
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; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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 *>(®val)); | |
regval.byte[0] = 1; | |
PIN_SetContextRegval(ctx, REG_CL, reinterpret_cast<UINT8 *>(®val)); | |
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; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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 *>(®val)); | |
if (!zf) { | |
regval.byte[0] |= zf_mask; | |
} else { | |
regval.byte[0] &= (~zf_mask); | |
} | |
PIN_SetContextRegval(ctx, REG_EFLAGS, reinterpret_cast<UINT8 *>(®val)); | |
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; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Pintool to call and instrument a function in a statically linked binary : https://gist.github.com/sudhackar/3fd44806e9edc73897156c1432f777ba