WriteProcessMemory的问题。写入的值并未被写进内存。

QQ348858444 2008-01-03 03:33:03
朋友,我也遇以这个问题啊,我能读取就是写不入,现在遇到的问题只有金山的游戏与传奇游戏,别的游戏全部能正常工作的.
DWORD hProcId;
GetWindowThreadProcessId(HWND0,&hProcId);
HANDLE nOK = OpenProcess(PROCESS_ALL_ACCESS ¦PROCESS_TERMINATE ¦PROCESS_VM_OPERATION ¦PROCESS_VM_READ ¦
PROCESS_VM_WRITE,1,hProcId);
ReadProcessMemory(nOK,(LPCVOID)(0x00834eec),(LPVOID)&PLAY_X0,4,NULL);//这里得到的地图坐标PLAY_X0=100
WriteProcessMemory(nOK,(LPVOID)(0x00834ee0),&PLAY_X0,4,NULL);<==这里我测试了,返回传是0写入不成功
ReadProcessMemory(nOK,(LPCVOID)(0x00834ee0),(LPVOID)&PLAY_X0,4,NULL);//这里却成了PLAY_X0=0,
CloseHandle(nOK);
有哪位朋友知道如何解决,希望能用QQ与我QQ348858444或43004790进行联系,或电话13459875177,我为了这个问题已经在网络上查找了一年半时间了,都没有找到啊.本人因为没有上过电脑课,所以无法学到好东东,望大家帮我一下,谢谢.
...全文
938 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
sunlin7 2008-01-05
  • 打赏
  • 举报
回复
我每次在windows(admin权限下)都能写成功(不包括驱动程序的内存地址),不知道楼主是不是在linux上面没有写成功?
阿呆_ 2008-01-05
  • 打赏
  • 举报
回复
你可以用VirtualQueryEx查一下对方内存是否可写。 如果不可以先用VirtualProtectEx改变一下保护标志再用WriteProcessMemory写。
另外最好先检查一下你进程中的相关API是否被hook了, 如果是的话可以先从文件中恢复原始值再调用。 不过如果对方使用ring0驱动保护的话就比较麻烦了。
QQ348858444 2008-01-04
  • 打赏
  • 举报
回复
朋友,我是在进行一种测试,我要把PLAY_X0的值写到0x00834ee0这个地方.然后再读取,如果写入成功就行了.但是没有办法写入成功.读取是会成功的.这个我测试过了.朋友,你能给我发个短信吗.我的手机是13459875177.我没有上过电脑课,所以我自己用C++6.0编写按键精灵实际上只会用IF与FOR两个指令然后就是API函数.汇编语言也是用了一种很垃圾的普通指令.这是我核心汇编代码,如果朋友有兴趣联系我的电话13459875177 QQ348858444.

//*********以上要开放成INI文件********

