【Android 逆向】代码调试器开发 ( ptrace 函数 | 向进程内存写出数据 )
文章目录
- 一、向进程内存写出数据
- 二、写出流程
- 三、完整代码
一、向进程内存写出数据
向内存写出数据 : 每次最多能写出 4 字节 ;
ptrace(PTRACE_POKETEXT, m_nPid, (void*)pDestAddr, d.val);
- 参数一 : 写出数据标志 PTRACE_POKETEXT ;
- 参数二 : 进程号 PID ;
- 参数三 : 写出去数据的地址 ;
- 参数四 : 写出的数据内容 , 4 字节 ;
二、写出流程
向进程内存写出数据时 , 每次最多只能写出 4 字节数据 , 先根据读取的大小 , 计算出读取次数 ,
// 每次读取 4 字节 , 读取次数为 nSize / 4j = nSize / 4;
然后再计算出最后不足 4 字节的部分 ,
// 读取最后不满 4 个字节的数据 remain = nSize % 4;
读取数据时 , 先循环 j 次 , 写出 j x 4 字节数据 ,
for (i = 0; i < j; i++) {// 准备写出数据 , 从 laddr 拷贝到 d.charsmemcpy(d.chars, laddr, 4);// 32 位的设备上 , 最长只能读取 4 字节 ptrace(PTRACE_POKETEXT, m_nPid, (void*)pDestAddr, d.val);pDestAddr += 4;laddr += 4;}
最后再读取一次末尾不足 4 字节的数据 ;
读取的时候 , 如果不足 4 字节 , 我们可以将数据直接读取出来 , 不影响程序运行 ; 写出的时候 , 如果写出数据不足 4 字节 , 是 3 字节 , 那么必须保证最后一位写出时 , 不会出错 , 原来进程中 第 4 位是什么数据 , 写出去时也必须是同样的数据 , 否则进程运行出错 ;
先 读取 当前进程内存的数据 ,
// 一次性必须写入 4 字节 , 如果不足 4 字节 , 先把数据读取出来 , 即读取 4 字节出来 d.val = ptrace(PTRACE_PEEKTEXT, m_nPid, (void*)pDestAddr, 0);
然后 , 设置数据 ; 假如数据有 3 字节 , 那么就将上述读取的 4 字节的前 3 个字节设置成我们要修改的数据 , 这就保证了第 4 个字节不会出错 ;
// 假如数据有 3 字节 , 那么就将上述读取的 4 字节的前 3 个字节设置成我们要修改的数据 // 这就保证了第 4 个字节不会出错 for (i = 0; i < remain; i++) {d.chars[i] = *laddr++;}
最后 , 将最终的 4 字节数据写入进程内存 ;
// 最后将最终的 4 字节数据写入进程内存ptrace(PTRACE_POKETEXT, m_nPid, (void*)pDestAddr, d.val);//整体写入
部分代码示例 :
// 写出末尾不足 4 字节的数据部分 // 读取的时候 , 如果不足 4 字节 , 我们可以将数据直接读取出来 , 不影响程序运行 // 写出的时候 , 如果写出数据不足 4 字节 , 是 3 字节 , 那么必须保证最后一位写出时 , 不会出错 , // 原来进程中 第 4 位是什么数据 , 写出去时也必须是同样的数据 , 否则进程运行出错 if (remain > 0) {// 一次性必须写入 4 字节 , 如果不足 4 字节 , 先把数据读取出来 , 即读取 4 字节出来 d.val = ptrace(PTRACE_PEEKTEXT, m_nPid, (void*)pDestAddr, 0);// 假如数据有 3 字节 , 那么就将上述读取的 4 字节的前 3 个字节设置成我们要修改的数据 // 这就保证了第 4 个字节不会出错 for (i = 0; i < remain; i++) {d.chars[i] = *laddr++;}// 最后将最终的 4 字节数据ptrace(PTRACE_POKETEXT, m_nPid, (void*)pDestAddr, d.val);//整体写入}
三、完整代码
向进程内存写出数据完整代码 :
// pDestAddr 写出地址 , const char* pData 写出的数据 , size_t nSize 写出数据大小
int CPtrace::write(char* pDestAddr, const char* pData, size_t nSize)
{uint32_t i, j, remain;// 写出数据的地址 , 该地址需要不断累加计算 , 记录写出的数据地址 const char *laddr;// 联合体 , 在同一个内存地址上 , 既可以以 long 类型解析这块数据 , 也可以以 char 数组类型解析这块数据union u {long val;char chars[sizeof(long)];} d;// 每次读取 4 字节 , 读取次数为 nSize / 4j = nSize / 4;// 读取最后不满 4 个字节的数据 remain = nSize % 4;// 写出数据准备 laddr = pData;for (i = 0; i < j; i++) {// 准备写出数据 , 从 laddr 拷贝到 d.charsmemcpy(d.chars, laddr, 4);// 32 位的设备上 , 最长只能读取 4 字节 ptrace(PTRACE_POKETEXT, m_nPid, (void*)pDestAddr, d.val);pDestAddr += 4;laddr += 4;}// 写出末尾不足 4 字节的数据部分 // 读取的时候 , 如果不足 4 字节 , 我们可以将数据直接读取出来 , 不影响程序运行 // 写出的时候 , 如果写出数据不足 4 字节 , 是 3 字节 , 那么必须保证最后一位写出时 , 不会出错 , // 原来进程中 第 4 位是什么数据 , 写出去时也必须是同样的数据 , 否则进程运行出错 if (remain > 0) {// 一次性必须写入 4 字节 , 如果不足 4 字节 , 先把数据读取出来 , 即读取 4 字节出来 d.val = ptrace(PTRACE_PEEKTEXT, m_nPid, (void*)pDestAddr, 0);// 假如数据有 3 字节 , 那么就将上述读取的 4 字节的前 3 个字节设置成我们要修改的数据 // 这就保证了第 4 个字节不会出错 for (i = 0; i < remain; i++) {d.chars[i] = *laddr++;}// 最后将最终的 4 字节数据ptrace(PTRACE_POKETEXT, m_nPid, (void*)pDestAddr, d.val);//整体写入}return PTERR_SUCCESS;
}
【Android 逆向】代码调试器开发 ( ptrace 函数 | 向进程内存写出数据 )相关推荐
- 【Android 逆向】代码调试器开发 ( ptrace 函数 | 读取进程内存数据 )
文章目录 一.读取进程内存数据 二.读取流程 三.完整代码 一.读取进程内存数据 使用 ptrace 函数读取内存数据 : ptrace(PTRACE_PEEKTEXT, m_nPid, (void* ...
- 【Android 逆向】代码调试器开发 ( ptrace 函数 | 读寄存器 | 写寄存器 )
文章目录 一.读寄存器 二.写寄存器 一.读寄存器 调用 ptrace(PTRACE_GETREGS, m_nPid, NULL, regs) 读取进程运行时的寄存器 ; 读取寄存器时 , 进程必须处 ...
- 【Android 逆向】代码调试器开发 ( 等待进程状态改变 | detach 脱离进程调试 PTRACE_DETACH | 调试中继续运行程序 PTRACE_CONT )
文章目录 一.等待进程状态改变 二.detach 脱离进程调试 PTRACE_DETACH 三.调试中继续运行程序 PTRACE_CONT 一.等待进程状态改变 上一篇博客 [Android 逆向]代 ...
- 【Android 逆向】代码调试器开发 ( 使用 NDK 中的 ndk-build + Android.mk 编译 Android 平台的代码调试器可执行应用 )
文章目录 一.Android 平台代码调试器代码 二.Android.mk 构建脚本内容 三.Application.mk 构建脚本内容 四.正式编译 五.博客资源 一.Android 平台代码调试器 ...
- 【Android 逆向】代码调试器开发 ( 代码调试器功能简介 | 设置断点 | 读写内存 | 读写寄存器 | 恢复运行 | Attach 进程 )
文章目录 一.代码调试器功能简介 二.Attach 进程 一.代码调试器功能简介 代码调试器功能 : 设置断点 : 无论什么类型的调试器 , 都必须可以设置断点 , 运行到断点处 , 挂起被调试进程 ...
- Android逆向之调试smali代码基础
点击上方↑↑↑蓝字[协议分析与还原]关注我们 " 介绍Android逆向中调试smali代码的方法." 最近在重整Android逆向分析环境,一切都在从零开始,做下记录,给大家分享 ...
- 【Android 逆向】修改运行中的 Android 进程的内存数据 ( Android 系统中调试器进程内存流程 | 编译内存调试动态库以及调试程序 )
文章目录 一.Android 系统中调试器进程内存流程 二.编译内存调试动态库以及调试程序 三.博客资源 一.Android 系统中调试器进程内存流程 修改游戏运行中的内存 , 游戏运行之后 , 游戏 ...
- Firebug 调试器开发中的12个技巧
Firebug 调试器开发中的12个技巧 相信很多从事Web开发工作的开发者都听说和使用过Firebug,但可能大部分人还不知道,其实它是一个在网页设计方面功能相当强大的编辑器,它可以对 HTML.D ...
- 【Android 逆向】类加载器 ClassLoader ( 使用 DexClassLoader 动态加载字节码文件 | 拷贝 DEX 文件到内置存储 | 加载并执行 DEX 字节码文件 )
文章目录 一.拷贝 Assets 目录下的 classes.dex 字节码文件到内置存储区 二.加载 DEX 文件并执行其中的方法 三.MainActivity 及执行结果 四.博客资源 一.拷贝 A ...
最新文章
- 分布式WebSocket架构
- 【笔试面试考试】C++基础知识点[转]
- javascript”面向对象编程”- 1万物皆对象
- php 判断3个数谁最小,Python编程学习之如何判断3个数的大小
- lua52 C API测试代码
- golang 数组、指针数组、数组指针使用总结
- zookeeper启动失败
- Jzoj3192 球
- css之多行文本输出
- linux增加虚拟内存
- mariadb配置主从同步遇到的问题
- 小程序/CSS的text-decoration属性
- win10系统文件拖拽卡顿_终于找到Win10卡顿病根了!看完秒懂
- PHP文件绕过后缀执行配置
- matlab plot函数画线,线型和颜色
- 数据库系统--码,超码,候选码,主属性,非主属性,主码,全码,外码基本概念
- stream流 lambda 练习
- Anaconda中的spyder安装Terminal插件
- python打开本地浏览器_python如何实现打开浏览器
- 程序员保护好自己的颈椎
热门文章
- C语言笔记系列文章 索引目录表(持续更新中......)
- Cisco堆叠交换机序号的改变
- 【C#食谱】【杭帮菜】菜单2:写一个TCP客户端
- python字典排序取最值总结
- 数据库 - mysql内置功能
- 法向量影响光源照射物体后,物体产生的视觉感光效果
- 268. Missing Number
- 算法导论之红黑树的学习
- Error: pgraster_wkb_reader: grayscale band type 10 unsupported
- [SSH] Eclipse+Struts+Hibernate的简单应用