滴水三期逆向基础系列(一)-读取文件到内存再读取回文件

跟着滴水三期学了很长时间了,本着,每一点都要吃透的精神,跟“读文件到内存(拉伸),再读回文件(压缩回来)”杠了一天。先看看按着老师的架构写的代码吧(老师的代码有很多问题(可能是我太菜了吧),踩了很多坑,最后自己推翻重写,全改过来了。)

先看看全部函数的声明


#include <windows.h>
#include <stdio.h>

#define FilePath_In      "d://test.exe"
#define FilePath_Out     "d://test_new.exe"
#define messageBoxAddr   0x77E5425F
#define shellCodeLength  0x12

extern BYTE shellCode[];

DWORD ReadPEFile(IN LPSTR lpszFile, OUT LPVOID *pFileBuffer);

VOID ReturnAllPEInfo(IN LPVOID pFileBuffer);

DWORD CopyFileBufferToImageBuffer(IN LPVOID pFileBuffer, OUT LPVOID *pImageBuffer);

DWORD CopyImageBufferToNewFileBuffer(IN LPVOID pImageBuffer, OUT LPVOID *pNewFileBuffer);

BOOL NewFileBufferToFile(IN LPVOID pNewFileBuffer, size_t size, OUT LPSTR lpszFile);

之后就是函数实现啦

#include "stdafx.h"
#include "global.h"
#include <stdio.h>
#include <windows.h>
#include <iostream>

//_CRT_SECURE_NO_WARNINGS

using namespace std;
BYTE shellCode[] = {
	0x6A, 0x00, 0x6A, 0x00, 0x6A, 0x00, 0x6A, 0x00,
	0xE8, 0x00, 0x00, 0x00, 0x00,
	0xE9, 0x00, 0x00, 0x00, 0x00
};

DWORD ReadPEFile(
	IN LPSTR lpszFile, 
	OUT LPVOID *pFileBuffer
){
	FILE *pFile = NULL;
	DWORD fileSize = 0;
	LPVOID pTempFileBuffer = NULL;

	pFile = fopen(lpszFile, "rb");
	if(!pFile){
		printf("fopen打开EXE文件失败...");
		return ERROR;
	}
	fseek(pFile, 0, SEEK_END);
	fileSize = ftell(pFile);
	fseek(pFile, 0, SEEK_SET);

	pTempFileBuffer = malloc(fileSize);
	memset(pTempFileBuffer,0x00,fileSize);
	if(!pTempFileBuffer){
		printf("pTempFileBuffer空间申请失败...");
		fclose(pFile);
		return ERROR;
	}
	size_t n = fread(pTempFileBuffer, fileSize, 1, pFile);
	if(!n){
		printf("fread数据读取失败...");
		free(pTempFileBuffer);
		fclose(pFile);
		return ERROR;
	}
	*pFileBuffer = pTempFileBuffer;
	pTempFileBuffer = NULL;
	fclose(pFile);
	return fileSize;
}

