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;
}