java 做外挂 内联汇编

java 做外挂 内联汇编前几天写了个QQ游戏练练看的外挂,不过实现原理很简单,先是从内存中读出练练看的棋盘数据,然后再用算法进行分析,得到两个可以连接的棋子坐标,再用软模拟鼠标在游戏窗口内点击两个棋子。    如果要做网络游戏的外挂,那么就要找游戏里的CALL,然后再在该游戏进程里注入汇编码,再执行注入的汇编码,来实现调用游戏CALL,那么这里就要用的汇编,其实并不是Java内联汇编,因为在Java里写汇编码,J

前几天写了个QQ游戏练练看的外挂,不过实现原理很简单,先是从内存中读出练练看的棋盘数据,然后再用算法进行分析,得到两个可以连接的棋子坐标,再用软模拟鼠标在游戏窗口内点击两个棋子。

    如果要做网络游戏的外挂,那么就要找游戏里的CALL,然后再在该游戏进程里注入汇编码,再执行注入的汇编码,来实现调用游戏CALL,那么这里就要用的汇编,其实并不是Java内联汇编,因为在Java里写汇编码,JAVA的JVM是不认识的,现在我们就要用的JNA,在系统函数里有这几个函数:

public HANDLE CreateRemoteThread(W32API.HANDLE hProcess,Structure lpThreadAttributes,int dwStackSize,int lpStartAddress,Structure lpParameter,int dwCreationFlags,IntByReference lpThreadId);

这个函数是调用远程线程。

public int VirtualAllocEx(W32API.HANDLE hProcess,IntByReference lpAddress,int dwSize,int flAllocationType,int flProtect);

这个函数是在指定进程内开辟一段内存空间。

public boolean WriteProcessMemory(W32API.HANDLE hProcess,int lpBaseAddress,byte []lpBuffer,int nSize,IntByReference lpNumberOfBytesWritten);

这个函数是在一段内存空间内,写入指定汇编码。

具体每个参数的意思可以在MSDN里面找到。

刚开始我是用StringBuffer把汇编码组成一个字符串,然后再转换成字节数组,写入内存,在去调用,在测试的时候,发现会把游戏直接送回娘家,游戏直接挂掉,让我纳闷了几个小时,到底是哪里出错了啦?在网上搜索发现,有个牛人已经用JAVA做过内联汇编,查看他的源代码才发现,汇编码不能直接转换成byte数组写入进去,必须要转换成机器码写入才能调用,下面把源码附上:

//获得窗口句柄
  W32API.HWND hwnd=User32.INSTANCE.FindWindow(null, “GameCall”);
  //获得窗口进程ID
  IntByReference id=new IntByReference();
  User32.INSTANCE.GetWindowThreadProcessId(hwnd,id);
  //获得进程句柄
  W32API.HANDLE handle=MyKernel32.INSTANCE.OpenProcess(MyKernel32.PROCESS_ALL_ACCESS, false, id.getValue());
  
  //开辟内存空间
  int l=MyKernel32.INSTANCE.VirtualAllocEx(handle, null, 0x3000, 0x1000, 0x40);
  if(l==0){

   System.out.println(“分配内存失败”);
   return;
  }else{

   System.out.println(“分配内存成功”);
   System.out.println(“内存地址:”+l);
  }
  //编写汇编码
  ASM asm = new ASM();
  //寄存器全部入栈
  asm._PUSHAD();
  //写入CALL汇编码
  asm._CALL(0x401cc0);     //0x401cc0这个是CALL的基址.
  //寄存器全部出栈
  asm._POPAD();
  // 结尾标记,操作开始执行
     asm._RET();
     //将汇编码写入内存
  boolean b=MyKernel32.INSTANCE.WriteProcessMemory(handle, l,ASM.getHexToBytes(asm.getASMCode()), 0x3000, null);
  if(b){

   System.out.println(“写入成功”);
  }else{

   System.out.println(“写入失败”);
   return;
  }
  //连续调用写入的汇编码
  for(int i=0;i<50;i++){

   int lpThreadId=0;
   MyKernel32.INSTANCE.CreateRemoteThread(handle, null, 0, l,null , 0, lpThreadId);
   if(lpThreadId==0){

    System.out.println(“调用成功”);
   }else{

    System.out.println(“调用失败”);
   }
  }

 

好了,今天就写到这,继续去研究呢。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:http://bianchenghao.cn/36568.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注