LyScript 中提供了多種記憶體特征掃描函式,每一種掃描函式用法各不相同,在使用掃描函式時應首先搞清楚他們之間的差異,如下將分別詳細介紹每一種記憶體掃描函式是如何靈活運用的,最后將實作一個簡易版記憶體查殼腳本,可快速定位目標程式加了什么殼,
先來了解第一個函式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編譯器特征輸出

文章出處:https://www.cnblogs.com/LyShark/p/16671876.html
著作權宣告:本博客文章與代碼均為學習時整理的筆記,文章 [均為原創] 作品,轉載請 [添加出處] ,您添加出處是我創作的動力!
轉載文章,請遵守《中華人民共和國著作權法》相關規定或遵守《署名CC BY-ND 4.0國際》禁止演繹規范,合理合規,攜帶原創出處轉載,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/506045.html
標籤:其他
