写之前需要准备以下内容
android studio
已ROOT安卓设备
GG修改器
打开android studio,创建Native C++ Project
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="btn" />
<TextView
android:id="@+id/tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="~" />
</LinearLayout>
MainActivity.java
package com.gs.jc;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private TextView textView;
private JNI jni;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
jni = new JNI();
textView = (TextView) findViewById(R.id.tv);
}
public void btn(View view) {
textView.setText(String.valueOf(jni.searchMem()));
}
}
新建一个java类,以实现java调用对应C代码
package com.gs.jc;
public class JNI {
static {
System.loadLibrary("native-lib");
}
/*
*定义native方法
*调用C代码对应的方法
*/
public native int searchMem();
}
O_RDONLY 只读打开
O_WRONLY 只写打开
O_RDWR 可读可写打开
O_SYNC 以同步的方式打开文件
C++核心代码
#include <jni.h>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <dirent.h>
#include <unistd.h>
static int fd = 0;
//查找游戏进程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;
if (pack_name == NULL) {
return -1;
}
dir = opendir("/proc");
if (dir == NULL) {
return -1;
}
while ((entry = readdir(dir)) != NULL) {
id = atoi(entry->d_name);
if (id > 0) {
sprintf(filename, "/proc/%d/cmdline", id);
file = fopen(filename, "r");
if (file) {
fgets(cmdline, sizeof(cmdline), file);
fclose(file);
if (strcmp(pack_name, cmdline) == 0) {
pid = id;
break;
}
}
}
}
closedir(dir);
return pid;
}
//打开文件句柄
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);
}
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;
}
C代码中需要自行修改的地方
char *game = “com.tencent.tmgp.sgame”; //包名
long *addr = (long *) 0x12C0085C;//内存地址
效果图链接:
https://www.lanzous.com/b0dppncji
以上是简单的内存地址修改方法,右上角关注后续讲解模糊搜索、联合搜索、特征码定位
转载:https://blog.csdn.net/qq_33522837/article/details/104593589
查看评论