• LyScript 实现对内存堆栈扫描


    LyScript插件中提供了三种基本的堆栈操作方法,其中push_stack用于入栈,pop_stack用于出栈,而最有用的是peek_stack函数,该函数可用于检查指定堆栈位置处的内存参数,利用这个特性就可以实现,对堆栈地址的检测,或对堆栈的扫描等。

    LyScript项目地址:https://github.com/lyshark/LyScript

    peek_stack命令传入的是堆栈下标位置默认从0开始,并输出一个十进制有符号长整数,首先实现有符号与无符号数之间的转换操作,为后续堆栈扫描做准备。

    1. from LyScript32 import MyDebug
    2. # 有符号整数转无符号数
    3. def long_to_ulong(inter,is_64 = False):
    4. if is_64 == False:
    5. return inter & ((1 << 32) - 1)
    6. else:
    7. return inter & ((1 << 64) - 1)
    8. # 无符号整数转有符号数
    9. def ulong_to_long(inter,is_64 = False):
    10. if is_64 == False:
    11. return (inter & ((1 << 31) - 1)) - (inter & (1 << 31))
    12. else:
    13. return (inter & ((1 << 63) - 1)) - (inter & (1 << 63))
    14. if __name__ == "__main__":
    15. dbg = MyDebug()
    16. connect_flag = dbg.connect()
    17. print("连接状态: {}".format(connect_flag))
    18. for index in range(0,10):
    19. # 默认返回有符号数
    20. stack_address = dbg.peek_stack(index)
    21. # 使用转换
    22. print("默认有符号数: {:15} --> 转为无符号数: {:15} --> 转为有符号数: {:15}".
    23. format(stack_address, long_to_ulong(stack_address),ulong_to_long(long_to_ulong(stack_address))))
    24. dbg.close()

    通过上述封装函数,即可实现对有符号和无符号数的转换。

    继续完善该功能,我们使用get_disasm_one_code()函数,扫描堆栈地址并得到该地址处的反汇编代码。

    1. from LyScript32 import MyDebug
    2. # 有符号整数转无符号数
    3. def long_to_ulong(inter,is_64 = False):
    4. if is_64 == False:
    5. return inter & ((1 << 32) - 1)
    6. else:
    7. return inter & ((1 << 64) - 1)
    8. # 无符号整数转有符号数
    9. def ulong_to_long(inter,is_64 = False):
    10. if is_64 == False:
    11. return (inter & ((1 << 31) - 1)) - (inter & (1 << 31))
    12. else:
    13. return (inter & ((1 << 63) - 1)) - (inter & (1 << 63))
    14. if __name__ == "__main__":
    15. dbg = MyDebug()
    16. connect_flag = dbg.connect()
    17. print("连接状态: {}".format(connect_flag))
    18. for index in range(0,10):
    19. # 默认返回有符号数
    20. stack_address = dbg.peek_stack(index)
    21. # 反汇编一行
    22. dasm = dbg.get_disasm_one_code(stack_address)
    23. # 根据地址得到模块基址
    24. if stack_address <= 0:
    25. mod_base = 0
    26. else:
    27. mod_base = dbg.get_base_from_address(long_to_ulong(stack_address))
    28. print("stack => [{}] addr = {:10} base = {:10} dasm = {}".format(index, hex(long_to_ulong(stack_address)),hex(mod_base), dasm))
    29. dbg.close()

    得到的堆栈参数如下:

    由此我们可以得到堆栈处的反汇编参数,但如果我们需要检索堆栈特定区域内是否存在返回到模块的地址,该如何实现呢?

    其实很简单,首先我们需要得到程序全局状态下的所有加载模块的基地址,然后得到当前堆栈内存地址内的实际地址,并通过实际内存地址得到模块基地址,对比全局表即可拿到当前模块是返回到了哪里。

    1. from LyScript32 import MyDebug
    2. # 有符号整数转无符号数
    3. def long_to_ulong(inter,is_64 = False):
    4. if is_64 == False:
    5. return inter & ((1 << 32) - 1)
    6. else:
    7. return inter & ((1 << 64) - 1)
    8. # 无符号整数转有符号数
    9. def ulong_to_long(inter,is_64 = False):
    10. if is_64 == False:
    11. return (inter & ((1 << 31) - 1)) - (inter & (1 << 31))
    12. else:
    13. return (inter & ((1 << 63) - 1)) - (inter & (1 << 63))
    14. if __name__ == "__main__":
    15. dbg = MyDebug()
    16. connect_flag = dbg.connect()
    17. print("连接状态: {}".format(connect_flag))
    18. # 得到程序加载过的所有模块信息
    19. module_list = dbg.get_all_module()
    20. # 向下扫描堆栈
    21. for index in range(0,10):
    22. # 默认返回有符号数
    23. stack_address = dbg.peek_stack(index)
    24. # 反汇编一行
    25. dasm = dbg.get_disasm_one_code(stack_address)
    26. # 根据地址得到模块基址
    27. if stack_address <= 0:
    28. mod_base = 0
    29. else:
    30. mod_base = dbg.get_base_from_address(long_to_ulong(stack_address))
    31. # print("stack => [{}] addr = {:10} base = {:10} dasm = {}".format(index, hex(long_to_ulong(stack_address)),hex(mod_base), dasm))
    32. if mod_base > 0:
    33. for x in module_list:
    34. if mod_base == x.get("base"):
    35. print("stack => [{}] addr = {:10} base = {:10} dasm = {:15} return = {:10}"
    36. .format(index,hex(long_to_ulong(stack_address)),hex(mod_base), dasm,
    37. x.get("name")))
    38. dbg.close()

    运行后,即可扫描到堆栈内的所有返回模块的位置。

  • 相关阅读:
    第四章:视图【mysql数据库-进阶】
    c#使用ExifLib库提取图像的相机型号、光圈、快门、iso、曝光时间、焦距信息等EXIF信息
    【电商】电商后台设计—库存模块
    数字孪生发展阶段报告与背景规划,面临数字孪生机遇。
    【cmake】find_package设置查找路径
    DTU配置工具-F2x16工具
    Centos7安装Gitlab--gitlab--ee版
    在 Wed 中应用 MyBatis(同时使用MVC架构模式,以及ThreadLocal 事务控制)
    Opencv项目实战:02 角度探测器
    HTML+CSS网页设计期末课程大作业:【中国传统文化——古诗词】学生网页设计作品 dreamweaver作业静态HTML网页设计
  • 原文地址:https://blog.csdn.net/lyshark_csdn/article/details/126136413