首页 > 系统相关 >记PE文件结构实验,模拟文件内存加载过程。

记PE文件结构实验,模拟文件内存加载过程。

时间:2023-09-08 19:11:50浏览次数:62  
标签:文件 putchar 0x10 0d PE 加载

记录文件结构试验

前言:使用的模拟程序是notepad.exe,主要记录其中的思路和遇到其中的困难。
实验目的:模拟内存加载PE文件的过程,将每个区段模拟加载到内存之中。
根据文件结构中头表中的信息,读取并sekk指针到Segment头。然后循环遍历Segment头将内容加载到Virtual Address中,主要目的是为了熟悉PE头的结构,同时也练习自己的代码能力。
贴出来最后的代码如下,只支持部分PE文件的模拟加载。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define QWORD unsigned long long
#define DWORD unsigned int
#define WORD unsigned short
void show_memory(unsigned char* s, int len) {
    printf("Addres:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F     0123456789ABCDEF");
    for (int i = 0; i < (len / 0x10) + 1; ++i) {
        printf("\n%06X: ", i * 0x10);
        for (int j = 0; j < 0x10; ++j) {
            printf("%02X", s[i * 0x10 + j]);
            if (j == 3 || j == 7 || j == 0xb)
                putchar('|');
            else
                putchar(' ');
        }
        putchar(' ');
        putchar(' ');
        putchar(' ');
        putchar(' ');
        for (int j = 0; j < 0x10; ++j) {
            if (s[i * 0x10 + j] >= 'A' && s[i * 0x10 + j] <= 'z')
                printf("%c", s[i * 0x10 + j]);
            else
                putchar('.');
        }
    }
}
int main() {
    const char* filename = "C:\\Users\\LENOVO\\Desktop\\Practice\\316Buffer\\notepad_xp.exe";
    FILE* fp = fopen(filename, "rb");
    unsigned char* VirtualBuffer;
    DWORD SizeOfImage;
    DWORD AddressOfNewEXEHeader;
    char SectionHeaderName[9] = { 0 };
    DWORD Misc;
    DWORD VirtualAddress;
    DWORD SizeOfRawData;
    DWORD PointerToRawData;
    DWORD Characteristics;
    WORD NumberOfSection;
    WORD SizeOfOptionalHeader;
    WORD SizeOfHeaders;

    if (fp == NULL) {
        printf("Failed to open the file");
        exit(1);
    }
    fseek(fp, 0x3C, SEEK_SET);
    fread(&AddressOfNewEXEHeader, 4, 1, fp);
    fseek(fp, AddressOfNewEXEHeader + 0x6, SEEK_SET); // seek for new NT header and NumberOfSection


    fread(&NumberOfSection, 2, 1, fp); // get NumberOfSection
    fseek(fp, 0xC, SEEK_CUR); // seek for opt size
    fread(&SizeOfOptionalHeader, 2, 1, fp);

    fseek(fp, AddressOfNewEXEHeader + 0x50, SEEK_SET);
    fread(&SizeOfImage, 4, 1, fp); // get img size
    fread(&SizeOfHeaders, 2, 1, fp); // get headers size


    VirtualBuffer = (unsigned char*)malloc(SizeOfImage); // //get vadr
    if (VirtualBuffer == NULL) {
        printf("Failed to malloc the size %X", SizeOfImage);
        exit(1);
    }
    memset(VirtualBuffer, 0, SizeOfImage);
    fseek(fp, 0, SEEK_SET);
    fread(&VirtualBuffer[i], 0x400, 1, fp);

    for (int i = 0; i < NumberOfSection; ++i) {
        fseek(fp, AddressOfNewEXEHeader + 0x18 + SizeOfOptionalHeader + i * 0x28, SEEK_SET);
        fread(&SectionHeaderName, 1, 8, fp);
        printf("段名称: %s\n", SectionHeaderName);
        fread(&Misc, 4, 1, fp);
        printf("Misc(实际大小): %X\n", Misc);
        fread(&VirtualAddress, 4, 1, fp);
        printf("虚拟地址: %X\n", VirtualAddress);
        fread(&SizeOfRawData, 4, 1, fp);
        printf("区段大小: %X\n", SizeOfRawData);
        fread(&PointerToRawData, 4, 1, fp);
        printf("文件中偏移: %X\n", PointerToRawData);
        fseek(fp, 0xC, SEEK_CUR);
        fread(&Characteristics, 4, 1, fp);
        printf("属性值: %8X\n\n", Characteristics);

        fseek(fp, PointerToRawData, SEEK_SET);
        fread(&VirtualBuffer[VirtualAddress], Misc, 1, fp);
    }
    show_memory(VirtualBuffer, 0x1000);
    free(VirtualBuffer);
}

