ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

LyScript 通过PEB结构解析堆基址

2022-09-11 14:35:18  阅读:150  来源: 互联网

标签:format 基址 dbg PEB LyScript ptr peb esi


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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有