吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 6681|回复: 10
收起左侧

[C&C++ 转载] 自己打造一个 PeView 工具 C语言实现(基本上可以了)

[复制链接]
By:刺刀 发表于 2016-9-27 16:58
本帖最后由 By:刺刀 于 2018-9-12 14:45 编辑

在还还没有写完的时候 放出来 主要是想和大家交流下 代码的写法什么的  感觉我自己写的好烂  看看大家还有没有更好的办法 .感谢 _stdcall 的帮助  终于对齐了
刚刚我还写了一个自动对其的函数喃
果然好蠢 代码已经更新 ~ 16/09/29
QQ截图20160927224552.png 现在是这样的了  
下面就是输入输出表这些东东了吧~
[C] 纯文本查看 复制代码
#include <stdio.h>
#include <tchar.h>
#include <stdlib.h>
#include <conio.h>
#include <Windows.h>


// 计算数组长度
#define GET_ARRAY_LEN(array) (sizeof(array) / sizeof(array[0]))
/*
        打印 IMAGE_DOS_HEADER 信息
        PIMAGE_DOS_HEADER pDosHeader: IMAGE_DOS_HEADER 结构体指针
*/
void printImageDosHeader (IN PIMAGE_DOS_HEADER pDosHeader) {
        printf ("IMAGE_DOS_HEADER:\n");
        char *DOS_HEADER_Name[] = {"e_magic", "e_cblp", "e_cp", "e_crlc", "e_cparhdr",
                "e_minalloc", "e_maxalloc", "e_ss", "e_sp",
                "e_csum", "e_ip", "e_cs", "e_lfarlc", "e_ovno",
                "e_res[4]", "e_oemid", "e_oeminfo",
                "e_res2[10]", 
                "e_lfanew", //指向IMAGE_NT_HEADERS的所在
        };
        int temp = 0;
        for (int i = 0; i < 31; i++) {

                if (i == 14) { // 打印 e_res[4] 的内容
                        for (int j = 0; j < 4; j++) {
                                printf ("\t%-20s:%04X\n", DOS_HEADER_Name[temp],
                                        *(&(pDosHeader->e_magic) + i++));
                        }
                        temp++;
                }
                else if (i == 20) { // 打印 e_res2[10] 的内容
                        for (int j = 0; j < 10; j++) {
                                printf ("\t%-20s:%04X\n", DOS_HEADER_Name[temp],
                                        *(&(pDosHeader->e_magic) + i++));
                        }
                        temp++;
                }
                printf ("\t%-20s:%04X\n", DOS_HEADER_Name[temp++], *(&(pDosHeader->e_magic) + i));
        }
}

