花指令
Pizza的脚本中是通过get_bytes和patch_bytes两个API来将所有机器码读出然后再Patch回去的
中间匹配pattern的过程是构造字符串然后find来控制
这样操作的优点是find的效率奇高,对于大量数据的处理非常的快
而我们之前使用的逐字符匹配pattern的优点是可控性比较强,例如通配符的存在
然而缺点就是速度很慢,对于数量级较大时格外明显,因此试图修复
刚开始以为速度在于多次取Byte,改成Python同样用get_bytes取出后再匹配,发现仍然很慢
于是想到了通过find来快速找到pattern开头非?的部分,然后再用原来的matchBytes匹配,发现能得到一定的效率提升,但还是有点问题
from ida_bytes import get_bytes, patch_bytes
addr = 0x401000
end = 0x4b9cd0
buf = "".join(["%02x"%ord(i) for i in get_bytes(addr,end-addr)]).lower()
def patch_at(p, ln):
global buf
buf = buf[:p] + "90" * ln + buf[p+ln:]
def matchBytes(s, Condition):
l = len(Condition)
for i in range(len(Condition)):
if(Condition[i]!="?" and s[i]!=Condition[i]):
return false
return True
Condition = "E801000000??83C404".lower()
l = len(Condition)/2
# for i in range(end-addr):
i = buf.find(Condition[:Condition.find("?")])
tmp = -1
while(i!=tmp):
i = tmp
if(matchBytes(buf[i:], Condition)):
patch_at(i, l)
print(i, l)
tmp = i+1+buf[i+1:].find(Condition[:Condition.find("?")])
# print(buf)
buf = "".join([chr(int(buf[2*i]+buf[2*i+1], 16)) for i in range(len(buf)//2) ])
patch_bytes(addr,buf)
print("Done")
自己实现匹配pattern的都是傻哔-!
from ida_bytes import get_bytes, patch_bytes
import re
addr = 0x401000
end = 0x4b9cd0
# buf = "".join(["%02x"%ord(i) for i in get_bytes(addr,end-addr)])
buf = get_bytes(addr, end-addr)
def handler1(s):
s = s.group(0)
print("".join(["%02x"%ord(i) for i in s]))
s = "\x90"*len(s)
return s
def handler2(s):
opcode1 = ord(s.group(1))
opcode2 = ord(s.group(2))
if(opcode1|1 == opcode2|1):
return "\x90"*5
else:
return s.group(0)
pattern1 = r"\xE8[\x01-\x03]\x00\x00\x00((?!\xE8).){1,5}(\x83\xC4\x04|\x58|\x83\x04\x24\x06\xc3)"
pattern2 = r"([\x70-\x7f])\x03([\x70-\x7f])\x01."
buf = re.sub(pattern1, handler1, buf, flags=re.I)
# buf = "".join([chr(int(buf[2*i]+buf[2*i+1], 16)) for i in range(len(buf)//2) ])
patch_bytes(addr, buf)
print("Done")
又简单又快(╯‵□′)╯︵┻━┻现成的sub函数提供了替换功能,handler提供了截取通配符并有选择地修改替换内容的功能,简直量身定做啊这个
pattern里有一个((?!E8).)
的部分,是(.*?)
的对.
的替换,要求中间部分不存在E8,否则可能会导致前一个E8衔接到后一个E8的83C404上,造成大范围的匹配
做完上述的以后突然想起来可以通过{1,5}
来限定通配符.
的匹配次数,进而控制大范围匹配的orz
另外还有\xE8
之后的第二个字符用[\x01-\x03]
做了限定
一共三处防止多余匹配的措施,对于其他题目可能会导致漏解,届时请自行修正~
另外还有(\x83\xc4\x01 | \x58 | \x83\x04\x24\x06\xc3)
的多选结构,意味着以\x83\xc4\x01
(add esp,4)或\x58
(pop eax)或\x83\x04\x24\x06\xc3
(add [esp], 6 ; retn)结尾的三种情况都会被匹配到并全部清除
这里可以想到的一种漏解可能情况是add [esp], 7; retn ; bad byte ; correct bytes;
这种形式,因为它没有确定的结束字符所以相对麻烦一点
感觉可以通过多写几个通配符做冗余匹配,然后在handler中做判断
文章最后发布于: 2019-03-22 02:11:22
相关阅读
[核心提示] 5 个月的报名、筛选、投票之后,哪些产品获得了 InnoAwards 的荣誉呢?每一个产品背后,都有⼀个苦逼的团队,他们日以继夜,充
A5创业网(公众号:iadmin5)10月8日消息,微信支付钱包入口低调上线了一个新服务——银行储蓄。当前,这项功能只有部分用户可
电脑忽然死机自动关机,重启后不一会会花屏死机, 建议可以先尝试拔下内存条去去灰尘在试一下. 博主就是这样恢复好.反正已经关机
各位注意没,今年春晚前的那个短片,马云穿了件湖蓝的花笙记唐装,当时我就觉得,它已经封神了。 我对这个品牌含有相当复杂的情感:羡慕丶
官方于1月12日开放了全新活动冰雪节限时回馈,这次的活动绝对诚意满满。只要收集雪花就能免费领取限定皮肤和传送门等豪华奖励,下面