long ADDR_10=(long)funcl+0xa0;//ADDR_10跳转代码
long ADDR_11=ADDR_10-4,ADDR_12=ADDR_11-4,ADDR_13=ADDR_12-4,ADDR_14=ADDR_13-4;//保存8个寄存器的数据
long ADDR_15=ADDR_14-4,ADDR_16=ADDR_15-4,ADDR_17=ADDR_16-4,ADDR_18=ADDR_17-4;//以防出错
long ADDR_19=ADDR_18-4,ADDR_110=ADDR_10+0x140,ADDR_111=ADDR_110+0x100;
//ADDR_29里面存实时的地址ADDR_210怪物地址起点ADDR_211怪物地址终点
DWORD A10=0xe9;//补丁处写入代码
DWORD A11=ADDR_10-5-ADDR_1;
DWORD B10[20]=
{
0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,
0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,//这里是20个空格
};
DWORD B11[208]=
{
0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,
0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,//这里是20个空格
0x90,0xa3,0x00,0x00,0x55,0x00,//mov [1],eax 01
0x89,0x1d,0x00,0x00,0x55,0x00,//mov [2],ebx 02
0x89,0x0d,0x00,0x00,0x55,0x00,//mov [3],ecx 03
0x89,0x15,0x00,0x00,0x55,0x00,//mov [4],edx 04
0x89,0x2d,0x00,0x00,0x55,0x00,//mov [5],ebp 05
0x89,0x3d,0x00,0x00,0x55,0x00,//mov [6],edi 06
0x89,0x35,0x00,0x00,0x55,0x00,//mov [7],esi 07
0x89,0x25,0x00,0x00,0x55,0x00,//mov [8],esp 08
0x8b,0x1d,0x00,0x00,0x55,0x00,//mov ebx,[3] 09
0x81,0xe3,0xff,0xff,0x00,0x00,//mov eax,[3]捡物品专用10 0x90,0xa1,0x00,0x00,0x00,0x00,
0x90,0x90,0x90,0x90,0x90,0x90,//mov edx,[3]捡物品专用11 0x8b,0x15,0x00,0x00,0x00,0x00,
0x90,0x90,0x90,0x90,0x90,0x90,//mov ecx,[9] 12
0x90,0x90,0x90,0x90,0x90,0x90,//mov[ecx],ebx 13
0x90,0x90,0x90,0x90,0x90,0x90,//mov[ecx+4],eax 捡物品专用14 0x90,0x90,0x89,0x41,0x04,0x90,
0x90,0x90,0x90,0x90,0x90,0x90,//mov[ecx+8],edx 捡物品专用15 0x90,0x90,0x89,0x51,0x08,0x90,
0x90,0x90,0x90,0x90,0x90,0x90,//add ecx,04 捡物品时变成1016
0x3b,0x1d,0x00,0x00,0x55,0x00,//cmp ebx,[9] 17
0x90,0x90,0x90,0x90,0x7f,0x06,//jg --------------|18 不是练级与捡物品代码为 0x90,0x90,0x90,0x90,0x90,0x90,
0x89,0x1d,0x00,0x00,0x55,0x00,//mov [9],ebx |19
0x90,0x90,0x90,0x90,0x90,0x90,//mov [9],ecx *<---|20
0x8b,0x25,0x00,0x00,0x55,0x00,//mov esp,[8] 21
0x8b,0x35,0x00,0x00,0x55,0x00,//mov esi,[7] 22
0x8b,0x3d,0x00,0x00,0x55,0x00,//mov edi,[6] 23
0x8b,0x2d,0x00,0x00,0x55,0x00,//mov ebp,[5] 24
0x8b,0x15,0x00,0x00,0x55,0x00,//mov edx,[4] 25
0x8b,0x0d,0x00,0x00,0x55,0x00,//mov ecx,[3] 26
0x8b,0x1d,0x00,0x00,0x55,0x00,//mov ebx,[2] 27
0x90,0xa1,0x00,0x00,0x55,0x00,//mov eax,[1] 28
0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,
0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,//这里是20个空格
};

DWORD C10=0xe9;//跟回代码处
DWORD C11=(ADDR_1+m_dmcd1)-5-(ADDR_10+208);

ADDR_1=0;//===================================>China损耗度//push 03fb
m_dmcd1=5;//代码的长度 用GameExpert找260968=0x 3fb68
m_jcq1="EAX";//寄存器名字
data_suml1=0;//数据与基址的偏差
A11=ADDR_10-5-ADDR_1;//在这里计算参数
C11=(ADDR_1+m_dmcd1)-5-(ADDR_10+208);//在这里计算参数
void allsever()//游戏机器码函数
{
//提升权限 EnableDebugPrivilege
HANDLE hToken;
if(OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES,&hToken))
{
TOKEN_PRIVILEGES tp;
tp.PrivilegeCount=1;
LookupPrivilegeValue(NULL,SE_DEBUG_NAME,&tp.Privileges[0].Luid);
tp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(hToken,FALSE,&tp,sizeof(tp),NULL,NULL);
CloseHandle(hToken);
}
// 提升权限结束
DWORD hProcId,buf1;
GetWindowThreadProcessId(HWND0,&hProcId);
HANDLE nOK = OpenProcess(PROCESS_ALL_ACCESS|PROCESS_TERMINATE|PROCESS_VM_OPERATION|PROCESS_VM_READ|
PROCESS_VM_WRITE,1,hProcId);
ReadProcessMemory(nOK,(LPCVOID)(ADDR_2-6),(LPVOID)&buf1,4,NULL);
if(buf1==(DWORD)M_tzz||(nOK==0))
{
BOOKTIME=1;
CloseHandle(nOK);
return;
}
BOOKTIME=0;//说明版本能用的
ReadProcessMemory(nOK,(LPCVOID)(Dz_0+m_Xl2),(LPVOID)&PLAY_X0,4,NULL);//自己角色的地图坐标X
ReadProcessMemory(nOK,(LPCVOID)(Dz_0+m_Xl2+4),(LPVOID)&PLAY_Y0,4,NULL);//自己角色的地图坐标Y

