// mfc.dll中间插入段.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include "windows.h"
#include "winternl.h"
#include <iostream>
#include <strsafe.h>
BOOL Str_cmp(char* a, char* b, long len)
{
for (int i = 0; i < len; i++)
{
if (0 == b[i])
return true;
if (a[i] != b[i])
return false;
}
return false;
}
int main()
{
UINT32 file_len;
void* file_data;
UINT32 File_len = 0;
void* File_data = 0;
void* addr = 0;
ULONG ret_len;
DWORD dwRet = 0;
HMODULE dll地址 = 0;
DWORD Remained_size = 0;
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
PIMAGE_SECTION_HEADER prsrcSection = NULL;
PIMAGE_FILE_HEADER pPEHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = NULL;
HANDLE hfile = CreateFileW(L"mfcdll.dll", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
//system("pause\n");
if (INVALID_HANDLE_VALUE == hfile) {
//GetLastError函数是取出当前线程调用的函数最近发生的一个错误的错误码
printf("CreateFileW fail with %u\n", GetLastError());
Sleep(-1);
}
//system("pause\n");
file_len = GetFileSize(hfile, 0);
if (INVALID_FILE_SIZE == file_len) {
//判断函数失败, 则输出失败代码, 这是编程的好习惯, 便于修正bug
printf("GetFileSize fail with %u\n", GetLastError());
Sleep(-1);
}
file_data = malloc(file_len);
if (0 == file_data) {
//malloc在进程内存严重不足的时候, 会返回0,表示申请内存失败, 当然这是比较极端的情况
printf("malloc fail\n");
Sleep(-1);
}
dwRet = ReadFile(hfile, file_data, file_len, &ret_len, 0);
if (!dwRet) {
printf("读取addr失败\n");
Sleep(-1);
}
File_len = file_len + 0x1000;
File_data = malloc(File_len);
if (0 == File_data) {
//malloc在进程内存严重不足的时候, 会返回0,表示申请内存失败, 当然这是比较极端的情况
printf("malloc fail\n");
Sleep(-1);
}
else {
memset(File_data, 0, File_len);
memcpy(File_data, file_data, file_len);
}
if (*(UINT16*)File_data != IMAGE_DOS_SIGNATURE)
{
printf("PE头标志不对\n");
Sleep(-1);
}
pDosHeader = (PIMAGE_DOS_HEADER)File_data;
if (*((PDWORD)((DWORD)(File_data)+pDosHeader->e_lfanew)) != IMAGE_NT_SIGNATURE)
{
printf("NT头标志不对\n");
Sleep(-1);
}
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)File_data + pDosHeader->e_lfanew);
pPEHeader = &pNTHeader->FileHeader;
pOptionalHeader = &pNTHeader->OptionalHeader;
pSectionHeader = (PIMAGE_SECTION_HEADER)((ULONG_PTR)pNTHeader + sizeof(IMAGE_NT_HEADERS));
int n = -1;
int section_len = 0x1000;
for (int i = pNTHeader->FileHeader.NumberOfSections - 1; i >= 0; i--)
{
pSectionHeader[i].VirtualAddress = pSectionHeader[i].VirtualAddress + 0x1000;
memcpy((UINT8*)File_data + pSectionHeader[i].PointerToRawData + 0x1000, (UINT8*)File_data + pSectionHeader[i].PointerToRawData, pSectionHeader[i].SizeOfRawData);
pSectionHeader[i].PointerToRawData = pSectionHeader[i].PointerToRawData+0x1000;
memcpy(&pSectionHeader[i + 1], &pSectionHeader[i], sizeof(pSectionHeader[i]));
if (Str_cmp((char*)pSectionHeader[i].Name, (char*)".rsrc", 8))
{
n = i;
printf("获取插入位置索引成功\n");
break;
}
}
if (-1 == n)
{
printf("获取插入位置索引失败\n");
Sleep(-1);
}
pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress += 0x1000;//重定位表偏移+0x1000
pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress += 0x1000;//资源表偏移+0x1000
//system("pause\n");
const char* szResName[0x11] = { 0,"Corsor","Bitmap","Icon","Menu","Dialog","StringTable","FontDir","Font","Accelerator","RCDATA","MessageTable","GroupCursor","zz","GroupIcon","xx","Version"};
PIMAGE_RESOURCE_DIRECTORY pResDir1 = (PIMAGE_RESOURCE_DIRECTORY)((DWORD)File_data + pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress);
PIMAGE_RESOURCE_DIRECTORY_ENTRY pResDirEntry1 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pResDir1 + 1);
DWORD dwTypeCount = pResDir1->NumberOfIdEntries + pResDir1->NumberOfNamedEntries;
//system("pause\n");
for (DWORD i = 0; i < dwTypeCount; i++)
{
if (!(pResDirEntry1[i].NameIsString))//最高位为0
{
if (pResDirEntry1[i].Id < 0x11)
{
//printf("资源类型ID:%d %s\n", pResDirEntry1[i].Id, szResName[pResDirEntry1[i].Id]);
}
else
{
//printf("资源类型ID:%d\n", pResDirEntry1[i].Id);
}
}
else //最高位为1
{
//显示资源字符串
//NameOffset为相对资源文件的偏移
//字符串偏移为:资源基地址 + NameOffset
PIMAGE_RESOURCE_DIR_STRING_U pStr = (PIMAGE_RESOURCE_DIR_STRING_U)((DWORD)pResDir1 + pResDirEntry1[i].NameOffset);
WCHAR szStr[MAX_PATH] = { 0 };
memcpy(szStr, pStr->NameString, pStr->Length * sizeof(WCHAR));
//printf("资源类型:%ls\n", szStr);
}
system("pause\n");
// 解析第二层
if (pResDirEntry1[i].DataIsDirectory==1 )//最高位为1
{
//printf("第二层目录偏移:%x\n", pResDirEntry1[i].OffsetToDirectory);
PIMAGE_RESOURCE_DIRECTORY pResDir2 = (PIMAGE_RESOURCE_DIRECTORY)((DWORD)pResDir1 + pResDirEntry1[i].OffsetToDirectory);
PIMAGE_RESOURCE_DIRECTORY_ENTRY pResDirEntry2 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pResDir2 + 1);
DWORD dwCount = pResDir2->NumberOfIdEntries + pResDir2->NumberOfNamedEntries;
for (DWORD j = 0; j < dwCount; j++)
{
if (pResDirEntry2[j].NameIsString == 0)//最高位为0
{
//printf(" ->资源标识ID:%d\n", pResDirEntry2[j].Id);
}
else//最高位为1
{
//显示资源字符串
//NameOffset为相对资源文件的偏移
//字符串偏移为:资源基地址 + NameOffset
PIMAGE_RESOURCE_DIR_STRING_U pStr = (PIMAGE_RESOURCE_DIR_STRING_U)((DWORD)pResDir1 + pResDirEntry2[j].NameOffset);
WCHAR szStr[MAX_PATH] = { 0 };
memcpy(szStr, pStr->NameString, pStr->Length * sizeof(WCHAR));
//printf(" ->资源名称:%ls\n", szStr);
}
//解析第三层
PIMAGE_RESOURCE_DIRECTORY pResDir3 = (PIMAGE_RESOURCE_DIRECTORY)((DWORD)pResDir1 + pResDirEntry2[j].OffsetToDirectory);
PIMAGE_RESOURCE_DIRECTORY_ENTRY pResDirEntry3 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pResDir3 + 1);
//printf(" -->代码页标号为:%x\n", pResDirEntry3->Id);
if (pResDirEntry3->DataIsDirectory==0)//最高位为0
{
PIMAGE_RESOURCE_DATA_ENTRY pResDataEntry = (PIMAGE_RESOURCE_DATA_ENTRY)((DWORD)pResDir1 + pResDirEntry3->OffsetToData);
//printf(" --数据RVA:%x\n", pResDataEntry->OffsetToData);
//printf(" --数据大小:%x\n", pResDataEntry->Size);
pResDataEntry->OffsetToData += 0x1000;
}
}
}
else//最高位为0
{
//取数据偏移,显示数据
PIMAGE_RESOURCE_DATA_ENTRY pResData = (PIMAGE_RESOURCE_DATA_ENTRY)((ULONG_PTR)pResDir1 + pResDirEntry1[i].OffsetToData);
//printf(" -->数据 RVA:%p\n", pResData->OffsetToData);
//printf(" -->数据偏移:%p\n", RVA2FOA(pResData->OffsetToData, nt_header));
//printf(" -->数据大小:%p\n", pResData->Size);
pResData->OffsetToData += 0x1000;
}
}
Remained_size = (DWORD)(pOptionalHeader->SizeOfHeaders - pDosHeader->e_lfanew - 4 - IMAGE_SIZEOF_FILE_HEADER - pPEHeader->SizeOfOptionalHeader - IMAGE_SIZEOF_SECTION_HEADER * pPEHeader->NumberOfSections);
if (Remained_size < 2 * IMAGE_SIZEOF_SECTION_HEADER) {
printf("文件头剩余空间不足\n");
free(File_data);
Sleep(-1);
}
//初始化节表信息
PVOID pSecName = &pSectionHeader[n].Name;
PDWORD pSecMisc = &pSectionHeader[n].Misc.VirtualSize;
PDWORD pSecVirtualAddress = &pSectionHeader[n].VirtualAddress;
PDWORD pSecSizeofRawdate = &pSectionHeader[n].SizeOfRawData;
PDWORD pSecPointertoRawData = &pSectionHeader[n].PointerToRawData;
pNTHeader->FileHeader.NumberOfSections = pNTHeader->FileHeader.NumberOfSections + 1;
//新段表名
memcpy(pSecName, ".newsec", 8);
for(int i=0;i< pNTHeader->FileHeader.NumberOfSections;i++)
printf("%s\n", pSectionHeader[i].Name);
HANDLE hFile = CreateFileW(L"New_mfcdll.dll", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
if (hFile == INVALID_HANDLE_VALUE)
{
printf("CreateFileW fail with %u\n", GetLastError());
Sleep(-1);
}
dwRet = WriteFile(hFile, File_data, File_len, &ret_len, NULL);
if (!dwRet)
{
printf("Write Virus DosHeader Failed\r\n");
Sleep(-1);
}
else {
printf("文件写入成功\n");
if (!ReadFile(hFile, File_data, File_len, &ret_len, 0)) {
printf("ReadFile fail with %u\n", GetLastError());
}
else {
dll地址 = LoadLibraryA("New_mfcdll.dll");
//dll地址 = LoadLibraryA("E:\\工作\\学习和例子\\mfc.dll中间插入段\\Release\\New_mfcdll.dll");
//dll地址 = LoadLibraryW(L"New_mfcdll.dll");
printf("一切都成功,则内存加载dll\n");
}
}
if (0 == dll地址)
{
printf("dll加载失败, 可能是路径不对\n");
}
else
{
printf("dll加载成功\n");
}
CloseHandle(hfile);
CloseHandle(hFile);
Sleep(0xFFFFFFFF);
}