滴水逆向3期作业——新增一个节

// testt.cpp : Defines the entry point for the console application.
//
#define _CRT_SECURE_NO_WARNINGS
#include "stdafx.h"
#include <malloc.h>
#include <windows.h>
#include <string.h>

int Read2file(char* file_path,PVOID* FileBuffer);
DWORD CopyImageBufferToNewBuffer(PVOID pFileBuffer,PVOID* pNeweBuffer,DWORD file_size);
void StoreNewBuffer(PVOID pNewBuffer,DWORD new_file_size,char* save_path);

void add_new_section()
{	// 0.初始化
	PVOID pFileBuffer = NULL;
	PVOID pNewBuffer = NULL;
	DWORD file_size = 0;
	DWORD new_buffer_size = 0;

	// 1.从文件中读取/计算文件大小/开辟一段内存/写入内存中
	char file_path[] = "D:\\2020学习\\逆向\\IPMSG2007.exe";
	char save_path[] = "D:\\Lib\\IPMSG2007附件.exe";
	file_size = Read2file(file_path,&pFileBuffer);
	// printf("file_size:%d",file_size);
	
	// 2.将filebuffer修改后转存到newbuffer
	new_buffer_size = CopyImageBufferToNewBuffer(pFileBuffer,&pNewBuffer,file_size);
	
	// 3.将修改后的newbuffer存盘
	StoreNewBuffer(pNewBuffer,new_buffer_size,save_path);
}


// exe->filebuffer
int Read2file(char* file_path,PVOID* FileBuffer)
{	
	FILE* pfile = NULL;
	DWORD file_size = 0;
	PVOID pTempFileBuffer = NULL;
	
	// 打开文件需要判断
	pfile = fopen(file_path,"rb");
	if(!pfile)
	{
		printf("打开.exe文件失败!\n");
		return 0;
	}
	// 计算文件大小
	fseek(pfile,0,SEEK_END);
	file_size = ftell(pfile);
	fseek(pfile,0,SEEK_SET);
	// 分配动态内存
	pTempFileBuffer = (char*)malloc(file_size);
	if(!pTempFileBuffer)
	{
		printf("分配动态内存失败!\n");
		fclose(pfile);
		return 0;
	}
	// 将文件中的数据读取到动态内存中
	size_t n = fread(pTempFileBuffer,file_size,1,pfile);
	if(!n)
	{
		printf("读取文件数据到内存中失败!\n");
		fclose(pfile);
		free(pTempFileBuffer);
		return 0;
	}
	// 关闭文件
	*FileBuffer = pTempFileBuffer;
	pTempFileBuffer = NULL;  // 注意这里不能free
	fclose(pfile);
	return file_size;
}

// filebuffer->NEWbuffer
DWORD CopyImageBufferToNewBuffer(PVOID pFileBuffer,PVOID* pNewBuffer,DWORD file_size)
{
	PVOID pNewTempBuffer = NULL;
	DWORD New_file_size = 0;
	DWORD Remained_size = 0;
	// 初始化PE头部结构体
	PIMAGE_DOS_HEADER pDosHeader = NULL;
	PIMAGE_NT_HEADERS pNTHeader = NULL;
	PIMAGE_FILE_HEADER pPEHeader = NULL;
	PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = NULL;
	PIMAGE_SECTION_HEADER pSectionHeader = NULL;
	PIMAGE_SECTION_HEADER pLastSection = NULL;
// ====================判断是否为有效exe文件======================================
	// 判断filebuffer是否有效
	
	if(!pFileBuffer)
	{
		printf("读取filebuffer失败!\n");
		return 0;
	}
	// 判断是否可执行文件
	if(*((PWORD)pFileBuffer) != IMAGE_DOS_SIGNATURE)
	{
		printf("不含MZ标志,不是合法的exe文件!\n");
		return 0;
	}
	// 强制类型转换
	pDosHeader = PIMAGE_DOS_HEADER(pFileBuffer);
	// 判断是否含有PE标志
	if(*((PDWORD)((DWORD)pFileBuffer+pDosHeader->e_lfanew)) != IMAGE_NT_SIGNATURE)
	{
		printf("不是有效的PE标志!\n");	
		return 0;
	}

// ====================开辟新的内存空间,并拷贝到新的内存中======================
	// 开辟新的内存空间+0x1000
	New_file_size = file_size+0x1000;
	pNewTempBuffer = (PVOID)malloc(New_file_size);
	// 判断开辟空间是否成功
	if(!pNewTempBuffer)
	{
		printf("pNewTempBuffer开辟空间失败!\n");
		return 0;
	}
	// 初始化内存
	memset(pNewTempBuffer,0,New_file_size);
	// 将旧空间的内容copy到新的空间
	memcpy(pNewTempBuffer,pFileBuffer,file_size);

// ============================判断剩余的空间是否足够============================
	// 初始化PE头部结构体
	pDosHeader = (PIMAGE_DOS_HEADER)(pNewTempBuffer);
	pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pNewTempBuffer+pDosHeader->e_lfanew);
	pPEHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader+4);
	pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader+IMAGE_SIZEOF_FILE_HEADER);
	pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionalHeader+pPEHeader->SizeOfOptionalHeader);
	//最后一个节表的地址
	pLastSection = &pSectionHeader[pPEHeader->NumberOfSections-1];

	// 判断剩余的空间是否足够
	Remained_size = (DWORD)(pOptionalHeader->SizeOfHeaders-
		pDosHeader->e_lfanew-4-
		sizeof(PIMAGE_FILE_HEADER)-
		pPEHeader->SizeOfOptionalHeader-
		sizeof(PIMAGE_SECTION_HEADER)*pPEHeader->NumberOfSections);
	if(Remained_size < 2*sizeof(PIMAGE_SECTION_HEADER))
	{
		printf("exe文件头部剩余空间不足!\n");
		free(pNewTempBuffer);
		return 0;
	}
	
