标签:混淆 cti 一个 byte div 指令 assert 编译 对象
例子中脚本解释:
0ctf_momo_3
由于程序对输入验证是单字符比较,可以用爆破的方式,由于mov混淆不具有变异特性,验证分支入口特点明显,有以下三个:
edx, dword ptr [edx*4 + 0x81fe260] al, byte ptr [0x81fe6e0] dl, byte ptr [0x81fe6e4]
将所有的验证分支存储起来之后,遍历爆破。
爆破验证指定两个寄存器中的值相等即输入字符正确。
insn_bytes = ‘‘.join(p.loader.memory.read_bytes(addr, size))
读取所需执行的字节
insns = [] for cs_insn in p.arch.capstone.disasm(insn_bytes, addr): insns.append(CapstoneInsn(cs_insn))
for _path in _path_list:
_cs = _load_lib(_path)
if _cs is not None:
break
根据程序的平台架构选择相应的库文件,将指定字节反编译,并根据指令类型生成CapstoneInsn对象。得到一个CapstoneInsn对象列表。
CapstoneInsn对象数据形如: 地址+指令+操作数
block = CapstoneBlock(addr, insns, 0, p.arch)
将CapstoneInsn对象转化为字符。
state.posix.files[0].content.store(0, flag + "\n")
相当于read(0,flag,len(flag))
e = p.surveyors.Explorer(start=state, find=(target,)) e.run()
运行模拟引擎(耗时原因),在地址范围内生成状态列表
assert len(e.found) == 1 np = e.found[0]
确保到达目标地址可行,取第一种状态 np类型为SimState
while(True): nb_size = target - np.addr if nb_size <= 0: break np=p.factory.successors(np, size=nb_size).flat_successors[0]
将指定的state进行具体化模拟
al = np.regs.eax[7:0] dl = np.regs.edx[7:0] al_val = al._model_concrete.value dl_val = dl._model_concrete.value if al_val == dl_val: flag_arr.append(trychar) break
对进行比较所用的寄存器中的值取出来比较,如果相等则保存该值。
爆破完成后输出即可,循环执行模拟引擎所以相当耗时。
标签:混淆 cti 一个 byte div 指令 assert 编译 对象
原文地址:http://www.cnblogs.com/fancystar/p/7893248.html