JAVA外挂开发及JNA如何调用原生函数库

package plugin.com;                //此处为我的包名删除即可


//以下三个包需要导入JNA库,JNA的官网:https://github.com/java-native-access/jna#jna
//JNA的安装链接:https://pan.baidu.com/s/1qNRGLU06V1oAx3gp0uKBBg 密码:pfbz   该链接有效时间为7天
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.ptr.IntByReference;


public class Xtgame
{
//继承了Library库顺便说一下StdCallLibrary库是遵循函数调用约定,如果你想让别的程序可以调用本程序中的方法那么可以采用StdCallLibrary这个库。
public interface XT extends Library
{
XT u = (XT) Native.loadLibrary("User32",XT.class);              //调用了User32.dll库
XT k = (XT) Native.loadLibrary("Kernel32",XT.class);            //调用了Kernel32.dll库


//以下是要用到的函数的声明,想用什么函数就在这里进行声明。
//举个例子int FindWindowA(形式参数),这个语句由两个部分组成即返回值和函数本身。这里的返回值为int型,函数即FindWindowA()不要忘了以分号作为结尾。
int FindWindowA(String lpClassName,String lpWindowName);
int GetWindowThreadProcessId(int HWND,IntByReference lpdwProcessId);
int OpenProcess(int PROCESS_ALL_ACCESS,boolean FALSE,int PID);
int CloseHandle(Object hProcess);
void ReadProcessMemory(int hProcess,int BaseAddress,IntByReference localAddress,int Size,IntByReference ReadSize);
void WriteProcessMemory(int hProcess,IntByReference BaseAddress,IntByReference Buffer,int Size,IntByReference WriteSize);
IntByReference VirtualAllocEx(int hProcess,IntByReference lpAddress,int Size,int flAllocationType,int flProtect);
}
public static void main(String[] args)      //这里就是java程序的入口处了即程序从该处开始运行,我们都知道每个程序都有一个自己的入口不然程序是得不到执行的。
{
//在Java语言中是没有地址这一概念,地址这一概念是C语言的强项java的弱项,所以要用Java开发一款对内存进行读写操作的应用(例如我们的外挂程序)程序是非常困难的一件事情。
//sun公司是注意到这一点的java作为一门跨平台的语言,为了能够调用其它系统自身提供的函数专门为Java编写了一项工具JNI,但是JNI要求编程人员必须具备C语言的知识,那对于那些
//只会Java的开发人员来说还是没有得到什么帮助,于是又在JNI的基础上引出了JNA的概念来实现纯Java编程。


//以下语句表示向一个声明好了的变量传入一个地址,这个地址是随机的每一次运行程序都会变动。
//举个例子IntByReference PID = new IntByReference()  其中IntByReference表示传入了一个长度为int型的地址。
//PID就是声明的变量用来存放要传入的地址,注意不是这个地址的值。
IntByReference PID = new IntByReference();
IntByReference LocalAddress0 = new IntByReference();
IntByReference LocalAddress1 = new IntByReference();
IntByReference LocalAddress2 = new IntByReference();
IntByReference LocalAddress3 = new IntByReference();
IntByReference LocalAddress4 = new IntByReference();
IntByReference LocalAddress5 = new IntByReference();
IntByReference LocalAddress6 = new IntByReference();
IntByReference LocalAddress7 = new IntByReference();
IntByReference LocalAddress8 = new IntByReference();
IntByReference ReadSize = new IntByReference();
IntByReference WriteSize = new IntByReference();
//这调用了FindWindowA()在java中要调用C里面的函数必须指明这个函数所属那个库,例如
//FindWindowA()是属于User32.dll中的那么可以用XT.u.FindWindowA(实际参数)这样的语法格式来表示。
//如果要进行调用的函数是属于Kernel32.dll那么可以用XT.k.函数名(实际参数)来表示。好比要调用OpenProcess()这个API
//语法格式为XT.k.OpenProcess(实际参数)。
int HWND = XT.u.FindWindowA("CLIENT_CLASS",null);
XT.u.GetWindowThreadProcessId(HWND,PID);
int hProcess = XT.k.OpenProcess(2035711,false,PID.getValue());
XT.k.ReadProcessMemory(hProcess,0x0090B614,LocalAddress0,4,ReadSize);
XT.k.ReadProcessMemory(hProcess,0x0090B618,LocalAddress1,4,ReadSize);
XT.k.ReadProcessMemory(hProcess,0x009147B8,LocalAddress2,4,ReadSize);
XT.k.ReadProcessMemory(hProcess,LocalAddress2.getValue()+0x5466C,LocalAddress3,4,ReadSize);
XT.k.ReadProcessMemory(hProcess,LocalAddress2.getValue()+0x54668,LocalAddress4,4,ReadSize);
XT.k.ReadProcessMemory(hProcess,LocalAddress2.getValue()+0x54674,LocalAddress5,4,ReadSize);
XT.k.ReadProcessMemory(hProcess,LocalAddress2.getValue()+0x54670,LocalAddress6,4,ReadSize);
XT.k.ReadProcessMemory(hProcess,LocalAddress2.getValue()+0x5467C,LocalAddress7,4,ReadSize);
XT.k.ReadProcessMemory(hProcess,LocalAddress2.getValue()+0x54678,LocalAddress8,4,ReadSize);
XT.k.CloseHandle(hProcess);


//以下是Java里的输出语句和C语言里的printf()易语言里的调试输出()命令是一样的道理。
//用getValue()方法输出地址里的值,Java中没有API这一概念在Java中函数被称之为“方法”。
System.out.println("角色横坐标:"+LocalAddress0.getValue());
System.out.println("角色纵坐标:"+LocalAddress1.getValue());
System.out.println("当前血量值:"+LocalAddress3.getValue());
System.out.println("最大血量值:"+LocalAddress4.getValue());
System.out.println("当前魔法值:"+LocalAddress5.getValue());
System.out.println("最大魔法值:"+LocalAddress6.getValue());
System.out.println("当前经验值:"+LocalAddress7.getValue());
System.out.println("最大经验值:"+LocalAddress8.getValue());
}
}










