from capstone import *
CODE = open(r"f:\新建文件夹\样本\dmp\kctf_crackme_sbls_00A41000.bin", mode='rb').read()
md = Cs(CS_ARCH_X86, CS_MODE_32)
md.detail = True
def MdDisasmLiteOne(md:Cs,eipCode,obfBase):
for v in md.disasm(eipCode, obfBase,1):
return v
def PrintIns(ins:CsInsn):
print("0x%x:\t%s\t%s" %(ins.address, ins.mnemonic, ins.op_str))
return
def GetInsStr(ins:CsInsn):
return "%s %s" %(ins.mnemonic, ins.op_str)
base = 0x00400000
obfBase = 0x000A41000
eipBlockAddress = obfBase-base
eipCode = CODE[eipBlockAddress:eipBlockAddress+16]
currentBlockList = []
ins = MdDisasmLiteOne(md=md,eipCode=eipCode,obfBase=obfBase)
scriptInsList = []
def ReadDword(addr):
fov = addr - base
v = CODE[fov:fov +4]
v = int.from_bytes(v,"little")
return v
def PrintScriptInsList(scriptInsList:list):
for i in scriptInsList:
print(i + ";")
def PrintScriptInsListOne(scriptInsList:list):
v = ""
for i in scriptInsList:
v += i + ";"
print(v)
def WriteScriptInsList(scriptInsList:list):
fo = open("reverseCFG_6.txt", "w")
fo.write("")
fo = open("reverseCFG_6.txt", "a")
for i in scriptInsList:
fo.write(i + "\r\n")
def WriteScriptInsListOne(scriptInsList:list):
fo = open("reverseCFG_6.txt", "w")
v = ""
for i in scriptInsList:
v += i + ";"
fo.write(v)
GlobalVariantTable = {}
def GetInsFromInsOffset(ins:CsInsn,offset):
if offset < 0:
return None
else:
for i in range(0,offset):
nextip = ins.address + ins.size
nextfov = nextip-base
eipCode = CODE[nextfov:nextfov+16]
ins = MdDisasmLiteOne(md=md,eipCode=eipCode,obfBase=nextip)
return ins
# push dword ptr ds:[0x00433088]
def FindGlobalVariantIsInvail(baseIns:CsInsn):
globalVariantAddress = baseIns.operands[0].mem.disp
globalVariantIsInvail = True
ins = baseIns
point = 0
itba = []
sil = []
while point < 200:
basePoint = point
# str = GetInsStr(ins=ins)
if ins.mnemonic == "push":
if ins.operands[0].mem.disp == globalVariantAddress:
# PrintIns(ins=ins)
itba.append(ins)
point +=1
if ins.mnemonic == "mov":
if ins.operands[0].mem.disp == globalVariantAddress:
# PrintIns(ins=ins)
itba.append(ins)
if ins.mnemonic == "pop":
if ins.operands[0].mem.disp == globalVariantAddress:
# PrintIns(ins=ins)
itba.append(ins)
ins = GetInsFromInsOffset(ins,point - basePoint + 1)
opsize = len(ins.operands)
if opsize > 1:
if ins.operands[1].mem.disp == disp:
PrintIns(ins=ins)
globalVariantIsInvail = False
point += 1
for ins in itba:
ins:CsInsn = ins
if ins.mnemonic == "push":
dins = GetInsFromInsOffset(ins,1)
if GetInsStr(dins) == "mov dword ptr [esp], eax":
sil.append("asm {},nop,1".format(hex(ins.address)))
sil.append("asm {},nop,1".format(hex(ins.address+6)))
sil.append("asm {},\"push eax\",1".format(hex(ins.address)))
if globalVariantIsInvail == True:
if ins.mnemonic == "mov":
sil.append("asm {},nop,1".format(hex(ins.address)))
if ins.mnemonic == "pop":
sil.append("asm {},nop,1".format(hex(ins.address)))
return sil
try:
while 1:
# PrintIns(ins=ins)
currentBlockList.append(ins)
if ins.mnemonic == "push":
disp = ins.operands[0].mem.disp
if disp>=0x0433000 and disp<=obfBase:
PrintIns(ins=ins)
if (disp in GlobalVariantTable) == False:
GlobalVariantTable[disp] = FindGlobalVariantIsInvail(ins)
if GlobalVariantTable[disp] != []:
for i in GlobalVariantTable[disp]:
scriptInsList.append(i)
ins = GetInsFromInsOffset(ins,1)
continue
nextip = ins.address+ins.size
nextfov = nextip-base
eipCode = CODE[nextfov:nextfov+16]
ins = MdDisasmLiteOne(md=md,eipCode=eipCode,obfBase=nextip)
except:
WriteScriptInsList(scriptInsList)
print("over 6")
// __readeflags
(i.op is idaapi.cit_expr and
i.cexpr.op is idaapi.cot_asg and
i.cexpr.x.op is idaapi.cot_var and
i.cexpr.y.op is idaapi.cot_call and
i.cexpr.y.x.op is idaapi.cot_helper)
(i.op is idaapi.cit_expr and
i.cexpr.op is idaapi.cot_asg and
i.cexpr.x.op is idaapi.cot_var and
i.cexpr.y.op is idaapi.cot_cast and
i.cexpr.y.x.op is idaapi.cot_call and
i.cexpr.y.x.x.op is idaapi.cot_helper)
// __writeeflags
(i.op is idaapi.cit_expr and
i.cexpr.op is idaapi.cot_call and
i.cexpr.x.op is idaapi.cot_helper and
i.cexpr.a[0].op is idaapi.cot_var)
// __writeeflags
(i.op is idaapi.cit_expr and
i.cexpr.op is idaapi.cot_call and
i.cexpr.x.op is idaapi.cot_helper and
i.cexpr.a[0].op is idaapi.cot_var)
编写如下代码,即可去除 ctree 中特定类型的指令。
import idaapi
import idc
import ida_bytes
import ida_hexrays
class JunkCodeVister(idaapi.ctree_visitor_t):
def __init__(self, cfunc):
global itlist
idaapi.ctree_visitor_t.__init__(self, idaapi.CV_PARENTS)
itlist = []
s = cfunc.body
s.swap(cfunc.body)
self.cfunc = cfunc
self.del_point = 0
def isjunk(self,ins) -> "int":
i = ins
if (i.op is idaapi.cit_expr and
i.cexpr.op is idaapi.cot_asg and
i.cexpr.x.op is idaapi.cot_var and
i.cexpr.y.op is idaapi.cot_call and
i.cexpr.y.x.op is idaapi.cot_helper):
return True
if (i.op is idaapi.cit_expr and
i.cexpr.op is idaapi.cot_call and
i.cexpr.x.op is idaapi.cot_helper and
i.cexpr.a[0].op is idaapi.cot_var):
return True
if (i.op is idaapi.cit_expr and
i.cexpr.op is idaapi.cot_call and
i.cexpr.x.op is idaapi.cot_helper and
i.cexpr.a[0].op is idaapi.cot_cast and
i.cexpr.a[0].x.op is idaapi.cot_var):
return True
return False
def visit_insn(self, ins: idaapi.cinsn_t) -> "int":
self.del_point +=1
if ins.op == idaapi.cit_if and self.del_point !=1:
my_visitor = JunkCodeVister(self.cfunc)
my_visitor.apply_to(ins, ins)
self.prune_now()
return 0
if not ins.cexpr:
return 0
f = self.isjunk(ins)
if f == True:
pd = self.parent_insn().details
dit = self.parent_insn().details.find(ins)
pd.erase(dit)
pass
return 0
class DelJunkCodeVister(idaapi.ctree_visitor_t):
def __init__(self, cfunc):
idaapi.ctree_visitor_t.__init__(self, idaapi.CV_FAST)
self.cfunc = cfunc
return
def main():
func = idaapi.get_func(idc.here())
cfunc = idaapi.decompile(func.start_ea)
my_visitor = JunkCodeVister(cfunc)
my_visitor.apply_to(cfunc.body, None)
print("deover")
if __name__ == '__main__':
main()