/*
        打印 IMAGE_OPTIONAL_HEADER32 结构体信息
        IMAGE_NT_HEADERS* pPeHeader: IMAGE_NT_HEADERS 结构体指针
*/
void printOptionalHead32 (IN IMAGE_NT_HEADERS* pPeHeader) {
        char *OptionalHeadName[] = {
                // Standard fields.
                "Magic", "MajorLinkerVersion", "MinorLinkerVersion", "SizeOfCode",
                "SizeOfInitializedData", "SizeOfUninitializedData", "AddressOfEntryPoint", "BaseOfCode", "BaseOfData",
                // NT additional fields.
                "ImageBase", "SectionAlignment", "FileAlignment", "MajorOperatingSystemVersion",
                "MinorOperatingSystemVersion", "MajorImageVersion", "MinorImageVersion", "MajorSubsystemVersion",
                "MinorSubsystemVersion", "Win32VersionValue", "SizeOfImage", "SizeOfHeaders", "CheckSum",
                "Subsystem", "DllCharacteristics", "SizeOfStackReserve", "SizeOfStackCommit", "SizeOfHeapReserve",
                "SizeOfHeapCommit", "LoaderFlags", "NumberOfRvaAndSizes", "IMAGE_DATA_DIRECTORY"};
        char *DataDirectory[] = {"VirtualAddress", "Size"};
        char *VirtualAddressp[] = {"IMAGE_DIRECTORY_ENTRY_EXPORT", "IMAGE_DIRECTORY_ENTRY_IMPORT",
                "IMAGE_DIRECTORY_ENTRY_RESOURCE", "IMAGE_DIRECTORY_ENTRY_EXCEPTION", "IMAGE_DIRECTORY_ENTRY_SECURITY",
                "IMAGE_DIRECTORY_ENTRY_DEBUG", "IMAGE_DIRECTORY_ENTRY_COPYRIGHT", "IMAGE_DIRECTORY_ENTRY_GLOBALPTR",
                "IMAGE_DIRECTORY_ENTRY_TLS", "IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG", "IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT",
                "IMAGE_DIRECTORY_ENTRY_IAT", "IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT", "IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR",
                "IMAGE_NUMBEROF_DIRECTORY_ENTRIES"
        };
        size_t structOffset = 0;
        DWORD* addr;
        printf ("IMAGE_OPTIONAL_HEADER32\n");
        for (size_t i = 0; i < GET_ARRAY_LEN (OptionalHeadName); i++) {
                if (i == 1) {
                        structOffset++;;
                        printf ("\t%-40s:%02X\n", OptionalHeadName[i++], pPeHeader->OptionalHeader.MajorLinkerVersion);
                        printf ("\t%-40s:%02X\n", OptionalHeadName[i++], pPeHeader->OptionalHeader.MinorLinkerVersion);
                }
                if (i == 3) {
                        for (size_t j = 0; j < 9; j++) {
                                addr = &(pPeHeader->OptionalHeader.Magic) + structOffset;
                                structOffset += 2;
                                printf ("\t%-40s:%08X\n", OptionalHeadName[i++], *addr);
                        }
                }
                if (i == 18) {
                        for (size_t j = 0; j < 4; j++) {
                                addr = &(pPeHeader->OptionalHeader.Magic) + structOffset;
                                structOffset += 2;
                                printf ("\t%-40s:%08X\n", OptionalHeadName[i++], *addr);
                        }
                }
                if (i == 24) {
                        for (size_t j = 0; j < 6; j++) {
                                addr = &(pPeHeader->OptionalHeader.Magic) + structOffset;
                                structOffset += 2;
                                printf ("\t%-40s:%08X\n", OptionalHeadName[i++], *addr);
                        }
                }
                printf ("\t%-40s:%04X\n", OptionalHeadName[i], *(&(pPeHeader->OptionalHeader.Magic) + structOffset));
                structOffset++;
        }
}

/*
        打印 IMAGE_NT_HEADERS 结构体信息
        IMAGE_NT_HEADERS *pPeHeader: IMAGE_NT_HEADERS 结构体指针
*/
void printImageNtHeaders (IN IMAGE_NT_HEADERS* pPeHeader) {

        char *PeHeaderName[] = {"Signature", "IMAGE_FILE_HEADER", "IMAGE_OPTIONAL_HEADER32"};

        char *FileHeaderName[] = {"Machine", "NumberOfSections", "TimeDateStamp", "PointerToSymbolTable",
                "NumberOfSymbols", "SizeOfOptionalHeader", "Characteristics"};

        printf ("IMAGE_NT_HEADERS:\n");
        printf ("\t%-20s:%08X\n", PeHeaderName[0], pPeHeader->Signature);
        printf ("IMAGE_FILE_HEADER:\n");
        int temp = 0;
        size_t structOffset = 0;
        DWORD *addr;
        for (int i = 0; i < 7; i++) {
                if (i == 2) {
                        for (int j = 0; j < 3; j++) {
                                /*
                                printf ("\t%-20s:%04X%04X\n", FileHeaderName[temp++], 
                                        // 这里实在是想不到什么好方法来处理了 求指导下 
                                        *(&(pPeHeader->FileHeader.Machine) + structOffset++), 
                                        *(&(pPeHeader->FileHeader.Machine) + structOffset++));
                                这里完全被自己带沟里去了......
                                果然对指针还是不了解啊
                                addr = (DOWRD *)&(pPeHeader->FileHeader.Machine) + structOffset; // 这个就偏移飞了.
                                */
                                addr = &(pPeHeader->FileHeader.Machine) + structOffset;
                                structOffset += 2;
                                printf ("\t%-40s:%08X\n", FileHeaderName[temp++], *addr);
                                i++;
                        }
                }
                printf ("\t%-40s:%04X\n", FileHeaderName[temp++], *(&(pPeHeader->FileHeader.Machine) + structOffset++));
        }
}

