更新的防止游戏修改的算法

防止游戏修改的一个小算法

太阳神上 posted @ 2008年4月19日 17:39 in Algorithm with tags Algorithm , 2567 阅读

  前几天我看到廖传政又在修改游戏,于是就给他较劲,故意编个游戏来让他修改不了。据他说,假如要让血槽不动,一般是找到内存变化的地方,然后锁定就是了。从这一点出发,我想到如果表示内存变化的那个地方完全没的规律,那么就比较难以查找了。
  我的想法是,真实的数据不能直接放在内存中,而是代之以一个神秘的数值,这个神秘的数值也完全零乱,也就是说血条上升或下降时,这个值会变化,但不一定也是上升或是下降,也是就他们之间不存在简单的线性关系,更进一步说,如果把这个神秘数与真实数的对应关系是一个函数的话,那这个函数是非线性的,其实光线性还不够,而且要是找不出单调的区间。但是它们之间又要可逆,就是要找出一个可逆的非单调函数
  我的基本思想是,假如要加密的是0到100之间的整数,那么就先生成把0到100随机存放到一个encode数组,作为加密的数组,例如一个真实数56,它所对应的加密数就是encode[56],然后产生一个解密数组,分别存放0到100在encode数组中的索引,也就是for any i in 0..100,encode[decode[i]]=i。如果把encode看成是一个函数,那它的逆函数就是decode。
  真正在内存里保存的数都是那个“神秘数”,而真实数都得通过decode数组才能读出,通过encode来写,由于加密和解密的部分都只是几次寻址操作,所以效率并不低,而且我们只对关键的数值进行加密。其它不管。
  这个算法我给他做了以后,他算是半个成功了,因为找到了那个显示血槽对象的相关内存,但是真正存放数据的地方却没有找到。本来游戏是用Irrlicht写的3D,很占内存和CPU,下面是我用SDL改写的,完全只保留了最基本的演示:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <time.h>
  5.  
  6. #include <SDL/SDL.h>
  7.  
  8. SDL_Surface *screen = NULL;
  9. int blood;
  10.  
  11. int *encode;
  12. int *decode;
  13.  
  14. int index_of(int array[],size_t size,int value){
  15.     int index;
  16.     for(index=0;index<size;index++){
  17.         if(array[index]==value)
  18.             return index;
  19.     }
  20.     return -1;
  21. }
  22.  
  23.  
  24. void begin_game(){
  25.     srand(time(NULL));
  26.     encode=(int *)malloc(1024*sizeof(int));
  27.     decode=(int *)malloc(1024*sizeof(int));
  28.    
  29.     int i,r;
  30.     for(i=0;i<101;i++){
  31.         r=rand()%101;
  32.         if(index_of(encode,i,r)==-1)
  33.             encode[i]=r;
  34.         else{
  35.             i--;
  36.             continue;
  37.         }           
  38.     }
  39.    
  40.     for(i=0;i<101;i++){
  41.         decode[i]=index_of(encode,101,i);
  42.     }   
  43.    
  44.     blood=encode[100];
  45. }
  46.  
  47. void end_game(){
  48.     free(encode);
  49.     free(decode);
  50. }
  51.  
  52. void draw (){
  53.    
  54.     Uint32 color;   
  55.     color=SDL_MapRGB(screen->format,0,0,0);
  56.     SDL_FillRect (screen, NULL, color);   
  57.     color = SDL_MapRGB (screen->format, 0xFF, 0, 0);
  58.    
  59.     SDL_Rect *rect=(SDL_Rect *)malloc(sizeof(SDL_Rect));
  60.     rect->w = decode[blood]*5;
  61.     rect->h = 20;
  62.     rect->x = 100;
  63.     rect->y = 100;
  64.     SDL_FillRect (screen, rect, color);
  65.     free(rect);
  66.  
  67.     SDL_Flip (screen);
  68.     SDL_Delay (10);
  69. }
  70.  
  71.  
  72.  
  73.  
  74. int main (int argc, char *argv[]){
  75.     char *msg;
  76.     int done;
  77.    
  78.     SDL_Init (SDL_INIT_VIDEO);
  79.     atexit (SDL_Quit);
  80.  
  81.     screen = SDL_SetVideoMode (640, 480, 16, SDL_SWSURFACE | SDL_DOUBLEBUF);
  82.     SDL_WM_SetCaption ("SDL MultiMedia Application", NULL);
  83.     begin_game();
  84.    
  85.  
  86.     done = 0;
  87.     SDL_Event event;
  88.    
  89.     while (!done){
  90.         SDL_WaitEvent (&event);
  91.         switch (event.type){
  92.             case SDL_KEYDOWN:{
  93.                 switch(event.key.keysym.sym){
  94.                     case SDLK_UP:blood = decode[blood]+10>100 ? blood : encode[decode[blood]+10];break;
  95.                     case SDLK_DOWN:blood = decode[blood]-10<0 ? blood : encode[decode[blood]-10];break;
  96.                 }
  97.             }
  98.                 break;
  99.             case SDL_QUIT:
  100.                 done = 1;
  101.                 break;
  102.             default:
  103.                 break;
  104.         }
  105.         draw ();
  106.     }
  107.    
  108.     end_game();
  109.  
  110.     return 0;
  111. }
  112.  
路人甲 说:
2010年1月30日 04:09

游戏中的每个数值都有个对应的内存地址 遇到可以锁定内存地址的修改猛药 比如CE 那该怎么办?


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter