LyScript 通过PEB结构解析堆基址
作者:互联网
LyScript中默认并没有提供获取进程堆基址的函数,不过却提供了获取PEB/TEB的函数,以PEB获取为例,可以调用dbg.get_peb_address(local_pid)
用户传入当前进程的PID号,通常PID号可以使用dbg.get_process_id()
函数得到,当得到了PEB进程环境块的基地址,那么获取堆基址就变得很简单了。
首先以获取kernel32.dll
模块基地址为例,如果使用汇编获取则代码是这样的,根据这段代码我们举一反三。
_asm
{
push esi
mov esi, dword ptr fs : [0x30] // PEB地址
mov esi, [esi + 0x0C] // PEB_LDR_DATA
mov esi, [esi + 0x1C] // InInitializationOrderModuleList
mov esi, [esi] //
mov eax, [esi + 0x08] // 模块基址
pop esi
}
使用lyscript
得到地址的代码就变得很简单了,只需要多次读取指针变量即可得到。
from LyScript32 import MyDebug
if __name__ == "__main__":
dbg = MyDebug()
conn = dbg.connect()
# 内置函数得到进程PEB
local_pid = dbg.get_process_id()
peb = dbg.get_peb_address(local_pid)
print("进程PEB: {}".format(hex(peb)))
# esi = PEB_LDR_DATA结构体的地址
ptr = peb + 0x0c
# 读取内存指针
PEB_LDR_DATA = dbg.read_memory_ptr(ptr)
print("读入PEB_LDR_DATA里面的地址: {}".format(hex(PEB_LDR_DATA)))
# esi = 模块链表指针InInitializationOrderModuleList
ptr = PEB_LDR_DATA + 0x1c
InInitializationOrderModuleList = dbg.read_memory_ptr(ptr)
print("读入InInitializationOrderModuleList里面的地址: {}".format(hex(InInitializationOrderModuleList)))
# 取出kernel32.dll模块基址
ptr = InInitializationOrderModuleList + 0x08
modbase = dbg.read_memory_ptr(ptr)
print("kernel32.dll = {}".format(hex(modbase)))
dbg.close()
读取效果如下:
如上kernel模块基地址的获取已经实现了,那么堆基址的获取也就非常简单了,我们只需要找到peb+0x90
的位置,将其读取出来即可。
0:000> dt _peb @$peb
ntdll!_PEB+0x090 ProcessHeaps
0:000> dd 7c99ffe0 l8
7c99ffe0 00150000 00250000 00260000 00000000
7c99fff0 00000000 00000000 00000000 00000000
读取内存指针即可得到堆地址,将堆地址获取封装成getHeapsAddress()
函数方便后续调用。
from LyScript32 import MyDebug
# 获取模块基址
def getKernelModuleBase(dbg):
# 内置函数得到进程PEB
local_pid = dbg.get_process_id()
peb = dbg.get_peb_address(local_pid)
# print("进程PEB: {}".format(hex(peb)))
# esi = PEB_LDR_DATA结构体的地址
ptr = peb + 0x0c
# 读取内存指针
PEB_LDR_DATA = dbg.read_memory_ptr(ptr)
# print("读入PEB_LDR_DATA里面的地址: {}".format(hex(PEB_LDR_DATA)))
# esi = 模块链表指针InInitializationOrderModuleList
ptr = PEB_LDR_DATA + 0x1c
InInitializationOrderModuleList = dbg.read_memory_ptr(ptr)
# print("读入InInitializationOrderModuleList里面的地址: {}".format(hex(InInitializationOrderModuleList)))
# 取出kernel32.dll模块基址
ptr = InInitializationOrderModuleList + 0x08
modbase = dbg.read_memory_ptr(ptr)
# print("kernel32.dll = {}".format(hex(modbase)))
return modbase
# 获取进程堆基址
def getHeapsAddress(dbg):
# 内置函数得到进程PEB
local_pid = dbg.get_process_id()
peb = dbg.get_peb_address(local_pid)
# print("进程PEB: {}".format(hex(peb)))
# 读取堆分配地址
ptr = peb + 0x90
peb_address = dbg.read_memory_ptr(ptr)
# print("读取堆分配: {}".format(hex(peb_address)))
heap_address = dbg.read_memory_ptr(peb_address)
# print("当前进程堆基址: {}".format(hex(heap_address)))
return heap_address
if __name__ == "__main__":
dbg = MyDebug()
conn = dbg.connect()
k32 = getKernelModuleBase(dbg)
print("kernel32 = {}".format(hex(k32)))
heap = getHeapsAddress(dbg)
print("heap 堆地址: {}".format(hex(heap)))
dbg.close()
读取效果如下:
标签:format,基址,dbg,PEB,LyScript,ptr,peb,esi 来源: https://www.cnblogs.com/LyShark/p/16683857.html