├── AnalysisAlgorithmFunc.py ├── Fundamental_idapython.py ├── GetAllSegLen ├── GetFuncGraphic.py ├── GetTextCodeNum.py ├── GetTextFunc.py ├── JarvisOJ _APK500.py ├── README.md ├── Xctf_simple_unpack.py ├── ctf(2018 TSRC 团队赛 第二题 半加器).py ├── ctf(ISC_CrazyAndroid).py ├── xctf_Shuffle.py ├── xctf_easyjni.py ├── xctf_re2-cpp-is-awesome.py └── 逆向破解010editor.py /AnalysisAlgorithmFunc.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 第一种方法: 3 | def mul(): 4 | return 1 5 | 6 | def imul(): 7 | return 1 8 | 9 | def opand(): 10 | return 1 11 | 12 | 13 | def opor(): 14 | return 1 15 | 16 | 17 | def opnot(): 18 | return 1 19 | 20 | 21 | def div(): 22 | return 1 23 | 24 | 25 | def xor(): 26 | return 1 27 | 28 | 29 | def default(): 30 | return 0 31 | 32 | switch = { 'mul': mul, 33 | 'imul': imul, 34 | 'and': opand, 35 | 'or': opor, 36 | 'not': opnot, 37 | 'div': div, 38 | 'xor': xor, 39 | } 40 | FunAddress = [] 41 | OpAndTypeNum=dict() 42 | FindFunc = dict() 43 | def GetKeyFunc(Start, End): 44 | #把代码段中的所有函数存放在列表FunAddress中 45 | for function_ea in Functions(Start, End): 46 | FunAddress.append(function_ea) 47 | FunAddress.append(End) 48 | #遍历所有的函数 49 | for i in range(0, len(FunAddress)): 50 | #获取函数名 51 | FunctionName = GetFunctionName(FunAddress[i]) 52 | #判断是否为用户函数 53 | if i + 1 != len(FunAddress) and FunctionName[0]=='s' and FunctionName[1]=='u' and FunctionName[2]=='b': 54 | OpNum=0 55 | #清空字典 56 | OpAndTypeNum.clear() 57 | #遍历所有函数中的指令 58 | for singfuc_ea in range(FunAddress[i], FunAddress[i + 1]): 59 | flag = GetFlags(singfuc_ea) 60 | #判断是否为操作码 61 | if isCode(flag): 62 | #获取汇编指令 63 | op = GetMnem(singfuc_ea) 64 | #使用switch判断是否为算术或逻辑指令 65 | OpAndTypeNum[op] = OpAndTypeNum.get(op,0)+switch.get(op, default)() 66 | #统计算术或逻辑指令的个数 67 | for OP,value in OpAndTypeNum.items(): 68 | if value>0: 69 | OpNum+=1 70 | 71 | #如果算术或逻辑指令的个数大于1,则可以初步判断该函数为用户写的算法函数(有误差) 72 | if OpNum>2: 73 | FindFunc[FunctionName]=FunAddress[i] 74 | #print "i:",FunAddress[i],"i+1:",FunAddress[i+1] 75 | 76 | for Name, ea in FindFunc.items(): 77 | print Name, ":", ea 78 | for seg in Segments(): # 遍历所有的段 79 | if SegName(seg) == '.text': 80 | GetKeyFunc(seg, SegEnd(seg)) 81 | 82 | 第二种方法: 83 | OpAndTypeNum=dict() 84 | FindFunc = dict() 85 | def IsDealFu(Op): 86 | if Op=='mul' or Op=='imul' or Op=='and' or Op=='or' or Op=='not' or Op=='div' or Op=='xor': 87 | return 1 88 | else: 89 | return 0 90 | def GetKeyFunc(Start, End): 91 | 92 | for function_ea in Functions(Start, End): 93 | FunctionName = GetFunctionName(function_ea) 94 | #获取下个函数地址 95 | NextFunctionAddr=NextFunction(function_ea) 96 | #判断是否是用户名、地址是否合法 97 | if NextFunctionAddr!= End and FunctionName[0:3]=='sub' and len(str(NextFunctionAddr))<9: 98 | OpNum=0 99 | OpAndTypeNum.clear() 100 | 101 | for singfuc_ea in range(function_ea,NextFunctionAddr): 102 | flag = GetFlags(singfuc_ea) 103 | 104 | if isCode(flag): 105 | 106 | op = GetMnem(singfuc_ea) 107 | #统计指令数量 108 | if IsDealFu(op)==1: 109 | OpAndTypeNum[op] = OpAndTypeNum.get(op,0)+1 110 | #统计算术或逻辑指令的个数 111 | for OP,value in OpAndTypeNum.items(): 112 | if value>0: 113 | OpNum+=1 114 | #如果算术或逻辑指令的个数大于2,则可以初步判断该函数为用户写的算法函数(有误差) 115 | if OpNum>2: 116 | FindFunc[FunctionName]=function_ea 117 | #print "i:",FunAddress[i],"i+1:",FunAddress[i+1] 118 | 119 | for Name, ea in FindFunc.items(): 120 | print Name, ":", ea 121 | for seg in Segments(): # 遍历所有的段 122 | if SegName(seg) == '.text': 123 | GetKeyFunc(seg, SegEnd(seg)) 124 | -------------------------------------------------------------------------------- /Fundamental_idapython.py: -------------------------------------------------------------------------------- 1 | #1.地址获取: 2 | print hex(MinEA()) 3 | print hex(MaxEA()) 4 | print hex(ScreenEA()) 5 | for seg in Segments(): 6 | #如果为代码段,则调用GetStr 7 | if SegName(seg) == '.text': 8 | print hex(SegEnd(seg)) 9 | #2.数值获取 10 | print isLoaded(0x401114) 11 | 12 | print Byte(0x401114) 13 | 14 | print Word(0x401114) 15 | 16 | print Dword(0x401114) 17 | 18 | print Qword(0x401114) 19 | #3.操作码获取 20 | print GetDisasm(0x401114) 21 | 22 | print GetOpnd(0x401114,1) 23 | 24 | print hex(GetFlags(0x401114)) 25 | 26 | print GetMnem(0x401114) 27 | 28 | print GetOpType(0x401114,1) 29 | 30 | print GetOperandValue(0x401114,1) 31 | #4.搜索操作 32 | print hex(FindBinary(MinEA(),SEARCH_DOWN,'41 42')) 33 | 34 | print hex(FindCode(MinEA(),SEARCH_DOWN)) 35 | 36 | print hex(FindData(MinEA(),SEARCH_DOWN)) 37 | #5.数据判断操作 38 | print isCode(GetFlags(0x401114)) 39 | 40 | print isData(GetFlags(0x401114)) 41 | 42 | print isTail(0x401134) 43 | 44 | print isUnknown(0x401214) 45 | 46 | print isHead(0x401114) 47 | #6.修改操作部分 48 | PatchByte(0x401114,0x12) 49 | 50 | PatchWord(0x401124,0x12456978) 51 | 52 | PatchDword(0x401134,0x00000000) 53 | #7.交互部分 54 | AskYN(1,'is it?') 55 | 56 | Jump(0x401114) 57 | 58 | AskStr('hello!','please enter!') 59 | 60 | Message('hello!') 61 | #8.函数操作部分 62 | for seg in Segments(): 63 | 64 | #如果为代码段 65 | 66 | if SegName(seg) == '.text': 67 | 68 | for function_ea in Functions(seg,SegEnd(seg)): 69 | 70 | FunctionName=GetFunctionName(function_ea) 71 | 72 | print FunctionName 73 | 74 | nextFunc=NextFunction(function_ea) 75 | 76 | print nextFunc 77 | -------------------------------------------------------------------------------- /GetAllSegLen: -------------------------------------------------------------------------------- 1 | 第一种实现方法: 2 | def OutDataAndName(SegName,Start,End): 3 | data = [] 4 | for ea in range(Start,End): #遍历段内每个地址 5 | data.append(chr(Byte(ea))) #获取字节及字节对应的字符 6 | print SegName,len(data) 7 | ea=ScreenEA() 8 | for seg_ea in Segments(): 9 | OutDataAndName(SegName(seg_ea),seg_ea, SegEnd(seg_ea)) 10 | 11 | 第二种实现方法:使用switch进行选择判断 12 | #-*- coding:utf-8 -*- 13 | segdata=[] 14 | def text(): 15 | return 'text:'+str(len(segdata)) 16 | 17 | 18 | def idata(): 19 | return 'idata:'+str(len(segdata)) 20 | 21 | 22 | def rdata(): 23 | return 'rdata:'+str(len(segdata)) 24 | 25 | 26 | def default(): 27 | return 'data:'+str(len(segdata)) 28 | 29 | 30 | switch = {'.text': text, 31 | '.idata': idata, 32 | '.rdata': rdata, 33 | } 34 | for seg in Segments(): 35 | segdata=[] 36 | for seg_ea in range(SegStart(seg),SegEnd(seg)):#遍历所有字段 37 | segdata.append(chr(Byte(seg_ea))) 38 | choice = SegName(seg_ea) # 获取选择 39 | print switch.get(choice, default)() # 执行对应的函数,如果没有就执行默认的函数 40 | 41 | 42 | 第三种方法:使用字典存储段名和段的长度 43 | AllData=dict()#字典数据类型 44 | for seg in Segments(): 45 | segdata=[] 46 | for seg_ea in range(SegStart(seg),SegEnd(seg)):#遍历所有字段 47 | segdata.append(chr(Byte(seg_ea))) 48 | AllData[SegName(seg_ea)]=segdata 49 | for segName ,data in AllData.items():#输出字段名和每个字段的大小 50 | print segName,len(data) 51 | 52 | -------------------------------------------------------------------------------- /GetFuncGraphic.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | from sets import Set 3 | import pydot 4 | 5 | # 获取段的起始地址 6 | ea = ScreenEA() 7 | 8 | callers = dict() 9 | callees = dict() 10 | 11 | # 遍历所有的函数 12 | for function_ea in Functions(SegStart(ea), SegEnd(ea)): 13 | 14 | f_name = GetFunctionName(function_ea) 15 | 16 | # 遍历每个函数的引用函数 17 | for ref_ea in CodeRefsTo(function_ea, 0): 18 | 19 | # 引用函数名 20 | caller_name = GetFunctionName(ref_ea) 21 | 22 | #将当前函数添加到引用函数调用的函数列表中 23 | callees[caller_name] = callees.get(caller_name, Set()) 24 | 25 | callees[caller_name].add(f_name) 26 | 27 | #创建图像对象 28 | g = pydot.Dot(type='digraph') 29 | 30 | #设置默认值 31 | g.set_rankdir('LR') 32 | g.set_size('11,11') 33 | g.add_node(pydot.Node('node', shape='ellipse', color='lightblue', style='filled')) 34 | g.add_node(pydot.Node('edge', color='lightgrey')) 35 | 36 | 37 | #获取所有函数 38 | functions = Set(callees.keys()+callers.keys()) 39 | 40 | # 对于每个函数和每个被引用的函数,添加相应的边。 41 | for f in functions: 42 | if callees.has_key(f): 43 | for f2 in callees[f]: 44 | g.add_edge(pydot.Edge(f, f2)) 45 | 46 | # 将输出写入到Postscript文件 47 | g.write_ps('example6.ps') 48 | -------------------------------------------------------------------------------- /GetTextCodeNum.py: -------------------------------------------------------------------------------- 1 | 第一种方法: 2 | num=[] 3 | Mnem=[] 4 | def GetMnemNum(Start,End): 5 | for head in Heads(Start,End):#遍历所有指令,head为地址 6 | if isCode(GetFlags(head)):#判断是否为指令 7 | flag=GetMnem(head)#获取汇编指令 8 | try: 9 | xb=Mnem.index(flag) #判断有无该指令 10 | except: 11 | Mnem.append(flag) 12 | num.append(0) 13 | num[len(num)-1]=1 14 | else: 15 | num[Mnem.index(flag)]=num[Mnem.index(flag)]+1 #统计指令个数 16 | 17 | for i in range(0,len(num)): 18 | print Mnem[i],':',num[i] 19 | 20 | for seg in Segments(): #遍历所有的段 21 | GetMnemNum(seg,SegEnd(seg)) 22 | 23 | 第二种方法: 24 | Mnem=[] 25 | single=[] 26 | Num=[] 27 | def GetMnemNum(Start,End): 28 | for head in Heads(Start,End):#遍历所有指令,head为地址 29 | if isCode(GetFlags(head)):#判断是否为指令 30 | flag=GetMnem(head)#获取汇编指令 31 | Mnem.append(flag) 32 | Mnem.sort(reverse=True)#排序 33 | single.append(Mnem[0]) 34 | for i in range(1,len(Mnem)): 35 | if Mnem[i]==Mnem[i-1]: 36 | continue 37 | else:#元素不同,则加入,统计不同元素 38 | single.append(Mnem[i]) 39 | for i in range(0,len(single)): 40 | print single[i],':',Mnem.count(single[i]) 41 | for seg in Segments(): #遍历所有的段 42 | GetMnemNum(seg,SegEnd(seg)) 43 | 44 | 第三种方法: 45 | CodeAndNum=dict() 46 | def GetMnemNum(Start,End): 47 | for head in Heads(Start,End):#遍历所有指令,head为地址 48 | if isCode(GetFlags(head)):#判断是否为指令 49 | flag=GetMnem(head)#获取汇编指令 50 | CodeAndNum[flag]=CodeAndNum.get(flag,0)+1 51 | items=CodeAndNum.items() 52 | NewItems=[[v[1],v[0]] for v in items] 53 | NewItems.sort() 54 | #print NewItems 55 | for i in range(0,len(NewItems)): 56 | t=NewItems[i] 57 | print t[1],t[0] 58 | for seg in Segments(): #遍历所有的段 59 | GetMnemNum(seg,SegEnd(seg)) 60 | -------------------------------------------------------------------------------- /GetTextFunc.py: -------------------------------------------------------------------------------- 1 | #-*- coding:utf-8 -*- 2 | #第一种方法: 3 | FunAndNum=dict() #保存函数名和函数数量 4 | def GetFuncAndNum(Start,End): 5 | for function_ea in Functions(Start, End): 6 | FunctionName=GetFunctionName(function_ea)#获取函数名 7 | FunAndNum[FunctionName]=FunAndNum.get(FunctionName,0)+1 #函数数量加一 8 | for Name,Num in FunAndNum.items(): 9 | print "Name:",Name," Num ",Num 10 | for seg in Segments(): #遍历所有的段 11 | if SegName(seg)=='.text': 12 | GetFuncAndNum(seg,SegEnd(seg)) 13 | 14 | #第二种方法: 15 | num=[] 16 | Func=[] 17 | def GetFuncAndNum(Start,End): 18 | for function_ea in Functions(Start, End): 19 | FunctionName=GetFunctionName(function_ea) 20 | try: 21 | xb=Func.index(FunctionName) #判断有无该函数 22 | except: 23 | Func.append(FunctionName) 24 | num.append(0) 25 | num[len(num)-1]=1 26 | else: 27 | num[Func.index(FunctionName)]=num[Func.index(FunctionName)]+1 #统计指令个数 28 | 29 | Min=min(num) #列表最小值 30 | Max=max(num) #列表最大值 31 | 32 | #按函数个数大小有序输出函数名 33 | for i in range(Min,Max+1): 34 | for j in range(0,len(num)): 35 | if num[j]==i: 36 | print Func[j],":",num[j] 37 | 38 | for seg in Segments(): #遍历所有的段 39 | if SegName(seg)=='.text': 40 | GetFuncAndNum(seg,SegEnd(seg)) 41 | 42 | 第三种方法: 43 | num=[] 44 | Func=[] 45 | def GetFuncAndNum(Start,End): 46 | str='' 47 | for function_ea in Functions(Start, End): 48 | FunctionName=GetFunctionName(function_ea) 49 | FunctionName1=FunctionName+'0'#加0,区分每个函数 50 | #print str 51 | xb=str.find(FunctionName) 52 | if xb!=-1: 53 | if xb-1>=0 and str[xb-1]!='0':#如果找到的是包含查找函数名的函数,则回到循环 54 | continue 55 | num[Func.index(FunctionName1)]=num[Func.index(FunctionName1)]+1 56 | else: 57 | str+=FunctionName1 58 | num.append(1) #初始化 59 | Func.append(FunctionName1) 60 | for i in range(0,len(num)): 61 | print Func[i][0:len(Func[i])-1],":",num[i] 62 | for seg in Segments(): #遍历所有的段 63 | if SegName(seg)=='.text': 64 | GetFuncAndNum(seg,SegEnd(seg)) 65 | 66 | -------------------------------------------------------------------------------- /JarvisOJ _APK500.py: -------------------------------------------------------------------------------- 1 | #1.使用如下脚本可以获取关键字符串v50 2 | # -*- coding:utf-8 -*- 3 | def GetStr(): 4 | #str_2C87字符串所在的位置 5 | str_addr=0x2C87 6 | tstr='' 7 | while(1): 8 | #判断循环是否结束 9 | if chr(Byte(str_addr))=='g' and chr(Byte(str_addr+1))=='X': 10 | break 11 | #叠加字符串字符生成字符串 12 | tstr+=chr(Byte(str_addr)) 13 | str_addr+=1 14 | #加上最后两个字符 15 | return tstr+'gX' 16 | print GetStr() 17 | #对应ida中的strdeal函数 18 | def strdeal(str,c): 19 | index=0 20 | s='' 21 | while(index=c: 56 | return (ord(c)-ord('0'))*t 57 | #如果是a-f的数 58 | for i in range(6): 59 | if Hex[i]==c: 60 | return Ord[i]*t 61 | #把ans字符串中十六进制数转换成十进制 62 | def getStrOrd(i): 63 | ord=[] 64 | j=0 65 | ans=0 66 | t=i 67 | #每两位进行转换 68 | while j<31: 69 | #ans追踪转换后的数值 70 | ans=0 71 | if j==t: 72 | ans+=0 73 | #如果j==i,把t标记为-1 74 | t=-1 75 | else: 76 | ans+=ChrToOrd(s[j],1) 77 | j+=1 78 | if j==31: 79 | ord.append(ans) 80 | break 81 | if j==t: 82 | ans+=0 83 | #如果j==i,把t标记为-1 84 | t=-1 85 | else: 86 | ans+=ChrToOrd(s[j],2) 87 | j+=1 88 | ord.append(ans) 89 | return ord 90 | def getC1Sz(): 91 | for i in range(32): 92 | t=getStrOrd(i) 93 | c1.append(t) 94 | #判断是否为可见字符 95 | def isSee(t): 96 | if(t>32 and t<127): 97 | return 0 98 | else: 99 | return 1 100 | def getFlag(): 101 | getC1Sz() 102 | for t in c1: 103 | XorC1 = [] 104 | flag = '' 105 | print 't ',t 106 | for i in range(16): 107 | t1 = t[i]^str_4004[i] 108 | #print 'p ',p 109 | XorC1.append(t1) 110 | #XorC1对应str 111 | XorC1 = XorC1[-7:] + XorC1[:-7] 112 | #把str中的前四个元素减1 113 | for i in range(4): 114 | XorC1[i] = XorC1[i]- 1 115 | #把str中的每个元素进行异或处理 116 | for i in range(16): 117 | t2 = XorC1[i] ^ i 118 | #如果不是可见字符则退出 119 | if(isSee(t2)==1): 120 | break 121 | flag+= chr(t2) 122 | else: 123 | print flag 124 | break 125 | getFlag() 126 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # idapython- 2 | idapython练习脚本 3 | -------------------------------------------------------------------------------- /Xctf_simple_unpack.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | def GetStr(start,end): 3 | flag='' 4 | for addr in range(start,end): 5 | #判断有没有找到'mov esi, offset flag' 6 | if GetOpnd(addr,0)=='esi' and 'flag' in GetOpnd(addr,1): 7 | #获取flag所在的地址 8 | address=hex(Dword(addr))[0:8] 9 | #把地址转换成十进制数 10 | taddress=int(address,16) 11 | #使用循环结构获取flag 12 | while(1): 13 | 14 | flag+=chr(Byte(taddress)) 15 | #判断flag读取是否结束 16 | if chr(Byte(taddress))=='}': 17 | break 18 | taddress+=1 19 | print flag 20 | break 21 | 22 | 23 | for seg in Segments(): # 遍历所有的段 24 | #如果为代码段,则调用GetStr 25 | if SegName(seg) == '.text': 26 | GetStr(seg,SegEnd(seg)) 27 | -------------------------------------------------------------------------------- /ctf(2018 TSRC 团队赛 第二题 半加器).py: -------------------------------------------------------------------------------- 1 | ''' 2 | 求解该题,我一共使用了三步 3 | ''' 4 | #1.找到使用'invalid argument'字符串的地方 5 | #invalid argument的前12个字符序列 6 | str1='69 6E 76 61 6C 69 64 20 61 72 67 75' 7 | def GetStrPos(start,end): 8 | #查找str2字符串所在的位置 9 | BinaryAddr=FindBinary(start,SEARCH_DOWN,str1) 10 | #判断查找是否失败 11 | if hex(BinaryAddr)=='0xffffffffL': 12 | print 'not bin' 13 | else: 14 | print 'Binary ',hex(BinaryAddr) 15 | #跳转到字符串所在的位置 16 | Jump(BinaryAddr) 17 | #遍历调用该字符串的位置 18 | for refhs in XrefsTo(BinaryAddr, flags=0): 19 | print "x: %s x.frm 0x%x"%(refhs,refhs.frm) 20 | Jump(refhs.frm) 21 | #做注释 22 | MakeComm(refhs.frm,"使用了invalid argument字符串") 23 | #询问用户 24 | AskYN(1,'看完'+hex(refhs.frm)+'地址处的代码吗?') 25 | 26 | for seg in Segments(): 27 | #如果为只读数据段,则调用GetStrPos 28 | if SegName(seg) == '.rdata': 29 | #print 'seg ',hex(seg) 30 | GetStrPos(seg,SegEnd(seg)) 31 | 32 | #2.找到使用操作指令的位置,分析找到起到关键作用的操作指令 33 | import re 34 | #算术逻辑操作码 35 | CalOp=['mul','imul','or','not','div','xor'] 36 | def isCalOp(Op): 37 | for i in CalOp: 38 | if Op==i: 39 | return 1 40 | return 0 41 | #清空字符串中的空格 42 | def clearspace(str1): 43 | str2='' 44 | for i in str1: 45 | if i==' ': 46 | continue 47 | else: 48 | str2+=i 49 | return str2 50 | #判断整个指令是否有注释 51 | def isComment(str): 52 | for i in str: 53 | if i==';': 54 | return True 55 | return False 56 | #判断算术逻辑指令有没有使用十六进制数进行计算 57 | def isHex(str1): 58 | #使用正则表达式构造匹配十六进制数的字符串 59 | pattern= re.compile(r'[-]*[0-9a-fA-F]+') 60 | sNum='' 61 | try: 62 | if isComment(str1): 63 | xb=str1.rindex(';') 64 | sNum=str1[str1.rindex(',')+1:xb] 65 | else: 66 | sNum=str1[str1.rindex(',')+1:] 67 | #找到十六进制字符串,若没有找到,则抛出异常 68 | ans=pattern.match(sNum) 69 | #判断找到的十六进制数是否准确 70 | if ans.group(0)==sNum and sNum!='0': 71 | return 1 72 | except: 73 | return 0 74 | else: 75 | return 0 76 | def GetOp(start,end): 77 | for addr in range(start,end): 78 | #获取操作指令 79 | Op=GetMnem(addr) 80 | #判断是否是操作指令 81 | if isCode(GetFlags(addr)): 82 | if isCalOp(Op)==1: 83 | #获取某地址处的字符串,包括指令和注释 84 | Comm=GetDisasm(addr) 85 | Comm=clearspace(Comm) 86 | if isHex(Comm)==1: 87 | #往ida中添加注释 88 | MakeComm(addr,"使用了操作码:"+Op) 89 | print "Op_addr ",hex(addr) 90 | for seg in Segments(): 91 | #是否为代码段 92 | if SegName(seg) == '.text': 93 | GetOp(seg,SegEnd(seg)) 94 | 95 | #3.分析关键的操作指令,得出如下求flag的算法 96 | def GetAns(): 97 | str="invalid argument" 98 | flag="" 99 | for i in range(0,len(str)): 100 | if i==7: 101 | flag+='A' 102 | else: 103 | flag+=chr(ord(str[i])^28^31) 104 | print flag 105 | 106 | GetAns() 107 | -------------------------------------------------------------------------------- /ctf(ISC_CrazyAndroid).py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | from random import choice 3 | pre6='pctfef' 4 | hehe3_8="Pctf2016" 5 | hehe3_8_o=[] 6 | javastr='170501' 7 | base='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+' 8 | #把hehe3_8中的字符转换成十进制数 9 | def Hehe3_8ToOrd(): 10 | for i in hehe3_8: 11 | hehe3_8_o.append(ord(i)) 12 | 13 | def GetBase(str_addr): 14 | base='' 15 | while(1): 16 | #判断循环是否结束 17 | if hex(Byte(str_addr))=='0x0': 18 | break 19 | #叠加字符串字符生成字符串 20 | base+=chr(Byte(str_addr)) 21 | str_addr+=1 22 | return base 23 | def Getpadding(str_addr): 24 | tpadding='' 25 | while(1): 26 | #判断循环是否结束 27 | if hex(Byte(str_addr))=='0x0': 28 | break 29 | #叠加字符串字符生成字符串 30 | tpadding+=chr(Byte(str_addr)) 31 | str_addr+=1 32 | return tpadding 33 | def getlast(): 34 | #base=GetBase(0x6004) 35 | last=base[-12:] 36 | return last 37 | def crazy(a,b): 38 | t1=a<<4 39 | t2=~b+1 40 | t2=0xD0-t2 41 | ans=(t2 ^ t1) | (t2 &t1 ) 42 | return ans & 0xFF 43 | 44 | def hehe2(): 45 | AnsT='' 46 | AllT=[] 47 | AnsT='' 48 | Hehe3_8ToOrd() 49 | last=getlast() 50 | for i in range(0,len(hehe3_8_o)): 51 | t= [] 52 | for j in last: 53 | for k in last: 54 | if crazy(ord(j), ord(k)) == hehe3_8_o[i]: 55 | t.append(j + k) 56 | AllT.append(t) 57 | for i in AllT: 58 | #在列表I中,找出任意值 59 | AnsT += choice(i) 60 | AnsTL = list(AnsT) 61 | index=[5,6,9,11,12,13,14,15] 62 | i=0 63 | #对列表值进行交换 64 | while i ='0': 35 | if int(new_addr,16)0x7f: 77 | break 78 | szint.append(Dword(taddress)) 79 | taddress+=4 80 | break 81 | for seg in Segments(): 82 | if SegName(seg) == '.text': 83 | getSzInt(seg,SegEnd(seg)) 84 | str1=GetStr() 85 | GetAns(seg,SegEnd(seg),str1) 86 | -------------------------------------------------------------------------------- /逆向破解010editor.py: -------------------------------------------------------------------------------- 1 | ''' 2 | 暴力破解010editor,我一共分为了三步 3 | ''' 4 | 1.找到使用了‘Invalid name or password. Please enter your name and password exa’字符串的地方 5 | import time 6 | #Invalid name or password的前12个字符序列 7 | str1='49 6E 76 61 6C 69 64 20 6E 61 6D 65' 8 | def GetStrPos(start,end): 9 | #查找str2字符串所在的位置 10 | BinaryAddr=FindBinary(start,SEARCH_DOWN,str1) 11 | #判断查找是否失败 12 | if hex(BinaryAddr)=='0xffffffffL': 13 | print 'not find' 14 | else: 15 | print 'BinaryAddr ',hex(BinaryAddr) 16 | #跳转到字符串所在的位置 17 | Jump(BinaryAddr) 18 | #遍历调用该字符串的位置 19 | for refhs in XrefsTo(BinaryAddr, flags=0): 20 | print "refhs: %s refhs.frm 0x%x"%(refhs,refhs.frm) 21 | #暂停2秒 22 | time.sleep(2) 23 | #跳转到引用该字符串的地方 24 | Jump(refhs.frm) 25 | #做注释 26 | MakeComm(refhs.frm,"使用了Invalid name or password. Please enter your name and password exa字符串") 27 | 28 | for seg in Segments(): 29 | #如果为只读数据段,则调用GetStrPos 30 | if SegName(seg) == '.rdata': 31 | GetStrPos(seg,SegEnd(seg)) 32 | 33 | 2.找到使用‘Invalid name or password. Please enter your name and password exa’字符串附近的跳转指令,分析找到关键跳 34 | def isJmp(addr): 35 | SzOp=['jo', 'jno', 'jb', 'jnb', 'je', 'jne', 'jbe', 'ja', 'js', 'jns', 'jp', 'jnz', 'jl', 'jnl', 'jng', 'jg', 'jcxz', 'jecxz','jmpe'] 36 | #获取操作指令 37 | Op=GetMnem(addr) 38 | #判断是否是操作指令 39 | if isCode(GetFlags(addr)): 40 | #判断是否是跳转指令 41 | for Sin in SzOp: 42 | if Sin==Op: 43 | return 1 44 | return 0 45 | def isRightJmp(start,end): 46 | for ea in range(start,end): 47 | if isJmp(ea)==1: 48 | Disasm=GetDisasm(ea) 49 | #判断指令后面的操作数是否为地址 50 | if Disasm[-9:-4]=='14070': 51 | #获取跳转地址 52 | new_addr=Disasm[-9:] 53 | #输出出现在‘Invalid name or password. Please ’附近的跳转指令 54 | print 'new_addr',new_addr 55 | MakeComm(ea,"跳转指令") 56 | for seg in Segments(): 57 | if SegName(seg) == '.text': 58 | isRightJmp(seg,SegEnd(seg)) 59 | 3.Nop掉关键跳 60 | PatchDword(0x140707B6B,0x00000000) 61 | --------------------------------------------------------------------------------