// ============================修改信息============================
	// 其他头部需要修改的内容
	PWORD pNumberOfSection = &pPEHeader->NumberOfSections;
	PDWORD pSizeOfImage = &pOptionalHeader->SizeOfImage;

	// 初始化新节表的信息
	PVOID pSecName = &pSectionHeader[pPEHeader->NumberOfSections].Name;
	PDWORD pSecMisc = &pSectionHeader[pPEHeader->NumberOfSections].Misc.VirtualSize;
	PDWORD pSecVirtualAddress = &pSectionHeader[pPEHeader->NumberOfSections].VirtualAddress;
	PDWORD pSecSizeofRawData = &pSectionHeader[pPEHeader->NumberOfSections].SizeOfRawData;
	PDWORD pSecPointerToRawData = &pSectionHeader[pPEHeader->NumberOfSections].PointerToRawData;
	PDWORD pSecCharacteristic = &pSectionHeader[pPEHeader->NumberOfSections].Characteristics;
	
	*pNumberOfSection = pPEHeader->NumberOfSections+1;
	printf("*pNumberOfSection:%#X\n",pPEHeader->NumberOfSections);
	*pSizeOfImage = pOptionalHeader->SizeOfImage+0x1000;
	// printf("pSizeOfImage:%#X\n",*pSizeOfImage);

	// 向节表中填入数据
	memcpy(pSecName,".newSec",8);
	*pSecMisc = 0x1000;
	//最后一个节表中VirtualAddress+max(VirtualSize,SizeOfRawData)
	
	DWORD add_size = pLastSection->Misc.VirtualSize > pLastSection->SizeOfRawData?
		pLastSection->Misc.VirtualSize:pLastSection->SizeOfRawData;
	/*
	printf("NumberOfSections:%d\n",pPEHeader->NumberOfSections);
	printf("virtualAddress:%X\n",pSectionHeader[pPEHeader->NumberOfSections-2].VirtualAddress);
	printf("add_size:%#X\n",add_size);
	return 0;*/

	*pSecVirtualAddress = pLastSection->VirtualAddress+add_size;
	//SectionAlignment对齐
	if(*pSecVirtualAddress % pOptionalHeader->SectionAlignment)
	{
		*pSecVirtualAddress = *pSecVirtualAddress / pOptionalHeader->SectionAlignment * pOptionalHeader->SectionAlignment+pOptionalHeader->SectionAlignment;
	}
	*pSecSizeofRawData = 0x1000;
	*pSecPointerToRawData = pLastSection->PointerToRawData+pLastSection->SizeOfRawData;
	// FILEAlignment对齐
	if(*pSecPointerToRawData % pOptionalHeader->FileAlignment)
	{
		*pSecPointerToRawData = (*pSecPointerToRawData) / pOptionalHeader->FileAlignment * pOptionalHeader->FileAlignment + pOptionalHeader->FileAlignment;
	}
	*pSecCharacteristic = 0xFFFFFFFF;
	
	*pNewBuffer = pNewTempBuffer;
	pNewTempBuffer = NULL;
	return New_file_size;

}

void StoreNewBuffer(PVOID pNewBuffer,DWORD new_file_size,char* save_path)
{	FILE* fp2;
	fp2 =  fopen(save_path,"wb");
	if(!fp2)
	{
		printf("写入文件失败!\n");
		fclose(fp2);
		return;
	}
	fwrite(pNewBuffer,new_file_size,1,fp2);
	fclose(fp2);
}

int main(int argc, char* argv[])
{

	add_new_section();
	getchar();
	return 0;
}



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值