1.簡介
BHO 全名: Browser Helper Object 即瀏覽器輔助對象
它是微軟推出的作為瀏覽器對第3方程序開發的交互接口的標准. 通過這個接口就可以編寫代碼來拓展瀏覽器, 獲取瀏覽器行為等.
因此同樣給了惡意代碼的可乘之機. 惡意代碼可以通過注冊插件等手段來對瀏覽器進行劫持.
借助BHO,可以寫一個進程內的COM對象,這個對象在每次啟動時都加載.
BHO對象依托於瀏覽器主窗口, BHO對象與瀏覽器實例生命周期是一致的
此外, BHO是個COM進程內服務, 注冊於注冊表某一鍵下. ie和explorer 將查詢那個鍵並加載鍵下所有對象.
在於: HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Explorer\Browser Helper Objects
2. 枚舉BHO
每個BHO對象會對應一個classid 簡稱為CLSID ,全局唯一的. 在HKEY_LOCAL_CLASSES_ROOT\CLSID\中包含了本系統所有的各種對象的classid和guid
如果該classid對應某個BHO對象, 將其展開將能得到它的詳細信息:包括dll路徑. 因此可以編寫工具枚舉BHO
// BHO.cpp : 定義控制台應用程序的入口點。 // #include "stdafx.h" #include <Windows.h> #include <wchar.h> #include <locale.h> int main() { setlocale(LC_ALL, "chs"); /* 復習注冊表操作: 打開子健: RegOpenKeyExW 參數傳遞句柄,返回執行情況 枚舉子健: RegEnumKeyExW 以某索引進行一一枚舉,返回執行情況 獲取子健里的值的信息:RegQueryValueExW,一次調用獲取信息大小,二次調用獲取信息 */ HKEY hBHOMainKey = HKEY_LOCAL_MACHINE; HKEY hClsidMainKey = HKEY_CLASSES_ROOT; HKEY hBHOs; //要枚舉的鍵句柄 HKEY hQueryBHO; //某注冊的BHO的子健句柄 DWORD result, valueType; DWORD keyNameSize = 128; DWORD keyInfoSize = 0; WCHAR keyName[128]; WCHAR queryKeyName[256]; BYTE *valueInfo; int i = 0; //打開存放BHO對象的子健 result = RegOpenKeyExW(hBHOMainKey, L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Browser Helper Objects", 0, KEY_ENUMERATE_SUB_KEYS, &hBHOs); if (result!=ERROR_SUCCESS) { wprintf(L"RegOpenKeyExW error code is %d\n", GetLastError()); return result; } while (1) { //一一枚舉其中子健名 memset((PVOID)keyName, 0, 128 * sizeof(WCHAR)); keyNameSize = 128; result = RegEnumKeyExW(hBHOs, i, keyName, &keyNameSize, 0, 0, 0, 0); if (result==ERROR_NO_MORE_ITEMS) { break; } wprintf(L"classid : %s\n", keyName); //構建查詢子健名 wsprintf(queryKeyName, L"CLSID\\%s\\InprocServer32", keyName); //打開該子健 result = RegOpenKeyExW(hClsidMainKey, queryKeyName, 0, KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE, &hQueryBHO); if (result != ERROR_SUCCESS) { i++; continue; } //一次調用獲取數據大小 result = RegQueryInfoKeyW(hQueryBHO, 0, 0, 0, 0, 0, 0, 0, 0, &keyInfoSize, 0, 0); if (result != ERROR_SUCCESS) { i++; RegCloseKey(hQueryBHO); continue; } valueInfo = (BYTE*)malloc(sizeof(BYTE)*keyInfoSize); //二次調用獲取數據, 這里獲取默認數據 result = RegQueryValueExW(hQueryBHO, 0, 0, &valueType, valueInfo, &keyInfoSize); if (result != ERROR_SUCCESS) { free(valueInfo); i++; RegCloseKey(hQueryBHO); continue; } wprintf(L"數據: %s \n\n", valueInfo); free(valueInfo); RegCloseKey(hQueryBHO); i++; } RegCloseKey(hBHOs); return 0; }
3.安裝BHO
根據以上的介紹, 病毒要利用BHO需要生成一個dll文件,並在注冊表HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Explorer\Browser Helper Objects下注冊一個子健
然后在HKEY_CLASSES_ROOT\CLSID下注冊一個CLSID子健並再建立一個名為InprocServer32的子健,設置默認值為dll的完整路徑
DWORD installBHO(WCHAR* dllpath) { DWORD result = 0; DWORD open = 0; GUID bhoUid; WCHAR sUid[50] = { 0 }; WCHAR subPath[200] = { 0 }; if (UuidCreate(&bhoUid)!=RPC_S_OK) { return result; } HKEY hBHOMainKey = HKEY_LOCAL_MACHINE; HKEY hClsidMainKey = HKEY_CLASSES_ROOT; //{7D886477 - D696 - 4de5 - 8CBB - 9975BDDCD33A} HKEY hBHOSubKey, hClsidSubKey; wsprintf(sUid, L"{%08X-%04X-%04x-%02X%02X-%02X%02X%02X%02X%02X%02X}", bhoUid.Data1, bhoUid.Data2, bhoUid.Data3, bhoUid.Data4[0], bhoUid.Data4[1], bhoUid.Data4[2], bhoUid.Data4[3], bhoUid.Data4[4], bhoUid.Data4[5], bhoUid.Data4[6], bhoUid.Data4[7]); wsprintf(subPath, L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Browser Helper Objects\\%s", sUid); result = RegCreateKeyExW(hBHOMainKey, subPath, 0, 0, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, 0, &hBHOSubKey, &open); memset((LPVOID)subPath, 0, sizeof(WCHAR) * 200); if (result!=ERROR_SUCCESS) { wprintf(L"RegCreateKeyExW hBHOMainKey error code is %d\n", GetLastError()); return result; } RegCloseKey(hBHOSubKey); wsprintf(subPath, L"CLSID\\%s\\InprocServer32", sUid); result = RegCreateKeyExW(hClsidMainKey, subPath, 0, 0, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, 0, &hClsidSubKey, &open); if (result != ERROR_SUCCESS) { wprintf(L"RegCreateKeyExW hClsidMainKey error code is %d\n", GetLastError()); return result; } result = RegSetValueExW(hClsidSubKey, 0, 0, REG_SZ, (BYTE*)dllpath, lstrlenW(dllpath)*sizeof(WCHAR)+2); if (result != ERROR_SUCCESS) { wprintf(L"RegSetValueExW hClsidSubKey error code is %d\n", GetLastError()); return result; } }
4.卸載BHO
根據傳遞的guid值來刪除bho對象及其涉及的鍵, 值, 和對應的dll文件