最近闲着蛋疼,无聊之中用CE耍了一哈游戏,发现挺好用的,于是就想,我自己能不能写个内存修改器呢?于是乎,这个软件就诞生了!

当然我只会Java,C++嘛,了解了解,嘿嘿,所以这个工具也是用Java写的

这个工具在写内存搜索时,简直累死了,最开始暴力搜索,效率慢的要死,经过三天的不懈努力,终于搞定这搜索功能!这也是整个工具最难的部分,至少我是这么认为的

微软的MSDN都被我翻了又翻 - - !

完整源码和项目我已上传csdn

http://download.csdn.net/detail/qq969422014/9707030

下载解压后的目录结构:

第一个是源代码:用Eclipse导入即可,记得修改Build Path

第二个是打包好的Jar,如果电脑安装了Java,就可以直接运行

第三个是打包好的exe安装程序,可以在没有安装Java的电脑上运行

不多说了,先上一张效果图: (这里用植物大战僵尸做实验,4399的小游戏)

原来阳光是150,被我改成1024了

先说说这个软件的使用步骤吧,与CE用法差不多,先打开游戏进程,输入搜索的游戏值(比如这里改阳光,所以输入150),然后开始搜索,搜索完成后,种一柱植物,或者捡一个阳光,总之让阳光值发生变化,然后再点击搜索变化,地址就出来啦,最后,鼠标点击,输入修改值,点击写入内存就可以咯如果搜索变化没有,就多搜两次哦

本工具开发环境如下:

开发工具:Eclipse

开发语言:Java

开发系统:windows7

JDK版本:1.6

项目所需的第三方包:

官网下载JNA包:https://github.com/java-native-access/jna   这个包用于调用windows系统函数库

官网下载皮肤包:http://www.jtattoo.net/   这个包是Swing的皮肤包,用于做界面用的

代码实现大致思路如下:

获取Debug权限->创建系统快照->获取进程ID->获取进程在内存中的首地址与结束地址->打开进程->遍历内存->查找数据->修改数据

项目包目录如下:


entity 这是实体包

event 这是窗体的事件监听相应包

impl 功能的核心实现

interfaces C++ API函数接口定义

quantity C++ API函数常量描述

structure C++结构体描述

wnd 软件界面

下面开始给出关键代码:

