2010年10月29日 星期五

Cs作弊器原理與實現(找時間弄成品)

首先製作作弊器我們要用到以下一些東西
  1 VC++6.0 編程工具
  2 作弊器 源代碼DLL ( DLL部分主要是實現以下功能.一個作弊器從功能方面來說大致可以分成2塊:一部分負責顯示方面的,比如透視、防閃、顯示人物名字武器等信息;另一部分則是控制本地玩家的動作,比如自動瞄準、開火、加速、256衝刺等。而這些功能則全部是由CS作弊器的主文件(DLL)實現的。)
  3 注入器源碼EXE { EXE部分是負責啟動或監視CS遊戲進程和在創建或檢測到遊戲進程後,將作弊器的主文件(DLL)注入到CS遊戲進程中(注入的意思是讓運行中的CS遊戲進程主動加載作弊器主文件(DLL),就象這個文件本身就是CS遊戲的一部分一樣) }當然你如果想要在平台上運行(比如豆客)你就必須先把豆客的反作弊代碼搞道,不過貌似現在豆客連續的升了幾次級豆是在給它的那個東東加密,呵呵不好破啊,連服務器都弄到黑卡了,
  先來說作弊器要實現的第一個功能:透視
  首先你要用API鉤子去鉤住glBegin函數,在被鉤住的glBegin函數裡,如果攔截到的參數mode是GL_TRIANGLE_STRIP,或 GL_TRIANGLE_FAN,那麼CS就有可能是準備畫一個模型(人物,武器等),那麼就可以用glDisable(GL_DEPTH_TEST)來告訴OpenGL:我們想顛倒這個模型的繪製順序。在遊戲中就可以看到,墻壁後背的人物,模型等全跑到了墻壁的前面。這看上去圖象順序有點亂,但這正是作弊器“透視”的原理所在!
  繪製所有模型之前調用這個函數,那就會把整個遊戲畫面都打亂了,這點比較重要請注意。
  void APIENTRY my_glBegin( GLenum mode )
  {
  if((mode==GL_TRIANGLE_STRIP||mode==GL_TRIANGLE_FAN))
  glDisable(GL_DEPTH_TEST);
  glBegin(mode);
  }
  實現功能2:高亮顯示(不過這個一般拿著也沒什麼用)
  由於光線的問題,在暗處人物也會顯得很暗,那怎樣把他變得更亮,以便我們遊戲時容易發現目標呢?為了達到這種效果,就得鉤住glVertex3f,然後在原有函數(區別於我們鉤住的函數)調用前加上這行代碼:
  glColor4f(1.0f, 1.0f, 1.0f, 1.0f)
  就這麼簡單就達到了想要的功能。
  void APIENTRY my_glVertex3f(GLFloat x, GLFloat y, GLFloat z)
  glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
  glVertex3f(x, y, z);
  }
  實現功能3:去除煙幕
  實現這個功能必須做的就是鉤住glBegin 和 glVertex3fv,然後定義一個bool變量bSmoke來作為開關。在鉤住的glBegin中,檢查當前參數mode的值是否為GL_QUADS。如果是的話,取當前顏色:
  glGetFloatv(GL_CURRENT_COLOR, &curcol)
  看curcol是否為灰色(灰色就是R=G=B)。然後就是要排除1.0和0.0,因為這樣才能不把某些其他物體去除了。
  所以如果當前顏色是灰色,並且不是白色(1.0)、黑色(0.0)時,我們就把bSmoke設為true。當然在別的時候或不是繪製煙幕時,要把bSmoke設為false。
  現在就可以在glVertex3fv中判斷bSmoke是否為true,如果是,直接return不處理它。這樣去除煙幕的功能便算完成了。
  void APIENTRY my_glBegin( GLenum mode )
  if(mode==GL_QUADS)
  {
  float curcol[4];
  glGetFloatv(GL_CURRENT_COLOR, curcol);
  if((curcol[0]==curcol[1])&&(curcol[1]==curcol[2])&&(curcol[0]!=1.0f)&&(curcol[0]!=0.0f))bSmoke=true;
  else bSmoke=false;
  glBegin(mode);
  }
  void APIENTRY my_glVertex3fv(const GLfloat *v)
  {
  if(bSmoke)return;
  else glVertex3fv(v);
  }
  實現功能4:去除閃光(如果是想過175的話就別加)
  實現這個功能要鉤兩個函數:glBegin和glVertex2f。
  CS在畫控制台和某些文字時也會用到glVertex2f,所以我們在做這個功能時要小心不要把不該屏蔽的東西屏蔽了。其實閃光的原理就是把一張白色方形貼到屏幕上,然後隨著時間改變Alpha透明度,就要檢查看有沒有白色的QUAD並且覆蓋了你的整個屏幕,如果有,那就要留意了。
  在glBegin中,檢查mode是否為GL_QUADS,如果是,取當前顏色:
  glGetFloatv(GL_CURRENT_COLOR, &curcol)
  現在來看看什麼是純白:純白就是R=1,G=1,B=1,如果檢測到符合這些條件的話,那就很有可能現在畫的就是閃光,但是還是不敢確定到底是不是,要同時從別處入手。
  當一個OpenGL程序調用glBegin時,接著將會調用glVertex*來畫模型的頂點,繪製完成後將調用glEnd來收尾。我研究發現CS畫簡單的方型是用glVertex2f,所以同樣我們也要鉤住這個函數。
  為了聯繫glBegin和glVertex2f,找到了詳細的實現方法,就是用bool變量bFlash來表示是否為一個白色的方型(即是否是煙幕效果)。下一步是獲取當前屏幕的尺寸:
  glGetFloatv(GL_VIEWPORT, &coords)
  這樣屏幕就保存在了coords裡:
  coords[0] = 0
  coords[1] = 0
  coords[2] = 寬
  coords[3] = 高
  現在鉤住的glVertex2f裡,如果不符合“閃光”的條件,調用回原有的函數,如果符合的話,就比較glVertex2f傳給我們的第二個參數y和 coords[3](屏幕高度)是否一樣,如果是,則表明CS準備繪製白色閃光或全屏模式的控制台,但是這兩者實在是不好區分,所以只有把阿爾法值設置得很小,這將不會影響到控制台,同時也把白色閃光去掉了:
  glColor4f(curcol[0], curcol[1], curcol[2], 0.01f)
  void APIENTRY my_glBegin( GLenum mode )
  if(mode==GL_QUADS)
  float curcol[4];
  glGetFloatv(GL_CURRENT_COLOR, curcol);
  glGetFloatv(GL_VIEWPORT, coords);
  if((curcol[0]==1)&&(curcol[1]==1)&&(curcol[2]==1))bFlash=true;
  void APIENTRY my_glVertex2f(GLfloat x, GLfloat y)
  float curcol[4];
  glGetFloatv(GL_CURRENT_COLOR, curcol);
  if(bFlash &&(y==coords[3]))
  glColor4f(curcol[0], curcol[1], curcol[2], 0.01f);
  glVertex2f(x, y);
  總的來說,作弊器主文件(DLL)就象一個高智商的間諜,打入敵方核心陣地(CS遊戲進程),劫持敵方各部門收集數據(掛接調用CS遊戲的函數),最後整理收集到的數據(計算)。夠簡單吧,對了,還有一個比較通用的說法,我們把除OpenGL以外的CS函數概略的稱為CS遊戲引擎函數。
  注入器(EXE)------------- 我方間諜的支持團體,負責將其打入敵方內部。
  作弊器主文件(DLL)------ 我方間諜,負責在敵方內部活動,完成實質性的工作