VOID ReturnAllPEInfo(
	IN LPVOID pFileBuffer	
){
	PIMAGE_DOS_HEADER idh = NULL;
	PIMAGE_NT_HEADERS inh = NULL;
	PIMAGE_FILE_HEADER ifh = NULL;
	PIMAGE_OPTIONAL_HEADER ioh = NULL;
	PIMAGE_SECTION_HEADER ish = NULL;

	idh = (PIMAGE_DOS_HEADER)pFileBuffer;
	inh = (PIMAGE_NT_HEADERS)((BYTE *)pFileBuffer + idh->e_lfanew);
	ifh = (PIMAGE_FILE_HEADER)((BYTE *)inh + sizeof(DWORD));
	ioh = (PIMAGE_OPTIONAL_HEADER)((BYTE *)ifh + IMAGE_SIZEOF_FILE_HEADER);
	ish = (PIMAGE_SECTION_HEADER)((BYTE *)ioh + ifh->SizeOfOptionalHeader);

	cout << hex << "-----------IMAGE_DOS_HEADER_BASE---------" << endl;
	cout << hex << "|-e_magic                           = " << idh->e_magic << endl;
	cout << hex << "|-e_lfanew                          = " << idh->e_lfanew << endl;
	cout << hex << "|" << endl;
	cout << hex << "|------------------IMAGE_NT_HEADERS_BASE-----------------" << endl;
	cout << hex << "|-signature                         = " << IMAGE_NT_SIGNATURE << endl;
	cout << hex << "|" << endl;
	cout << hex << "|---------IMAGE_FILE_HEADER_BASE---------" << endl;
	cout << hex << "||-Machine                          = " << ifh->Machine << endl;
	cout << hex << "||-NumberOfSections                 = " << ifh->NumberOfSections << endl;
	cout << hex << "||-TimeDataStamp                    = " << ifh->TimeDateStamp << endl;
	cout << hex << "||-PointerToSymbolicTable           = " << ifh->PointerToSymbolTable << endl;
	cout << hex << "||-NumberOfSymbols                  = " << ifh->NumberOfSymbols << endl;
	cout << hex << "||-SizeOfOptionalHeader             = " << ifh->SizeOfOptionalHeader << endl;
	cout << hex << "||-Characteristics                  = " << ifh->Characteristics << endl;
	cout << hex << "||" << endl;
	cout << hex << "||-----------IMAGE_OPTIONAL_HEADER---------" << endl;
	cout << hex << "||-Magic                            = " << ioh->Magic << endl;
	printf(        "||-MajorLinkerVersion               = %x\n", ioh->MajorLinkerVersion);
	printf(        "||-MinorLinkerVersion               = %x\n", ioh->MinorLinkerVersion);
	cout << hex << "||-SizeOfCode                       = " << ioh->SizeOfCode << endl;
	cout << hex << "||-SizeOfInitializedData            = " << ioh->SizeOfInitializedData << endl;
	cout << hex << "||-SizeOfUninitializedData          = " << ioh->SizeOfUninitializedData << endl;
	cout << hex << "||-AddressOfEntryPoint              = " << ioh->AddressOfEntryPoint << endl;
	cout << hex << "||-BaseOfCode                       = " << ioh->BaseOfCode << endl;
	cout << hex << "||-BaseOfData                       = " << ioh->BaseOfData << endl;
	cout << hex << "||"<< endl;
	cout << hex << "||-----------NT 结构增加的领域---------" << endl;
	cout << hex << "||-ImageBase                        = " << ioh->ImageBase << endl;
	cout << hex << "||-SectionAlignment                 = " << ioh->SectionAlignment << endl;
	cout << hex << "||-FileAlignment                    = " << ioh->FileAlignment << endl;
	cout << hex << "||-MajorOperatingSystemVersion      = " << ioh->MajorOperatingSystemVersion << endl;
	cout << hex << "||-MinorOperatingSystemVersion      = " << ioh->MinorOperatingSystemVersion << endl;
	cout << hex << "||-MajorImageVersion                = " << ioh->MajorImageVersion << endl;
	cout << hex << "||-MinorImageVersion                = " << ioh->MinorImageVersion << endl;
	cout << hex << "||-MajorSubsystemVersion            = " << ioh->MajorSubsystemVersion << endl;
	cout << hex << "||-MinorSubsystemVersion            = " << ioh->MinorSubsystemVersion << endl;
	cout << hex << "||-Win32VersionValue                = " << ioh->Win32VersionValue << endl;
	cout << hex << "||-SizeOfImage                      = " << ioh->SizeOfImage << endl;
	cout << hex << "||-SizeOfHeaders                    = " << ioh->SizeOfHeaders << endl;
	cout << hex << "||-CheckSum                         = " << ioh->CheckSum << endl;
	cout << hex << "||-Subsystem                        = " << ioh->Subsystem << endl;
	cout << hex << "||-DllCharacteristics               = " << ioh->DllCharacteristics << endl;
	cout << hex << "||-SizeOfStackReserve               = " << ioh->SizeOfStackReserve << endl;
	cout << hex << "||-SizeOfStackCommit                = " << ioh->SizeOfStackCommit << endl;
	cout << hex << "||-SizeOfHeapReserve                = " << ioh->SizeOfHeapReserve << endl;
	cout << hex << "||-SizeOfHeapCommit                 = " << ioh->SizeOfHeapCommit << endl;
	cout << hex << "||-LoaderFlags                      = " << ioh->LoaderFlags << endl;
	cout << hex << "||-NumberOfRvaAndSizes              = " << ioh->NumberOfRvaAndSizes << endl;
	cout << hex << "|" << endl;
	cout << hex << "|-------PE结构大小----------------------" << endl;
	cout << hex << "|-sizeof(IMAGE_DOS_HEADER)          = " << sizeof(IMAGE_DOS_HEADER)<< endl;
	cout << hex << "|-sizeof(IMAGE_FILE_HEADER)         = " << sizeof(IMAGE_FILE_HEADER) << endl;
	cout << hex << "|-sizeof(IMAGE_OPTIONAL_HEADER)     = " << sizeof(IMAGE_OPTIONAL_HEADER) << endl;
	cout << hex << "|-realSizeof(IMAGE_OPTIONAL_HEADER) = " << sizeof(IMAGE_OPTIONAL_HEADER) << endl;
	cout << hex << "|-sizeof(IMAGE_NT_HEADERS)          = " << sizeof(IMAGE_NT_HEADERS) << endl;
	cout << hex << "|" << endl;
	cout << hex << "|-------文件中PE头基址----------------------" << endl;
	cout << hex << "|-IMAGE_DOS_HEADER_BASE             = " << (void *)((BYTE *)idh - (BYTE *)idh) << endl;
	cout << hex << "|-IMAGE_NT_HEADERS_BASE             = " << (void *)((BYTE *)inh - (BYTE *)idh)  << endl;
	cout << hex << "|-IMAGE_FILE_HEADER_BASE            = " << (void *)((BYTE *)ifh - (BYTE *)idh)  << endl;
	cout << hex << "|-IMAGE_OPTIONAL_HEADER_BASE        = " << (void *)((BYTE *)ioh - (BYTE *)idh)  << endl;
	cout << hex << "|" << endl;
	for(int i = 0; i < ifh->NumberOfSections; i ++){
			char *postion = (char *)((char *)ioh + ifh->SizeOfOptionalHeader + (sizeof(IMAGE_SECTION_HEADER) * i));
			if(*postion == 0x00){
				break;
			}
			IMAGE_SECTION_HEADER *ish = (IMAGE_SECTION_HEADER*)postion;
			cout << hex << "|----------------------------------------"<< endl;
			cout << hex << "|---------------节表"<< i + 1 << "--------------" << endl;
			cout << hex << "||-SectionName               = " << ish->Name << endl;
			cout << hex << "||-BaseAddress               = " << (void *)((char *)postion - (char *)idh) << endl;
			cout << hex << "||-MemoryBaseAddress         = " << (void *)(char *)postion << endl;
			printf(        "||-VirtualSize               = %x\n", ish->Misc);
			cout << hex << "||-VirtualAddress            = " << ish->VirtualAddress << endl;
			cout << hex << "||-SizeOfRawData             = " << ish->SizeOfRawData << endl;
			cout << hex << "||-PointerToRawData          = " << ish->PointerToRawData << endl;
			cout << hex << "||-PointerToRelocations      = " << ish->PointerToRelocations << endl;
			cout << hex << "||-PointerToLinenumbers      = " << ish->PointerToLinenumbers << endl;
			cout << hex << "||-NumberOfRelocation        = " << ish->NumberOfRelocations << endl;
			cout << hex << "||-NumberOfLinenumbers       = " << ish->NumberOfLinenumbers << endl;
			cout << hex << "||-Characteristics           = " << ish->Characteristics << endl;
		}
		cout << hex << "|----------------------------------------"<< endl;
	return;
}

