游戏外挂内存数据读取

armytg 2011-09-18

源地址:http://hi.baidu.com/probill/blog/item/1d07d11efbd641f01ad576f3.html

网络游戏.每一个数据比如你的血值.MP值.怪的血值..在内存中是以16进制的形式存放的.而显示给我们看的是10进制的形式显示的,,[16进制转就是123456789ABCDEF,好比十进制的0123456789,逢16进1,十进制是逢十进1,不想算可以用windows自带的计算器,在附件中有]

网络游戏几乎全是动态内存存放[大话战国居然不是.那天写辅助工具时发现的],,就是每上线一次,数据在内存中分配位置会变,但是.数据间地址的差值是不变的.就是所谓的偏移量..我们要做的工作就是要让动态的,转换成静态的,只要找到一个就成了.别的根据偏移量可以知道.步骤如下:

1.我们进游戏.首先要做的就是找动态内存地址[我以HP值举例],找动态内存的工具软件很多,我推荐金山游侠,FPE,CE,GE等...软件用法很简单..就好比你现在的HP值是1000.你先定位好程序.输入1000搜索,会搜到一串地址..然后让自己的血值变(比如穿件加HP的装备,比如是加了50血),再搜1050,这样试几次就找到了唯一的动态内存地址.[虽然唯一,但一下线就会变的],第一步工作完全了...

2.然后我们要用到调试工具设断点,调试工具很多,比如OD或softice等,我以softice举例:

比如我们搜索到HP的动态地址是044321A7..我们按CRTL+D呼出SOFICE..下命令设断点BPM044321A7W然后按F5退出进游戏..只要HP值一变.就会跳出调试的界面.比如说位置跳到了001B:0047EB17moveax,[edx+000000fc]处..其中..edx是基值[也可以是esi等等],000000fc是一个固定的地址偏移量,每次进游戏在变的就是基值中的数值.

3.到这..有多种方法可以求得静态地址..一种就是内存注入的方法.网上有很多这类的资料..主要是太麻烦..我就不写了.我讲我自己的方法.我是用到指针的指针的思想..就是.我们的HP值是存放在一个动态内存地址中..地址其实也是数据..地址也是存放在地址中的..当然.要基值的地址..所以我们要做的就是找存放基值地址的地址,可以用金山等软件搜索到..不过地址是16进制的..所以要转换成10进制.再找存放基值地址的地址..比如说找到011076EC.好了.我们的工作完成了...现在就到了怎么写读语句..用C语言写起来很简单..用VB也可以写..[别人说VB没指针.但并不代表不能用].因为按键是VBS语言.那我就用VB写..当然.我要调用WIN32API函数

VB调用API要申明,如下:DdeclareFunctionReadProcessMemoryLib"kernel32"(ByValhProcessAsLong,lpBaseAddressAsAny,lpBufferAsAny,ByValnSizeAsLong,lpNumberOfBytesWrittenAsLong)AsLong

dimedxaslong

dimhpaslong

ReadProcessMemorynOK,ByVal&H011076EC,edx,4,0

ReadProcessMemorynOK,ByValedx+000000fc,hp,4,0

就这样两条语句..hp中的数值就是我们的血值了..非常精准的可以得到..比如我血有1000点.我要在666点时加血..你就可以ifhp<666thenkeypress"加血的按键"

补充一点..搜索基址的地址是会搜到不少个的..但是一般来说..第一个就是...

------------------------------------------------------------------------------------------------------------------------------

源地址:http://www.wgx4.com/article/html/257.html

从游戏中得到动态内存数据  

作者:sbsummer

刚才我玩了几把疯狂坦克,输了好几盘,觉得无聊就搞搞这个,下面开始说说如何得到游戏中的动态数据(地址改变),以得到疯狂坦克中坦克X坐标为例

------------------------------------------------------------------------------

工具:

SoftICE动态调试程序,游戏修改工具(金山游侠),反汇编(W32Dasm),HexWorkshop

------------------------------------------------------------------------------

一、找到内存中坦克X坐标

用金山游侠搜索,方法如下(金山游侠的使用我就不说了)

把坦克往左移动一些,就搜索“减少”;坦克往右移动,就搜索“增大”

反复搜索将会找到一个地址(当然其他游戏可能不止一个),这里是08BFAACC

注:动态的内存分配就是下次你如果再次搜索,地址将不再是08BFAACC

二、找到那条代码修改了这个数据(X坐标)

加载SoftIce

