This series of tutorials is copyright "I spring and Autumn" All, reproduced please indicate the source.
for video tutorials, please visit "I Spring" (www.ichunqiu.com).
Preface
This time we will be based on the last content, programming implementation of a RING3 layer of simple active defense software. The entire program uses MFC implementation, the program starts monitoring, the DLL program will be injected into the Explorer.exe process, so that whenever a new process is created, the program will first carry out signature matching, so as to determine whether the target program is a virus program, if so, then intercept, and not intercept. When you stop monitoring, then uninstall the DLL program. Here is the code implementation for each part of the program.
Package Inlinehook class
For this hook technique, I intend to take an object-oriented approach, encapsulating an inline hook class in C + + for later use. In general, encapsulated classes have two files, one is the header file for the class, and the other is the implementation file for the class. The class name usually begins with the letter "C", which means "class name", so the class name is "Cinlinehook" and the header file is called "InlineHook.h", so the implementation file of the class can be named "InlineHook.cpp". The first is the header file code for the class:
#include <windows.h>class cinlinehook{public: cinlinehook (); constructor, used to initialize ~cinlinehook (); destructor, the release of the resource after the user program ends //hook function BOOL Hook (LPSTR pszmodulename, LPSTR pszfuncname, PROC pfnhookfunc); Cancel the hook function void unhook ();//re-hook function bool Rehook ();p rivate: PROC m_pfnorig; The address of the custom function is BYTE m_boldbytes[5]; Primitive function Entry Code BYTE m_bnewbytes[5]; The code of the constructed jump instruction};
The main file in the header is to declare some functions and variables that need to be used, and the corresponding comments are given in the code. Next is the code for the class implementation file (InlineHook.cpp):
#include "stdafx.h" #include "InlineHook.h" Cinlinehook::cinlinehook () {//Initialize the member variable M_pfnorig = NULL; ZeroMemory (M_boldbytes, 5); ZeroMemory (M_bnewbytes, 5);} Cinlinehook::~cinlinehook () {//Cancel hook unhook ();} The hook function, followed by the module name, the function name, and the custom hook function bool Cinlinehook::hook (LPSTR pszmodulename, LPSTR pszfuncname, PROC pfnhookfunc) {BO OL bRet = FALSE; Gets the address of the function in the specified module M_pfnorig = (PROC) GetProcAddress (GetModuleHandle (pszmodulename), pszfuncname); if (m_pfnorig! = NULL) {//Save the contents of the first 5 bytes at the address DWORD dwnum = 0; ReadProcessMemory (GetCurrentProcess (), M_pfnorig, M_boldbytes, 5, &dwnum); Constructs the JMP directive, "\xe9" for jmp opcode m_bnewbytes[0] = ' \xe9 '; Pfnhookfunc is the address after the hook, M_pfnorig is the original address, 5 is the instruction length * (DWORD *) (m_bnewbytes + 1) = (DWORD) Pfnhookfunc-(DWORD) m_ pfnOrig-5; Write the constructed address at the address WriteprocessmemOry (GetCurrentProcess (), M_pfnorig, M_bnewbytes, 5, &dwnum); BRet = TRUE; } return BRet;} Cancels the function of the hook void Cinlinehook::unhook () {if (M_pfnorig! = 0) {DWORD dwnum = 0; WriteProcessMemory (GetCurrentProcess (), M_pfnorig, M_boldbytes, 5, &dwnum); }}//re-hooks the function BOOL Cinlinehook::rehook () {bool BRet = FALSE; if (M_pfnorig! = 0) {DWORD dwnum = 0; WriteProcessMemory (GetCurrentProcess (), M_pfnorig, M_bnewbytes, 5, &dwnum); BRet = TRUE; } return BRet; }
The above is the entire Inlinehook package, the code is very simple, here no longer repeat, using it can easily implement the hook of the function.
Writing DLL Programs
Here you need to create a simple Win32 Dynamiclink library project:
Figure 1
and add the "InlineHook.h" and "InlineHook.cpp" written above to the project:
Figure 2
Then create a new file named HookCreateProcess.cpp in the source file and add the following code:
HookCreateProcess.cpp:Defines the entry point for the DLL application.//#include "stdafx.h" #include "InlineHook.h" #in Clude "Windows.h" #define Namelen 20#define signlen 32typedef struct sign{char Szvirusname[namelen]; LONG Lfileoffset; BYTE bvirussign[signlen+1];} _sign, *psign;//virus program signature sign SIGN[2] ={{//setup.exe "setup.exe", 0x0c040, "\x2a\x2a\x2a\xce \xe4\x2a\xba\xba\x2a\xc4\xd0\x2a\xc9\xfa\x2a\xb8 "" \xd0\x2a\xc8\xbe\x2a\xcf\xc2\x2a\xd4\xd8\x2a\xd5\xdf\x2a\x2a \X2A "},{//Unpacked.exe" Unpacked.exe ", 0x1920," \x13\x8b\x45\xf0\xe8\x00\x00\x00\x00\x81\x04 \x24\xd7\x86\x00\x00 "" \xff\xd0\xeb\x11\x6a\x10\x68\x30\x80\x40\x00\xff\x75\xfc\x53\xff "}};//signature detection function bool Checksig (Lpcwstr FilePath) {DWORD dwsignum = 0; DWORD dwnum = 0; BYTE Buffer[signlen+1];int i; HANDLE hfile = NULL; hfile = Createfilew (FilePath, Generic_read | Generic_write, File_share_read, NULL, Open_existing, File_attribute_normal, NULL); for (i=0; I <= 1; i++) {//The file pointer of the program to be instrumented points to the offset position of the signature SetFilePointer (hfile, Sign[i].lfileoffset, NULL, file_begin);//Read Take the target program to specify the offset location of the signature ReadFile (hfile, buffer, sizeof (buffer), &dwnum, NULL); The comparison of the signatures if (memcmp (sign[i].bvirussign, buffer, signlen) = = 0) {CloseHandle (hfile); return TRUE;}} CloseHandle (hfile); return FALSE;} Create a Cinlinehook class named Createprocesshook Cinlinehook createprocesshook;//We implement the hook function BOOLWINAPIMYCREATEPROCESSW ( LPCWSTR Lpapplicationname, LPWStr lpcommandline, Lpsecurity_attributes Lpprocessattribu TES, Lpsecurity_attributes lpthreadattributes, BOOL binherithandles, DWORD dwcre Ationflags, LPVoid lpenvironment, Lpcwstr lpcurrentdirectory, lpstartupinfow Lpstartupinfo, Lpprocess_information Lpprocessinformation) {BOOL bRet = FALSE; if (! Checksig (Lpapplicationname)) {//If the target program is not a virus after a signature match, uninstall the hook, execute the program, and then install the hook createprocesshook.unhook (); BRet = CREATEPROCESSW (Lpapplicationname, lpCommandLine, Lpprocessattributes, Lpthreadattributes, bInheritHandles, dwCreationFlags , Lpenvironment, Lpcurrentdirectory, Lpstartupinfo, Lpprocessinformation); Createprocesshook.rehook (); } else {//if the target program is a virus after a signature match, intercept the MessageBox (NULL, "The program you started is a virus that has been intercepted!") "," Important note ", MB_OK); } return BRet;} BOOL apientry DllMain (HANDLE hmodule, DWORD ul_reason_for_call, LPVOID lpres erved) {switch (ul_reason_for_call) {case Dll_process_attach: {//Hoo K CREATEPROCESSW () LetterNumber Createprocesshook.hook ("Kernel32.dll", "CREATEPROCESSW", (PROC) MYCREATEPROCESSW ); Break } case Dll_process_detach: {Createprocesshook.unhook (); Break }} return TRUE;
The above program will generate the DLL files we need after compiling and running. The principle is that after the hook succeeds, every time the CreateProcess () function is encountered, it will parse its first parameter, get the full path of the program to be started, and then match it with the matching pattern of the previously mentioned signature to determine whether the target program is safe. If a virus program is encountered, it is intercepted so that it cannot be run and the normal program is released.
the production of the program Interface
The program uses MFC implementations with only two buttons in the interface:
Figure 3
Then add two variables for the two buttons separately:
Figure 4
We want the "Enable monitoring" button to be available while the program is running, and "Turn off monitoring" is unavailable, so you need to add the following code to the bool Csimplehipsdlg::oninitdialog ():
Figure 5
"Turn on Monitoring" button code writingThe function of the "Enable monitoring" button is to first obtain the full path of the DLL program to be injected, that is, in the current directory. You then need to find out if there is a Explorer.exe process in the current process and get its PID value, and then you can use that PID value to inject the DLL. The process of DLL injection has been talked about in the last time. The complete code is as follows:
void Csimplehipsdlg::onbuttonon () {//Todo:add your control notification handler code Herebool BRet = False;dword dwpid = 0;//Gets the full path to the DLL file to be injected char *szdllname = GETCWD (NULL, 0); strcat (Szdllname, "\\HookCreateProcess.dll");//Find Explorer.exe process, get its PID value bret = Findtargetprocess ("Explorer.exe", &DWPID); If the Explorer.exe process is found, inject dllif (BRet = = TRUE) {//Take advantage of the PID value, get the handle of the process HANDLE hprocess = OpenProcess (process_all_access, FALSE, DWPID); if (hprocess = = NULL) {AfxMessageBox ("Process open failed!"); return;} Length is the length of the DLL name plus the character terminator int ndlllen = strlen (szdllname) + sizeof (char); Request memory space PVOID pdlladdr = VirtualAllocEx (hprocess,//process to allocate memory NULL,//desired starting address ndlllen,//size of region to allocate mem_commit,// Type of allocation page_readwrite); Type of Access Protection if (pdlladdr = = NULL) {AfxMessageBox ("Request memory Area failed!"); CloseHandle (hprocess); return;}DWORD dwwritenum = 0; if (! WriteProcessMemory (hprocess, Pdlladdr, Szdllname, Ndlllen, &dwwritenum)) {AfxMessageBox ("process write Failed!"); Failure to release the original requested memory area, undo the memory page submission status VirtualFreeEx (hprocess, Pdlladdr, Ndlllen, Mem_decommit); return;} Get the address of LoadLibraryA farproc pfunaddr = GetProcAddress (GetModuleHandle ("kernel32.dll"), "LoadLibraryA"); Create a remote thread HANDLE hthread = CreateRemoteThread (hprocess,//HANDLE to process NULL, SD 0,//initial stack size (lpthread_start_routine) pfunaddr,/ /thread function pdlladdr,//thread argument 0, Creation option NULL); Thread identifier if (hthread = = NULL) {AfxMessageBox ("Create Remote thread failed!"); Releases the previously requested memory area and revokes the commit state of the memory page VirtualFreeEx (hprocess, PDLLADDR, NDLllen, Mem_decommit); return;} AfxMessageBox ("Monitor successfully turned on!"); M_btnon.enablewindow (FALSE); M_btnoff.enablewindow (TRUE); Wait for thread to exit WaitForSingleObject (Hthread, INFINITE); Frees the previously requested memory area to revoke the commit status of the memory page VirtualFreeEx (hprocess, Pdlladdr, Ndlllen, Mem_decommit); Close handle CloseHandle (Hthread); CloseHandle (hprocess);} If the Explorer.exe process is not found, prompt else{afxmessagebox ("Explorer.exe process not found, monitoring failed!") "); return;}}
The above program uses the function findtargetprocess (), which is used to find the specified process, which is consistent with the code in the previous "Panda Incense Killing Tool", which is not described here. Because the program uses the GETCWD () function to get the current path, you need to add the header file Direct.h, and to implement the process traversal, you need to include the header file Tlhelp32.h.
"Turn off Monitoring" button code writing
The function of the "Turn off Monitoring" button is to find out if the Explorer.exe process contains the HookCreateProcess.dll file we injected, and if so, uninstall it. For the sake of insurance, you also need to take action to elevate permissions first. The code for elevation of privilege is consistent with the code in the previous "Panda Burn Tools", which is not mentioned here. The complete code is as follows:
void Csimplehipsdlg::onbuttonoff () {//Todo:add your control notification handler code here BOOL flag = False;dword Dwpid = 0;char *szdllname = "HookCreateProcess.dll";//Elevation of Privilege Enabledebugprivilege (se_debug_name);// Find the Explorer.exe process, get its PID value findtargetprocess ("Explorer.exe", &dwpid);//Get the list of System run modules HANDLE Hsnap = CreateToolhelp32Snapshot (Th32cs_snapmodule, dwpid); MODULEENTRY32 Me32 = {0}; me32.dwsize = sizeof (MODULEENTRY32); Retrieves information about the first module associated with a process BOOL BRet = Module32first (Hsnap, &me32); while (BRet) {//Find injected DLL if (strcmp (me32.szmodule, szdllname) = = 0) {flag = TRU E;break; }//Retrieve the next module information BRet = Module32next (Hsnap, &me32); } if (flag = = FALSE) {AfxMessageBox ("the corresponding module cannot be found!"); Return } closehandle (HSNAP); HANDLE hprocess = OpenProcess (process_all_access, FALSE, dwpid); if (hprocess = = NULL) {AfxMessageBox ("Process open failed!"); return; } Farproc pfunaddr = GetProcAddress (GetModuleHandle ("kernel32.dll"), "FreeLibrary"); HANDLE hthread = CreateRemoteThread (hprocess, NULL, 0, (lpthread_start_routine) pfunaddr, Me32.hmodule, 0, NULL), if (hthread = = NULL) {AfxMessageBox ("Create Remote thread failed!"); Return }afxmessagebox ("Monitor successfully closed!"); M_btnon.enablewindow (TRUE); M_btnoff.enablewindow (FALSE); Wait for thread to exit WaitForSingleObject (Hthread, INFINITE); CloseHandle (Hthread); CloseHandle (hprocess);}
At this point, all programs have been written.
test of the active defense program
We put the active defense program in the same directory as the DLL that is ready to be injected, and run the active defense program, when the "Close Monitoring" button is unavailable:
Figure 6
Then we can use the processexplorer to help us observe. Click "Start Monitoring", you can find in the Explorer.exe process, a number of a file called HookCreateProcess.dll, indicating that our injection is successful, and the "Enable monitoring" button is also in an unusable state:
Figure 7
At this point, you can try the two virus programs running Setup.exe and Unpacked.exe:
Figure 8
Our proactive defense systems are able to successfully intercept virus programs, and normal procedures are proactively released, stating that our program achieves the intended purpose. and click "Close Monitoring", through the Process Explorer, the DLL file has been uninstalled, it is also explained that our program has done a good job of the corresponding function.
SummaryThe Active defense program we discussed this time is still relatively rudimentary and can only be used to prevent viruses contained in the feature library, and there is nothing to do with the unknown virus, which is the limitation of using the feature library to search for poison. In fact, we can build on the basis of our code to improve the functionality, through the various API functions of the hook, to protect our system against infringement. Also hope that this procedure can play a role, so that everyone has a harvest.
Virus Trojan killing actual combat No. 021: Programming implementation of RING3 layer active defense