int ab;
if(ADDR_1!=0||1)
{
/////////////////////////////损耗度///////////////////////////////////
// for(ab=0;ab<m_dmcd1;ab++)//读取入口代码
// ReadProcessMemory(nOK,(LPCVOID)(ADDR_1+ab),(LPVOID)&B10[ab],1,NULL);
// WriteProcessMemory(nOK,(LPVOID)(ADDR_1),&A10,1,NULL);//跳转
// WriteProcessMemory(nOK,(LPVOID)(ADDR_1+1),&A11,4,NULL);

for(ab=0;ab<208;ab++)//将块代码写入
WriteProcessMemory(nOK,(LPVOID)(ADDR_10+ab),&B11[ab],1,NULL);

WriteProcessMemory(nOK,(LPVOID)(ADDR_10+208),&C10,1,NULL);//跳回
WriteProcessMemory(nOK,(LPVOID)(ADDR_10+209),&C11,4,NULL);

for(ab=0;ab<m_dmcd1;ab++)//将源代码写入到补丁函数中
WriteProcessMemory(nOK,(LPVOID)(ADDR_10+ab),&B10[ab],1,NULL);
long addr_19=10000;
WriteProcessMemory(nOK,(LPVOID)(ADDR_19),&addr_19,4,NULL);//写放一个初始的损耗度
ReadProcessMemory(nOK,(LPCVOID)(0x00834eec),(LPVOID)&PLAY_X0,4,NULL);
if(WriteProcessMemory(nOK,(LPVOID)(0x00834ee0),&PLAY_X0,4,NULL)==0)
{
CString tmp1_111="";
tmp1_111.Format ("错误:%d",GetLastError());
MessageBox(HWND0,tmp1_111,"请重新更新游戏或脚本",MB_OKCANCEL);
}
ReadProcessMemory(nOK,(LPCVOID)(0x00834ee0),(LPVOID)&PLAY_X0,4,NULL);
WriteProcessMemory(nOK,(LPVOID)(ADDR_10+22),&ADDR_11,4,NULL);//保存EAX
WriteProcessMemory(nOK,(LPVOID)(ADDR_10+28),&ADDR_12,4,NULL);//保存EBX
WriteProcessMemory(nOK,(LPVOID)(ADDR_10+34),&ADDR_13,4,NULL);//保存ECX
WriteProcessMemory(nOK,(LPVOID)(ADDR_10+40),&ADDR_14,4,NULL);//保存EDX
WriteProcessMemory(nOK,(LPVOID)(ADDR_10+46),&ADDR_15,4,NULL);//保存EBP
WriteProcessMemory(nOK,(LPVOID)(ADDR_10+52),&ADDR_16,4,NULL);//保存EDI
WriteProcessMemory(nOK,(LPVOID)(ADDR_10+58),&ADDR_17,4,NULL);//保存ESI
WriteProcessMemory(nOK,(LPVOID)(ADDR_10+64),&ADDR_18,4,NULL);//保存ESP
if(m_jcq1=="EAX")
WriteProcessMemory(nOK,(LPVOID)(ADDR_10+70),&ADDR_11,4,NULL);//地址在EAX
else if(m_jcq1=="EBX")
WriteProcessMemory(nOK,(LPVOID)(ADDR_10+70),&ADDR_12,4,NULL);//地址在EBX
else if(m_jcq1=="ECX")
WriteProcessMemory(nOK,(LPVOID)(ADDR_10+70),&ADDR_13,4,NULL);//地址在ECX
else if(m_jcq1=="EDX")
WriteProcessMemory(nOK,(LPVOID)(ADDR_10+70),&ADDR_14,4,NULL);//地址在EDX
else if(m_jcq1=="EBP")
WriteProcessMemory(nOK,(LPVOID)(ADDR_10+70),&ADDR_15,4,NULL);//地址在EBP
else if(m_jcq1=="EDI")
WriteProcessMemory(nOK,(LPVOID)(ADDR_10+70),&ADDR_16,4,NULL);//地址在EDI
else if(m_jcq1=="ESI")
WriteProcessMemory(nOK,(LPVOID)(ADDR_10+70),&ADDR_17,4,NULL);//地址在ESI
else if(m_jcq1=="ESP")
WriteProcessMemory(nOK,(LPVOID)(ADDR_10+70),&ADDR_18,4,NULL);//地址在ESP
// WriteProcessMemory(nOK,(LPVOID)(ADDR_10+88),&ADDR_19,4,NULL);//取出实时地址
WriteProcessMemory(nOK,(LPVOID)(ADDR_10+118),&ADDR_19,4,NULL);//比较一下是不是到最后的空间
WriteProcessMemory(nOK,(LPVOID)(ADDR_10+130),&ADDR_19,4,NULL);//重头再来
// WriteProcessMemory(nOK,(LPVOID)(ADDR_10+136),&ADDR_19,4,NULL);//保存实时地址
WriteProcessMemory(nOK,(LPVOID)(ADDR_10+142),&ADDR_18,4,NULL);//恢复ESP
WriteProcessMemory(nOK,(LPVOID)(ADDR_10+148),&ADDR_17,4,NULL);//恢复ESI
WriteProcessMemory(nOK,(LPVOID)(ADDR_10+154),&ADDR_16,4,NULL);//恢复EDI
WriteProcessMemory(nOK,(LPVOID)(ADDR_10+160),&ADDR_15,4,NULL);//恢复EBP
WriteProcessMemory(nOK,(LPVOID)(ADDR_10+166),&ADDR_14,4,NULL);//恢复EDX
WriteProcessMemory(nOK,(LPVOID)(ADDR_10+172),&ADDR_13,4,NULL);//恢复ECX
WriteProcessMemory(nOK,(LPVOID)(ADDR_10+178),&ADDR_12,4,NULL);//恢复EBX
WriteProcessMemory(nOK,(LPVOID)(ADDR_10+184),&ADDR_11,4,NULL);//恢复EAX
}
CloseHandle(nOK);
}
此代码能实现基本上所有游戏动态数据的固定处理.让游戏的动态地址的数据固定下来.
sheenl 2008-01-03
  • 打赏
  • 举报
