前言: 博客好长时间都没有管了,最近放假了,正好有空了。 从学编程之前就对外挂比较感兴趣,刚开始学了一段时间E语言,又后来学了C语言, 上大学之后,找准了目标,主学JAVA和Android,不过对外挂这块儿还是很有兴趣, 就打算用JAVA看看能不能写一个小的游戏修改器,但是因为java是通过JVM虚拟机来运行的, 不能直接操作其他程序的数据,后来了解了一下,可以换一种方式, 那就是通过JNI去调用系统底层的函数,去修改游戏内的数据, 然后我也参考其他的示例代码,用JAVA写了一个简陋的植物大战僵尸的阳光修改器, 可以实现读取阳光值和修改阳光值,那么接下来几天就从JNI到CE找游戏基址到编写游戏修改器。
关于JNI我就不多做介绍了,网上也有很多资料和教程。
工欲善其事,必先利其器。第一步我们肯定要先配置好开发环境了。 jni在github上的开源地址:https://github.com/java-native-access/jna 首先下载jni的jar包配置到我们的eclipse中,下载地址:https://www.lanzous.com/i1brp2b
首先新建一个java项目,然后在项目里面新建一个文件夹命名为libs,
然后把我打包好的jni的jar包导入进去, 注意只需导入“jna-4.5.1.jar”和“jna-platform-4.5.1.jar”即可,其他的jar包为帮助文档
Demo1:
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Platform;
public class JNITest {
public static void main(String[] args) {
//调用printf打印信息
Clibrary.Instance.printf("Hello,JNA!\n");
}
//定义接口Clibrary,继承自com.sun.jna.Library
public interface Clibrary extends Library{
//定义并初始化接口的静态变量
Clibrary Instance = (Clibrary) Native.loadLibrary((Platform.isWindows()?"msvcrt":"c"),Clibrary.class);
//printf函数声明
void printf(String format,Object...args);
}
}
运行这段代码之后,就会调用本地C的动态库的printf函数,然后输出"Hello,JNA!\n"
Demo2:
import com.sun.jna.Native;
import com.sun.jna.win32.StdCallLibrary;
public class JNITest2 {
public static void main(String[] args) throws InterruptedException {
int hwnd = User32.INSTANCE.FindWindowA(null, null);
//设置编码,防止乱码
System.setProperty("jna.encoding", "GBK");
//调用消息对话框
User32.INSTANCE.MessageBoxA(hwnd, "闪闪闪", 0, 0);
int i = 0;
while(true) {
//阻塞鼠标键盘的输入
User32.INSTANCE.BlockInput(true);
//关闭显示器
User32.INSTANCE.SendMessageA(hwnd, 0x0112, 0xF170, 2);
Thread.sleep(2000);
//打开显示器
User32.INSTANCE.SendMessageA(hwnd, 0x0112, 0xF170, -1);
Thread.sleep(2000);
i++;
if(i>3) {
break;
}
}
//释放鼠标键盘
User32.INSTANCE.BlockInput(false);
}
public interface User32 extends StdCallLibrary{
//加载系统User32 DLL文件 也可以是C++写的DLL文件
User32 INSTANCE = Native.loadLibrary("User32",User32.class);
int SendMessageA(int hwnd, int msg, int wparam, int lparam);
int FindWindowA(String arg0, String arg1);
void BlockInput(boolean isBlock);
//对话框
int MessageBoxA(int hWnd, String IpText, int IpCaption, int uType);
}
}
执行这段代码,首先会弹出一个对话框,然后屏幕会每隔2秒闪烁一下。 聪明如你,一定发现这两段代码的共同之处,都是自定义一个接口然后继承JNI的类, 然后主函数里面通过创建接口里面的实例,调用系统底层的函数。