DWORD CopyFileBufferToImageBuffer(
	IN LPVOID pFileBuffer,
	OUT LPVOID *pImageBuffer
){
	PIMAGE_DOS_HEADER pDosHeader = NULL;
	PIMAGE_NT_HEADERS pNTHeader = NULL;
	PIMAGE_FILE_HEADER pFileHeader = NULL;
	PIMAGE_OPTIONAL_HEADER pOptionHeader = NULL;
	PIMAGE_SECTION_HEADER pSectionHeader = NULL;
	LPVOID pTempFileBuffer = NULL;

	if(pFileBuffer ==NULL){
		printf("pFileBuffer缓冲区指针出错...\n");
		return ERROR;
	}

	//判断是否含有有效MZ和PE标志
	if(*((PWORD)pFileBuffer) != IMAGE_DOS_SIGNATURE){
		printf("无有效的MZ标志\n");
		return ERROR;
	}
	pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
	if(*((PDWORD)((BYTE *)pFileBuffer + pDosHeader->e_lfanew)) != IMAGE_NT_SIGNATURE){
		printf("无有效的PE标志\n");
		return ERROR;
	}

	//找到所有PE文件结构的头地址
	pNTHeader = (PIMAGE_NT_HEADERS)((BYTE *)pFileBuffer + pDosHeader->e_lfanew);
	pFileHeader = (PIMAGE_FILE_HEADER)((BYTE *)pNTHeader + sizeof(DWORD));
	pOptionHeader = (PIMAGE_OPTIONAL_HEADER)((BYTE *)pFileHeader + IMAGE_SIZEOF_FILE_HEADER);
	pSectionHeader = (PIMAGE_SECTION_HEADER)((BYTE *)pOptionHeader + pFileHeader->SizeOfOptionalHeader);

	//根据SizeOfImage申请空间哦
	pTempFileBuffer = malloc(pOptionHeader->SizeOfImage);
	if(!pTempFileBuffer){
		printf("pTempFileBuffer空间申请失败...");
		return ERROR;
	}
	memset(pTempFileBuffer, 0, pOptionHeader->SizeOfImage);
	memcpy(pTempFileBuffer, pDosHeader, pOptionHeader->SizeOfHeaders);

	for(DWORD i = 0; i < pFileHeader->NumberOfSections; i++){
		memcpy((PVOID)((BYTE *)pTempFileBuffer + (pSectionHeader + i)->VirtualAddress), (PVOID)((BYTE *)pDosHeader + (pSectionHeader + i)->PointerToRawData), (pSectionHeader + i)->SizeOfRawData);
	}

	*pImageBuffer = pTempFileBuffer;
	pTempFileBuffer = NULL;

	return pOptionHeader->SizeOfImage;
}

