共计 2638 个字符,预计需要花费 7 分钟才能阅读完成。
LyScript 中提供了多种内存特色扫描函数,每一种扫描函数用法各不相同,在应用扫描函数时应首先搞清楚他们之间的差别,如下将别离具体介绍每一种内存扫描函数是如何灵活运用的,最初将实现一个简易版内存查壳脚本,可疾速定位目标程序加了什么壳。
- 插件地址:https://github.com/lyshark/Ly…
先来理解第一个函数 scan_memory_all()
的特点,该函数用来扫描以后过程内 EIP 所指向地位处整个内存段中符合条件的特色,如果找到了则返回一个列表,如果没有找到则返回 False,该函数与 scan_memory_one()
函数原理是统一的,惟一的不同是 all 以列表模式返回所有匹配到的行,one 则只返回匹配到的第一条记录,这两个函数都反对 ??
含糊匹配。
如果载入一个程序,默认停留在零碎领空,则调用该函数你所能失去的特色记录只能是零碎领空特定 dll 内的特色集。
例如扫描 ntdll.dll
模块内的所有特色字段是 55 8b ec 83 e4
的记录,代码是这样的。
from LyScript32 import MyDebug
if __name__ == "__main__":
dbg = MyDebug()
conn = dbg.connect()
ref_one = dbg.scan_memory_one("55 8b ec 83 e4")
print("扫描一行: {}".format(hex(ref_one)))
ref_all = dbg.scan_memory_all("55 8b ec 83 e4")
for index in range(0, len(ref_all)):
print("记录: {} 地址: {}".format(index,hex(ref_all[index])))
dbg.close()
运行成果如下:
有时咱们须要指定扫描某个模块,例如扫描过程内的 msvcr120.dll
模块,外面的特征值。
此时须要想得到该模块的入口地址,而后将 EIP 切换过来,此时在调用 scan_memory_all()
来实现搜寻,当然最好先备份原始 EIP 地位,这样扫描完当前能够间接切回去。
from LyScript32 import MyDebug
if __name__ == "__main__":
dbg = MyDebug()
conn = dbg.connect()
# 失去所有模块
local_module_base = dbg.get_all_module()
for index in local_module_base:
# 找到须要的模块
if index.get("name") == "msvcr120.dll":
entry = index.get("entry")
print("扫描入口: {}".format(hex(entry)))
# 切过去
dbg.set_register("eip",entry)
# 开始搜寻特色
scan_ref = dbg.scan_memory_all("5d c2 0c 00 55 8b ec")
for x in scan_ref:
print("扫描到: {}".format(hex(x)))
dbg.close()
输入后果如下:
当然为了使扫描效率更高一些,新版插件中新增了 scan_memory_any()
函数,该函数无需切换到模块入口处即可实现扫描特定模块内的特色,不过该函数只能返回找到的第一条记录,且须要传入扫描起始地位以及扫描长度,不过失去这些参数并不难。
from LyScript32 import MyDebug
if __name__ == "__main__":
dbg = MyDebug()
conn = dbg.connect()
# 失去过程模块
local_module = dbg.get_all_module()[0]
# 失去模块参数
module_base = local_module.get("base")
module_size = local_module.get("size")
print("基地址: {} 长度: {} 完结地址: {}".format(hex(module_base),hex(module_size),hex(module_base+module_size)))
# 扫描内存
ref = dbg.scan_memory_any(module_base,module_size,"51 5c a8 f8 4c 34 33")
if ref != False:
print("找到内存: {}".format(hex(ref)))
dbg.close()
扫描后果如下:
如上内存扫描办法如果能够搞明确,那么查壳这个性能就变得很简略了,市面上的查壳软件 PEID 等根本都是采纳特色码定位的形式,所以咱们想要实现查壳以及检测编译器特色能够采纳特色码扫描法,如下代码即可实现查壳性能。
from LyScript32 import MyDebug
# 查壳性能
def scan(dbg, string):
# 失去过程模块
local_module = dbg.get_all_module()[0]
# 失去模块参数
module_base = local_module.get("base")
module_size = local_module.get("size")
# print("基地址: {} 长度: {} 完结地址: {}".format(hex(module_base),hex(module_size),hex(module_base+module_size)))
# 扫描内存
ref = dbg.scan_memory_any(module_base,module_size,string)
if ref != False:
return True
return False
if __name__ == "__main__":
dbg = MyDebug()
conn = dbg.connect()
# 存储特色码
signs = [{"key": "Microsoft Visual C++ 2013", "value": "e8 ?? ?? ?? ?? e9 ?? ?? ?? ?? 55 8b ec"},
{"key": "UPX 3.96w", "value": "60 be ?? ?? ?? ?? 8d be 00 90 ff ff 57"}
]
for index in signs:
check = scan(dbg, index.get("value"))
if check == True:
print("编译特色:{}".format(index.get("key")))
dbg.close()
别离检测后输入后果如下:
upx 加壳软件输入为
vs2013 编译器特色输入