萌新一个,从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(¬epad, "C:\\windows\\system32\\notepad.exe", "rb");
//errno_t err2 = fopen_s(¬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);
}
|