DWORD CopyImageBufferToNewFileBuffer(
	IN LPVOID pImageBuffer, 
	OUT LPVOID *pNewFileBuffer
){
	PIMAGE_DOS_HEADER pDosHeader = NULL;
	PIMAGE_NT_HEADERS pNTHeader = NULL;
	PIMAGE_FILE_HEADER pFileHeader = NULL;
	PIMAGE_OPTIONAL_HEADER pOptionHeader = NULL;
	PIMAGE_SECTION_HEADER pSectionHeader = NULL;

	if(pImageBuffer ==NULL){
		printf("pImageBuffer缓冲区指针出错...\n");
		return ERROR;
	}

	//判断是否含有有效MZ和PE标志
	if(*((PWORD)pImageBuffer) != IMAGE_DOS_SIGNATURE){
		printf("无有效的MZ标志\n");
		return ERROR;
	}
	pDosHeader = (PIMAGE_DOS_HEADER)pImageBuffer;
	if(*((PDWORD)((BYTE *)pImageBuffer + pDosHeader->e_lfanew)) != IMAGE_NT_SIGNATURE){
		printf("无有效的PE标志\n");
		return ERROR;
	}

	//找到所有PE文件结构的头地址
	pNTHeader = (PIMAGE_NT_HEADERS)((BYTE *)pImageBuffer + pDosHeader->e_lfanew);
	pFileHeader = (PIMAGE_FILE_HEADER)((BYTE *)pNTHeader + sizeof(DWORD));
	pOptionHeader = (PIMAGE_OPTIONAL_HEADER)((BYTE *)pFileHeader + IMAGE_SIZEOF_FILE_HEADER);
	pSectionHeader = (PIMAGE_SECTION_HEADER)((BYTE *)pOptionHeader + pFileHeader->SizeOfOptionalHeader);

	for(DWORD i = 0; i < pFileHeader->NumberOfSections; i++){
		cout << "pSectionHeader->Name = " << (pSectionHeader + i)->Name << endl;
		memcpy((PVOID)((BYTE *)pDosHeader + (pSectionHeader + i)->PointerToRawData), (PVOID)((BYTE *)pImageBuffer + (pSectionHeader + i)->VirtualAddress), (pSectionHeader + i)->SizeOfRawData);
	}
	*pNewFileBuffer = pImageBuffer;
	pImageBuffer = NULL;

	return pOptionHeader->SizeOfImage;
}

BOOL NewFileBufferToFile(
	IN LPVOID pNewFileBuffer, 
	size_t size,
	OUT LPSTR lpszFile
){
	if(pNewFileBuffer == NULL){
		printf("pNewFileBuffer缓冲区出差...\n");
		return ERROR;
	}
	FILE *pFile = NULL;
	size_t fileSize = size;
	pFile = fopen(lpszFile, "wb");
	if(!pFile){
		printf("fopen保存EXE文件失败...\n");
		return ERROR;
	}
	size_t n = fwrite(pNewFileBuffer, fileSize, 1, pFile);
	if(!n){
		printf("fwrite数据写入失败...\n");
		fclose(pFile);
		return ERROR;
	}
	fclose(pFile);
	return TRUE;
}

之后就是调用了

// test.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "global.h"


int _tmain(int argc, _TCHAR* argv[]){

	LPVOID pFileBuffer = NULL;
	LPVOID pImageBuffer = NULL;
	LPVOID pNewFileBuffer = NULL;
	ReadPEFile(FilePath_In, &pFileBuffer);
	//ReturnAllPEInfo(pFileBuffer);
	CopyFileBufferToImageBuffer(pFileBuffer, &pImageBuffer);
	DWORD FileSize = CopyImageBufferToNewFileBuffer(pImageBuffer, &pNewFileBuffer);
	NewFileBufferToFile(pNewFileBuffer, FileSize, FilePath_Out);

	printf("为防止闪屏消失,请手动按任意键结束..."); 
	getchar();
	return 0;
}

一起学习的小伙伴可以互相关注,一起学习,一起加油噢!

这个系列会一直更新,最重要的是,想练习前面的小伙伴,记得自己写Hello World来测试。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值