LyScript 可實作自定義匯編指令的替換功能,用戶可以自行撰寫一段匯編指令,將程式中特定的通用函式進行功能改寫與轉向操作,此功能原理是簡單的Hook操作,
首先我們先來實作一個Hook模板,在代碼中實作中轉機制,如下代碼以MessageBoxA函式為案例實作修改匯編引數傳遞,
from LyScript32 import MyDebug
# 傳入匯編串列,寫出到記憶體
def assemble(dbg, address=0, asm_list=[]):
asm_len_count = 0
for index in range(0,len(asm_list)):
# 寫出到記憶體
dbg.assemble_at(address, asm_list[index])
# print("地址: {} --> 長度計數器: {} --> 寫出: {}".format(hex(address + asm_len_count), asm_len_count,asm_list[index]))
# 得到asm長度
asm_len_count = dbg.assemble_code_size(asm_list[index])
# 地址每次遞增
address = address + asm_len_count
if __name__ == "__main__":
dbg = MyDebug()
connect_flag = dbg.connect()
print("連接狀態: {}".format(connect_flag))
# 找到MessageBoxA
messagebox_address = dbg.get_module_from_function("user32.dll","MessageBoxA")
print("MessageBoxA記憶體地址 = {}".format(hex(messagebox_address)))
# 分配空間
HookMem = dbg.create_alloc(1024)
print("自定義記憶體空間: {}".format(hex(HookMem)))
# 寫出FindWindowA記憶體地址,跳轉地址
asm = [
f"push {hex(HookMem)}",
"ret"
]
# 將串列中的匯編指令寫出到記憶體
assemble(dbg,messagebox_address,asm)
dbg.close()
上方代碼中可以看到,首先獲取到MessageBoxA函式記憶體地址,然后我們通過dbg.create_alloc(1024)分配一段空間,并利用assemble()函式寫出一個跳轉指令,
此段代碼執行后,MessageBoxA處的指令將被替換,跳轉到我們自己分配的記憶體中去,

接著我們就來實作功能改寫,將彈窗中的訊息替換成我們自己的著作權資訊,此處先給出代碼,
from LyScript32 import MyDebug
# 傳入匯編串列,寫出到記憶體
def assemble(dbg, address=0, asm_list=[]):
asm_len_count = 0
for index in range(0,len(asm_list)):
# 寫出到記憶體
dbg.assemble_at(address, asm_list[index])
# print("地址: {} --> 長度計數器: {} --> 寫出: {}".format(hex(address + asm_len_count), asm_len_count,asm_list[index]))
# 得到asm長度
asm_len_count = dbg.assemble_code_size(asm_list[index])
# 地址每次遞增
address = address + asm_len_count
if __name__ == "__main__":
dbg = MyDebug()
connect_flag = dbg.connect()
print("連接狀態: {}".format(connect_flag))
# 找到MessageBoxA
messagebox_address = dbg.get_module_from_function("user32.dll","MessageBoxA")
print("MessageBoxA記憶體地址 = {}".format(hex(messagebox_address)))
# 分配空間
HookMem = dbg.create_alloc(1024)
print("自定義記憶體空間: {}".format(hex(HookMem)))
# 寫出FindWindowA記憶體地址,跳轉地址
asm = [
f"push {hex(HookMem)}",
"ret"
]
# 將串列中的匯編指令寫出到記憶體
assemble(dbg,messagebox_address,asm)
# 定義兩個變數,存放字串
MsgBoxAddr = dbg.create_alloc(512)
MsgTextAddr = dbg.create_alloc(512)
# 填充字串內容
# lyshark 標題
txt = [0x6c, 0x79, 0x73, 0x68, 0x61, 0x72, 0x6b]
# 內容 lyshark.com
box = [0x6C, 0x79, 0x73, 0x68, 0x61, 0x72, 0x6B, 0x2E, 0x63, 0x6F, 0x6D]
for txt_count in range(0,len(txt)):
dbg.write_memory_byte(MsgBoxAddr + txt_count, txt[txt_count])
for box_count in range(0,len(box)):
dbg.write_memory_byte(MsgTextAddr + box_count, box[box_count])
print("標題地址: {} 內容: {}".format(hex(MsgBoxAddr),hex(MsgTextAddr)))
# 此處是MessageBox替換后的片段
PatchCode =\
[
"mov edi, edi",
"push ebp",
"mov ebp,esp",
"push -1",
"push 0",
"push dword ptr ss:[ebp+0x14]",
f"push {hex(MsgBoxAddr)}",
f"push {hex(MsgTextAddr)}",
"push dword ptr ss:[ebp+0x8]",
"call 0x76030E20",
"pop ebp",
"ret 0x10"
]
# 寫出到自定義記憶體
assemble(dbg, HookMem, PatchCode)
print("地址已被替換,可以運行了.")
dbg.set_debug("Run")
dbg.set_debug("Run")
dbg.close()
首先程式運行后,會經過assemble(dbg,messagebox_address,asm)匯撰寫出的位置,此處是一個跳轉,直接跳轉到我們自己申請的記憶體空間內,

當EIP走到此處后,跳轉到我們自己構建的彈窗位置,此處的代碼如下,

當彈窗運行后,讀入的記憶體地址有兩處MsgBoxAddr是訊息MsgTextAddr是文本,這兩處位置都被python中的push {hex()}替換掉了,當運行彈窗后,就是執行我們自己的函式,

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