在游戏状态Ctrl+D调出SoftIce,输入BPM08BFAACCW,这里的W表示如果这个地址被写将中断

回到游戏,移动坦克,左移一下,程序中断,SoftIce指向的上面一句是

004640B3MOVDWORDPTR[ESI+000001A4],EAX

这句就是修改坦克坐标的代码,当然右移也能找到一句,这里就不重复了

三、修改程序使动态的数据变成静态

这里说点题外话,修改程序包括两种,一种是直接修改程序,一种是修改内存中的程序(内存补丁),这里由于我懒,所以用了第一种

修改程序:

疯狂坦克程序存在Fortress2.dat当中,如果你把这个文件改名为EXE文件一样可以运行,这里我们就把他修改成Fortress2.exe

打开W32Dasm反汇编,SHIFT+F12跳到004046B3,你看到这几行

004046B38986A4010000MOVDWORDPTR[ESI+000001A4],EAX

004046B98B8644020000MOVEAX,DWORDPTR[ESI+00000244]

004046BFC744241001000000MOV[ESP+10],00000001

刚才我们说了004046B3是修改X坐标的那条语句,现在我们要让他每次修改完程序就能够把X坐标存储到一个固定的地址

现在要让它运行到这里就JMP到一个我们自己的代码的地方,于是在程序的尾部我们找到一段空白的区域00465A52,于是我修改004046BF为代码JMP00465A52,机器码为E98E130600,因为这句的长度不够以前的那句长,所以要加入几个NOP,机器码为90,所以我们打开HEXWorkshop修改程序,CTRL+G跳到位移为000046BF的地方,看到了C744241001000000,我们把它修改为E98E130600909090,现在程序将一运行到这里就跳到00465A52运行我们的代码。

四、实现我们自己的代码,然后跳回

我们的代码要做的是把动态变成静态,

PUSHEAX

MOVEAX,[ESI+000001A4]

MOV[00470000],EAX

POPEAX

JMP004046C7

这样这个数值无论运行多少次,只要你移动(当然右移也要修改)就能在00470000中找到X坐标,这段机器码为508B86A4010000

A30000470058E95BECF9FF

忘了说刚才我们把004046BF替换掉的那句MOV[ESP+10],00000001也必须加上,所以打开HEX

Workshop,CTRL+G跳到00465A52,修改加入

C744241001000000508B86A4010000A30000470058E95BECF9FF

这样动态数据就变成了静态

------------------------------------------------------------------------------

现在回顾一下

首先搜索坐标地址

找到改变这个地址的代码

修改代码让他跳到自己的代码中运行

在程序的空白段加入自己的代码,当然要补上被替换了的那句,还有修改了寄存器,必须先PUSH,再POP

下面的工作就是写一个程序读取这个地址了,我用VC写了一个,顺便贴一下关键代码

------------------------------------------------------------------------------

CProcessm_process;

boolm_ret=m_process.FindProcess("FortressII");

if(m_ret)

{

BYTEtank1xL=m_process.ReadByte(0x00470000);

BYTEtank1xR=m_process.ReadByte(0x00470001);

WORDtank1x=tank1xL+tank1xR*256;

temp=tank1x;

str.Format("%d",temp);

m_tank1x=str;

UpdateData(FALSE);

returnTRUE;

}

elsereturnFALSE;

-----------------------------------------------------------------------------

CProcess是一个我编写的游戏修改类,以下是部分函数代码:

HANDLECProcess::OpenProcess(char*p_ClassName,char*p_WindowTitle)

{

HWNDhWindow;

DWORDpid;

hWindow=FindWindow(p_ClassName,p_WindowTitle);

if(hWindow){

GetWindowThreadProcessId(hWindow,&pid);

return::OpenProcess(PROCESS_ALL_ACCESS,false,pid);

}

returnNULL;

}

boolCProcess::FindProcess(char*p_WindowTitle)

{

if(m_hProcess==NULL){

m_hProcess=this->OpenProcess(NULL,p_WindowTitle);

if(m_hProcess)

m_bGameRunning=true;

returnm_bGameRunning;

}

else

returnfalse;

}

BYTECProcess::ReadByte(DWORDp_Address)

{

DWORDbytes;

BYTEtmpValue;

if(m_bGameRunning){

if(ReadProcessMemory(m_hProcess,(void*)p_Address,

(void*)&tmpValue,1,&bytes)==0)

return0;

else

returntmpValue;

}

return0;

}

-----------------------------------------------------------------------------

相关推荐