使用java来写一个游戏外挂-内存修改程序(辅助-开篇)

很久以前研究过如何使用java写一个内存读写的程序,但是java都是知道的

它是在虚拟机上进行运行的,所以没办法进行内存的读写

所以用到了jan来执行windows自带的 kernel32.dll程序

感谢

Java - 游戏内存外挂 - 腾讯云开发者社区-腾讯云 (tencent.com)

的相应教程,我只是结合一下目前教程和没有提到的知识

首先引入jar包

<dependency>   
 <groupId>net.java.dev.jna</groupId>   
 <artifactId>jna</artifactId>  
  <version>4.1.0</version>
</dependency>
package cn.ttext.test.wg;

import com.sun.jna.Library;

import java.io.IOException;

public interface MemoryManager extends Library {
    int OpenProcess(int processId);
    int OpenProcess(String processName) throws IOException;
    void CloseHandle(int processId);
    int ReadIntProcessMemory(int processId,int address);
    int ReadIntProcessMemory(int processId,int ... addresss);
    void WriteIntProcessMemory(int processId,long value,int address);
    void WriteIntProcessMemory(int processId,long value,int ... addresss);
}

这是接口MemoryManager

MemoryManagerImpl

package cn.ttext.test.wg;

import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Pointer;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;

public class MemoryManagerImpl implements MemoryManager {

    private interface Memory extends Library {
        Memory INSTANCE = (Memory) Native.loadLibrary("kernel32", Memory.class);

        int OpenProcess(int desiredAccess,boolean heritHandle,int pocessID);
        void CloseHandle(int process);
        boolean ReadProcessMemory(int process, int baseAddress, Pointer buffer, int size, int bytesread);
        boolean WriteProcessMemory(int process,int baseAddress,long[] value,int size,int byteswrite);
    }

    public int OpenProcess(int processId) {
        //0x1F0FFF获取最大权限
        return Memory.INSTANCE.OpenProcess(0x1F0FFF, false, processId);
    }

    public int OpenProcess(String processName) throws IOException {
        Process process = Runtime.getRuntime().exec("TASKLIST /FI \"IMAGENAME eq " + processName + "\"");
        BufferedReader bufferedReader = new BufferedReader(
                new InputStreamReader(
                        new BufferedInputStream(process.getInputStream()), Charset.forName("UTF-8")));
        String str;
        int pid = -1;
        while ((str = bufferedReader.readLine()) != null){
            if (str.contains(processName)){
                pid = Integer.parseInt(str.substring(processName.length(),str.indexOf("Console")).trim());
            }
        }
        if (pid != -1){
            return this.OpenProcess(pid);
        }else{
            return -1;
        }
    }

    public void CloseHandle(int processId) {
        Memory.INSTANCE.CloseHandle(processId);
    }

    public int ReadIntProcessMemory(int processId, int address) {
        Pointer buffer = new com.sun.jna.Memory(4);
        Memory.INSTANCE.ReadProcessMemory(processId,address,buffer,4,0);
        return buffer.getInt(0);
    }

    public int ReadIntProcessMemory(int processId, int... addresss) {
        int address = 0;
        for (int addr:addresss){
            address = ReadIntProcessMemory(processId, addr + address);
        }
        return address;
    }

    public void WriteIntProcessMemory(int processId, long value, int address) {
        Memory.INSTANCE.WriteProcessMemory(processId,address,new long[]{value},4,0);
    }

    public void WriteIntProcessMemory(int processId, long value, int... addresss) {
        int[] t_a = new int[addresss.length - 1];
        for (int i = 0; i < t_a.length; i++) {
            t_a[i] = addresss[i];
        }
        WriteIntProcessMemory(processId,value,
                this.ReadIntProcessMemory(processId, t_a) + addresss[addresss.length - 1]);
    }
}

我们本次使用到的游戏是 植物大战僵尸作为参考

著名:如果需要写其他游戏辅助等,做好还是用其他语言(因为教程很多)

首先,我们需要获取到游戏的pid

其次需要一定的逆向基础等 可以参考其他论坛来学习

并在学习过程中发现各大教程或者讨论贴都没有相应的介绍和详细的使用

因为那些都是只可以获取动态内存,所以说没办法从基地址进行偏移来获取指针的值

现在先拿一个案例来示范和探讨,有错误请指出,看到会改,或者问题 会回复

main方法

//用来获取游戏pid
int process = memoryManager.OpenProcess("PlantsVsZombies.exe");
package cn.ttext.test.wg;

import java.io.IOException;

public class Main {
    public static void main(String[] args) throws Exception {
        MemoryManager memoryManager = new MemoryManagerImpl();
        //打开进程名:PlantsVsZombies.exe
        int process = memoryManager.OpenProcess("PlantsVsZombies.exe");
        System.out.println("启动成功。。。。。。。。。。");
        //向阳光的地址写入数量
        memoryManager.WriteIntProcessMemory(process,999999,0x006A9EC0, 0x768, 0x5560);

        //清除冷却,每500毫秒清一次
        new Thread(()->{
            while (true){
                for (int i = 0; i < 7; i++) {
                    memoryManager.WriteIntProcessMemory(process,1,0x006A9EC0, 0x768, 0x144,0x70 + 0x50 * i);
                }
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();

        //退出进程
        //memoryManager.CloseHandle(process);
    }
}

好了,问题来了,我想获取CSGO中的矩阵基地址该怎么读呢?

 
     int process = memoryManager.OpenProcess("cstrike.exe");
     System.out.println(process);
     System.out.println("启动成功。。。。。。。。。。");
//读取矩阵cstrike.exe+1820100
    float[] Matrix=new float[16];
    Matrix= memoryManager.ReadMatrixProcessMemory(process, 0x1400000+0x1820100);
    for (int i=0;i<Matrix.length;i++){
        System.out.print(Matrix[i]+"\t");
    }
    System.out.println();

其次我们要明白 0x1400000是基地址 0x1820100 是偏移量

这就是锁定本地静态地址,每次可便宜到,如果需要画框则需要swing等,请自行研究,仅供学习和参考!

如果有新的我会补充,仅供学习使用!

  • 2
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值