温馨提示:感兴趣的看到最后有惊喜!!! 温馨提示:感兴趣的看到最后有惊喜!!!
温馨提示:感兴趣的看到最后有惊喜!!!
通过游戏学指针系列12:编码修改游戏人物名称(字符数组实战)
一.确认游戏人物名称地址 1.打开ce,复制GameClient.exe+5882EC过去,此时会出来一个地址 2.在od中使用db [19082EC]+24公式确定人物名称的地址 二.理解字符数组本质 表示一个字符串 char a[]={‘a’,’b’,’c’,’\0’}; char a[]=”abc”; 三.理解指针与字符串本质 char a[]=”abc”; char* p=a; 四.字符串长度 //获取角色名称的长度 int GetStrLen(char* p) { int i=0; while(*p!=0) { i++; p++; } return i; } 五.字符串复制 六.字符串比较 七.字符串连接 八.综合,判断如果游戏中角色名称是azaz,则根据指定的名称(前缀和后缀)改变角色名称 九.所有代码 //获取人物血值地址 void GetRolelnfo(byte* arrAddr,byte* queryBlood) { //两个字节搜索内存优化 for(int i=0;i<16;i++) { if(memcmp(arrAddr+i+0,queryBlood,sizeof(queryBlood))==0) { DebugViewPrintf("血值的地址=%x",arrAddr+i); } } } //获取角色名称的长度 int GetStrLen(char* p) { int i=0; while(*p!=0) { i++; p++; } return i; } //StrCopy(roleName,a) char* StrCopy(char* p1,char* p2) { char* start=p1; while(*p2!=0) { *p1=*p2; p2++; p1++; } *p1=0; return start; } void CWGForm::OnButton1() { int guizi[5]={17,3,47,8,12}; int* p=(int*)&guizi[0]; int i=0; for(i=0;i<5;i++) { DebugViewPrintf("第%d个元素是:%d,第%d个元素的地址是:%x",i,*(p+i),i,p+i); } HMODULE h=GetModuleHandle("GameClient.exe"); int temp1=(int)h+0x5882EC; //[17B82EC]+0x726 这个里面的值就是当前血值 int* roleBase=(int*)temp1; //当前血值的地址 int* roleCurBlood=(int*)(*roleBase+0x726); //最大血值的地址 int* roleMaxBlood=(int*)(*roleBase+0x726+8); //[17B82EC]+24 这个里面的值就是人物角色名称 char* roleName=(char*)(*roleBase+0x24); DebugViewPrintf("temp1=%x,当前血值和最大血值是:%d,%d,角色名称:%s",temp1,*roleCurBlood,*roleMaxBlood,roleName); //以16字节为例,0-15 100E0746 1B 00 00 00 11 00 00 00 1B 00 00 00 11 00 00 00 ....... byte* arrAddr=(byte*)roleCurBlood;//int----DWORD char WORD byte queryBlood[]={0x1B,0x00,0x00,0x00}; for(i=0;i<16;i++) { //一个字节 /* if(*(arrAddr+i+0)==0x00) { DebugViewPrintf("血值的地址=%x",arrAddr+i); } */ //两个字节 /* if((*(arrAddr+i+0)==0x00) && (*(arrAddr+i+1)==0x00)) { DebugViewPrintf("血值的地址=%x",arrAddr+i); } */ //四个字节 /* if((*(arrAddr+i+0)==0x00) && (*(arrAddr+i+1)==0x00) && (*(arrAddr+i+2)==0x00) && (*(arrAddr+i+3)==0x00)) { DebugViewPrintf("血值的地址=%x",arrAddr+i); } */ /* if(memcmp(arrAddr+i+0,queryBlood,sizeof(queryBlood))==0)//第三个表示要比较的内容的长度 { DebugViewPrintf("血值的地址=%x",arrAddr+i); }*/ } //查找的内容是四个字节 GetRolelnfo(arrAddr,queryBlood); char a[]="bbb"; int len=GetStrLen(a); DebugViewPrintf("角色名称的长度=%x",len); char* newRolename=StrCopy(roleName,a); DebugViewPrintf("角色的名称是=%s",newRolename);
|