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()

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

LyScript 实现对内存堆栈扫描的更多相关文章

  1. STM32/GD32上内存堆栈溢出探测研究

    无数次遭受堆栈溢出折磨,随着系统变得复杂,故障点越来越难以查找!主要溢出情况如下:1,一般RAM最后两块空间是堆Heap和栈Stack,堆从下往上用,栈从上往下用,任意一个用完,都会进入对方的空间2, ...

  2. 关于掌握C#的内存堆栈概念

    很多时候,我们使用C#语言书写业务逻辑时,并不会太多地主动考虑到内存的占用和分配问题,但编的程序多了,就总会遇到一些性能问题.提到"性能"二字,就不得不考虑CPU和内存,而提到内存 ...

  3. arcgis engine 中出现的内存堆栈溢出问题。

    两种解决方案: 1.循环加载mxd文档的时候出现的堆栈溢出,解决办法是每次循环结束时清空FeatureLayer,感觉并不好,但是确实可以实现功能. 2.循环调取featureclass的search ...

  4. PHP对象在内存堆栈中的分配

    对象在PHP里面和整型.浮点型一样,也是一种数据类,都是存储不同类型数据用的, 在运行的时候都要加载到内存中去用,那么对象在内存里面是怎么体现的呢?内存从逻辑上说大体上是分为4段,栈空间段.堆空间段. ...

  5. JAVA对象及属性的内存堆栈管理(通过小程序简单说明)

    JAVA在执行过程中会划分4个内存区域(heap.stack.data segment.code segment)代码区(codesegment):java开始执行会把代码加载到code segmen ...

  6. eclipse JVM Tomcat 内存堆栈大小设置

    1,  设置Eclipse内存使用情况 修改eclipse根目录下的eclipse.ini文件 -vmargs  //虚拟机设置 -Xms40m //初始内存 -Xmx256m //最大内存 -Xmn ...

  7. openjdk-alpine镜像无法打印线程堆栈和内存堆栈问题

    基于openjdk:8u171-alpine构建的java镜像,使用jstack命令打印线程的时候会提示以下错误: /opt # ps -ef PID USER TIME COMMAND 1 root ...

  8. C语言:一个涉及指针函数返回值与printf乱码、内存堆栈的经典案例

    一个奇怪的C语言问题,涉及到指针.数组.堆栈.以及printf.以下实现: 整数向字符串的转换,返回字符串指针,并在main函数中调用printf显示. #include<stdio.h> ...

  9. AJ整理问题之:内存堆栈

    内存 数据在内存中的存放 在计算机中,运行的应用程序的数据都是保存在内存中的. 不同类型的数据,保存的内存区域不同,其中包括: 1:栈区(stack)由编译器自动分配并释放,一半存放函数的参数值,局部 ...

随机推荐

  1. JavaScript 模块的循环加载(循环依赖问题分析)

    简介 "循环加载"(circular dependency)指的是,a 脚本的执行依赖 b 脚本,而 b 脚本的执行又依赖 a 脚本. 分析 使用 madge 工具进行循环加载分析 ...

  2. 6. ZigZag Conversion - LeetCode

    Question 6. ZigZag Conversion Solution 题目大意:将字符串按Z字型排列,然后再一行一行按字符输出 思路:按题目中的第一个例子,画出如下图,通过n的不同值,可以找出 ...

  3. 455. Assign Cookies - LeetCode

    Question 455. Assign Cookies Solution 题目大意:数组g的大小表示有几个小孩,每个元素表示小孩的食量,数组s的大小表示有多少个饼干,每个元素的大小表示每个饼干的大小 ...

  4. python基础学习5

    Python的基础学习5 内容概要 流程控制理论 if判断 while循环 内容详情 流程控制理论 # 流程控制:即控制事物执行的流程 # 执行流程的分类 1.顺序结构 从上往下按顺序依次执行 2.分 ...

  5. c++ 超长整数减法 高精度减法

    c++ 超长整数减法 高精度减法 实现思路 和加法类似,设置临时变量记录借位 当对应位数相减得到的结果大于等于0时,该位数字为本身值,否则需要加上借位的10.则\(t=(t+10)%10\) 打卡代码 ...

  6. ForEach遍历集合、 集合容器

    ForEach遍历集合 foreach循环是一种更加简洁的for循环,也称增强for循环,能用于遍历数组或集合中的元素. 格式: for(容器元素类型 临时变量:容器变量){ 执行语句} 从上面格式可 ...

  7. HIPPO-4J 1.3.0 正式发布:支持 Dubbo、RibbitMQ、RocketMQ 框架线程池

    文章首发在公众号(龙台的技术笔记),之后同步到个人网站:xiaomage.info Hippo-4J 距离上一个版本 1.2.1 已经过去一个月的时间.在此期间,由 8 位贡献者 提交了 170+ c ...

  8. camunda BPM支持的开发和运行环境

    以Camunda7.13版本为例,介绍Camunda支持的开发运行环境. 一.支持的Java开发环境 • Java版本: 8 / 9 / 10 / 11 / 12 / 13 / 14• Springb ...

  9. 微信小程序使用 ECharts

    echarts-for-weixin 是 ECharts 官方维护的一个开源项目,提供了一个微信小程序组件(Component),我们可以通过这个组件在微信小程序中使用 ECharts 绘制图表. e ...

  10. pytorch初学

    (pytorch_gpu) D:\pytorch-text>pythonPython 3.7.9 (default, Aug 31 2020, 17:10:11) [MSC v.1916 64 ...