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文件