好久沒(méi)寫(xiě)代碼了,花了幾個(gè)小時(shí)寫(xiě)了這個(gè)程序。因?yàn)橐子螐?qiáng)制推送廣告方面更新了,朋友找我更新一下之前那個(gè)程序。這次易游生成的路徑規(guī)則改變了,負(fù)責(zé)廣告推送的DLL沒(méi)變,只是隨機(jī)路徑,隨機(jī)文件夾,隨機(jī)文件名。雖然有個(gè)文件夾文件名最后有tmp三個(gè)字母是確定,但是為了防止它再次更新文件生成的方式,導(dǎo)致程序失效,這次利用了殺毒軟件的特征碼查殺機(jī)制,去定位該文件。這樣即使以后易游再次改變路徑規(guī)則也一樣能找到。這方式有個(gè)缺點(diǎn)就是若日后易游出現(xiàn)大幅度更新該DLL(修改瀏覽器主頁(yè)的DLL)就會(huì)導(dǎo)致特征碼不匹配。現(xiàn)在這個(gè)程序是應(yīng)急的,下次若是有時(shí)間,就改成把特征碼外置到配置文件中,在配置文件中可以修改掃描路徑、修改特征碼等關(guān)鍵參數(shù),這樣即使易更新了DLL,那就只需要重新提取特征碼(幾分鐘的事)就能讓程序根據(jù)新的特征碼鎖定新的文件,至于鎖定機(jī)制還是和以前一樣,采用獨(dú)占方式打開(kāi)文件的方法來(lái)鎖定該文件,讓其無(wú)法被加載。
這和殺毒軟件與病毒變種之間的對(duì)抗很像啊。。。好懷念和小凡以前與殺毒軟件對(duì)抗的日子,哈哈。。。
個(gè)人最討厭強(qiáng)制推送廣告了,給出完整的源碼,以供日后復(fù)習(xí),這次寫(xiě)的代碼不是很滿意,還有很多地方可以提升性能,初步估計(jì),預(yù)計(jì)至少速度上能提升50%,其實(shí)現(xiàn)在不慢了,不過(guò)明天要上班了,朋友又急用,就暫時(shí)這樣吧。
// KEyoo.cpp : Defines the entry point for the console application.
//
//
/************************************************************************/
/* 設(shè)計(jì)者:【L、】QQ:1007566569 */
/************************************************************************/
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
// 特征碼地址
int TZM_Addr[9] = {0x00014C49,
0x00014D65,
0x00014EB2,
0x0001511E,
0x000151CA,
0x000153DA,
0x000155F5,
0x000157F8,
0x00016E10};
// 特征碼 考慮到網(wǎng)吧文件的多樣性,這里取9處特征碼 均取該DLL 相關(guān)HOOK代碼
unsigned char TZM_Code_0[] = {0x68, 0x44, 0xE3, 0x03, 0x10, 0xE8, 0xBD, 0x21, 0x00, 0x00};
unsigned char TZM_Code_1[] = {0x68, 0x68, 0xE3, 0x03, 0x10, 0xE8, 0xA1, 0x20, 0x00, 0x00};
unsigned char TZM_Code_2[] = {0x51, 0x68, 0x84, 0xE3, 0x03, 0x10, 0xE8, 0x53, 0x1F, 0x00};
unsigned char TZM_Code_3[] = {0x68, 0x98, 0xE3, 0x03, 0x10, 0xE8, 0xE8, 0x1C, 0x00, 0x00};
unsigned char TZM_Code_4[] = {0x68, 0xAC, 0xE3, 0x03, 0x10, 0xE8, 0x3C, 0x1C, 0x00, 0x00};
unsigned char TZM_Code_5[] = {0x68, 0xF8, 0xE3, 0x03, 0x10, 0xE8, 0x2C, 0x1A, 0x00, 0x00};
unsigned char TZM_Code_6[] = {0x68, 0xC4, 0xE3, 0x03, 0x10, 0xE8, 0x11, 0x18, 0x00, 0x00};
unsigned char TZM_Code_7[] = {0x68, 0x4C, 0xE4, 0x03, 0x10, 0xE8, 0x0E, 0x16, 0x00, 0x00};
unsigned char TZM_Code_8[] = {0x55, 0x8B, 0xEC, 0xB8, 0x01, 0x00, 0x00, 0x00, 0x5D, 0xC3};
// 指針,將所有特征碼關(guān)聯(lián)在一起 方便比對(duì)
unsigned char *TZM_Code[9];
// 鎖定文件
BOOL OccupyFile( LPCTSTR lpFileName );
// 鎖定文件數(shù)累加 這里只是用來(lái)判斷是否找到文件
BOOL KillFileCout = 0;
// 遍歷文件
int viewfiles(char *directory);
// 特征碼匹配
DWORD WINAPI ScanKill_ttsB( LPVOID lpParam )
{
char *File = new char[MAX_PATH];
strcpy(File, (char*)lpParam);// 盡早取出參數(shù)
char Code[10] = {0};
FILE *fhand = fopen(File, "rb");
if (fhand == NULL)// 如果無(wú)法打開(kāi)文件則退出
return 1;
// 特征碼一一匹配
for (int i=0; i<9; i++)
{
fseek(fhand, (long)TZM_Addr[i], SEEK_SET);// 移動(dòng)文件指針到指定位置
fread(Code, 1, 10, fhand);// 取10字節(jié)
// 比較
if (memcmp(TZM_Code[i], Code, 10) == 0)
continue;
else
break;// 如果不同則跳出
}
fclose(fhand);
if (i==9)// 如果已經(jīng)完成了9次比對(duì) 說(shuō)明該文件就是自己要尋找文件。
{
OccupyFile(File);// 將文件鎖定
KillFileCout++;// 累計(jì)
}
delete []File;
return 1;
}
// 權(quán)限提升
void RaiseToDebugP()
{
HANDLE hToken;
HANDLE hProcess = GetCurrentProcess();
if ( OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken) )
{
TOKEN_PRIVILEGES tkp;
if ( LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tkp.Privileges[0].Luid) )
{
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
BOOL bREt = AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, NULL, 0) ;
}
CloseHandle(hToken);
}
}
// 這個(gè)函數(shù)是為了把文件句柄復(fù)制到 System 進(jìn)程 這樣本程序即使退出 被鎖定的文件也不會(huì)失效
BOOL OccupyFile( LPCTSTR lpFileName )
{
BOOL bRet;
RaiseToDebugP();
// 打開(kāi)System進(jìn)程
HANDLE hProcess = OpenProcess( PROCESS_DUP_HANDLE, FALSE, 4); // 4為system進(jìn)程號(hào)
if ( hProcess == NULL )
{
hProcess = OpenProcess( PROCESS_DUP_HANDLE, FALSE, 8);
if ( hProcess == NULL )
return FALSE;
}
HANDLE hFile;
HANDLE hTargetHandle;
// 獨(dú)占方式打開(kāi)文件 網(wǎng)上的不是打開(kāi)
hFile =CreateFile(lpFileName,GENERIC_READ,0,NULL,OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS,0);
if ( hFile == INVALID_HANDLE_VALUE )
{
CloseHandle( hProcess );
return FALSE;
}
// 禁止內(nèi)核關(guān)閉該句柄 一般情況下如果在內(nèi)核關(guān)閉該句柄會(huì)藍(lán)屏
SetHandleInformation(hFile,HANDLE_FLAG_PROTECT_FROM_CLOSE,HANDLE_FLAG_PROTECT_FROM_CLOSE);
// 這步是關(guān)鍵 從當(dāng)前進(jìn)程復(fù)制文件句柄到System進(jìn)程空間 這樣本程序即使退出 但是句柄在System進(jìn)程內(nèi)仍有效
bRet = DuplicateHandle( GetCurrentProcess(), hFile, hProcess, &hTargetHandle,
0, FALSE, DUPLICATE_SAME_ACCESS|DUPLICATE_CLOSE_SOURCE);
CloseHandle( hProcess );
return bRet;
}
// 遍歷指定文件夾
int viewfiles(char *directory)
{
WIN32_FIND_DATA fdFindData;
HANDLE hFind, hFile;
char *filename;
int count=0;
BOOL done;
DWORD FileSize ;
filename=new char[strlen(directory)+5];
strcpy(filename,directory);
strcat(filename,"\\*.*");
hFind=FindFirstFile(filename,&fdFindData);
delete[] filename;
done=hFind!=INVALID_HANDLE_VALUE;
while(done)
{
if(strcmp(fdFindData.cFileName,".") && strcmp(fdFindData.cFileName,".."))
{
filename=new char[strlen(directory)+strlen(fdFindData.cFileName)+2];
strcpy(filename,directory);
strcat(filename,"\\");
strcat(filename,fdFindData.cFileName);
if((fdFindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY )
{
viewfiles(filename);// 如果是文件夾則遞歸遍歷
}
else if (strstr(filename, ".dll"))// 第一次過(guò)濾 簡(jiǎn)單從文件中判斷是否為DLL
{
hFile = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL,OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
FileSize = GetFileSize(hFile, NULL);
CloseHandle(hFile);
if (FileSize > 340000 && FileSize < 350000)// 第二次過(guò)濾 只要指定文件大小范圍的DLL文件
{
CreateThread(NULL, NULL, ScanKill_ttsB, (LPVOID)filename, NULL, NULL);
Sleep(10); // 保證線程參數(shù)傳遞完畢 其實(shí)應(yīng)該采用互斥量的形式,這樣能提升性能和穩(wěn)定性
}
}
delete[] filename;
}
done=FindNextFile(hFind,&fdFindData);
}
FindClose(hFind);
return(count);
}
void Scan()
{
while(1)
{
viewfiles("C:");// 掃描C盤(pán)
Sleep(1000);
if (KillFileCout)// 如果已經(jīng)鎖定了文件則退出
exit(1);
}
}
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// 運(yùn)行時(shí) 去除鼠標(biāo)指針漏斗
GetInputState();
PostThreadMessage(GetCurrentThreadId(), NULL, NULL, NULL);
MSG msg;
GetMessage(&msg, NULL, NULL, NULL);
printf("用于解決易游鎖定IE廣告主頁(yè) 2013.9.21 更新 【L、】1007566569\n");
// 將所有特征碼關(guān)聯(lián)
TZM_Code[0] = TZM_Code_0;
TZM_Code[1] = TZM_Code_1;
TZM_Code[2] = TZM_Code_2;
TZM_Code[3] = TZM_Code_3;
TZM_Code[4] = TZM_Code_4;
TZM_Code[5] = TZM_Code_5;
TZM_Code[6] = TZM_Code_6;
TZM_Code[7] = TZM_Code_7;
TZM_Code[8] = TZM_Code_8;
// 以線程的形式去掃描
CreateThread(NULL, NULL,(LPTHREAD_START_ROUTINE)Scan, NULL, NULL, NULL);
Sleep(120000); // 如果 兩分鐘后還沒(méi)有找到文件 那么就退出
return 0;
}
|