中途遇到了一个问题:是文件偏移为 75h 的 0d 0d 0a 读出来只有 0d 0a,莫名其妙少了一个 0d ,但是从此往后的内容又都是正确的,本人为此甚至尝试了多个编译器,均失败告终。最后查找到原因是因为打开方式为"r",fread检测到 0d 0a 时认为这是文件结束标识,于是结束了读取内容。导致此处丢失了一个 0d 。在网络上找到原因后,将"r"改为"rb",最后成功读取了文件内容。

标签:文件,putchar,0x10,0d,PE,加载
From: https://www.cnblogs.com/F145H/p/17688351.html

相关文章

  • GO语言中import GitHub的包 会影响加载速度吗
    在Go语言中使用GitHub的包不会影响加载速度。在Go语言中,所有包都是静态导入的,因此使用import关键字导入GitHub的包时,Go编译器会将包中的代码文件解压缩到您的项目目录中,并在运行时直接调用这些文件,而不是通过网络下载它们。这意味着import语句不会增加项目的启动时间,而且使用import......
  • 设置电脑文件的打开方式
    设置电脑文件的打开方式不知道怎么搞的,有几个markdown文件的默认打开方式了变成了calibre图书馆了1.设置==>应用==>默认应用==>按文件类型指定默认应用......
  • KdMapper扩展实现之CPUID(cpuz141.sys)
    1.背景  KdMapper是一个利用intel的驱动漏洞可以无痕的加载未经签名的驱动,本文是利用其它漏洞(参考《【转载】利用签名驱动漏洞加载未签名驱动》)做相应的修改以实现类似功能。需要大家对KdMapper的代码有一定了解。 2.驱动信息 驱动名称cpuz141.sys 时间戳583446......
  • 大文件 MD5 SHA 校验时间优化之路
    最近研发apk校验服务,很多游戏安装包两三个G,如果整个拿去校验,耗时基本二十多秒,这还仅仅是校验的时间,如果加上下载的时间,等待时间太长了网上很多方案尝试了一下,不太行1、fastmd5一个第三方库,csdn有人用过说可以提升40%的速度,然后我去试了一下,本来9秒可以完成的校验,变成了2分多钟......
  • mupdf实用操作demo,C++操作PDF文件
    前文:最近有个项目,需要读写PDF,本来想着挺简单的,读写PDF有那么多的库可以使用,唰唰的就完成了。忘记了我写C++的,还是在国产系统上开发的。所以一般的东西还不好使,因为项目需要在多个架构的电脑上使用,所以必须要开源,还要支持读写才行。 找了很多个PDF库(libharu、mupdf、pdfium、......
  • python写的文件比对脚本:
    上代码:#-*-coding:utf-8-*-importdifflib,webbrowserimportosimporttkinterastkfromtkinterimportfiledialog,messageboxdefreadfile(filename):try:withopen(filename,'r+',encoding='utf-8')asf:text=f.read().splitlines......
  • React项目笔记-环境搭建、路由封装(跳转Navigate、懒加载lazy)、模块化样式引入、状态管
    环境准备nodev16.15.0npm8.5.5AntDesignofReact:https://ant.design/docs/react/introduce-cn一,创建项目npminitvite√Projectname:...vite-project-react√Selectaframework:»React√Selectavariant:»TypeScript然后使用vscode打开项目,由于......
  • 使用GlobeMapper下载谷歌影像
    1谷歌图源1.1有路网标注无偏移 http://gac-geo.googlecnapps.cn/maps/vt?lyrs=s,h&gl=CN&h1=zh-CN&x=%x&y=%y&z=%z1.2无标注无偏移  http://gac-geo.googlecnapps.cn/maps/vt?lyrs=s&x=%x&y=%y&z=%z2下载步骤2.1添加相应的数据源-点击连接到联机数据......
  • 项目管理工具----普加项目管理中间件(PlusProject )入门教程(10):数据加载
    普加项目管理中间件是用于跨浏览器和跨平台应用程序的功能齐全的Gantt图表,可满足项目管理应用程序的所有需求,是最完善的甘特图图表库。PlusProject提供了加载json数据方式来显示。规定的数据格式如下:{ UID:100, Name:'ProjectName', StartDate:'2007-01-01T08:00:00', Fin......
  • 打开vhdx格式文件
    Windows,打开磁盘管理器,AttachVHDLinux-Ubuntusudoaptinstalllibguestfs-tools查看vhdx分区:sudovirt-list-filesystems/vhdx-filesudoguestmount-a/vhdx-file-m/dev/sda1-r/path/mount-oallow_other注:-r:readonlyallow_other:允许其他用户使用......