文章目录

  • 一、向进程内存写出数据
  • 二、写出流程
  • 三、完整代码

一、向进程内存写出数据


向内存写出数据 : 每次最多能写出 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 函数 | 向进程内存写出数据 )相关推荐

  1. 【Android 逆向】代码调试器开发 ( ptrace 函数 | 读取进程内存数据 )

    文章目录 一.读取进程内存数据 二.读取流程 三.完整代码 一.读取进程内存数据 使用 ptrace 函数读取内存数据 : ptrace(PTRACE_PEEKTEXT, m_nPid, (void* ...

  2. 【Android 逆向】代码调试器开发 ( ptrace 函数 | 读寄存器 | 写寄存器 )

    文章目录 一.读寄存器 二.写寄存器 一.读寄存器 调用 ptrace(PTRACE_GETREGS, m_nPid, NULL, regs) 读取进程运行时的寄存器 ; 读取寄存器时 , 进程必须处 ...

  3. 【Android 逆向】代码调试器开发 ( 等待进程状态改变 | detach 脱离进程调试 PTRACE_DETACH | 调试中继续运行程序 PTRACE_CONT )

    文章目录 一.等待进程状态改变 二.detach 脱离进程调试 PTRACE_DETACH 三.调试中继续运行程序 PTRACE_CONT 一.等待进程状态改变 上一篇博客 [Android 逆向]代 ...

  4. 【Android 逆向】代码调试器开发 ( 使用 NDK 中的 ndk-build + Android.mk 编译 Android 平台的代码调试器可执行应用 )

    文章目录 一.Android 平台代码调试器代码 二.Android.mk 构建脚本内容 三.Application.mk 构建脚本内容 四.正式编译 五.博客资源 一.Android 平台代码调试器 ...

  5. 【Android 逆向】代码调试器开发 ( 代码调试器功能简介 | 设置断点 | 读写内存 | 读写寄存器 | 恢复运行 | Attach 进程 )

    文章目录 一.代码调试器功能简介 二.Attach 进程 一.代码调试器功能简介 代码调试器功能 : 设置断点 : 无论什么类型的调试器 , 都必须可以设置断点 , 运行到断点处 , 挂起被调试进程 ...

  6. Android逆向之调试smali代码基础

    点击上方↑↑↑蓝字[协议分析与还原]关注我们 " 介绍Android逆向中调试smali代码的方法." 最近在重整Android逆向分析环境,一切都在从零开始,做下记录,给大家分享 ...

  7. 【Android 逆向】修改运行中的 Android 进程的内存数据 ( Android 系统中调试器进程内存流程 | 编译内存调试动态库以及调试程序 )

    文章目录 一.Android 系统中调试器进程内存流程 二.编译内存调试动态库以及调试程序 三.博客资源 一.Android 系统中调试器进程内存流程 修改游戏运行中的内存 , 游戏运行之后 , 游戏 ...

  8. Firebug 调试器开发中的12个技巧

    Firebug 调试器开发中的12个技巧 相信很多从事Web开发工作的开发者都听说和使用过Firebug,但可能大部分人还不知道,其实它是一个在网页设计方面功能相当强大的编辑器,它可以对 HTML.D ...

  9. 【Android 逆向】类加载器 ClassLoader ( 使用 DexClassLoader 动态加载字节码文件 | 拷贝 DEX 文件到内置存储 | 加载并执行 DEX 字节码文件 )

    文章目录 一.拷贝 Assets 目录下的 classes.dex 字节码文件到内置存储区 二.加载 DEX 文件并执行其中的方法 三.MainActivity 及执行结果 四.博客资源 一.拷贝 A ...

最新文章

  1. 分布式WebSocket架构
  2. 【笔试面试考试】C++基础知识点[转]
  3. javascript”面向对象编程”- 1万物皆对象
  4. php 判断3个数谁最小,Python编程学习之如何判断3个数的大小
  5. lua52 C API测试代码
  6. golang 数组、指针数组、数组指针使用总结
  7. zookeeper启动失败
  8. Jzoj3192 球
  9. css之多行文本输出
  10. linux增加虚拟内存
  11. mariadb配置主从同步遇到的问题
  12. 小程序/CSS的text-decoration属性
  13. win10系统文件拖拽卡顿_终于找到Win10卡顿病根了!看完秒懂
  14. PHP文件绕过后缀执行配置
  15. matlab plot函数画线,线型和颜色
  16. 数据库系统--码,超码,候选码,主属性,非主属性,主码,全码,外码基本概念
  17. stream流 lambda 练习
  18. Anaconda中的spyder安装Terminal插件
  19. python打开本地浏览器_python如何实现打开浏览器
  20. 程序员保护好自己的颈椎

热门文章

  1. C语言笔记系列文章 索引目录表(持续更新中......)
  2. Cisco堆叠交换机序号的改变
  3. 【C#食谱】【杭帮菜】菜单2:写一个TCP客户端
  4. python字典排序取最值总结
  5. 数据库 - mysql内置功能
  6. 法向量影响光源照射物体后,物体产生的视觉感光效果
  7. 268. Missing Number
  8. 算法导论之红黑树的学习
  9. Error: pgraster_wkb_reader: grayscale band type 10 unsupported
  10. [SSH] Eclipse+Struts+Hibernate的简单应用