吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 836|回复: 1
收起左侧

[学习记录] 滴水三期 3.13课后作业

[复制链接]
lich134671 发表于 2023-9-9 09:32
萌新一个,从0解除PE,下面是完成的3.13课后作业,有不对和需要优化的地方,请论坛大佬们批评指正!!!
[C++] 纯文本查看 复制代码
// 滴水.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include <Windows.h>

LPVOID ReadPEFile(char* buff) {
	FILE* notepad = NULL;
	FILE* exe = NULL;
	errno_t err1 = fopen_s(&#172;epad, "C:\\windows\\system32\\notepad.exe", "rb");
	//errno_t err2 = fopen_s(&#172;epad, "C:\\Users\\zyjsuper\\Desktop\\test", "wb");
	if (err1 != 0) {
		fclose(notepad);
		std::cout << "打开软件失败!" << std::endl;
	}
	/*if (err2 != 0) {
		fclose(notepad);
		fclose(exe);
		std::cout << "打开exe失败!" << std::endl;
	}*/
	else {
		std::cout << "打开成功!" << std::endl;
		long size = 0;
		fseek(notepad, 0, SEEK_END);
		size = ftell(notepad);
		fseek(notepad, 0, SEEK_SET);

		buff = (char*)malloc(size);
		if (buff == NULL) {
			std::cout << "分配内存失败" << std::endl;
		}
		else {
			fread(buff, 1, size, notepad);
			//fwrite(buff, 1, size, exe);
			;
		}
		fclose(notepad);
		//fclose(exe);
	}
	return buff;
}

//打印DOS头
void GET_DOS_HEADER(LPVOID addr) {
	//打印DOS头
	PIMAGE_DOS_HEADER dosHeader = NULL;
	dosHeader = (PIMAGE_DOS_HEADER)addr;
	std::cout << std::hex << dosHeader->e_magic << std::endl;
	std::cout << dosHeader->e_lfanew;
	std::cout << std::hex<< dosHeader->e_lfanew<<std::endl;;

}

void GET_NT_HEADER(LPVOID addr) {
	PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)addr;
	PIMAGE_NT_HEADERS ntHeader = (PIMAGE_NT_HEADERS)((DWORD_PTR)addr + dosHeader->e_lfanew);
	std::cout << std::endl << ntHeader->Signature << std::endl;;
}


void GET_标准_HEADER(LPVOID addr) {
	PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)addr;
	PIMAGE_NT_HEADERS ntHeader = (PIMAGE_NT_HEADERS)((DWORD_PTR)addr + dosHeader->e_lfanew);
	std::cout << ntHeader->Signature << std::endl;
	PIMAGE_FILE_HEADER fileHeader = &(ntHeader->FileHeader);  // 直接获取FileHeader

	std::cout << std::hex << "file => " << fileHeader->Machine << std::endl;
}

void GET_可选_HEADER(LPVOID addr) {
	PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)addr;
	PIMAGE_NT_HEADERS ntHeader = (PIMAGE_NT_HEADERS)((DWORD_PTR)addr + dosHeader->e_lfanew);

	//得到可选PE头
	PIMAGE_OPTIONAL_HEADER optionHeader = &(ntHeader->OptionalHeader);


}

void GET_节表(LPVOID addr) {
	PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)addr;
	PIMAGE_NT_HEADERS ntHeader = (PIMAGE_NT_HEADERS)((DWORD_PTR)addr + dosHeader->e_lfanew);
	PIMAGE_FILE_HEADER fileHeader = &(ntHeader->FileHeader);

	std::cout << "节的数量" << fileHeader->NumberOfSections << std::endl;

	PIMAGE_OPTIONAL_HEADER optionHeader = &(ntHeader->OptionalHeader);
	PIMAGE_SECTION_HEADER sectionHeader = (PIMAGE_SECTION_HEADER)((DWORD_PTR)optionHeader + fileHeader->SizeOfOptionalHeader);
	std::cout << "第一个节:" << sectionHeader->Name << std::endl;
	PIMAGE_SECTION_HEADER sectionHeader2 = sectionHeader + 1;
	std::cout << "第二个节:" << sectionHeader2->Name << std::endl;
	//后续以此类推,当然打印节表名称最好是用下面的这样的例子,这样可以避免超出范围返回错误,当然只是做简单的举例,细节还需要优化。
	char sectionName[9] = { 0 };
	memcpy(sectionName, sectionHeader->Name, 8);
	std::cout << "sectionName:" << sectionName << std::endl;
}

//找到具体的节的位置,其实和上面的方法大同小异,无非是找到相对的偏移,然后相加即可,这里就不重复了。有兴趣的自己可以做做。
void GET_节(LPVOID addr) {

}

int main()
{
	char* buff = NULL;
	LPVOID addr = ReadPEFile(buff);
	std::cout << std::hex <<"addr => " << addr << std::endl;
	GET_DOS_HEADER(addr);
	GET_NT_HEADER(addr);
	GET_标准_HEADER(addr);
	GET_节表(addr);
	free(buff);

}


发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| lich134671 发表于 2023-9-9 09:36
通过完成课后练习,我发现了几个问题,希望各位能够给予解答,鄙人将感激不尽!!!
1.通过手动分析,notepad.exe为7个节表,但是通过代码只有6个,这是何故。
2.为什么标准PE头的Machine用代码为014C,手动分析为84 86。

目前已经解决第二个问题,百度的结果是:其实这两个是一样的值,一个是大端存储,一个是小端存储。
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2025-1-10 21:28

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表