众所周知,Bandizip以前是个很优秀的压缩软件,但最近增加了很多广告。最开始是横幅,然后变成现在的弹窗。那么,如何去除广告呢?
很多帖子已经通过修改Bandizip\data\skin.data的方式来去除部分广告。但实测发现还是会有右下角弹窗广告。既然是窗口,于是我打算通过hook掉CreateWindow相关函数的方式来阻止弹窗。
第一步肯定是抓窗口和进程名,这软件很鸡贼,每天只会弹一次窗。不过只需要修改本地日期就能让它弹,方便抓窗口。
经过spy++的查找,确定了这玩意弹出的窗口名叫"BandiViewAdWnd",而且通过pid比对,我还发现它创建这个窗口的方法居然是拉一个bandizip.exe的进程专门创建,那这样就很容易解决了,直接匹配窗口名,然后TerminateProcess就可以了。
[C] 纯文本查看 复制代码 HWND WINAPI HCreateWindowExW(DWORD dwExStyle,LPCWSTR lpClassName,LPCWSTR lpWindowName,DWORD dwStyle,int X,int Y,int nWidth,int nHeight,HWND hWndParent,HMENU hMenu,HINSTANCE hInstance,LPVOID lpParam)
{
if(lpWindowName && memcmp(L"BandiViewAdWnd",lpWindowName,30)==0) TerminateProcess(GetCurrentProcess(),0);
return pCreateWindowExW(dwExStyle,lpClassName,lpWindowName,dwStyle,X,Y,nWidth,nHeight,hWndParent,hMenu,hInstance,lpParam);
}
然后是hook的方法,这里我用inline hook
[C] 纯文本查看 复制代码 void apihook(void* apiname, void* apiname2, void* apiname3){
if (!apiname)return;
SIZE_T size = 16;
unsigned int OldProtect;
if (NtProtectVirtualMemory((HANDLE)-1,&apiname,&size,PAGE_EXECUTE_READWRITE,&OldProtect)==0){
PBYTE addr=0;SIZE_T size=128;
NTSTATUS status=NtAllocateVirtualMemory((HANDLE)-1,(void**)&addr,0,&size,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE);
if (status==0){
memcpy(addr,apiname,12);
addr[12]=0xFF;addr[13]=0x25;addr[14]=0x00;addr[15]=0x00;addr[16] = 0x00;addr[17] = 0x00;
*(UINT_PTR*)(addr+18)=(UINT_PTR)apiname+12;PBYTE p =(PBYTE)apiname;
p[0]=0x48; p[1]=0xb8;*(void**)((PBYTE)p+2)=(void*)apiname3;
p[10]=0xFF; p[11]=0xE0;
*(PBYTE*)apiname2=addr;
NtProtectVirtualMemory((HANDLE)-1,&apiname,&size,OldProtect,&OldProtect);
}
}
}
apihook((void*)CreateWindowExW,(void*)&pCreateWindowExW,(void*)HCreateWindowExW);
注入这段代码的办法很多,比如dll劫持等等,这里就不多说了。举个用version.dll的示例:
[C] 纯文本查看 复制代码 static HMODULE g_realDll = NULL;
static void LoadRealDll(void) {
if (g_realDll) return;
char sysPath[MAX_PATH];
GetSystemDirectoryA(sysPath, MAX_PATH);
char dllPath[MAX_PATH];
wsprintfA(dllPath, "%s\\version.dll", sysPath);
g_realDll = LoadLibraryA(dllPath);
}
#define DECLARE_PROXY(ret, name, args, callargs) \
typedef ret (WINAPI *PFN_##name) args; \
static PFN_##name g_##name = NULL; \
extern "C" __declspec(dllexport) ret WINAPI name args\
{ \
LoadRealDll(); \
if (!g_##name && g_realDll) \
g_##name = (PFN_##name)GetProcAddress(g_realDll, #name); \
if (!g_##name) { \
SetLastError(ERROR_PROC_NOT_FOUND); \
return (ret)0; \
} \
return g_##name callargs; \
}
DECLARE_PROXY(BOOL, GetFileVersionInfoA,(LPCSTR a, DWORD b, DWORD c, LPVOID d),(a, b, c, d))
另外还有个更新软件的弹窗,这个也好解决,把安装目录下的Updater.exe破坏掉就行了。 |