代码一:获取Debug权限,这里可以理解为赋予软件管理员,如果不获取Debug权限,会导致有些进程可能会拒绝访问

 /*** processHandle 需要给予的进程句柄* privilegeValue 特权值,详情请参阅LookupPrivilegeValue接口* **/public ExecuteResult give(int processHandle,String privilegeValue){ExecuteResult executeResult = new ExecuteResult();//创建令牌句柄指針,用于保存OpenProcessToken函数返回的令牌HANDLEByReference tokenHandle = new HANDLEByReference();try {//打开进程令牌,用于查询和修改令牌if(Advapi32_DLL.INSTANCE.OpenProcessToken(processHandle, OpenProcessToken.TOKEN_ADJUST_PRIVILEGES|OpenProcessToken.TOKEN_QUERY, tokenHandle)){//创建一个令牌特权,初始化为1,用于保存LookupPrivilegeValue函数返回的令牌特权TOKEN_PRIVILEGES tkp = new TOKEN_PRIVILEGES(1);//初始化令牌特LUID值tkp.Privileges[0] = new LUID_AND_ATTRIBUTES();tkp.Privileges[0].Luid = new LUID();tkp.Privileges[0].Attributes = OpenProcessToken.SE_PRIVILEGE_ENABLED;//查看系统权限的特权值,返回到tkp LUIDif(Advapi32_DLL.INSTANCE.LookupPrivilegeValue(null, privilegeValue, tkp.Privileges[0].Luid)){//告诉系统启用该令牌Advapi32_DLL.INSTANCE.AdjustTokenPrivileges(tokenHandle.getValue(), false, tkp, tkp.size(), null, null);}}} finally {//释放令牌指针ReferenceFree.free(tokenHandle);//获取执行结果executeResult.setLastError(Kernel32_DLL.INSTANCE.GetLastError());//释放句柄资源Kernel32_DLL.INSTANCE.CloseHandle(processHandle);}return executeResult;}

代码二:创建系统快照,获取系统进程相关信息

 /*** 得到系统进程列表* */public ExecuteResult getProcess(){ExecuteResult executeResult = new ExecuteResult();//获取结果集List<Process> list = new ArrayList<Process>();//创建当前系统进程快照,返回快照句柄,具体参考com.memory.interfaces.Kernel32_DLL中的描述int processHandle = Kernel32_DLL.INSTANCE.CreateToolhelp32Snapshot(CreateToolhelp32Snapshot.TH32CS_SNAPPROCESS, 0);//快照結果int lastError = Kernel32_DLL.INSTANCE.GetLastError();if(processHandle==0 || lastError!=0){executeResult.setLastError(lastError);executeResult.setMessage("获取系统进程信息失败,错误代码:"+lastError);return executeResult;}try {//创建进程结构体,用于保存进程的相关信息,具体参考com.memory.entity.Process中的描述PROCESSENTRY32 lppe = new PROCESSENTRY32();//根据快照句柄遍历系统进程while(Kernel32_DLL.INSTANCE.Process32Next(processHandle, lppe)){Process temp = new Process();temp.setProcessName(lppe.getSzExeFileStr());temp.setPid(lppe.th32ProcessID);list.add(temp);}if(list.size()!=0){executeResult.setValue(list);}else{lastError = Kernel32_DLL.INSTANCE.GetLastError();executeResult.setLastError(lastError);executeResult.setMessage("获取系统进程信息失败,错误代码:"+lastError);}} finally{//释放句柄资源Kernel32_DLL.INSTANCE.CloseHandle(processHandle);}return executeResult;}

代码三: 获取进程的开始内存地址与结束内存地址,获取系统的内存地址

 /*** 查询进程在内存中的开始地址与结束地址* **/public ExecuteResult queryProcessRange(int pid){ExecuteResult executeResult = new ExecuteResult();//创建内存范围对象MemoryRange range = new MemoryRange();//创建进程模版快照,查询应用程序的在内存中的基地址int handleModule = Kernel32_DLL.INSTANCE.CreateToolhelp32Snapshot(CreateToolhelp32Snapshot.TH32CS_SNAPMODULE, pid);//快照执行结果int lastError = Kernel32_DLL.INSTANCE.GetLastError();executeResult.setLastError(lastError);//判断结果if(lastError==5){executeResult.setMessage("无法打开进程,系统Debug权限获取失败,请以管理员方式重新运行程序!");return executeResult;}//如果为299,说明只有部分权限,判断该进程是否是64位进程else if(lastError==299){//声明INT指针,保存IsWow64Process返回的值IntByReference Wow64Process = new IntByReference();int handle = Kernel32_DLL.INSTANCE.OpenProcess(OpenProcess.PROCESS_ALL_ACCESS, false, pid);if(Kernel32_DLL.INSTANCE.IsWow64Process(handle, Wow64Process)){//如果为64位进程,那么久获取系统的内存范围if(Wow64Process.getValue()==0){executeResult = querySystemRange();}}else{executeResult.setMessage("无法打开该进程,错误代码:"+lastError);}//释放内存ReferenceFree.free(Wow64Process);Kernel32_DLL.INSTANCE.CloseHandle(handle);return executeResult;}else if(lastError!=0){executeResult.setMessage("无法打开该进程,OpenProcess函数返回错误码:"+lastError);return executeResult;}try {MODULEENTRY32 lpme = new MODULEENTRY32();if(Kernel32_DLL.INSTANCE.Module32First(handleModule, lpme)){range.setMinValue(lpme.modBaseAddr);if(Kernel32_DLL.INSTANCE.Module32Next(handleModule, lpme)){range.setMaxValue(lpme.modBaseAddr);}}//执行结果返回值executeResult.setValue(range);//执行结果lastError = Kernel32_DLL.INSTANCE.GetLastError();if(range.getMinValue() == 0 && lastError!=0){executeResult.setLastError(lastError);executeResult.setMessage("Module32Next失败,错误代码:"+lastError);}} finally {//释放快照Kernel32_DLL.INSTANCE.CloseHandle(handleModule);}return executeResult;}/*** 查询当前系统的可搜索的开始地址与结束地址* **/public ExecuteResult querySystemRange(){ExecuteResult executeResult = new ExecuteResult();//创建内存范围对象MemoryRange range = new MemoryRange();//创建描述系统信息的结构SYSTEM_INFO info = new SYSTEM_INFO();//获取系统内存范围Kernel32_DLL.INSTANCE.GetSystemInfo(info);range.setMinValue(Pointer.nativeValue(info.lpMinimumApplicationAddress));range.setMaxValue(Pointer.nativeValue(info.lpMaximumApplicationAddress));//返回值executeResult.setValue(range);//调用结果int lastError = Kernel32_DLL.INSTANCE.GetLastError();if(lastError!=0){executeResult.setLastError(lastError);executeResult.setMessage("获取系统内存地址范围失败,错误代码:"+lastError);}return executeResult;}

代码四:搜索内存,也是最核心的部分,个人感觉也是最难的部分,可能是之前没做个之类的软件吧,反正耗费我三天,头都要炸了

package com.memory.impl;import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;import com.memory.entity.ExecuteResult;
import com.memory.entity.MemoryValue;
import com.memory.interfaces.Kernel32_DLL;
import com.memory.quantity.OpenProcess;
import com.memory.quantity.VirtualProtect;
import com.memory.structure.MEMORY_BASIC_INFORMATION;
import com.sun.jna.Memory;
import com.sun.jna.Pointer;/*** 内存搜索实现类* 作者:Code菜鸟* 技术交流QQ:969422014* CSDN博客:http://blog.csdn.net/qq969422014* */
public class MemorySearchImpl
{   //保存查询内存结果信息的结构体类private MEMORY_BASIC_INFORMATION memoryInfo = new MEMORY_BASIC_INFORMATION();//查询结果的大小private int size = memoryInfo.size();//统计内存扫描数量public int memoryScore = 0;//保存搜索public List<MemoryValue> searchResult = Collections.synchronizedList(new ArrayList<MemoryValue>());/*** 值搜索* pid 进程ID* value 需要搜索的值* searchDataType 搜索的实际数据类型 0=INT 1=Short 2=long 3=float 4=double 5=byte* equalsSearchValue 与搜索值相比较 0等于,1大于,2小于* startBaseAddr 搜索开始的内存基址* endBaseAddr 搜索结束的内存基址* increasing 搜索地址的递增量* **/public ExecuteResult search(int pid,String searchValue,int searchDataType,int equalsSearchValue,int startBaseAddr,int endBaseAddr){if(searchResult.size()!=0) searchResult.clear();ExecuteResult executeResult = new ExecuteResult();memoryScore = 0;//根据进程ID,打开进程,返回进程句柄int handle = Kernel32_DLL.INSTANCE.OpenProcess(OpenProcess.PROCESS_ALL_ACCESS, false, pid);//判断进程句柄是否打开成功int lastError = Kernel32_DLL.INSTANCE.GetLastError();executeResult.setLastError(lastError);if(lastError==5){executeResult.setMessage("无法打开进程,系统Debug权限获取失败,请以管理员方式重新运行程序!");return executeResult;}else if(lastError!=0){executeResult.setMessage("无法打开该进程,OpenProcess函数返回错误码:"+lastError);return executeResult;}try {//根据基址遍历内存while(startBaseAddr <= endBaseAddr){//读取内存信息int vqe = Kernel32_DLL.INSTANCE.VirtualQueryEx(handle, startBaseAddr, memoryInfo, size);if(vqe==0) break;//判断内存是否已提交,非空闲内存     if (memoryInfo.state == MEMORY_BASIC_INFORMATION.MEM_COMMIT){//更改内存保护属性为可写可读,成功返回TRUE,执行这个函数,OpenProcess函数必须为PROCESS_ALL_ACCESSboolean vpe = Kernel32_DLL.INSTANCE.VirtualProtectEx(handle, startBaseAddr, memoryInfo.regionSize, VirtualProtect.PAGE_READWRITE, memoryInfo.protect);//判断内存是否可读可写if(vpe || memoryInfo.protect == MEMORY_BASIC_INFORMATION.PAGE_READWRITE){//声明一块内存空间,保存读取内存块的值,这个空间的大小与内存块大小相同Pointer buffer = new Memory(memoryInfo.regionSize);//判断是否读取成功if(Kernel32_DLL.INSTANCE.ReadProcessMemory(handle, startBaseAddr, buffer, memoryInfo.regionSize, 0)){  //对比的值double searchValueDouble = Double.parseDouble(searchValue);//根据搜索类型查找对应数据switch(searchDataType){//查找整形int,4字节,所以i+=4case 0:for(int i = 0; i < memoryInfo.regionSize; i+=4) { double memoryValue = buffer.getInt(i);//统计内存数量memoryScore++;//与搜索值相比较释放符合条件 0等于,1大于,2小于if((equalsSearchValue ==0 &&  memoryValue == searchValueDouble) || (equalsSearchValue==1 && memoryValue > searchValueDouble) ||(equalsSearchValue==2 && memoryValue < searchValueDouble)){MemoryValue temp = new MemoryValue();temp.setAddress(startBaseAddr + i);temp.setAddress16("0x"+Long.toString((startBaseAddr + i), 16).toUpperCase());temp.setValue(memoryValue+"");searchResult.add(temp);}}break;//查找短整形short,2字节,所以i+=2case 1:for(int i = 0; i < memoryInfo.regionSize; i+=2) { double memoryValue = buffer.getShort(i);//统计内存数量memoryScore++;//与搜索值相比较释放符合条件 0等于,1大于,2小于if((equalsSearchValue ==0 &&  memoryValue == searchValueDouble) || (equalsSearchValue==1 && memoryValue > searchValueDouble) ||(equalsSearchValue==2 && memoryValue < searchValueDouble)){MemoryValue temp = new MemoryValue();temp.setAddress(startBaseAddr + i);temp.setAddress16("0x"+Long.toString((startBaseAddr + i), 16).toUpperCase());temp.setValue(memoryValue+"");searchResult.add(temp);}}break;//查找长整形Long,8字节,所以i+=8case 2:for(int i = 0; i < memoryInfo.regionSize; i+=8) { double memoryValue = buffer.getLong(i);//统计内存数量memoryScore++;//与搜索值相比较释放符合条件 0等于,1大于,2小于if((equalsSearchValue ==0 &&  memoryValue == searchValueDouble) || (equalsSearchValue==1 && memoryValue > searchValueDouble) ||(equalsSearchValue==2 && memoryValue < searchValueDouble)){MemoryValue temp = new MemoryValue();temp.setAddress(startBaseAddr + i);temp.setAddress16("0x"+Long.toString((startBaseAddr + i), 16).toUpperCase());temp.setValue(memoryValue+"");searchResult.add(temp);}}break;//查找单精度浮点 float,4字节,所以i+=4case 3:for(int i = 0; i < memoryInfo.regionSize; i+=4) { double memoryValue = buffer.getFloat(i);//统计内存数量memoryScore++;//与搜索值相比较释放符合条件 0等于,1大于,2小于if((equalsSearchValue ==0 &&  memoryValue == searchValueDouble) || (equalsSearchValue==1 && memoryValue > searchValueDouble) ||(equalsSearchValue==2 && memoryValue < searchValueDouble)){MemoryValue temp = new MemoryValue();temp.setAddress(startBaseAddr + i);temp.setAddress16("0x"+Long.toString((startBaseAddr + i), 16).toUpperCase());temp.setValue(memoryValue+"");searchResult.add(temp);}}break;//查找双精度浮点 double,8字节,所以i+=8case 4:for(int i = 0; i < memoryInfo.regionSize; i+=8) { double memoryValue = buffer.getDouble(i);//统计内存数量memoryScore++;//与搜索值相比较释放符合条件 0等于,1大于,2小于if((equalsSearchValue ==0 &&  memoryValue == searchValueDouble) || (equalsSearchValue==1 && memoryValue > searchValueDouble) ||(equalsSearchValue==2 && memoryValue < searchValueDouble)){MemoryValue temp = new MemoryValue();temp.setAddress(startBaseAddr + i);temp.setAddress16("0x"+Long.toString((startBaseAddr + i), 16).toUpperCase());temp.setValue(memoryValue+"");searchResult.add(temp);}}break;//查找字节byte,1字节,所以i++case 5:for(int i = 0; i < memoryInfo.regionSize; i++) { double memoryValue = buffer.getByte(i);//统计内存数量memoryScore++;//与搜索值相比较释放符合条件 0等于,1大于,2小于if((equalsSearchValue ==0 &&  memoryValue == searchValueDouble) || (equalsSearchValue==1 && memoryValue > searchValueDouble) ||(equalsSearchValue==2 && memoryValue < searchValueDouble)){MemoryValue temp = new MemoryValue();temp.setAddress(startBaseAddr + i);temp.setAddress16("0x"+Long.toString((startBaseAddr + i), 16).toUpperCase());temp.setValue(memoryValue+"");searchResult.add(temp);}}break;}}//释放内存ReferenceFree.free(buffer);}}//设置基地址偏移startBaseAddr = (int) Pointer.nativeValue(memoryInfo.baseAddress) + memoryInfo.regionSize; }}catch (Exception e){e.printStackTrace();executeResult.setLastError(-1);executeResult.setMessage("内存地址扫描错误!\n"+e.getMessage());return executeResult;}finally{//释放资源Kernel32_DLL.INSTANCE.CloseHandle(handle);}return executeResult;}/*** 再次搜索实现* pid 进程ID* addressList 搜索的内存地址列表* searchDataType 搜索的数据类型* **/public ExecuteResult search(int pid,List<MemoryValue> addressList,int searchDataType){ExecuteResult executeResult = new ExecuteResult();if(searchResult.size()!=0) searchResult.clear();memoryScore = 0;//获取进程句柄int handle = Kernel32_DLL.INSTANCE.OpenProcess(OpenProcess.PROCESS_ALL_ACCESS, false,pid);try{//保存读取的新值Map<String,MemoryValue> tableValueMap = new HashMap<String,MemoryValue>();//声明一块内存,保存读取值Pointer readResult = new Memory(1024);for(int i = 0;i<addressList.size();i++){memoryScore++;//将0xffff table中的值转换为int类型int temp = Integer.parseInt(addressList.get(i).getAddress16().replace("0x", ""),16);if(Kernel32_DLL.INSTANCE.ReadProcessMemory(handle, temp, readResult, 1024, 0)){MemoryValue m = new MemoryValue();m.setAddress(temp);m.setAddress16("0x"+(Integer.toString(temp, 16).toUpperCase()));//根据搜索类型读取对应数据switch(searchDataType){//整形intcase 0:m.setValue(readResult.getInt(0)+"");break;//短整形shortcase 1:m.setValue(readResult.getShort(0)+"");break;//长整形Longcase 2:m.setValue(readResult.getLong(0)+"");break;//单精度浮点 floatcase 3:m.setValue(readResult.getFloat(0)+"");break;//双精度浮点 doublecase 4:m.setValue(readResult.getDouble(0)+"");break;//字节bytecase 5:m.setValue(readResult.getByte(0)+"");break;}tableValueMap.put(m.getAddress16(), m);}}//释放内存ReferenceFree.free(readResult);//移除列表中没有发生变化的内存值for(int i = 0;i<addressList.size();i++){String key = addressList.get(i).getAddress16();String value = addressList.get(i).getValue();if(tableValueMap.get(key)!=null&& Double.parseDouble(tableValueMap.get(key).getValue())==Double.parseDouble(value)){tableValueMap.remove(key);}}//搜索结果for(String key:tableValueMap.keySet()){searchResult.add(tableValueMap.get(key));}executeResult.setLastError(Kernel32_DLL.INSTANCE.GetLastError());if(executeResult.getLastError()!=0){executeResult.setMessage("搜索内存发生错误!错误代码:"+executeResult.getLastError());}} catch (Exception e){e.printStackTrace();executeResult.setLastError(-1);executeResult.setMessage("内存地址扫描错误!\n"+e.getMessage());}finally{//资源释放Kernel32_DLL.INSTANCE.CloseHandle(handle);}return executeResult;}
}

代码五:内存的写实现

package com.memory.impl;import com.memory.entity.ExecuteResult;
import com.memory.interfaces.Kernel32_DLL;
import com.memory.quantity.OpenProcess;
import com.memory.structure.MEMORY_BASIC_INFORMATION;
import com.sun.jna.Memory;
import com.sun.jna.Pointer;/*** 内存的写实现类* 作者:Code菜鸟* 技术交流QQ:969422014* CSDN博客:http://blog.csdn.net/qq969422014* */
public class MemoryWrite
{   /*** 写入内存实现方法* pid 进程ID* lpBaseAddress 写入地址* value 写入值* dataType 数据类型,这个值确定value的实际数据类型* **/public ExecuteResult write(int pid,int lpBaseAddress,String value,int dataType){ExecuteResult result = new ExecuteResult();int hProcess = Kernel32_DLL.INSTANCE.OpenProcess(OpenProcess.PROCESS_ALL_ACCESS, false, pid);//判断进程句柄是否打开成功int lastError = Kernel32_DLL.INSTANCE.GetLastError();result.setLastError(lastError);if(lastError==5){result.setMessage("进程拒绝访问,可能是系统Debug权限获取失败,请以管理员方式重新运行程序!");return result;}else if(lastError!=0){result.setMessage("无法打开该进程,错误代码:"+lastError);return result;}try {//判断内存地址是否合法幷且是否满足读写权限MEMORY_BASIC_INFORMATION lpBuffer = new MEMORY_BASIC_INFORMATION();Kernel32_DLL.INSTANCE.VirtualQueryEx(hProcess, lpBaseAddress, lpBuffer, lpBuffer.size());if(!(lpBuffer.state == MEMORY_BASIC_INFORMATION.MEM_COMMIT && lpBuffer.protect == MEMORY_BASIC_INFORMATION.PAGE_READWRITE)){result.setLastError(-1);result.setMessage("内存地址不存在或者该内存无法读写!");return result;}//新内存地址,用于写入内存用Pointer updatePointer = null;int size = 4;switch(dataType){//整形intcase 0:size = 4;updatePointer = new Memory(size);updatePointer.setInt(0, Integer.parseInt(value));break;//短整形shortcase 1:size = 2;updatePointer = new Memory(size);updatePointer.setShort(0, Short.parseShort(value));break;//长整形Longcase 2:size = 8;updatePointer = new Memory(size);updatePointer.setLong(0, Long.parseLong(value));break;//单精度浮点 floatcase 3:size = 4;updatePointer = new Memory(size);updatePointer.setFloat(0, Float.parseFloat(value));break;//双精度浮点 doublecase 4:size = 8;updatePointer = new Memory(size);updatePointer.setDouble(0, Double.parseDouble(value));break;//字节bytecase 5:size = 1;updatePointer = new Memory(size);updatePointer.setByte(0, Byte.parseByte(value));break;}//写入内存boolean writeResult = Kernel32_DLL.INSTANCE.WriteProcessMemory(hProcess, lpBaseAddress, updatePointer, size, 0);//是否写入成功lastError = Kernel32_DLL.INSTANCE.GetLastError();if((!writeResult) || lastError!=0){result.setLastError(lastError);result.setMessage("内存写入发生错误,错误代码:"+lastError);return result;}result.setLastError(0);result.setMessage("写入成功!");return result;} catch (Exception e){result.setLastError(-1);result.setMessage("写入失败,请检查输入值是否正确或超出范围!\n错误代码:"+e.getMessage());}finally{Kernel32_DLL.INSTANCE.CloseHandle(hProcess);}return result;}
}

代码六:进程的杀死实现

package com.memory.impl;import com.memory.entity.ExecuteResult;
import com.memory.interfaces.Kernel32_DLL;
import com.memory.quantity.OpenProcess;
import com.sun.jna.ptr.IntByReference;/*** 进程杀死实现类* 作者:Code菜鸟* 技术交流QQ:969422014* CSDN博客:http://blog.csdn.net/qq969422014* */
public class KillProcess
{/*** 具体解释,请查看com.memory.interfaces.Kernel32_DLL接口中的描述* pid 进程ID,这个值可以通过任务管理器查看或通过CreateToolhelp32Snapshot函数获取* **/public ExecuteResult kill(int pid){ExecuteResult executeResult = new ExecuteResult();int hProcess = Kernel32_DLL.INSTANCE.OpenProcess(OpenProcess.PROCESS_ALL_ACCESS, false, pid);//INT指针,保存GetExitCodeProcess函数调用成功后,返回的程序退出值IntByReference lpExitCode = new IntByReference();try {//获取程序的退出代码if(Kernel32_DLL.INSTANCE.GetExitCodeProcess(hProcess, lpExitCode)){//退出程序Kernel32_DLL.INSTANCE.TerminateProcess(hProcess, lpExitCode.getValue());}}finally{//释放INT指针ReferenceFree.free(lpExitCode);Kernel32_DLL.INSTANCE.CloseHandle(hProcess);}//获取执行结果int lastError = Kernel32_DLL.INSTANCE.GetLastError();executeResult.setLastError(lastError);if(lastError!=0)executeResult.setMessage("杀死进程时发生错误,错误代码:"+lastError);return executeResult;}
}

Java外挂开发之内存修改器(类似CE)相关推荐

  1. 超漂亮的内存修改器,可以媲美某类似软件,UI界面反复调整 功能更加人性化,更多隐藏功能待您发现

    内存修改器:(有个比较有名的Cheat Engine修改器,功能十分相似,可能没ce专业,界面UI是反复调整后的) 对比图 一般是修改某应用在变化的某值,确定其内存地址(通过2次搜索锁定目标)然后写入 ...

  2. andorid平台游戏内存修改器的开发思路

    实现一个linux下的命令行内存修改器,然后安卓程序调用这个外置命令 1. 对指定andorid程序的内存进行扫描,把符合条件的数据都列表显现. 这个研究下/proc/pid/maps文件结构,主要分 ...

  3. 给初学者:用VB写外挂 ———— 实战六:幽城幻剑录-幽城幻劍錄内存修改器

    先起个头,有时间再写,今天病的,到现在也没睡着...本来写了好几天了,哎. 前几天下了这个游戏看了看,感觉还可以吧,发现有诸多存盘修改器.随时存档补丁.穿墙等补丁,很乱,玩家打上一个免CD还要打其他补 ...

  4. Android For JNI(二)——C语言中的数据类型,输出,输入函数以及操作内存地址,内存修改器

    Android For JNI(二)--C语言中的数据类型,输出,输入函数以及操作内存地址,内存修改器 当我们把Hello World写完之后,我们就可以迈入C的大门了,今天就来讲讲基本的一些数据类型 ...

  5. 手机html5游戏内存修改,一种防止游戏被内存修改器修改的方法

    一种防止游戏被内存修改器修改的方法 [技术领域] [0001]本发明涉及游戏数据处理领域,尤其涉及一种防止游戏被内存修改器修改的方法. [背景技术] [0002]目前,电子游戏越来越受到大家的喜爱,丰 ...

  6. 内存修改器对游戏的危害

    内存修改器是游戏外挂里面的一个大类,通过修改器可实现很多魔幻且具有很大破坏性的功能. 下面几张图是使用修改器实现的游戏破解效果. 内存修改器实现的透视功能 内存修改器实现的遁地功能 修改器实现的飞天功 ...

  7. 使用VC2008制作简单大航海外传内存修改器

    作者 :小草 日期 :2010/7/4 始发于 http://bbs.evewind.net/read.php?tid=2815 程序源代码下载地址: http://code.google.com/p ...

  8. 【术】游戏内存修改器原理及游戏敏感数值加密建议

    介绍市面上主流游戏内存修改器的原理,对症下药,让游戏从数据加密层面上更好的抵御这类内存修改器. 主流游戏内存修改器有三大内存搜索功能: 1. 基础数值搜索 2. 模糊搜索 3. 反加密搜索 基础数值搜 ...

  9. Windows编程_Lesson008_内存_内存修改器

    内存修改器 修改指定进程名字中的指定值所在的地址,进而改变这个值. 单线程版本 #include <Windows.h> #include <stdio.h> #include ...

最新文章

  1. [转载]Android开发常用调试技术记录
  2. VMware vSphere 4.1虚拟化学习手册6:Distributed vSwitch分布式交换机
  3. 武汉大学计算机学院参考书目,2020武汉大学计算机与软件工程考研初试科目、参考书目及复试详情...
  4. python爬虫能秒杀么_面试题之用python爬取并夕夕不同时段秒杀商品信息
  5. 博文视点大讲堂第30期——职场新人胜出关键点
  6. linux后台运行和关闭、查看后台任务(转)
  7. 30个极简python代码(demo)
  8. python开源bi_推荐一套开源BI工具?
  9. 最新CISP模拟考试题库及答案(二)
  10. 想成为时间管理大师?试试番茄工作法!
  11. mysql后台_使用MySQL在后台运行SQL查询
  12. 计算机软件能删除吗,怎么彻底清除电脑软件鲁大师?卸载对系统有影响吗?
  13. APP在线制作平台,手机应用,手机App开发,手机客户端开发
  14. 华为OD机考 2022
  15. 谷歌Chrome浏览器对单个网站清理Cookie
  16. java实验报告6:异常处理程序设计
  17. MyBatis SSM
  18. iqoo手机可以刷鸿蒙系统吗,华为老机型可以更新鸿蒙系统么-华为哪些老机型支持鸿蒙系统...
  19. 【Linux】系统管理命令
  20. 安卓移动微信页调试大法

热门文章

  1. 删除 iPhone 在 Mac 上的备份
  2. 使用SVG实现,波浪效果
  3. Java动态代理中报java.lang.IllegalArgumentException非法参数异常
  4. 【HTML+CSS+JavaScript】实现萤火虫闪烁效果
  5. 麻省理工学院7门最受欢迎的MOOC课程
  6. aws认证有用吗?怎么备考AWS认证考试?
  7. 音频数据文件的合并----以python程序为例
  8. 发个2D太空射击游戏代码
  9. html5 css3基础知识详解
  10. 阿里云服务器+docker+jenkins+nginx+自定义访问路径