顯示具有 GameBoT 標籤的文章。 顯示所有文章
顯示具有 GameBoT 標籤的文章。 顯示所有文章

2011年5月31日 星期二

隱藏驅動 搜尋方法(可找出某Np開頭的遊戲保護)

下面是關鍵代碼,可以查找斷開 PsLoadedModuleList 鏈的驅動,比如 Np開頭的遊戲保護



PDIRECTORY_BASIC_INFORMATION    pDriverBuffer = NULL;


pDriverBuffer = (PDIRECTORY_BASIC_INFORMATION)m_cSysInfo.QueryDirectoryObject(L"\\Driver", &uMemSize);




查找驅動物件目錄下的所有物件,查找代碼如下。



PVOID CNativeSysInfo::QueryDirectoryObject(PWSTR pwsDirPath, PULONG puMemSize)

{

    NTSTATUS            ntStatus;

    UNICODE_STRING      usDirPath;

    OBJECT_ATTRIBUTES   oa;

    HANDLE              hDir = NULL;

    PVOID               pBuffer = NULL;

    ULONG               uLength = 0x800;

    ULONG               uContext = 0;

    ULONG               uResult = 0;



    // 
判斷函數是否存在

    if(m_lpRtlInitUnicodeString == NULL ||

       m_lpZwOpenDirectoryObject == NULL ||

       m_lpZwQueryDirectoryObject == NULL ||

       m_lpZwClose == NULL)

    {

        return NULL;

    }



    // 
打開目錄物件

    m_lpRtlInitUnicodeString(&usDirPath, pwsDirPath);

    InitializeObjectAttributes(&oa, &usDirPath, OBJ_CASE_INSENSITIVE, NULL, NULL);

    ntStatus = m_lpZwOpenDirectoryObject(&hDir, DIRECTORY_QUERY, &oa);

    if(ntStatus != STATUS_SUCCESS)

    {

        TRACE(_T("ZwOpenDirectoryObject failed!"));

        goto _exit;

    }



    // 
查詢目錄物件

    do

    {

        if(pBuffer)

            VirtualFree(pBuffer, uLength, MEM_DECOMMIT);



        uLength *= 2;



        pBuffer = VirtualAlloc(NULL, uLength, MEM_COMMIT, PAGE_READWRITE);

        if(pBuffer == NULL)

            goto _exit;



        ntStatus = m_lpZwQueryDirectoryObject(hDir, pBuffer, uLength, FALSE, TRUE, &uContext, &uResult);



    } while(ntStatus == STATUS_MORE_ENTRIES || ntStatus == STATUS_BUFFER_TOO_SMALL);



    // 
判斷查詢是否成功完成

    if(ntStatus == STATUS_SUCCESS)

    {

        if(puMemSize)

            *puMemSize = uLength;

    }

    else

    {

        VirtualFree(pBuffer, uLength, MEM_DECOMMIT);

        pBuffer = NULL;

    }



_exit:



    if(hDir)

    {

        m_lpZwClose(hDir);

        hDir = NULL;

    }



    return pBuffer;

}



然後把得到的結果和常規結果比較就可以找到隱藏驅動。隱藏驅動的相關資訊可以通過下面的方式得到。



    PDRIVER_OBJECT          pDrvObject = NULL;



    RtlInitUnicodeString(&usDirPath, (PCWSTR)pvInBuf);

    ntStatus = ObReferenceObjectByName(&usDirPath,

                                       OBJ_CASE_INSENSITIVE,

                                       NULL,

                                       0,

                                       *IoDriverObjectType,

                                       KernelMode,

                                       NULL,

                                       (PVOID*)&pDrvObject);



有了 DRIVER_OBJECT 結構就啥都有了!:)



下面是一個隱藏驅動的例子,用上面的辦法可以發現。



void _EraseDrvFromModList(PDRIVER_OBJECT pDrvObject)

{

    PLDR_DATA_TABLE_ENTRY   pOwen;

    PLDR_DATA_TABLE_ENTRY   pPrev;

    PLDR_DATA_TABLE_ENTRY   pNext;



    pOwen = (PLDR_DATA_TABLE_ENTRY)pDrvObject->DriverSection;

    pPrev = (PLDR_DATA_TABLE_ENTRY)pOwen->InLoadOrderModuleList.Blink;

    pNext = (PLDR_DATA_TABLE_ENTRY)pOwen->InLoadOrderModuleList.Flink;

    pPrev->InLoadOrderModuleList.Flink = (PLIST_ENTRY)pNext;

    pNext->InLoadOrderModuleList.Blink = (PLIST_ENTRY)pPrev;



    pOwen->InLoadOrderModuleList.Flink = (PLIST_ENTRY)pOwen;

    pOwen->InLoadOrderModuleList.Blink = (PLIST_ENTRY)pOwen;

}


Rootkit


Rootkit   


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)------ 我方間諜,負責在敵方內部活動,完成實質性的工作