回复
错误代码6 ERROR_INVALID_HANDLE? 真是奇怪了。

另外, 你究竟是要写 0X00834EEC 还是 0X00834EE0?
QQ348858444 2008-01-03
  • 打赏
  • 举报
回复
DWORD hProcId;
GetWindowThreadProcessId(HWND0,&hProcId);
HANDLE nOK = OpenProcess(PROCESS_ALL_ACCESS ¦PROCESS_TERMINATE ¦PROCESS_VM_OPERATION ¦PROCESS_VM_READ ¦
PROCESS_VM_WRITE,1,hProcId);
ReadProcessMemory(nOK,(LPCVOID)(0x00834eec),(LPVOID)&PLAY_X0,4,NULL);//这里得到的地图坐标PLAY_X0=100
if(WriteProcessMemory(nOK,(LPVOID)(0x00834ee0),&PLAY_X0,4,NULL)==0)
{
CString tmp1_111="";
tmp1_111.Format ("错误:%d",GetLastError());
MessageBox(HWND0,tmp1_111,"请重新更新游戏或脚本",MB_OKCANCEL);
}<==我得到的参数是6
ReadProcessMemory(nOK,(LPCVOID)(0x00834ee0),(LPVOID)&PLAY_X0,4,NULL);//这里却成了PLAY_X0=0,
CloseHandle(nOK);
sheenl 2008-01-03
  • 打赏
  • 举报
回复
if (0 == WriteProcessMemory(...))
{
char szBuffer[80];
sprintf(szBuffer, "%d", GetLastError());
MessageBox(NULL, szBuffer, "Error Code", MB_ICONERROR);
}
QQ348858444 2008-01-03
  • 打赏
  • 举报
回复
GetLastError这个函数要如何用啊,加在哪里啊,你能在我的程序上做一个例子吗
QQ348858444 2008-01-03
  • 打赏
  • 举报
回复
我现在做的都是网络游戏的按键精灵
sheenl 2008-01-03
  • 打赏
  • 举报
回复
GetLastError能得到什么错误号?
sheenl 2008-01-03
  • 打赏
  • 举报
回复
你写外挂的? :)
这个帮不了你.
我最近刚写了一个修改器, 不过是普通的单机游戏, 没遇到过你这样的能读不能写的情况.

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