/*最后讲一下XT u = (XT) Native.loadLibrary("User32",XT.class);这个语句的用意。
 *它表示Java程序中要调用的库函数,这里就为大家介绍那些东西是可以自由命名的吧。
 *我做了一下标号这样可以方便讲解,(1)XT (2)u (3)= (4)(XT) Native.loadLibrary("User32",XT.class);
 *其中(1)(2)的内容是可以任意改变的,(3)是赋值语句的意思我想每一门语言都是一样的意思吧。
 *重点来了(4)中唯一可以自由改变了就是引号里面的内容这里指明了Java要调用的函数库,如果你开发了一个DLL想要用Java来调用的话
 *可以在这个引号里面输入你DLL的名称,加上文件的后缀名也没关系比如这样XT u = (XT) Native.loadLibrary("User32.dll",XT.class);
 *(XT) Native.loadLibrary("User32",XT.class)中间的空格是可以去掉的,这里之所以加上空格是因为我觉得这样比较美观。
 *(4)里的(XT)和XT.class是必须对应(1)中的内容,如果我把(1)的内容改为WG,那么就应该写成WG u = (WG) Native.loadLibrary("User32",WG.class);
 *值得注意的是XT必须是大写的而不能是xt,Java是一门严格区分大小写的语言。
 *另外提一下我目前对getValue()的研究只发现它取的内容为整数值,并不能取字符串也就是说如果你要读的地址存储的是字符串的内容(例如读取角色名称或地图名称),那么getValue()方法
 *只会把这个地址存放的十六进制的数据转为整数值输出,你看到的会是一大堆十进制的数字而不是字符串。
 *Windows内核安全技术开源交流,QQ群:728096809
 *好了到这里基本就已经结束了,如果你是一个喜欢Java语言或是正在学习Java的朋友可以加上面的QQ群欢迎你们,再者如果是一个想用Java写挂的朋友可以加群一起讨论JNA的使用
 *对JNA的研究目前国内的网站还是非常缺少这方面的资料的。
 */

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值