Virus exclusive tool self-edited
Information Source: neeao blog
Nowadays, virus, Trojan, and worms emerge one after another. Anti-Virus companies and major security companies will provide virus exclusive tools free of charge as a result of the emergence of a virus that has a major impact. This measure is indeed very helpful for common users. In fact, writing a virus killing tool is not as mysterious as you may think. You can use the SDK to write a console program to implement virus killing. Because you do not need to write a graphic interface, it is easy and quick! You can write it yourself! Believe it? Let's talk about the ideas and implementation methods of the virus killing tool.
The virus killing tool described in this article is a generalized virus for independent programs such as Trojans and worms, instead of the narrow virus that is self-replication infected with PE files attached to other programs. Because the virus killing tool requires PE file structure and other knowledge, it is relatively difficult, so we will start from a relatively simple point, difficult to introduce later.
For most viruses, the anti-virus idea is actually very simple: Terminate the virus process, delete the self-starting project (generally in the registry, run * under the primary key), delete the virus file, you also need to modify the Registry to restore the file association if the file association virus is set. The following is a separate statement.
I. Terminate the process
In the past, many people on the internet asked me how to terminate the specified process based on the file name, and why the terminateprocess () function cannot directly terminate the specified process. First, let's take a look at the Declaration of the terminateprocess () function: bool terminateprocess (handle hpeocess, uint uexitcode). The first parameter is the process handle, not the process name (file name ). How can I obtain the handle of a specified process? We can use the OpenProcess () function. Its prototype is
Handle OpenProcess (
DWORD dwdesiredaccess, // access flag
Bool binherithandle, // process the inherited flag
DWORD dwprocessid // process ID
);
The last parameter is the ID of the process. The process handle and process ID are two different things. At this time, you may be very depressed: How do you know the process ID? Of course there are methods! In Windows 9x/2000/XP/2003, Microsoft provides toolhelp API series functions used to enumerate processes. Use the createmedilhelp32snapshot () function to obtain the snapshot handle, and then use process32first () and process32next () to enumerate the current process. During the enumeration process, the information of each process is stored in the processentry32 structure. The prototype of processentry32 is:
Typedef struct tagprocessentry32
{
DWORD dwsize; // structure size;
DWORD cntusage; // reference count of this process;
DWORD th32processid; // process ID;
DWORD th32defaultheapid; // The default heap ID of the process;
DWORD th32moduleid; // Process Module ID;
DWORD cntthreads; // The number of threads enabled by this process;
DWORD th32parentprocessid; // parent process ID;
Long pcpriclassbase; // thread priority;
DWORD dwflags; // reserved;
Char szexefile [max_path]; // process full name;
} Processentry32;
Th32processid indicates the process ID, and szexefile indicates the process file name. To terminate a specified process, we can enumerate the process and determine whether the szexefile is the same as the process name we want to terminate. If the process name is the same, take the th32processid parameter and use it as the OpenProcess function, obtain the handle of the target process. In this way, the terminateprocess () function can be used to terminate the process. I wrote a function to terminate a specified process, as shown below:
Void killprocessfromname (lpctstr name) // name is the name of the process to be terminated. For Win9x, the path must be included.
{
Processentry32 PE; // defines a variable of the processentry32 knot type.
Handle hshot = createconlhelp32snapshot (th32cs_snapprocess, 0); // create a snapshot handle
PE. dwsize = sizeof (processentry32); // You must assign a value to dwsize first.
If (process32first (hshot, & PE ))
{
Do
{If (strcmp (PE. szexefile, name) = 0) // determines whether the process is for the process you want to terminate
Handle hprocess = OpenProcess (process_all_access, false, PE. th32processid); // obtain the handle using its ID if yes
Terminateprocess (hprocess, 0); // terminate the process
}
While (process32next (hkz, & PE ));
}
Closehandle (hshot); // do not forget to close
}
In use, you only need to call the killprocessfromname () function in the main () main function and set the parameter to the name of the process to be terminated. In Win9x, You need to include the path. Another point worth noting is that do not forget # include <tlhelp32.h>.
Ii. delete an object
This step is very simple. Just call the deletefile () function, and set the lpfilename to the pointer to the name of the file to be deleted by calling the bool deletefile (lpctstr lpfilename) function, which can contain the specific path.
3. Modify the registry and delete startup items and file associations
First, use the regopenkeyex () function to open the target primary key. The regopenkeyex () function prototype is
Long regopenkeyex (
Hkey, // handle of the key to be opened
Lptstr lpsubkey, // point to the name string pointer containing the child to be opened
DWORD uloptions, // reserved word, must be null
Regsam samdesired, // access permission
Phkey phkresult // pointer to the handle to open the key
);
After obtaining the handle, use the regsetvalueex () function to modify the key value. The function prototype is:
Long regsetvalueex (
Hkey, // handle of the currently opened key
Lpctstr lpvaluename, // point to a non-null string pointer containing the name of the value to be queried
DWORD reserved, // reserved value, must be null
DWORD dwtype, // key value type, such as REG_SZ and REG_DWORD
Const byte * lpdata, // pointer to the key-value data. Note that this variable type is not an lpctstr!
DWORD cbdata // pointer to the variable that saves the set value length, in bytes
);
Of course, you can also use the regdeletevalue () function to delete the key value. After completing the operation, do not forget to use the regclosekey () function to close.
Using these functions is simple. You only need to replace the corresponding parameters with the values you want to delete or modify the registry. The only thing worth noting is regsetvalueex () the type of the 5th parameters in the function is byte rather than the lpctstr! With this, you can easily Delete the specified startup Item and restore the file association. for your understanding, I will give an example of how to fix the EXE file association, you can modify the corresponding parameters to apply the modification of other key values. In addition, you can use the regdeletevalue function to delete the self-startup items.
Hkey;
Lpctstr data1 = "/" % 1/"% *"; // default open mode for EXE files, "% 1/" Table EXE file itself
DWORD lresult = regopenkeyex (hkey_classes_root, "exefile // shell // open // command", 0, key_write, & hkey );
If (lresult = error_success)
Regsetvalueex (hkey, "", null, REG_SZ, (lpbyte) data1, 9); // modify the key value
Regclosekey (hkey );
By now, the model of a virus killing tool has been initially completed. When you write your own code, you only need to replace the form parameters of the function in this article with the corresponding feature data of the target virus to be killed. This is a simple exclusive tool that can only deal with common trojans, worms, and other viruses. You should analyze the specific situation and expand the program functions as needed, for example, some Trojans are modified by win. INI, system. INI to achieve automatic operation, we need to delete the corresponding data in the Operation file. In addition, sometimes we need to add and terminate the service, uninstall the DLL module, and enter the ring0 operation. In short, I believe everyone can write their own virus and Trojan killing tools! Oh, is it a sense of accomplishment!
This is the method for killing Trojans and worms. Here is an example of how to kill the file virus.
Spam written N years ago
# Include <stdio. h>
# Include <windows. h>
Void usage (void );
Int enumdisk (void );
Int enumallfile (char * lpdir );
Int anivirus (char * lpfilename );
Int main (void)
{
Usage ();
Printf ("START scan disk.../N ");
Enumdisk ();
Return 1;
}
Int enumdisk (void)
{
Int I;
Char alldisk [3] [3] = {"C:", "d:", "E :"};
For (I = 0; I <3; I ++)
{
Enumallfile (alldisk);
}
Return 1;
}
Int enumallfile (char * lpdir)
{
Win32_find_data finddata;
Handle hfindfile = invalid_handle_value;
Char lpbuf [max_path], lptmp [max_path];
Char lpfilename [max_path];
Int intsize = 0;
Zeromemory (lpbuf, max_path );
Zeromemory (lptmp, max_path );
Zeromemory (lpfilename, max_path );
Strcpy (lpbuf, lpdir );
Strcat (lpbuf ,"//*.*");
Hfindfile = findfirstfile (lpbuf, & finddata );
If (hfindfile = invalid_handle_value)
{
Printf ("findfirstfile error, code: % d/N", getlasterror ());
Return 0;
}
While (findnextfile (hfindfile, & finddata )! = 0)
{
If (finddata. dwfileattributes = file_attribute_directory)
{
If (strncmp (finddata. cfilename, "..", 2) = 0)
{
Continue;
}
Strcpy (lptmp, lpdir );
Strcat (lptmp ,"//");
Strcat (lptmp, finddata. cfilename );
Enumallfile (lptmp );
}
Intsize = strlen (finddata. cfilename );
If (strcmp (finddata. cfilename + IntSize-4, ". EXE") = 0 | strcmp (finddata. cfilename + IntSize-4, ". EXE") = 0)
{
Printf ("Find a EXE file filename: % s/n", finddata. cfilename );
Strcpy (lpfilename, lpdir );
Strcat (lpfilename ,"//");
Strcat (lpfilename, finddata. cfilename );
Anivirus (lpfilename );
}
}
Return 1;
}
Void usage (void)
{
Printf ("Kill my virus, I don't like it/nready go! /N ");
Return;
}
Int anivirus (char * lpfilename)
{
Handle hfile = invalid_handle_value;
Handle hmap = NULL;
Lpvoid pfile = NULL;
Pimage_dos_header dosheader;
Pimage_nt_headers peheader;
Pimage_section_header sectionheader;
Char * sectionname = NULL;
DWORD * virusentry = NULL;
Byte * bttmp = NULL;
DWORD dwcount = 0;
DWORD dwentry = 0;
Int ecode;
Hfile = createfile (lpfilename, generic_read | generic_write, file_share_read, null, open_existing, file_attribute_archive, 0 );
If (hfile = invalid_handle_value)
{
Printf ("openfile error, code: % d/N", getlasterror ());
Return 0;
}
Hmap = createfilemapping (hfile, null, page_readwrite, null );
If (hmap = NULL)
{
Printf ("createfilemapping error, code: % d/N", getlasterror ());
Closehandle (hfile );
Return 0;
}
Pfile = mapviewoffile (hmap, file_map_read | file_map_write, null, null );
If (pfile = NULL)
{
Printf ("mapviewoffile error, code: % d/N", getlasterror ());
Closehandle (hmap );
Closehandle (hfile );
Return 0;
}
Dosheader = (pimage_dos_header) pfile;
_ Try
{
If (image_dos_signature! = Dosheader-> e_magic)
{
Unmapviewoffile (pfile );
Closehandle (hmap );
_ Leave;
}
Peheader = pimage_nt_headers (DWORD) pfile + dosheader-> e_lfanew );
_ Try
{
If (image_nt_signature! = Peheader-> signature)
{
Unmapviewoffile (pfile );
Closehandle (hmap );
_ Leave;
}
Sectionheader = (pimage_section_header) (DWORD) peheader + (peheader-> fileheader. NumberOfSections-1) * sizeof (image_section_header) + sizeof (image_nt_headers ));
Sectionname = (char *) & (sectionheader-> name );
If (strncmp (sectionname, ". Chi", 4 )! = 0)
{
Unmapviewoffile (pfile );
Closehandle (hmap );
_ Leave;
}
Printf ("virus detected, prepare to clear the virus/N ");
Virusentry = (DWORD *) (DWORD) pfile + sectionheader-> pointertorawdata );
For (dwcount = 0; dwcount <sectionheader-> sizeofrawdata/4; dwcount ++, virusentry ++)
{
If (* virusentry = 0x00401375)
{
// Printf ("find source program entry code features/N ");
Virusentry = virusentry + 6;
Bttmp = (byte *) virusentry;
Bttmp ++;
Virusentry = (DWORD *) bttmp;
Dwentry = * virusentry-peheader-> optionalheader. imagebase;
// Printf ("entry: 0x % x/N", dwentry );
Peheader-> optionalheader. addressofentrypoint = dwentry;
Peheader-> fileheader. numberofsections --;
Peheader-> optionalheader. sizeofimage = peheader-> optionalheader. sizeofimage-(sectionheader-> Misc. virtualsize/peheader-> optionalheader. Authorization + 1) * peheader-> optionalheader. sectionalignment;
Zeromemory (sectionheader-> name, 8 );
Ecode = setfilepointer (hfile, sectionheader-> pointertorawdata, 0, file_begin );
Unmapviewoffile (pfile );
Closehandle (hmap );
Ecode = setendoffile (hfile );
If (ecode! = 0)
{
Printf ("virus cleared successfully/N ");
}
Else
{
Printf ("virus cleanup failed, but the virus has been blocked/N ");
}
_ Leave;
}
}
}
_ Partition T (1)
{
_ Leave;
}
}
_ Finally
{
Closehandle (hfile );
}
Return 0;
}