[vc] dll永久注入exe文件
本帖最后由 舒默哦 于 2020-5-22 20:07 编辑https://static.52pojie.cn/static/image/hrline/1.gif
说明:
就是把dll文件拉伸贴在exe文件后面,先执行dll,然后跳回主程序入口继续执行。(其实,dll想什么时候执行就什么时候执行,具体看需求)
https://static.52pojie.cn/static/image/hrline/1.gif
遇到的问题:
这儿修复IAT表,不能是静态修复,因为计算机每次重启,系统dll映射到exe程序所在的地址都会变,IAT表必须动态修复。
修复IAT表需要用到"LoadLibraryA"和GetProcAddress两个函数,这两个函数存在于KERNEL32这个DLL中,
可以通过FS寄存器找到进程环境块PEB,得到kernel32的地址,找到GetProcAddress函数所在地址,再通过GetProcAddress找到LoadLibraryA的地址。
https://static.52pojie.cn/static/image/hrline/1.gif
具体步骤:
1、分别加载exe和dll到内存
2、给exe添加新节
3、处理dll(拉伸dll和以及修复重定位表)
4、申请新内存(大小=exe文件大小+新节大小)
5、获取dll的入口函数的指针
6、构造ShellCode
7、修改程序入口,跳到ShellCode地址处执行
8、保存文件
https://static.52pojie.cn/static/image/hrline/1.gif
实验测试文件用到了LoadPE.exe和test_dll.dll,最后输出的文件是newfile.exe。
test_dll.dll
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
{
CString str = "\t注入成功!!!!!\r\n\r\n";
str = str + "\tDLL模块在进程空间中的起始地址:" + (DWORD)hModule;
MessageBox(NULL, str.GetString(), "恭喜", MB_OK);
}
case DLL_THREAD_ATTACH:
//MessageBox(NULL, "DLL_THREAD_ATTACH", "", MB_OK);
case DLL_THREAD_DETACH:
//MessageBox(NULL, "DLL_THREAD_DETACH", "", MB_OK);
case DLL_PROCESS_DETACH:
//MessageBox(NULL, "DLL_PROCESS_DETACH", "", MB_OK);
break;
}
return TRUE;
}
main.cpp
#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
#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);
//处理dll的函数
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()
{
//1.0 把exe文件加载到内存
DWORD pFileBuf_exe = 0;//exe在内存中的地址
DWORD FileSize_exe = 0;//exe的内存大小
DWORD FileSize_exe_1 = 0;//exe的文件大小
if (GetBuffAddrAndSizeofFile((char*)path_exe, &pFileBuf_exe, &FileSize_exe, &FileSize_exe_1) == 0)
{
return;
}
//1.1 把dll文件加载到内存
DWORD pFileBuf_dll = 0;//dll在内存中的地址
DWORD FileSize_dll = 0;//dll的内存大小
DWORD FileSize_dll_1 = 0;//dll的文件大小
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;
//2.添加新节
addSeciton(pFileBuf_exe, NewSectionSize);
//3.处理dll(拉伸dll和修复重定位表)
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);
//4.申请新内存 = exe文件大小 + 新节大小
DWORD nLength = FileSize_exe_1 + NewSectionSize;
char* TotalBuff = new char;
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));
// 5.获取DLL的入口函数的指针 = exe的基址 + exe添加新节前的内存对齐后的大小 + dll入口
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;
//6.构造shellcode
//call GetKernel32Addr
//E8 XXXXXXXX = 要跳转的地址-E8所在的地址-5
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;
//call MyGetProcessAddress
//E8 XXXXXXXX = 要跳转的地址-E8所在的地址-5
DWORD s_MyGetProcessAddress = temp + sizeof(Getkernel32Addr) - (temp + temp_1 + 0x14) - 5;
//call RebuildImportTable
//E8 XXXXXXXX = 要跳转的地址-E8所在的地址-5
DWORD s_RebuildImportTable = temp + sizeof(Getkernel32Addr) + sizeof(GetprocessAddress) -
(temp + temp_1 + 0x38) - 5;
//call DllFunc 调用dll
//E8 XXXXXXXX = 要跳转的地址-E8所在的地址-5
DWORD DllFunc = DllEntry - (temp + temp_1 + 0x49) - 5;
//"GetProcAddress"字符串所在的地址
DWORD GPA = pNtHeader->OptionalHeader.ImageBase + FileSize_exe + NewSectionSize - 0x40;
//"LoadLibraryA"字符串所在的地址
DWORD LLA= pNtHeader->OptionalHeader.ImageBase + FileSize_exe + NewSectionSize - 0x30;
//DLL模块在进程虚拟空间中的起始地址
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,0x2F,0x7C,0xCE,0xFF,
0xE8,
s_GetKernel32Addr & 0xFF,(s_GetKernel32Addr & 0xFF00) >> 8,(s_GetKernel32Addr & 0xFF0000) >> 16,s_GetKernel32Addr >> 24,
0x89,0x45,0xFC,
0x68,//0x00,0x00,0x89,0x00,
GPA & 0xFF,(GPA & 0xFF00) >> 8,(GPA & 0xFF0000) >> 16,GPA >> 24,
0x50,
//0xE8,0x21,0x7C,0xFE,0xFF,
0xE8,
s_MyGetProcessAddress & 0xFF,(s_MyGetProcessAddress & 0xFF00) >> 8,(s_MyGetProcessAddress & 0xFF0000) >> 16,s_MyGetProcessAddress >> 24,
0x83,0xC4,0x08,
0x89,0x45,0xF8,
0x68,//0x00,0x00,0x45,0x00,
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,0xFB,0x7B,0xC3,0xFF,
0xE8,
s_RebuildImportTable & 0xFF,(s_RebuildImportTable & 0xFF00) >> 8,(s_RebuildImportTable & 0xFF0000) >> 16,s_RebuildImportTable >> 24,
0x83,0xC4,0x04,
0x6A,0x00,
0x6A,0x01,
0x68,//0x00,0x00,0x40,0x00,
DLLAddr & 0xFF,(DLLAddr & 0xFF00) >> 8,(DLLAddr & 0xFF0000) >> 16,DLLAddr >> 24,
//0xE8,0xEA,0x7B,0xBE,0x04,
0xE8,
DllFunc & 0xFF,(DllFunc & 0xFF00) >> 8,(DllFunc & 0xFF0000) >> 16,DllFunc >> 24,
0x68,
//0x00,0x00,0x04,0x00,
jmp_orig & 0xFF,(jmp_orig & 0xFF00) >> 8,(jmp_orig & 0xFF0000) >> 16,jmp_orig >> 24,
0xC3
};
//计算shellcode存放的地址
DWORD Addr = (DWORD)TotalBuff + FileSize_exe_1 + NewSectionSize - 0x100;
for (int i = 0; i < sizeof(ShellCode); i++)
{
((char*)Addr) = ShellCode;
}
//7.修改入口
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;
//8.保存文件
SaveFile((DWORD)TotalBuff, nLength);
}
int main()
{
File_Forever_Inject();
system("pause");
return 0;
}
//处理dll的函数
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);
//1.1 根据内存大小 申请内存
char* NewFileBuff = new char;
if (NewFileBuff==NULL)
{
printf("内存申请失败!");
return 0;
}
memset(NewFileBuff, 0, FileSize);
//1.2 拉伸文件
// 拷贝DOS头 + DOS STUB + PE头到headers地址处
memcpy(NewFileBuff, pDosHeader, pNtHeader->OptionalHeader.SizeOfHeaders);
// 从dll文件内容中拷贝每个section(节)的数据到新的内存区域
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);
}
//1.3 修复重定位表
// 检查加载到进程地址空间的位置和之前PE文件中指定的基地址是否一致,如果不一致,则需要重定位
int locationDelta = (SIZE_T)((DWORD)BaseAddress - pNtHeader->OptionalHeader.ImageBase);
if (locationDelta != 0)
{
//修复重定位表
PerformBaseRelocation((char*)NewFileBuff, locationDelta);
}
//1.4 修复IAT表
// 加载依赖dll,并构建"PEHeader.OptionalHeader.DataDirectory.Image_directory_entry_import"导入表
/*if (!RebuildImportTable((char*)NewFileBuff, myLoadLibrary, myGetProcAddress))
{
printf("修复失败!");
return 0;
}*/
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);
//1.1 根据内存大小 申请内存
char* NewFileBuff = new char;
if (NewFileBuff == NULL)
{
printf("内存申请失败!");
return 0;
}
memset(NewFileBuff, 0, FileSize);
//1.2 拉伸文件
// 拷贝DOS头 + DOS STUB + PE头到headers地址处
memcpy(NewFileBuff, pDosHeader, pNtHeader->OptionalHeader.SizeOfHeaders);
// 从dll文件内容中拷贝每个section(节)的数据到新的内存区域
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)
{
//1.1 获取文件句柄
HANDLE hFile = CreateFile(
FilePath,
GENERIC_READ,
0,
NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
//1.2 获取文件大小
DWORD dwFileSize = GetFileSize(hFile, NULL);
CHAR *pFileBuf = new CHAR;
memset(pFileBuf, 0, dwFileSize);
//1.3 将文件读取到内存
DWORD ReadSize = 0;
ReadFile(hFile, pFileBuf, dwFileSize, &ReadSize, NULL);
//1.4 关闭句柄
CloseHandle(hFile);
//2.1 判断是否为PE文件
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;
}
//2.2 把文件的在内存中的地址和大小分别赋值输出参数
*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);
//判断节表尾部是否有80个字节的空闲区域
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);
//space空间指的是节表最后都是0,没有其他数据,如果有其他数据,则即使满足了有80个字节的空间,也不能添加数据,这样会破坏其他数据
//如果空间不够,那么,doc头下面的垃圾数据不要了,后面的PE头 标准PE头 和节表上提;
//并且要判断pDosHeader->e_lfanew-64这段距离是否大于80,否则上提没有意义
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++)//把节表尾部80个字节格式化
*((char*)pFileBuff + 64 + i + len) = 0;
space = pDosHeader->e_lfanew - 64;//更新space空间
}
if (space > 80)
{
BYTE(*p) = &(pse_temp->Name);
int name = { 0x2E,0x74,0x74,0x74,0x74 };
for (int i = 0; i < 8; i++)
p = name;
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.Size > 0)
{
PIMAGE_BASE_RELOCATION relocation = (PIMAGE_BASE_RELOCATION)((DWORD)buff + pDataDirectory.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;
//the upper 4 bits define the type of relocation
type = *relInfo >> 12;
//the lower 12 bits define the offset
offset = *relInfo & 0xFFF;
switch (type)
{
case IMAGE_REL_BASED_ABSOLUTE:
//skip relocation
break;
case IMAGE_REL_BASED_HIGHLOW:
//change comlete 32 bit address
patchAddrHL = (PDWORD)(dest + offset);
*patchAddrHL += Value;
break;
default:
break;
}
}
//advance to next relocation block
relocation = PIMAGE_BASE_RELOCATION((DWORD)relocation + relocation->SizeOfBlock);
}
}
}
https://static.52pojie.cn/static/image/hrline/1.gif
结语:
newfile.exe能够在win10上运行,不能在win7上跑(32位和64位都失败)。
有低版本的编译器的老铁可以试一下,在支持win7的编译器上编译,然后在win7上跑看能不能跑得动
这是来骗C币的吗? {:301_974:}大佬大佬,膜拜一下 hj170520 发表于 2020-5-22 19:10
大佬大佬,膜拜一下
别这样,老铁 奇安信要拦截这个dll 纯学习一下吧,包装exe,典型的shellcode模式啊 不名物 发表于 2020-5-23 10:49
纯学习一下吧,包装exe,典型的shellcode模式啊
我只想到这种,还有其他方式吗?还有种方法是把dll分离出exe,放到一个临时文件加载后删掉,这样可以不用修复重定位和IAT表
页:
[1]