LyScript插件中提供了三種基本的堆疊操作方法,其中push_stack用于入堆疊,pop_stack用于出堆疊,而最有用的是peek_stack函式,該函式可用于檢查指定堆疊位置處的記憶體引數,利用這個特性就可以實作,對堆疊地址的檢測,或對堆疊的掃描等,
LyScript專案地址:https://github.com/lyshark/LyScript
peek_stack命令傳入的是堆疊下標位置默認從0開始,并輸出一個十進制有符號長整數,首先實作有符號與無符號數之間的轉換操作,為后續堆疊掃描做準備,
from LyScript32 import MyDebug
# 有符號整數轉無符號數
def long_to_ulong(inter,is_64 = False):
if is_64 == False:
return inter & ((1 << 32) - 1)
else:
return inter & ((1 << 64) - 1)
# 無符號整數轉有符號數
def ulong_to_long(inter,is_64 = False):
if is_64 == False:
return (inter & ((1 << 31) - 1)) - (inter & (1 << 31))
else:
return (inter & ((1 << 63) - 1)) - (inter & (1 << 63))
if __name__ == "__main__":
dbg = MyDebug()
connect_flag = dbg.connect()
print("連接狀態: {}".format(connect_flag))
for index in range(0,10):
# 默認回傳有符號數
stack_address = dbg.peek_stack(index)
# 使用轉換
print("默認有符號數: {:15} --> 轉為無符號數: {:15} --> 轉為有符號數: {:15}".
format(stack_address, long_to_ulong(stack_address),ulong_to_long(long_to_ulong(stack_address))))
dbg.close()
通過上述封裝函式,即可實作對有符號和無符號數的轉換,

繼續完善該功能,我們使用get_disasm_one_code()函式,掃描堆疊地址并得到該地址處的反匯編代碼,
from LyScript32 import MyDebug
# 有符號整數轉無符號數
def long_to_ulong(inter,is_64 = False):
if is_64 == False:
return inter & ((1 << 32) - 1)
else:
return inter & ((1 << 64) - 1)
# 無符號整數轉有符號數
def ulong_to_long(inter,is_64 = False):
if is_64 == False:
return (inter & ((1 << 31) - 1)) - (inter & (1 << 31))
else:
return (inter & ((1 << 63) - 1)) - (inter & (1 << 63))
if __name__ == "__main__":
dbg = MyDebug()
connect_flag = dbg.connect()
print("連接狀態: {}".format(connect_flag))
for index in range(0,10):
# 默認回傳有符號數
stack_address = dbg.peek_stack(index)
# 反匯編一行
dasm = dbg.get_disasm_one_code(stack_address)
# 根據地址得到模塊基址
if stack_address <= 0:
mod_base = 0
else:
mod_base = dbg.get_base_from_address(long_to_ulong(stack_address))
print("stack => [{}] addr = {:10} base = {:10} dasm = {}".format(index, hex(long_to_ulong(stack_address)),hex(mod_base), dasm))
dbg.close()
得到的堆疊引數如下:

由此我們可以得到堆疊處的反匯編引數,但如果我們需要檢索堆疊特定區域內是否存在回傳到模塊的地址,該如何實作呢?

其實很簡單,首先我們需要得到程式全域狀態下的所有加載模塊的基地址,然后得到當前堆疊記憶體地址內的實際地址,并通過實際記憶體地址得到模塊基地址,對比全域表即可拿到當前模塊是回傳到了哪里,
from LyScript32 import MyDebug
# 有符號整數轉無符號數
def long_to_ulong(inter,is_64 = False):
if is_64 == False:
return inter & ((1 << 32) - 1)
else:
return inter & ((1 << 64) - 1)
# 無符號整數轉有符號數
def ulong_to_long(inter,is_64 = False):
if is_64 == False:
return (inter & ((1 << 31) - 1)) - (inter & (1 << 31))
else:
return (inter & ((1 << 63) - 1)) - (inter & (1 << 63))
if __name__ == "__main__":
dbg = MyDebug()
connect_flag = dbg.connect()
print("連接狀態: {}".format(connect_flag))
# 得到程式加載過的所有模塊資訊
module_list = dbg.get_all_module()
# 向下掃描堆疊
for index in range(0,10):
# 默認回傳有符號數
stack_address = dbg.peek_stack(index)
# 反匯編一行
dasm = dbg.get_disasm_one_code(stack_address)
# 根據地址得到模塊基址
if stack_address <= 0:
mod_base = 0
else:
mod_base = dbg.get_base_from_address(long_to_ulong(stack_address))
# print("stack => [{}] addr = {:10} base = {:10} dasm = {}".format(index, hex(long_to_ulong(stack_address)),hex(mod_base), dasm))
if mod_base > 0:
for x in module_list:
if mod_base == x.get("base"):
print("stack => [{}] addr = {:10} base = {:10} dasm = {:15} return = {:10}"
.format(index,hex(long_to_ulong(stack_address)),hex(mod_base), dasm,
x.get("name")))
dbg.close()
運行后,即可掃描到堆疊內的所有回傳模塊的位置,

著作權宣告:本博客文章與代碼均為學習時整理的筆記,文章 [均為原創] 作品,轉載請 [添加出處] ,您添加出處是我創作的動力!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/500797.html
標籤:訊息安全
