安卓跨进程读取并修改内存

38 阅读2分钟

简要的理解了一下安卓跨进程读取并修改内存的几种方法

  1. 通过ptrace这个linux/unix系统提供的系统调用
  2. 通过/proc虚拟文件系统
  3. 通过syscall系统调用
ptrace系统调用
#include<stdio.h>
#include<sys/ptrace.h>
#include<unistd.h>
int main()
{
    printf("ptrace\n");
    int pid=2853;
    long address=0xA301550C;

    printf("please input pid=>");//因为水平有限pid直接先手动输入(十进制)
    scanf("%d",&pid);
    printf("please input address=>");
    scanf("%lx",&address);//lx is fro reading a sixteen-digit adress
    //这里的格式说明符一定要注意,地址必须得是十六进制
    
    long ret=ptrace(PTRACE_ATTACH,pid,NULL,NULL);//strat debug 附加进程
    printf("PTRACE_ATTACH:%d\n",ret);
    //这里本来得有一个判断ret的值,但我想有时间再完善所以只保留了核心的函数
    //如果你想修改完善必须得注意分离进程,不然你会看到应用卡死,并且如果没有基址,数据就得重抓
   
    //write memory
    int data=0;
    printf("please input new data=>");
    scanf("%d",&data);
    ptrace(PTRACE_POKEDATA,pid,address,data);
    sleep(1);

    //read memory
    ret=ptrace(PTRACE_PEEKDATA,pid,address,NULL);//strat debug 读内存
    printf("PTRACE_PEEKDATA:%d\n",ret);

    ret=ptrace(PTRACE_DETACH,pid,NULL,NULL);//end debug  分离进程
    printf("PTRACE_DETACH:%d\n",ret);
    printf("\n");
    return 0;
}
proc虚拟文件
#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<stdint.h>

int main()
{
    printf("proc\n");
    char* mem_path="/proc/2864/mem";//中间一般是进程pid
    int fd =open(mem_path,O_RDWR);//read and write

    
    //read memory
    uintptr_t address=0xB0D19E14;
    int res;
    lseek(fd,address,SEEK_SET);//更改指针位置
    read(fd,&res,sizeof(int));
    printf("%lx read int %d\n",address,res);

    lseek(fd,address,SEEK_SET);//更改指针位置
    int buf[1]={999};
    write(fd,buf,sizeof(int));
    printf("%lx write int %d\n",address,res);

    
    close(fd);
    return 0;
}
  • 因为还没有摸清门道,所以地址和pid就写死了,有望大佬指点
  • 个人暂时感觉proc最为好用,syscall并不了解(看到代码量有点大,还得提供结构体,直接劝退)
  • ptrace在使用时selinux老是搞鬼,得在root权限下暂时关闭,即su setenforce 0(1是开)
  • 还有一个注意的点是在使用ptrace调用读取内存时,如果你刚用ce抓完数据一定先把ceserver先关闭,不然进程附加不上怎么试都返回-1(失败)
  • 为了保证很高的改写度,我只保留了核心的代码,现在看起来可能很烂,所以大佬勿喷。