吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 10721|回复: 45
收起左侧

[Android 原创] Android应用内存外部读写方案研究 植物大战僵尸

  [复制链接]
Shocker 发表于 2021-12-28 20:22
本帖最后由 Shocker 于 2023-1-4 10:10 编辑

前言

市面上的PC端读写内存的教程太多了,而Android端的内存读写教程则非常少,故此研究一番.
app:植物大战僵尸单机版
部分代码参考ce-server和网上各种资料.

环境

1.雷电模拟器3(3.120)
2.Android Studio (3.6)
3.ndk (22.1.7171670)

ce搜索

模拟器连接ce-server

在ce官网下载ce-server
https://www.cheatengine.org/downloads.php
1640669604(1).jpg
将压缩包里的ceserver_x86传到模拟器上

adb push ceserver_x86 /data/local/tmp

更改权限并启动

adb shell
cd /data/local/tmp
chmod 777 ceserver_x86
./ceserver_x86

端口转发

adb forward tcp:52736 tcp:52736

ce附加里选择网络
1640671054(1).jpg
1640671093(1).jpg

ce搜索阳光

先搜初始阳光150,捡起阳光再次搜索,很容易搜索到阳光地址
1641778465(1).jpg

特征码搜索阳光地址

我尝试了许多次,按照传统的找指针方法始终没用找到阳光的指针,只能选择用特征码搜索,-_-.
1641778287(1).jpg
ce浏览相关内存区域,可以找到一组特征码

96 00 00 00 04 00 00 00

结合maps文件可知(cat /proc/xxxx/maps)
1641778203(1).jpg
阳光地址分布在
9d400000-9d401000
9d401000-a1402000
间,且模块无名称.
改写这些特征地址游戏并无崩溃.
则可将所有的特征地址都当作阳光地址处理.(我偷懒了)

外部读写内存

读内存

百度得知,读内存大致有3种方法

  • open /proc/xx/mem 文件,并使用lseek64和read读取对应地址的内存
    (参考ce源码 Cheat Engine\ceserver\api.c ReadProcessMemory)
  • ptrace读内存
    (参考ce源码 Cheat Engine\ceserver\api.c ReadProcessMemory)
  • syscall读内存

写内存

我这里采用mem方式读取内存,ptrace写入内存
部分代码参考ce-server
https://github.com/cheat-engine/cheat-engine/tree/master/Cheat%20Engine/ceserver

实验过程

代码就不一一展开了,大致过程如下,大家可以去github查看代码及注释:
1.根据包名获取待读取进程pid.
2.根据pid获取maps文件并筛选出符合条件的内存区域.
3.读取待读取内存到本地内存.
4.特征码搜索出对应的内存地址.
5.修改对应的内存地址.

int main(int argc, char *argv[])
{
    auto pid = find_pid("com.popcap.pvz");//获取pid
    if (pid == 0)
    {
        printf("Can't find pid\n");
        return -1;
    }
    else
    {
        printf("%d\n", pid);
    }

    PModuleListEntry ml = get_process_map(pid);//读取进程的模块信息,PModuleListEntry是一个链表

    while (ml->next_ptr != nullptr)//循环所有的模块
    {
        if (!ml->moduleName[0]) //判断是否有模块名,注意,这个例子是没有模块名的.
        {
            int size = ml->moduleSize;
            unsigned char *target = (unsigned char *)malloc(size);
            unsigned char *target_ = target;
            int r = ReadProcessMemory(pid, (void *)ml->baseAddress, target, size);//读取内存
            if (r == 0)
            {
                goto lable; //unreadable
            }
            while (true) //循环搜索所有匹配到的特征地址
            {
                int offset = AOBScan(target, size, pattern, sizeof(pattern));
                if (offset != -1)
                {
                    target += offset + sizeof(pattern);
                    size -= offset + sizeof(pattern);
                    unsigned long long offset_ = target - target_ - sizeof(pattern);//这里是拿到偏移
                    unsigned long long address = ml->baseAddress + offset_;//搜索到的目标进程的内存地址
                    // printf("offset_:%llx\n", offset_);
                    printf("%llx\n", address);
                    unsigned int data[] = {0x12345678};
                    WriteProcessMemory(pid, (void *)address, (void *)data, sizeof(data)/sizeof(unsigned int));//写内存
                    continue;
                }
                break;
            }
            free(target_);
        }
    lable:
        ml = (PModuleListEntry)ml->next_ptr;
    }

    return 0;
}

