2007-03-31 08:35
--------------------------------------------------------------------------------
#define DEBUGMSG #include <windows.h> #include <windef.h> #include <string.h> #include <stdlib.h> #include <stdio.h> #include "Psapi.h" #pragma comment (lib,"Psapi.lib") #define erron GetLastError () TCHAR name[50]=; //保存虫虫的文件名+路径 FILE *Gfp=NULL; //输出到文件 BOOL ScanVXER (LPTSTR V_FileName,long V_FileOffset,int V_Length,TCHAR *V_Contents); //匹配特征码函数 BOOL ScanFileVXER (LPTSTR FileName); //文件遍历函数 BOOL ProcessVXER (void); //枚举进程函数 BOOL KillProc (DWORD ProcessID); //杀进程函数 BOOL EnablePrivilege(LPTSTR PrivilegeName); //提升权限函数 BOOL RegDelVXER (void); //删除注册表项函数 void Usage (LPCTSTR Parameter); //帮助函数 int main (int argc, TCHAR *argv[]) { if (argc!=2) { Usage(argv[0]); return 0; } #ifdef DEBUGMSG Gfp=fopen("VXER.txt","a+"); if (Gfp==NULL) { printf("Open /"VXER.txt/" fail/n"); return 0; } fprintf(Gfp,"%s/n/n","[-------------------------File list-------------------------]"); #endif if (strlen(argv[1])>10) { printf("Fine name no larger than /"10/"/n"); return 0; } if (!(ScanFileVXER(argv[1]))) { #ifdef DEBUGMSG printf("ScanFileVXER() GetLastError reports %d/n",erron); #endif fclose(Gfp); return 0; } if (!(ProcessVXER())) { #ifdef DEBUGMSG printf("ProcessesVXER() GetLastError reports %d/n",erron); #endif fclose(Gfp); return 0; } if (!(RegDelVXER())) { #ifdef DEBUGMSG printf("RegDelVXER() GetLastError reports %d/n",erron); #endif fclose(Gfp); return 0; } fclose(Gfp); return 0; } BOOL ScanFileVXER (LPTSTR FileName) { WIN32_FIND_DATA FindFileData; DWORD lpBufferLength=255; TCHAR lpBuffer[255]=; TCHAR DirBuffer[255]=; HANDLE hFind=NULL; UINT count=0; long FileOffset=0x1784; //偏移地址 int FileLength=0x77; //长度 TCHAR Contents[]={ 0x49, 0x20, 0x6A, 0x75, 0x73, 0x74, 0x20, 0x77, 0x61, 0x6E, 0x74, 0x20, 0x74, 0x6F, 0x20, 0x73, 0x61, 0x79, 0x20, 0x4C, 0x4F, 0x56, 0x45, 0x20, 0x59, 0x4F, 0x55, 0x20, 0x53, 0x41, 0x4E, 0x21, 0x21, 0x20, 0x62, 0x69, 0x6C, 0x6C, 0x79, 0x20, 0x67, 0x61, 0x74, 0x65, 0x73, 0x20, 0x77, 0x68, 0x79, 0x20, 0x64, 0x6F, 0x20, 0x79, 0x6F, 0x75, 0x20, 0x6D, 0x61, 0x6B, 0x65, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x70, 0x6F, 0x73, 0x73, 0x69, 0x62, 0x6C, 0x65, 0x20, 0x3F, 0x20, 0x53, 0x74, 0x6F, 0x70, 0x20, 0x6D, 0x61, 0x6B, 0x69, 0x6E, 0x67, 0x20, 0x6D, 0x6F, 0x6E, 0x65, 0x79, 0x20, 0x61, 0x6E, 0x64, 0x20, 0x66, 0x69, 0x78, 0x20, 0x79, 0x6F, 0x75, 0x72, 0x20, 0x73, 0x6F, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x21, 0x21}; //从冲击波中提取出来的,用做特征码 //获取系统目录的完整路径 if (GetSystemDirectory(DirBuffer,lpBufferLength)!=0) { if (SetCurrentDirectory(DirBuffer)!=0) //设置为当前目录 { hFind=FindFirstFile(FileName,&FindFileData); //查找文件 if (hFind==INVALID_HANDLE_VALUE) { #ifdef DEBUGMSG printf("FindFirstFile() GetLastError reports %d/n",erron); #endif if (hFind!=NULL) FindClose(hFind); return FALSE; } else { count++; //获得文件的完整路径 if (GetFullPathName(FindFileData.cFileName,lpBufferLength,lpBuffer,NULL)!=0) { #ifdef DEBUGMSG fprintf(Gfp,"File:/t/t%s/n",lpBuffer); #else printf("File:/t/t%s/n",lpBuffer); #endif } else { #ifdef DEBUGMSG printf("GetFullPathName() GetLastError reports %d/n",erron); #endif if (hFind!=NULL) FindClose(hFind); return FALSE; } } //进行特征码匹配工作 ScanVXER(FindFileData.cFileName,FileOffset,FileLength,Contents); } } while (FindNextFile(hFind,&FindFileData)) //继续查找文件 { count++; //以"."和".."除外 if (strcmp(".",FindFileData.cFileName)==0||strcmp("..",FindFileData.cFileName)==0) { #ifdef DEBUGMSG printf("File no include /"./" and /"../"/n"); #endif if (hFind!=NULL) FindClose(hFind); fclose(Gfp); exit(0); } if (GetFullPathName(FindFileData.cFileName,lpBufferLength,lpBuffer,NULL)!=0) { #ifdef DEBUGMSG fprintf(Gfp,"Next File:/t%s/n",lpBuffer); #else printf("Next File:/t%s/n",lpBuffer); #endif } else { #ifdef DEBUGMSG printf("GetFullPathName() GetLastError reports %d/n",erron); #endif if (hFind!=NULL) FindClose(hFind); fclose(Gfp); exit(0); } ScanVXER(FindFileData.cFileName,FileOffset,FileLength,Contents); } fprintf(Gfp,"/nFile Total:%d/n/n",count); fprintf(Gfp,"%s/n/n","[-------------------------File end---------------------------]/n"); printf("File Total:%d/n",count); //打印出查找到的文件各数 if (hFind!=NULL) FindClose(hFind); //关闭搜索句柄 return TRUE; } BOOL ScanVXER ( LPTSTR V_FileName, //文件名 long V_FileOffset, //偏移地址 int V_Length, //长度 TCHAR *V_Contents) //具体内容 { TCHAR FileContents[255]=; int cmpreturn=0; FILE *fp=NULL; fp=fopen(V_FileName,"rb"); //以二进制只读方式打开 if (fp==NULL) { #ifdef DEBUGMSG printf("fopen() File open FAIL/n"); #endif fclose(fp); return FALSE; } fseek(fp,V_FileOffset,SEEK_SET); //把文件指针指向特征码在文件的偏移地址处 fread(FileContents,V_Length,1,fp);//读取长度为特征码长度的内容 cmpreturn=memcmp(V_Contents,FileContents,V_Length); //进行特征码匹配。失败返回FALSE if (cmpreturn==0) { #ifdef DEBUGMSG printf("File match completely/n"); //打印文件匹配消息 #endif strcpy(name,V_FileName); //将文件名保存在全局变量name中 if (fp!=NULL) fclose(fp); return TRUE; } else { fclose(fp); return FALSE; } } BOOL ProcessVXER (void) { DWORD lpidProcess[1024]=; DWORD cbNeeded_1,cbNeeded_2; HANDLE hProc=NULL; HMODULE hMod[1024]=; TCHAR ProcFile[MAX_PATH]; TCHAR FileName[50]=; UINT Pcount=0; int i=0; EnablePrivilege(SE_DEBUG_NAME); //提升调试进程权限 fprintf(Gfp,"%s/n/n","[------------------------Process list--------------------------]"); strcpy(FileName,"C://WINNT//system32//"); strcat(FileName,name);//把文件名+路径复制到FileName变量中 //枚举进程 if (!(EnumProcesses(lpidProcess,sizeof(lpidProcess),&cbNeeded_1))) { #ifdef DEBUGMSG printf("EnumProcesses() GetLastError reports %d/n",erron); #endif if (hProc!=NULL) CloseHandle(hProc); return FALSE; } for (i=0;i<(int)cbNeeded_1/4;i++) { //打开找到的第一个进程 hProc=OpenProcess(PROCESS_ALL_ACCESS,FALSE,lpidProcess); if (hProc) { //枚举进程模块 if (EnumProcessModules(hProc,hMod,sizeof(hMod),&cbNeeded_2)) { //枚举进程模块文件名,包含全路径 if (GetModuleFileNameEx(hProc,hMod[0],ProcFile,sizeof(ProcFile))) { #ifdef DEBUGMSG fprintf(Gfp,"[%5d]/t%s/n",lpidProcess,ProcFile); #else printf("[%5d]/t%s/n",lpidProcess,ProcFile); //输出进程 #endif //可以考虑将其注释掉,这样就不会输出进程列表了 Pcount++; //查找进程中是否包含FileName if (strcmp(FileName,ProcFile)==0) { //如果包含,则杀掉。KillProc为自定义的杀进程函数 if (!(KillProc(lpidProcess))) { #ifdef DEBUGMSG printf("KillProc() GetLastError reports %d/n",erron); #endif if (hProc!=NULL) CloseHandle(hProc); fclose(Gfp); exit(0); } DeleteFile(FileName); //进程杀掉后,再将文件删除 } } } } } if (hProc!=NULL) CloseHandle(hProc); //关闭进程句柄 fprintf(Gfp,"/nProcess total:%d/n/n",Pcount); fprintf(Gfp,"%s/n/n","[------------------------Process end----------------------------]"); printf("/nProcess total:%d/n/n",Pcount); //打印进程各数 return TRUE; } BOOL KillProc (DWORD ProcessID) { HANDLE hProc=NULL; //打开由ProcessVXER()传递的进程PID hProc=OpenProcess(PROCESS_ALL_ACCESS,FALSE,ProcessID); if (hProc!=NULL) { //终止进程 if (!(TerminateProcess(hProc,0))) { #ifdef DEBUGMSG printf("TerminateProcess() GetLastError reports %d/n",erron); #endif CloseHandle(hProc); return FALSE; } } else { #ifdef DEBUGMSG printf("OpenProcess() GetLastError reports %d/n",erron); #endif return FALSE; } if (hProc!=NULL) CloseHandle(hProc); return TRUE; } BOOL EnablePrivilege(LPTSTR PrivilegeName) { HANDLE hProc=NULL,hToken=NULL; TOKEN_PRIVILEGES TP; hProc=GetCurrentProcess(); //打开当前进程的一个伪句柄 //打开进程访问令牌,hToken表示新打开的访问令牌标识 if(!OpenProcessToken(hProc,TOKEN_ADJUST_PRIVILEGES,&hToken)) { #ifdef DEBUGMSG printf("OpenProcessToken() GetLastError reports %d/n",erron); #endif goto Close; } //提升权限 if(!LookupPrivilegeValue(NULL,PrivilegeName,&TP.Privileges[0].Luid)) { #ifdef DEBUGMSG printf("LookupPrivilegeValue() GetLastError reports %d/n",erron); #endif goto Close; } TP.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED; TP.PrivilegeCount=1; //允许权限,主要根据TP这个结构 if(!AdjustTokenPrivileges(hToken,FALSE,&TP,sizeof(TP),0,0)) { #ifdef DEBUGMSG printf("AdjustTokenPrivileges() GetLastError reports %d/n",erron); #endif goto Close; } Close: if (hProc!=NULL) CloseHandle(hProc); if (hToken!=NULL) CloseHandle(hToken); return FALSE; if (hProc!=NULL) CloseHandle(hProc); if (hToken!=NULL) CloseHandle(hToken); return TRUE; } BOOL RegDelVXER (void) { HKEY hkey; DWORD ret=0; //打开注册表的Run项 ret=RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE//Microsoft//Windows//CurrentVersion//Run//", 0, KEY_ALL_ACCESS, &hkey); if (!(ret==ERROR_SUCCESS)) { #ifdef DEBUGMSG printf("RegOpenKeyEx() GetLastError reports %d/n",erron); #endif return FALSE; } //删除键值windows auto update。 ret=RegDeleteValue(hkey,"windows auto update"); if (ret==ERROR_SUCCESS) { #ifdef DEBUGMSG printf("Success Delete/n"); #endif } else { #ifdef DEBUGMSG printf("RegDeleteValue() GetLastError reports %d/n",erron); #endif RegCloseKey(hkey); //exit(0); } RegCloseKey(hkey); //关闭打开的注册表项 return TRUE; } void Usage (LPCTSTR Parameter) { LPCTSTR Path="%SystemRoot%//system32//"; fprintf(stderr,"============================================================================/n" " 杀毒软件的简单实现/n" "环境:Win2K Adv Server + Visual C++ 6.0/n" "作者:laoxie/n" "主页: www.vipshell.net/n" "OICQ:77199033/n" "邮件: dtzj@avl.com.cn/n" "使用方法:/n" "%s 文件名。例如:%s msblast.exe or %s *.exe /n/n" "注意事项:/n" "本程序只是简单介绍杀毒软件的编写方法,所以有很多不完善的地方,包括:/n" "1,本程序是以冲击波蠕虫做的例子/n" "2,文件遍历只搜索了%s目录下的文件/n" "3,本程序不能查杀冲击波变种/n/n" "本程序只是用做代码交流,如有错误,还请多多包含!/n" "============================================================================" ,Parameter,Parameter,Parameter,Path); } |