LyScript 实现对内存堆栈扫描
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()
运行后,即可扫描到堆栈内的所有返回模块的位置。

LyScript 实现对内存堆栈扫描的更多相关文章
- STM32/GD32上内存堆栈溢出探测研究
无数次遭受堆栈溢出折磨,随着系统变得复杂,故障点越来越难以查找!主要溢出情况如下:1,一般RAM最后两块空间是堆Heap和栈Stack,堆从下往上用,栈从上往下用,任意一个用完,都会进入对方的空间2, ...
- 关于掌握C#的内存堆栈概念
很多时候,我们使用C#语言书写业务逻辑时,并不会太多地主动考虑到内存的占用和分配问题,但编的程序多了,就总会遇到一些性能问题.提到"性能"二字,就不得不考虑CPU和内存,而提到内存 ...
- arcgis engine 中出现的内存堆栈溢出问题。
两种解决方案: 1.循环加载mxd文档的时候出现的堆栈溢出,解决办法是每次循环结束时清空FeatureLayer,感觉并不好,但是确实可以实现功能. 2.循环调取featureclass的search ...
- PHP对象在内存堆栈中的分配
对象在PHP里面和整型.浮点型一样,也是一种数据类,都是存储不同类型数据用的, 在运行的时候都要加载到内存中去用,那么对象在内存里面是怎么体现的呢?内存从逻辑上说大体上是分为4段,栈空间段.堆空间段. ...
- JAVA对象及属性的内存堆栈管理(通过小程序简单说明)
JAVA在执行过程中会划分4个内存区域(heap.stack.data segment.code segment)代码区(codesegment):java开始执行会把代码加载到code segmen ...
- eclipse JVM Tomcat 内存堆栈大小设置
1, 设置Eclipse内存使用情况 修改eclipse根目录下的eclipse.ini文件 -vmargs //虚拟机设置 -Xms40m //初始内存 -Xmx256m //最大内存 -Xmn ...
- openjdk-alpine镜像无法打印线程堆栈和内存堆栈问题
基于openjdk:8u171-alpine构建的java镜像,使用jstack命令打印线程的时候会提示以下错误: /opt # ps -ef PID USER TIME COMMAND 1 root ...
- C语言:一个涉及指针函数返回值与printf乱码、内存堆栈的经典案例
一个奇怪的C语言问题,涉及到指针.数组.堆栈.以及printf.以下实现: 整数向字符串的转换,返回字符串指针,并在main函数中调用printf显示. #include<stdio.h> ...
- AJ整理问题之:内存堆栈
内存 数据在内存中的存放 在计算机中,运行的应用程序的数据都是保存在内存中的. 不同类型的数据,保存的内存区域不同,其中包括: 1:栈区(stack)由编译器自动分配并释放,一半存放函数的参数值,局部 ...
随机推荐
- 详细剖析pyecharts大屏的Page函数配置文件:chart_config.json
目录 一.问题背景 二.揭开json文件神秘面纱 三.巧用json文件 四.关于Table图表 五.同步讲解视频 5.1 讲解json的视频 5.2 讲解全流程大屏的视频 5.3 讲解全流程大屏的文章 ...
- 在Vmware虚拟机(win10)中安装逍遥安卓模拟器遇到的问题及解决办法
0x00 下载正确的安装包 逍遥模拟器官网:逍遥安卓模拟器下载官网 (xyaz.cn) 为什么要强调下载正确的安装包? 因为我在第一次下载的时候就下错了,下的是 逍遥模拟器 - 电脑玩手游神器 (me ...
- drools中的条件 when
目录 1.介绍 2.语法结构 3.模式例子 3.1 单个对象匹配 3.2 匹配任何对象 3.3 带条件匹配 3.3.1 注意事项 3.4 嵌套属性的匹配 3.4.1 访问单个嵌套属性 3.4.2 访问 ...
- 基于Python的渗透测试信息收集系统的设计和实现
信息收集系统的设计和实现 渗透测试是保卫网络安全的一种有效且必要的技术手段,而渗透测试的本质就是信息收集,信息搜集整理可为后续的情报跟进提供强大的保证,目标资产信息搜集的广度,决定渗透过程的复杂程度, ...
- Vue基础之 动态组件
为什么会有动态组件> vue 通过组件机制 实现的页面功能的模块化处理,通常情况下 我们在vue中使用组件 就是先定义组件 然后再需要的地方 插入组件即可 但是在某些情况下 需要根据不同的需求 ...
- springSecurity + jwt + redis 前后端分离用户认证和授权
记录一下使用springSecurity搭建用户认证和授权的代码... 技术栈使用springSecurity + redis + JWT + mybatisPlus 部分代码来自:https://b ...
- [CF1073G]LCP问题
题意:给一个长n的字符串S,q组询问,每组给两个集合A,B.求集合A中的点和集合B中的点所有组合情况的lcp的和. 思路: 好像比较常规,可是代码能力差还是调了1.5h.主要还是虚树板子不熟(加入的时 ...
- DYOJ 【20220317模拟赛】瞬间移动 题解
瞬间移动 题意 三维空间中从 \((0,0,0)\) 开始,每次移动 1,问刚好走 \(N\) 次能到 \((X,Y,Z)\) 的方案数 \(N\le10^7\),答案模 \(998244353\) ...
- Eureka高可用集群搭建
就是搭建Eureka的集群. 每个Eureka Server需要相互注册,确保数据一致. 我这里准备两个Eureka Server 他两的POM文件配置是一样的 <dependencies&g ...
- JS:&&运算符
&&逻辑运算符 当&&连接语句时,两边的语句会转化为布尔类型 1.两边条件都为true时,结果才为true: 2.如果有一个为false,结果就为false: 3.当第 ...