|
发表于 2018-4-16 15:50:58
|
显示全部楼层
本楼为最佳答案
我什么也不想说
main.c
- #pragma warning(disable:4996)
- #include "PE_Functions.h"
- #include <stdio.h>
- #include <stdlib.h>
- #include <windows.h>
- #define FREE_SPACE 0x2000
- // *************************************************************************************
- IMAGE_IMPORT_DESCRIPTOR *g_dest_iid = NULL;
- IMAGE_THUNK_DATA *g_dest_itd = NULL;
- IMAGE_IMPORT_BY_NAME *g_dest_iibn = NULL;
- char *g_dest_string = NULL;
- // 使用全局变量 g_dest_string
- // 返回复制后的字符串的 RVA
- static DWORD MoveString(char *base, char *src)
- {
- DWORD ret = OffsetToRva(base, ((char *)g_dest_string - base));
-
- strcpy(g_dest_string, src);
- g_dest_string += strlen(g_dest_string) + 1; // g_dest_string 指向下一个
- return ret;
- }
- // 使用全局变量 g_dest_iibn
- static DWORD MoveImportByName(char *base, IMAGE_IMPORT_BY_NAME *src)
- {
- DWORD ret = OffsetToRva(base, ((char *)g_dest_iibn - base));
- g_dest_iibn->Hint = src->Hint;
- strcpy(g_dest_iibn->Name, src->Name);
- // 要确保 g_dest_iibn 指向下一个,由于结构体对齐,其他环境可能会出问题
- g_dest_iibn = (IMAGE_IMPORT_BY_NAME *)((char *)g_dest_iibn + sizeof(IMAGE_IMPORT_BY_NAME) + strlen(g_dest_iibn->Name) - 1);
- return ret;
- }
- // 使用全局变量 g_dest_itd
- // 返回复制后的 IMAGE_THUNK_DATA 结构的RVA
- static DWORD MoveThunkData(char *base, IMAGE_THUNK_DATA *src)
- {
- DWORD ret = OffsetToRva(base, ((char *)g_dest_itd - base));
- for(int i = 0; src[i].u1.AddressOfData != 0; ++i)
- {
- g_dest_itd->u1.AddressOfData = MoveImportByName(base, (IMAGE_IMPORT_BY_NAME *)(RvaToOffset(base, src[i].u1.AddressOfData) + base));
- ++g_dest_itd;
- }
- memset(g_dest_itd, 0, sizeof(IMAGE_THUNK_DATA)); // 最后一个全为0的结构
- ++g_dest_itd; // 指向下一个
- return ret;
- }
- // 使用全局变量 g_dest_iid
- static void MoveImportDescriptor(char *base, IMAGE_IMPORT_DESCRIPTOR *src)
- {
- for(int i = 0; src[i].Characteristics != 0; ++i)
- {
- g_dest_iid->OriginalFirstThunk = MoveThunkData(base, (IMAGE_THUNK_DATA *)(RvaToOffset(base, src[i].OriginalFirstThunk) + base));
- g_dest_iid->TimeDateStamp = src[i].TimeDateStamp; // 原样复制
- g_dest_iid->ForwarderChain = src[i].ForwarderChain; // 原样复制
- g_dest_iid->Name = MoveString(base, RvaToOffset(base, src[i].Name) + base);
- g_dest_iid->FirstThunk = src[i].FirstThunk; // FirstThunk 不做改变
- ++g_dest_iid;
- }
- memset(g_dest_iid, 0, sizeof(IMAGE_IMPORT_DESCRIPTOR)); // 最后一个全为0的结构
- ++g_dest_iid; // 指向下一个
- }
- // ----------------------------------------------------------------
- void DebugPrintImportByName(char *base, IMAGE_IMPORT_BY_NAME *iibn)
- {
- printf("\t\tiibn->Hint: %x\n", iibn->Hint);
- printf("\t\tiibn->Name: %s\n", iibn->Name);
- }
- void DebugPrintThunkData(char *base, IMAGE_THUNK_DATA *itd)
- {
- for(int i = 0; itd[i].u1.AddressOfData != 0; ++i)
- {
- printf("\t{\n");
- printf("\t\titd[i].u1.AddressOfData: %x\n", itd[i].u1.AddressOfData);
- DebugPrintImportByName(base, (IMAGE_IMPORT_BY_NAME *)(RvaToOffset(base, itd[i].u1.AddressOfData) + base));
- printf("\t}\n");
- }
- }
- void Debug(char *base)
- {
- IMAGE_DOS_HEADER *idh = (IMAGE_DOS_HEADER *)base;
- IMAGE_NT_HEADERS32 *inh = (IMAGE_NT_HEADERS32 *)(base + idh->e_lfanew);
- DWORD import_rva = inh->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
- IMAGE_IMPORT_DESCRIPTOR *iid = (IMAGE_IMPORT_DESCRIPTOR *)(base + RvaToOffset(base, import_rva));
- for(int i = 0; iid[i].Characteristics != 0; ++i)
- {
- printf("{\n");
- printf("\tiid[i].OriginalFirstThunk: %x\n", iid[i].OriginalFirstThunk);
- DebugPrintThunkData(base, (IMAGE_THUNK_DATA *)(RvaToOffset(base, iid[i].OriginalFirstThunk) + base));
- printf("}\n");
- printf("iid[i].TimeDateStamp: %x\n", iid[i].TimeDateStamp);
- printf("iid[i].ForwarderChain: %x\n", iid[i].ForwarderChain);
- printf("iid[i].Name: %x\t\t\t%s\n", iid[i].Name, RvaToOffset(base, iid[i].Name) + base);
- printf("{\n");
- printf("\tiid[i].FirstThunk: %x\n", iid[i].FirstThunk);
- DebugPrintThunkData(base, (IMAGE_THUNK_DATA *)(RvaToOffset(base, iid[i].FirstThunk) + base));
- printf("}\n");
- printf("------------------------------------------------\n");
- }
- }
- // ----------------------------------------------------------------
- // 将导入表移动到 ish 指向的区块
- void MoveImportTable(char *base, IMAGE_SECTION_HEADER *ish)
- {
- // 0x00 - 0x1FF 存放 IMAGE_IMPORT_DESCRIPTOR
- // 0x200 - 0x3FF 存放 IMAGE_THUNK_DATA
- // 0x400 - 0x9FF 存放 IMAGE_IMPORT_BY_NAME
- // 0xa00 - 0xaFF 存放 dll字符串(ASCII 字符串)
- // 初始化全局变量
- char *data = (char *)(base + ish->PointerToRawData);
- g_dest_iid = (IMAGE_IMPORT_DESCRIPTOR *)(data + 0x00);
- g_dest_itd = (IMAGE_THUNK_DATA *)(data + 0x200);
- g_dest_iibn = (IMAGE_IMPORT_BY_NAME *)(data + 0x400);
- g_dest_string = (char *)(data + 0xa00);
- IMAGE_DOS_HEADER *idh = (IMAGE_DOS_HEADER *)base;
- IMAGE_NT_HEADERS32 *inh = (IMAGE_NT_HEADERS32 *)(base + idh->e_lfanew);
- DWORD import_rva = inh->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
- IMAGE_IMPORT_DESCRIPTOR *iid = (IMAGE_IMPORT_DESCRIPTOR *)(base + RvaToOffset(base, import_rva));
- MoveImportDescriptor(base, iid);
- // 修正数据目录表
- inh->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress = OffsetToRva(base, ish->PointerToRawData);
- }
- // *************************************************************************************
- int main(void)
- {
- //char *filename = "NewHello.exe";
- //CopyFile("Hello.exe", "NewHello.exe", FALSE);
-
- char *filename = "NewMessageBox.exe";
- CopyFile("MessageBox.exe", "NewMessageBox.exe", FALSE);
- HANDLE hFile = CreateFile(filename, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
- if(hFile == INVALID_HANDLE_VALUE)
- {
- printf("Could not open: %s", filename);
- exit(1);
- }
-
- DWORD orig_file_size = GetFileSize(hFile, NULL);
-
- HANDLE hMap = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, orig_file_size + FREE_SPACE, NULL);
- LPVOID pMem = MapViewOfFile(hMap, FILE_MAP_WRITE | FILE_MAP_READ | FILE_MAP_COPY, 0, 0, 0);
- MoveImportTable(pMem, (IMAGE_SECTION_HEADER *)(AddSection(pMem, "hello", 0xb00) + (char *)pMem));
- UnmapViewOfFile(pMem);
- CloseHandle(hMap);
- CloseHandle(hFile);
- return 0;
- }
复制代码
PE_Functions.c
- #pragma warning(disable:4996)
- #include "PE_Functions.h"
- #include <windows.h>
- #include <time.h>
- DWORD PE_Align(DWORD tar_num, DWORD align_to)
- {
- DWORD n = tar_num / align_to;
- if(n * align_to < tar_num)
- ++n;
- return n * align_to;
- }
- DWORD RvaToOffset(LPVOID base, DWORD rva)
- {
- IMAGE_DOS_HEADER *idh = (IMAGE_DOS_HEADER *)base;
- IMAGE_NT_HEADERS32 *inh = (IMAGE_NT_HEADERS32 *)((char *)base + idh->e_lfanew);
- IMAGE_SECTION_HEADER *ish = (IMAGE_SECTION_HEADER *)(inh + 1);
- for(int i = 0; i < inh->FileHeader.NumberOfSections; ++i)
- {
- if((ish[i].VirtualAddress <= rva) && (rva < ish[i].VirtualAddress + ish[i].SizeOfRawData))
- {
- return rva - ish[i].VirtualAddress + ish[i].PointerToRawData;
- }
- }
- return -1;
- }
- DWORD OffsetToRva(LPVOID base, DWORD offset)
- {
- IMAGE_DOS_HEADER *idh = (IMAGE_DOS_HEADER *)base;
- IMAGE_NT_HEADERS32 *inh = (IMAGE_NT_HEADERS32 *)((char *)base + idh->e_lfanew);
- IMAGE_SECTION_HEADER *ish = (IMAGE_SECTION_HEADER *)(inh + 1);
- for(int i = 0; i < inh->FileHeader.NumberOfSections; ++i)
- {
- if((ish[i].PointerToRawData <= offset) && (offset < ish[i].PointerToRawData + ish[i].SizeOfRawData))
- {
- return offset - ish[i].PointerToRawData + ish[i].VirtualAddress;
- }
- }
- return -1;
- }
- // **************************************************************************************
- static DWORD GetVirtualAddress(IMAGE_NT_HEADERS32 *inh, IMAGE_SECTION_HEADER *ish)
- {
- DWORD address = ish[inh->FileHeader.NumberOfSections - 1].VirtualAddress;
- DWORD size = ish[inh->FileHeader.NumberOfSections - 1].Misc.VirtualSize;
- return address + size;
- }
- static DWORD GetPointerToRawData(IMAGE_NT_HEADERS32 *inh, IMAGE_SECTION_HEADER *ish)
- {
- DWORD address = ish[inh->FileHeader.NumberOfSections - 1].PointerToRawData;
- DWORD size = ish[inh->FileHeader.NumberOfSections - 1].SizeOfRawData;
- return address + size;
- }
- // 返回值为 新增区块表的偏移
- DWORD AddSection(LPVOID base, const char *section_name, DWORD section_size)
- {
- IMAGE_DOS_HEADER *idh = (IMAGE_DOS_HEADER *)base;
- IMAGE_NT_HEADERS32 *inh = (IMAGE_NT_HEADERS32 *)((char *)base + idh->e_lfanew);
- IMAGE_SECTION_HEADER *ish = (IMAGE_SECTION_HEADER *)(inh + 1);
- DWORD ret = (DWORD)((char *)&ish[inh->FileHeader.NumberOfSections] - (char *)base);
- strncpy(ish[inh->FileHeader.NumberOfSections].Name, section_name, 8);
- ish[inh->FileHeader.NumberOfSections].Misc.VirtualSize = section_size;
- ish[inh->FileHeader.NumberOfSections].VirtualAddress = PE_Align(GetVirtualAddress(inh, ish), inh->OptionalHeader.SectionAlignment);
- ish[inh->FileHeader.NumberOfSections].SizeOfRawData = PE_Align(section_size, inh->OptionalHeader.FileAlignment);
- ish[inh->FileHeader.NumberOfSections].PointerToRawData = PE_Align(GetPointerToRawData(inh, ish), inh->OptionalHeader.FileAlignment);
- ish[inh->FileHeader.NumberOfSections].PointerToRelocations = 0;
- ish[inh->FileHeader.NumberOfSections].PointerToLinenumbers = 0;
- ish[inh->FileHeader.NumberOfSections].NumberOfRelocations = 0;
- ish[inh->FileHeader.NumberOfSections].NumberOfLinenumbers = 0;
- ish[inh->FileHeader.NumberOfSections].Characteristics = 0xE00000E0; // 可读可写可执行
- // 对数据区填0
- RtlZeroMemory((char *)base + ish[inh->FileHeader.NumberOfSections].PointerToRawData, ish[inh->FileHeader.NumberOfSections].SizeOfRawData);
- inh->FileHeader.TimeDateStamp = (DWORD)time(NULL); // 修改时间戳
- inh->OptionalHeader.SizeOfImage =
- PE_Align(ish[inh->FileHeader.NumberOfSections].VirtualAddress + ish[inh->FileHeader.NumberOfSections].Misc.VirtualSize,
- inh->OptionalHeader.SectionAlignment); // 调整 SizeOfImage
- inh->FileHeader.NumberOfSections += 1; // 区块个数加1
- return ret;
- }
- // **************************************************************************************
复制代码
PE_Functions.h
- #ifndef _PE_FUNCTIONS_H_
- #define _PE_FUNCTIONS_H_
- #include <windows.h>
- DWORD PE_Align(DWORD tar_num, DWORD align_to);
- DWORD RvaToOffset(LPVOID base, DWORD rva);
- DWORD OffsetToRva(LPVOID base, DWORD offset);
- // 返回值为 新增区块表的偏移
- DWORD AddSection(LPVOID base, const char *section_name, DWORD section_size);
- #endif
复制代码
|
|