procedure DisableQQAd(Wnd: LongInt);
label DoNext;
var
h, t: THandle;
cn: array [0..254] of Char;
begin
// get root Win control
while GetParent(Wnd) > 0 do Wnd := GetParent(Wnd);
// remove QQ 2007 II tips url label
h := GetWindow(Wnd, GW_CHILD or GW_HWNDFIRST);
while h > 0 do
begin
cn := '';
GetClassName(h, @cn, SizeOf(cn));
if cn = '#32770' then // QQ frame
begin
h := GetWindow(h, GW_CHILD or GW_HWNDFIRST);
while h > 0 do
begin
GetClassName(h, @cn, SizeOf(cn));
if cn = 'Static' then
if GetWindowText(h, @cn, SizeOf(cn)) > 0 then
if Trim(cn) <> '' then
begin
DestroyWindow(h);
goto DoNext;
end;
h := GetWindow(h, GW_HWNDNEXT);
end;
end;
h := GetWindow(h, GW_HWNDNEXT);
end;
DoNext:
// remove QQ AD panel
h := GetWindow(Wnd, GW_CHILD or GW_HWNDFIRST);
while h > 0 do
begin
cn := '';
GetClassName(h, @cn, SizeOf(cn));
if cn = '#32770' then // QQ frame
begin
h := GetWindow(h, GW_CHILD or GW_HWNDFIRST);
while h > 0 do
begin
t := GetWindow(h, GW_CHILD or GW_HWNDFIRST);
if t > 0 then // has child control
begin
GetClassName(h, @cn, SizeOf(cn));
if cn = 'Static' then // found!
begin
DestroyWindow(t); // destroy Ad window
{ CreateWindow('Static', 'Hello world!!!', // 这里可以做什么?
// 创建一个Form,用SetParent让你的Form附着在上面的,
// 这样可以用你自己的窗口替换QQ的广告栏,TX一定会非常生气的,
// 为了避免麻烦,最好还是不要做此类事情啦.这里只是讨论方法而已.
// 如果要添加自己的Form,那么你还得用SetWindowLong来Hook WndProc过程,
// 以用来处理WM_CLOSE,确保关闭聊天窗口时能释放你的Form.
WS_VISIBLE or WS_CHILD or SS_LEFT,
0, 0, 242, 36, h, 0, h, nil); }
Exit;
end;
end;
h := GetWindow(h, GW_HWNDNEXT);
end;
end;
h := GetWindow(h, GW_HWNDNEXT);
end;
end;
03605EFF FF15 38506C03 call dword ptr [<&BasicCtrlDll.IsVIP>] ; BasicCtr.IsVIP
* ^判断当前登陆的QQ是否为VIP,因为VIP用户是可以关闭QQ广告的
03605F05 8365 FC 00 and dword ptr [ebp-4], 0
03605F09 8BF0 mov esi, eax
03605F0B 8D45 FC lea eax, dword ptr [ebp-4]
03605F0E 6A 01 push 1
03605F10 50 push eax
03605F11 68 E8A76D03 push 036DA7E8 ; ASCII "m_bMemberDisableAD"
03605F16 FF15 206D6C03 call dword ptr [<&QQHelperDll.GetSysBoolData'>; QQHelper.GetSysBoolData
* ^获取广告显示设置
03605F1C 83C4 10 add esp, 10
03605F1F 85F6 test esi, esi
03605F21 5E pop esi
03605F22 74 0B je short 03605F2F
* ^关键!!! 不是VIP就跳的,所以把这个NOP了
03605F24 837D FC 00 cmp dword ptr [ebp-4], 0
03605F28 74 05 je short 03605F2F
* ^关键!!! 没关闭AD就跳,所以再把这个NOP了
03605F2A 6A 01 push 1
03605F2C 58 pop eax
这样,就实现了去AD了
具体可以使直接NOP代码,或者采用Hook方法:
function IsVIP(pQQCore: Pointer): Integer; cdecl;
begin
Result := 1;
end;
function GetSysBoolData(AText: PChar; p: Pointer; bIsVIP: Boolean): Integer; cdecl;
// int __cdecl GetSysBoolData(char const *,int &,int)
begin
if AText = 'm_bMemberDisableAD' then
begin
Integer(p^) := 1;
Result := 1;
Exit;
end;
Result := Call original Func; 调用原函数
end;