int main (int argc, char *argv[]) 
{
        if (argc < 2) {
                printf ("Help: %s FileName\n", argv[0]);
                exit (EXIT_FAILURE);
        }

        IMAGE_DOS_HEADER DosHeader; // Dos 头 结构体
        IMAGE_NT_HEADERS PeHeader; // PE 头 结构体
        FILE *fpPeFile = fopen (argv[1], "rb"); // 以二进制方式打开文件

        if (!fpPeFile) {
                fprintf (stderr, "打开文件失败\n");
                exit (EXIT_FAILURE);
        }

        fread (&DosHeader.e_magic, 1, sizeof(DosHeader), fpPeFile);
        if (DosHeader.e_magic != IMAGE_DOS_SIGNATURE) { // e_magic --> DOS可执行文件标记
                fprintf (stderr, "请确定该文件是PE文件\n");
                exit (EXIT_FAILURE);
        }

        /* 
        这里我想多了 其实可以一次性读取出来的
        fseek (fpPeFile, 0, SEEK_SET);
        for (int i = 0; i < 30; i++) {
                // 取 DosHeader.e_magic 首地址
                // 根据这个地址来计算 结构体偏移
                fread (&DosHeader.e_magic + i, 1, sizeof(WORD), fpPeFile);
        }
        fread (&DosHeader.e_lfanew, 1, sizeof(LONG), fpPeFile); // 获取 指向PE文件头的文件偏移 
        */
        
        printImageDosHeader (&DosHeader);

        // 直接跳过了 Dos Stub
        fseek (fpPeFile, DosHeader.e_lfanew, 0); // 移动文件偏移到PE头
        // 获取PeHeader 信息
        fread (&PeHeader, 1, sizeof(PeHeader), fpPeFile);

        printImageNtHeaders (&PeHeader);
        printOptionalHead32 (&PeHeader);
        return 0;
}



有时候想太多 真不好!  






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

Raohz520 发表于 2016-9-27 17:19
那你都可以发原创区了   加油楼主
 楼主| By:刺刀 发表于 2016-9-27 17:29
Raohz520 发表于 2016-9-27 17:19
那你都可以发原创区了   加油楼主

我在想怎么对齐字符串喃
现在这样输出出来好丑
levelangel 发表于 2016-9-27 17:38
哈喽灬沐沐 发表于 2016-9-27 17:55
感谢分享
_stdcall 发表于 2016-9-27 17:57
By:刺刀 发表于 2016-9-27 17:29
我在想怎么对齐字符串喃
现在这样输出出来好丑

printf( "%-20s" , ....);   就对齐了

免费评分

参与人数 1热心值 +1 收起 理由
By:刺刀 + 1 学到了 很实用喃~

查看全部评分

lbmtl 发表于 2016-9-27 17:59
加油加油 支持技术流
艺海小田 发表于 2016-9-27 18:05 来自手机
喜欢这样的交流,中国未来程序因你们无私交流而大放光彩!
营州都督 发表于 2016-9-27 19:14
小白支持一下,感谢楼主!!!!
sumile 发表于 2016-9-27 22:20
Process Hacker附带一个Peview工具,而且是开源的,可以参考一下。
peview.png
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

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

GMT+8, 2024-5-7 12:56

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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