vcasm的多程式反跟蹤技術學習心得(菜鳥篇)

看雪資料發表於2004-12-15

vcasm的vprotector程式中使用的多程式(Process)反跟蹤技術很有新意,反跟蹤技術中比較常見的是多執行緒(Thread)技術。我以前見到的多程式主要是使用一個程式除錯另一個程式。這種方式只能認為是除錯反跟蹤,不能稱為真正的多程式反跟蹤技術。而vcasm的方法本人認為是真正意義上的多程式反跟蹤技術。這裡簡單說明一下。
要想利用多程式,必須處理好多個程式之間的資料交換問題和程式同步問題。如果各程式之間沒有資料交換就不成其為多程式技術了,談到程式間的資料交換,我們首先想到的是動態連線庫(dll),但vcasm採用了一種更為簡便的方法。下面就說說這種方法。
在談vcasm的資料交換的方法之前先看幾個API函式。
CreateFileMapping函式用來生成一個記憶體檔案對映物件,函式定義如下
HANDLE CreateFileMapping(
  HANDLE hFile,              // 對映檔案控制程式碼
  LPSECURITY_ATTRIBUTES lpFileMappingAttributes,
                             // 安全屬性
  DWORD flProtect,           // 物件的保護屬性
  DWORD dwMaximumSizeHigh,   // 物件大小高32位
  DWORD dwMaximumSizeLow,    //物件大小第32位e
  LPCTSTR lpName             // 檔案對映物件名
);
當hFile=(HANDLE)-1時得到的不是實際檔案的對映物件,而是一個作業系統分頁檔案返回的一個特定大小的記憶體塊物件。這個記憶體塊物件可以被多個程式用物件名進行操作。這就是說,可以用它來交換資料了。判斷這個物件是否存在呢?這又要用到一個函式。
DWORD GetLastError(VOID)
當返回值等於ERROR_ALREADY_EXISTS時則說明這個物件已經存在了。
好了,下面就用程式實際說明一下,vcasm的程式比較複雜,我並沒按原程式寫程式碼,而是簡化成了一段說明方法的程式碼,目的只想說明一下這種方法。執行緒同步的程式碼這裡就不寫了,
有興趣自己逆向一下。

  GetModuleFileName(0,lpFilename,0x200); //取得檔名
   然後將檔名加以變動作為mapview的名
for(i=0;i<0x200;i++)
  {
  //  將檔名中的\變成-
    if(*(char*)(lpFilename+i)==0x5c)*(char*)(lpFilename+i)=0x2d;
  }
mHandle=CreateFileMapping((HANDLE)-1,0,PAGE_READWRITE,0,0x400,lpFilename);
GetLastError()必須緊跟在後面,如果中間還有其他的api,他返回的就不知道是什麼了.
if(GetLastError()!=ERROR_ALREADY_EXISTS)
  {
    mapview=MapViewOfFile(mHandle,FILE_MAP_ALL_ACCESS,0,0,0); //提交實體記憶體
        sum =(char*)((char*)mapview+0x3ff);
        *sum=0;                                        //初始化累加值
  }
  else
  {
    mapview=MapViewOfFile(mHandle,FILE_MAP_ALL_ACCESS,0,0,0); //提交實體記憶體
        sum =(char*)((char*)mapview+0x3ff);
        *sum+=1;                                        //累加值+1
  }

   if(*sum>5)     //大於5次就該結束了
   {
     MessageBox(0,"yes","ok",0);
     UnmapViewOfFile(mapview);   開啟的fileview可以不要了
     CloseHandle(mHandle);        handle也可以關掉了
   }
   else
   {
    還沒到五次,再開一個程式
    CreateProcess(0,GetCommandLine(),0,0,0,0,0,0,&StartupInfo,&ProcessInformation);
   }
   Sleep(50);    將執行權交出去,休息一下
   ExitProcess(0);  其他的程式已經開啟了,本程式就可以關掉了.

vc++的程式碼如下:
#include "stdafx.h"

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
   
  DWORD i;
  LPVOID mapview;
  HANDLE mHandle;
  PCHAR  sum;
  LPTSTR lpFilename=(LPTSTR)malloc(0x200);
  STARTUPINFO StartupInfo;
  StartupInfo.cb=sizeof(STARTUPINFO);
  PROCESS_INFORMATION ProcessInformation;  
  GetModuleFileName(0,lpFilename,0x200); //取得檔名
  GetStartupInfo(&StartupInfo); //填寫StartupInfo結構
    for(i=0;i<0x200;i++)
  {
  //  將檔名中的\變成-
    if(*(char*)(lpFilename+i)==0x5c)*(char*)(lpFilename+i)=0x2d;
  }
    mHandle=CreateFileMapping((HANDLE)-1,0,PAGE_READWRITE,0,0x400,lpFilename);
  if(GetLastError()!=ERROR_ALREADY_EXISTS)
  {
    mapview=MapViewOfFile(mHandle,FILE_MAP_ALL_ACCESS,0,0,0); //提交實體記憶體
        sum =(char*)((char*)mapview+0x3ff);
        *sum=0;                                        //初始化累加值
  }
  else
  {
    mapview=MapViewOfFile(mHandle,FILE_MAP_ALL_ACCESS,0,0,0); //提交實體記憶體
        sum =(char*)((char*)mapview+0x3ff);
        *sum+=1;                                        //累加值+1
  }

   if(*sum>5)
   {
     MessageBox(0,"yes","ok",0);
     UnmapViewOfFile(mapview);
     CloseHandle(mHandle);
   }
   else
   {
    
    CreateProcess(0,GetCommandLine(),0,0,0,0,0,0,&StartupInfo,&ProcessInformation);
   }
   Sleep(0);
   ExitProcess(0);

  return 0;
}

相關文章