环境
C4droid (这个对于我这个不会写Android的玩家比较友好,可惜不太会用)
Android
代码
//打开文件句柄
int open_proc_mem(int pid) {
if (pid <= 0)
return -1;
char mempath[64] = {0};
int handle = -1;
sprintf(mempath, "/proc/%d/mem", pid);
handle = open(mempath, O_RDWR, O_SYNC);
return handle;
}
//读内存
void pread64_mem(int fd, void *buff, int size, long *addr) {
if (fd <= 0 || buff == NULL || size <= 0 || addr == NULL)
return;
pread64(fd, buff, size, (unsigned long) addr);
}
//写内存
void pwrite64_mem(int fd, const void *buff, int size, long *addr) {
if (fd <= 0 || buff == NULL || size <= 0 || addr == NULL)
return;
pwrite64(fd, buff, size, (unsigned long) addr);
}
关于获取 PID
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
int main(int argc, char **argv)
{
DIR *pDir = NULL;
struct dirent * pEnt = NULL;
unsigned int cnt = 0;
// if (argc != 2)
/// {
// printf("usage: %s dirname\n", argv[0]);
// return -1;
// }
pDir = opendir("/proc");
if (NULL == pDir)
{
perror("opendir");
return -1;
}
while (1)
{
pEnt = readdir(pDir);
//printf("%d\n", pEnt->d_ino);
if(pEnt != NULL)
{
if (pEnt->d_type == DT_REG)
{
printf("是普通文件:");
}
else
{
printf("不是普通文件:");
}
printf("name:[%s] \n", pEnt->d_name);
cnt++;
}
else
{
break;
}
};
printf("总文件数为:%d\n", cnt);
return 0;
}
sprintf(filename, "/proc/%d/cmdline", id);
file = fopen(filename, "r");
// printf("%s \n",cmdline);
if (file) {
fgets(cmdline, sizeof(cmdline), file);
fclose(file);
if (strcmp(pack_name, cmdline) == 0) {
pid = id;
sprintf(filename, "/proc/%d/maps", id);
file = fopen(filename, "r");
fgets(cmdline, sizeof(cmdline), file);
fclose(file);
printf("%s \n",cmdline); //cmdline 为名称
break;
}
内存搜索
id = 5623;
fd = open_proc_mem(id); //打开进程内存
// pread64_mem(fd, &base, 4, addr);
// printf("%ld\n",base);
// printf("%d %d",fd,pid);
sprintf(filename, "/proc/%d/maps", id);
file = fopen(filename, "r");
while(fgets(cmdline,256,file)!=NULL)
{
for(int i=0;i<10;i++){
memsize[i] = cmdline[39+i-1];
}
for(int i=0;i<4;i++){
memt[i] = cmdline[19+i-1];
}
for(int i=0;i<8;i++){
memadd[i] = cmdline[1+i-1];
}
//memsize[11] = '\0';
// for(int i=0;i<4;i++){
// memt[i] = cmdline[19+i-1];
// }
// memt[5] = '\0';
// printf(memsize);
//printf(" ");
//printf(memt);
//printf(" ");
// printf(atoi(memadd));
//printf("%d %d",hex2dec(memadd),sizeof(memadd));
printf("\n");
// printf("%d %d",atoi(memsize),sizeof(memsize));
if(atoi(memsize) != 0 && memt[0] =='r'){
char pn[atoi(memsize)] = {0};
//printf("%d %d %d ",atoi(memsize), (long*)hex2dec(memadd),sizeof(pn));
// pread64_mem(fd, &pn, atoi(memsize), (long*)hex2dec(memadd));
pread64_mem(fd, &pn,atoi(memsize) ,(long*)hex2dec(memadd));
int ss_int = 200;
char ss[4] = {char(200),0,0,0};
map<long,int> res;
int pos=0;
int index = -1;
while(1){
index = FindString(pn,atoi(memsize),ss,4,pos);
if(index == -1)break;
pos = index +1 ;
//res.push_back(hex2dec(memadd) + index);
res[hex2dec(memadd) + index] = 200;
printf("%d \n",res[hex2dec(memadd) + index]);
}
总代码
#include <jni.h>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <dirent.h>
#include <unistd.h>
#include <vector>
#include <map>
//#include <mm_types.h>
using namespace std;
static int fd = 0;
int c2i(char ch)
{
// 如果是数字,则用数字的ASCII码减去48, 如果ch = '2' ,则 '2' - 48 = 2
if(isdigit(ch))
return ch - 48;
// 如果是字母,但不是A~F,a~f则返回
if( ch < 'A' || (ch > 'F' && ch < 'a') || ch > 'z' )
return -1;
// 如果是大写字母,则用数字的ASCII码减去55, 如果ch = 'A' ,则 'A' - 55 = 10
// 如果是小写字母,则用数字的ASCII码减去87, 如果ch = 'a' ,则 'a' - 87 = 10
if(isalpha(ch))
return isupper(ch) ? ch - 55 : ch - 87;
return -1;
}
/*
* 功能:将十六进制字符串转换为整型(int)数值
* */
int hex2dec(char *hex)
{
int len;
int num = 0;
int temp;
int bits;
int i;
// 此例中 hex = "1de" 长度为3, hex是main函数传递的
len = strlen(hex);
for (i=0, temp=0; i<len; i++, temp=0)
{
// 第一次:i=0, *(hex + i) = *(hex + 0) = '1', 即temp = 1
// 第二次:i=1, *(hex + i) = *(hex + 1) = 'd', 即temp = 13
// 第三次:i=2, *(hex + i) = *(hex + 2) = 'd', 即temp = 14
temp = c2i( *(hex + i) );
// 总共3位,一个16进制位用 4 bit保存
// 第一次:'1'为最高位,所以temp左移 (len - i -1) * 4 = 2 * 4 = 8 位
// 第二次:'d'为次高位,所以temp左移 (len - i -1) * 4 = 1 * 4 = 4 位
// 第三次:'e'为最低位,所以temp左移 (len - i -1) * 4 = 0 * 4 = 0 位
bits = (len - i - 1) * 4;
temp = temp << bits;
// 此处也可以用 num += temp;进行累加
num = num | temp;
}
// 返回结果
return num;
}
//打开文件句柄
int open_proc_mem(int pid) {
if (pid <= 0)
return -1;
char mempath[64] = {0};
int handle = -1;
sprintf(mempath, "/proc/%d/mem", pid);
handle = open(mempath, O_RDWR, O_SYNC);
return handle;
}
//读内存
void pread64_mem(int fd, void *buff, int size, long *addr) {
if (fd <= 0 || buff == NULL || size <= 0 || addr == NULL)
return;
pread64(fd, buff, size, (unsigned long) addr);
}
//写内存
void pwrite64_mem(int fd, const void *buff, int size, long *addr) {
if (fd <= 0 || buff == NULL || size <= 0 || addr == NULL)
return;
pwrite64(fd, buff, size, (unsigned long) addr);
}
int FindString(char * pSrc, int srcSize, char * pDest, int dstSize,int qishi)
{
int iFind = -1;
for(int i=qishi;i<srcSize;i++){
int iCnt = 0;
for (int j=0; j<dstSize; j++) {
if(pDest[j] == pSrc[i+j])
iCnt++;
}
if (iCnt==dstSize) {
iFind = i;
break;
}
}
return iFind;
}
//查找游戏进程pid
int getPID(const char *pack_name) {
int id = -1, pid = -1;
DIR *dir = 0;
FILE *file = 0;
char filename[32] = {0};
char cmdline[256] = {0};
struct dirent *entry = 0;
char memsize[11]={0};
char memt[5]={0};
char memadd[9]={0};
if (pack_name == NULL) {
return -1;
}
id = 5623;
fd = open_proc_mem(id); //打开进程内存
// pread64_mem(fd, &base, 4, addr);
// printf("%ld\n",base);
// printf("%d %d",fd,pid);
sprintf(filename, "/proc/%d/maps", id);
file = fopen(filename, "r");
while(fgets(cmdline,256,file)!=NULL)
{
for(int i=0;i<10;i++){// 内存大小
memsize[i] = cmdline[39+i-1];
}
for(int i=0;i<4;i++){//内存权限
memt[i] = cmdline[19+i-1];
}
for(int i=0;i<8;i++){//内存起始地址
memadd[i] = cmdline[1+i-1];
}
//memsize[11] = '\0';
// for(int i=0;i<4;i++){
// memt[i] = cmdline[19+i-1];
// }
// memt[5] = '\0';
// printf(memsize);
//printf(" ");
//printf(memt);
//printf(" ");
// printf(atoi(memadd));
//printf("%d %d",hex2dec(memadd),sizeof(memadd));
printf("\n");
// printf("%d %d",atoi(memsize),sizeof(memsize));
if(atoi(memsize) != 0 && memt[0] =='r'){
char pn[atoi(memsize)] = {0};
//printf("%d %d %d ",atoi(memsize), (long*)hex2dec(memadd),sizeof(pn));
// pread64_mem(fd, &pn, atoi(memsize), (long*)hex2dec(memadd));
pread64_mem(fd, &pn,atoi(memsize) ,(long*)hex2dec(memadd));
int ss_int = 200;
char ss[4] = {char(200),0,0,0};
map<long,int> res;
int pos=0;
int index = -1;
while(1){
index = FindString(pn,atoi(memsize),ss,4,pos);
if(index == -1)break;
pos = index +1 ;
//res.push_back(hex2dec(memadd) + index);
res[hex2dec(memadd) + index] = 200;
printf("%d \n",res[hex2dec(memadd) + index]);
}
//int oooo=0;
//while((int)pn[oooo]!=0)
//for(int i=0;i<sizeof(pn);i++)printf("%d %d\n",(int)pn[i],i);
// printf("11111");
// delete pn;
return 0;
}
//pread64_mem(fd, &base, 4, addr);
}
// fgets(cmdline, sizeof(cmdline), file);
// printf("%s \n",cmdline);
printf("结束");
fclose(file);
//printf("proc 打开成功 \n");
return 0;
while ((entry = readdir(dir)) != NULL) {
id = atoi(entry->d_name);
//printf("%d\n",id);
if (id > 0) {
sprintf(filename, "/proc/%d/cmdline", id);
file = fopen(filename, "r");
// printf("%s \n",cmdline);
if (file) {
fgets(cmdline, sizeof(cmdline), file);
fclose(file);
if (strcmp(pack_name, cmdline) == 0) {
pid = id;
sprintf(filename, "/proc/%d/maps", id);
file = fopen(filename, "r");
fgets(cmdline, sizeof(cmdline), file);
fclose(file);
printf("%s \n",cmdline);
break;
}
}
}
}
closedir(dir);
return pid;
}
/*
extern "C"
jint Java_com_gs_jc_JNI_searchMem(JNIEnv *env, jobject thiz) {
char *game = "com.tencent.tmgp.sgame"; //包名
int pid = getPID(game); //获取进程PID
fd = open_proc_mem(pid); //打开进程内存
//long base = 0;
long buf[1] = {666}; //需要修改内存的值
long *addr = (long *) 0x12C0085C; //内存地址:0x12C0085C
pwrite64_mem(fd, &buf[0], 4, addr); //写入内存数据
//pread64_mem(fd, &base, 4, addr);
return pid;
}
*/
int main(){
char *game = "com.tencent.mobileqq";//"com.tencent.tmgp.sgame"; //包名
int pid = getPID(game); //获取进程PID
fd = open_proc_mem(pid); //打开进程内存
long *addr = (long *) 0x04003144;
long base = 0;
// pread64_mem(fd, &base, 4, addr);
// printf("%ld\n",base);
// printf("%d %d",fd,pid);
return 0;
}
Comment here is closed