最后效果如图:
1640693328.png

写在最后

本文仅仅是在模拟器上做了测试,对于其他几种读写内存方式也没有尝试,希望对小伙伴们有所帮助.
也推荐一个b站爱分享的up主:赶码人
https://space.bilibili.com/669962565?spm_id_from=333.788.b_765f7570696e666f.2

github地址:
https://github.com/PShocker/Android_ndk_mem

文中所用app:
链接:https://pan.baidu.com/s/11slA0I_OAHpgVltIv3n1Pw?pwd=724z
提取码:724z

免费评分

参与人数 30威望 +2 吾爱币 +131 热心值 +27 收起 理由
HarryPotter9 + 1 + 1 热心回复!
h080294 + 1 + 1 用心讨论,共获提升!
二娃 + 2 + 1 谢谢@Thanks!
lqwer123456 + 1 我很赞同!
axy + 1 用心讨论,共获提升!
kdrew + 1 + 1 热心回复!
jnez112358 + 1 + 1 谢谢@Thanks!
szkent + 1 + 1 谢谢@Thanks!
KylinYang + 1 + 1 热心回复!
pelephone + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
solidajun + 1 + 1 我很赞同!
爱你小吉君 + 1 我很赞同!
fengbolee + 2 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
石碎大胸口 + 1 + 1 谢谢@Thanks!
gaosld + 1 + 1 谢谢@Thanks!
qtfreet00 + 2 + 100 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
qaz003 + 1 + 1 谢谢分享,有空学一下
笙若 + 1 + 1 谢谢@Thanks!
qwertyuiop1822 + 1 + 1 用心讨论,共获提升!
Lucifer_BW + 1 + 1 热心回复!
RongJ + 1 热心回复!
zhchxu123 + 1 热心回复!
小朋友呢 + 2 + 1 谢谢@Thanks!
lyl610abc + 3 + 1 我很赞同!
dwq308 + 2 + 1 已关注,坐等更新
zxougweschyjb + 1 我很赞同!
赶码人 + 1 + 1 我很赞同!
lingyun011 + 1 热心回复!
ywlYWL + 1 + 1 用心讨论,共获提升!
GousuYS + 1 + 1 用心讨论,共获提升!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

Shark丶XiaoHuai 发表于 2021-12-28 22:43
哈哈哈竟然是你,之前在B站看了你的视频,思路扩展
 楼主| Shocker 发表于 2022-1-8 11:18
cici21212 发表于 2021-12-29 20:06
手机上应该不能直接修改吧,比如屏蔽个信息框什么的。比如NOP什么的,那才好玩

可以,这个方法是android下读写内存的方法,与模拟器无关.
lingyun011 发表于 2021-12-28 20:46
kimeti 发表于 2021-12-28 21:00
前几天刚看,新手前来学习
aonima 发表于 2021-12-28 21:09
感谢分享,学习了
 楼主| Shocker 发表于 2021-12-28 22:49
Shark丶XiaoHuai 发表于 2021-12-28 22:43
哈哈哈竟然是你,之前在B站看了你的视频,思路扩展

我不是赶码人...
ych13846701169 发表于 2021-12-28 23:12
想学习,弄不懂,谢谢分享
p0weredBy 发表于 2021-12-28 23:17
阿哲 模拟器,感觉怪怪的
qqpoly 发表于 2021-12-29 07:45
什么情况,怎么一点都看不懂啊。落伍了
cydiansu 发表于 2021-12-29 09:53
可以用模拟器修改,这个有点意思,晚上我试试.
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-28 05:44

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表