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)由编译器自动分配并释放,一半存放函数的参数值,局部 ...
随机推荐
- 运维:ITIL V3
TIL 简史 在20 世纪80 年代末期,英国商务部(OGC,Office Government Commerce)发布了ITIL .OGC 最初的目标是通过应用IT 来提升政府业务的效率:目标是能够 ...
- 好客租房17-jsx的样式处理
1行内样式-style <h1 style={{color:"red",backgroundColor:"skyblue"}}> jsx的样式处理 ...
- PostgreSQL(一) 编译安装运行
原创,如转发需注明出处. 多年没写博客,一直用的个人笔记软件,最近准备阅读PostgreSQL源码,故记录.(这两年PostgreSQL数据库在某些环境下是比较火的,原因想必大家都清楚.) Postg ...
- 【HEOI2014】大工程<虚树>
虚树 我们每天都用心思索着,这究竟是为了什么呢?我想我也不知道,只是觉得如果人不思考问题就很无聊. 我觉得虚树不是什么数据结构,就是一种技巧或者工具.它能把树中\(k\)个关键点以\(O(klogk) ...
- 【NFLSPC#4】嘉然今天吃什么(踩标做法)
[NFLSPC#4]嘉然今天吃什么 感谢 @zhoukangyang 神仙的帮助. Solution 令 \(s_i\) 表示选了 \(i\) 个灯后仍然不合法的概率,那么 \(E(x)=\sum_{ ...
- React简单教程-1-组件
前言 React,Facebook开发的前端框架.当时Facebook对市面上的前端框架都不满意,于是自己捣鼓出了React,使用后觉得特别好用,于是就在2013年开源了. 我也用React开发了一个 ...
- Halodoc使用 Apache Hudi 构建 Lakehouse的关键经验
Halodoc 数据工程已经从传统的数据平台 1.0 发展到使用 LakeHouse 架构的现代数据平台 2.0 的改造.在我们之前的博客中,我们提到了我们如何在 Halodoc 实施 Lakehou ...
- Maven POM文件介绍
1. POM文件是什么 1.1 Super POM 1.2 Minimal POM 1.3 Effective POM 3. 项目继承 和 项目聚合 2.1 Project Inheritance 项 ...
- 【实操干货】做好这 16 项优化,你的 Linux 操作系统焕然一新
大家好,这次跟大家谈谈又拍云的操作系统优化方案.往简单地说,我们使用的 Linux 操作系统主要都是基于 CentOS6/7 的精简和优化.往复杂地说,则是我们有两套系统,业务上使用的定制 Linux ...
- VMware 虚拟机安装CentOS镜像详细步骤
CentOS目前官网提供的下载版本有6.7.8,最新的版本为8,不过个人推荐CentOS 7 的版本,因为相比较于最新版本,版本7更加地稳定.而相比于版本6,版本7新增了很多的功能.CentOS 7 ...