1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184
| #include <Windows.h> #include <stdio.h> #include <DbgHelp.h>
#pragma comment(lib,"DbgHelp.lib")
HANDLE OpenPe(char* filename) {
HANDLE hfile = NULL; HANDLE hMapfile = NULL; HANDLE 起始基地址 = NULL; DWORD size = 0; hfile = CreateFile(filename, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); size = GetFileSize(hfile, NULL); hMapfile = CreateFileMapping(hfile, NULL, PAGE_READONLY, 0, size, NULL);
起始基地址 = MapViewOfFile(hMapfile, FILE_MAP_READ, 0, 0, size); if(起始基地址 != NULL){ return 起始基地址; } printf("未能成功打开!\n"); return FALSE; }
void showDosHeadInfo(HANDLE imageBase) { PIMAGE_DOS_HEADER DosHaeder = imageBase; printf("DOS头:%x \n", DosHaeder->e_magic); printf("PE偏移:%x \n", DosHaeder->e_lfanew);
}
BOOL isPE(HANDLE imageBase) { PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)imageBase;
if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE) { return FALSE; }
PIMAGE_NT_HEADERS pNthead = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);
if (pNthead->Signature != IMAGE_NT_SIGNATURE) { return FALSE; } return TRUE;
}
PIMAGE_NT_HEADERS GetNTHead(HANDLE imageBase) { PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)imageBase; PIMAGE_NT_HEADERS pNthead = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);
return pNthead; }
void 读取PE文件头(HANDLE imageBase) { PIMAGE_NT_HEADERS pNthead = GetNTHead(imageBase); PIMAGE_FILE_HEADER pFileHeader = &pNthead->FileHeader;
printf("运行平台: %x\n", pFileHeader->Machine); printf("节区数目: %x\n", pFileHeader->NumberOfSections); printf("创建日期: %lu\n", pFileHeader->TimeDateStamp); printf("可选头大小: %x\n", pFileHeader->SizeOfOptionalHeader); printf("文件属性: %0x\n", pFileHeader->Machine); printf("运行平台: 0x%08x\n", pFileHeader->Characteristics);
}
void 读取PE可选头(HANDLE imageBase) { PIMAGE_NT_HEADERS pNthead = GetNTHead(imageBase); PIMAGE_OPTIONAL_HEADER pOptionalHeader = &pNthead->OptionalHeader;
printf("入口点: %x\n", pOptionalHeader->AddressOfEntryPoint); printf("基地址: %x\n", pOptionalHeader->ImageBase); }
void 读取节表(HANDLE imageBase){ PIMAGE_NT_HEADERS pNthead = GetNTHead(imageBase); PIMAGE_FILE_HEADER pFileHeader = &pNthead->FileHeader; DWORD NumberOfSectionsCount = pFileHeader->NumberOfSections;
PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(pNthead); printf("节区名称\tRVA_偏移\t节区大小\tRaw_尺寸\tRaw_偏移\t节区属性\t\n "); for (size_t i = 0; i < NumberOfSectionsCount; i++, section++) { printf("%s\t", section->Name); printf("0x%08x\t", section->VirtualAddress); printf("0x%08x\t", section->Misc.VirtualSize); printf("0x%08x\t", section->SizeOfRawData); printf("0x%08x\t", section->PointerToRawData); printf("0x%08x\t\n", section->Characteristics); } }
void 读取导入表(HANDLE imageBase) { PIMAGE_NT_HEADERS pNthead = GetNTHead(imageBase); PIMAGE_IMPORT_DESCRIPTOR dll描述符 = ImageRvaToVa(pNthead, imageBase, pNthead->OptionalHeader.DataDirectory[1].VirtualAddress, NULL); PIMAGE_THUNK_DATA stthunk = NULL; DWORD dwthunk = NULL; USHORT Hint;
printf("导入表为:\n"); printf("函数地址\t模块名称\t函数名称\t\n"); while (dll描述符->Name != NULL) { char* 模块名称 = ImageRvaToVa(pNthead, imageBase, dll描述符->Name, NULL); stthunk = ImageRvaToVa(pNthead, imageBase, dll描述符->OriginalFirstThunk, NULL); dwthunk = dll描述符->OriginalFirstThunk; while (stthunk->u1.AddressOfData != NULL) { PIMAGE_IMPORT_BY_NAME funname = stthunk->u1.AddressOfData; char* 函数名称 = ImageRvaToVa(pNthead, imageBase, funname->Name, NULL); if (函数名称 != NULL) { printf("%0.8x\t%s\t%s\n", dwthunk, 模块名称, 函数名称); } dwthunk += 4; stthunk++; } dll描述符++; }
}
VOID 读取导出表(HANDLE ImageBase) { PIMAGE_EXPORT_DIRECTORY pExport; PIMAGE_NT_HEADERS pNtHead = GetNTHead(ImageBase);
pExport = ImageRvaToVa(pNtHead, ImageBase, pNtHead->OptionalHeader.DataDirectory[0].VirtualAddress, NULL); if (pExport == NULL) { printf("导出表为空\n"); return; }
DWORD NumberOfNames = pExport->NumberOfNames; DWORD** ppdwNames = pExport->AddressOfNames;
ppdwNames = ImageRvaToVa(pNtHead, ImageBase, ppdwNames, NULL);
DWORD** ppdwAddr = pExport->AddressOfFunctions;
ppdwAddr = ImageRvaToVa(pNtHead, ImageBase, ppdwAddr, NULL);
char* szFunction = ImageRvaToVa(pNtHead, ImageBase, *ppdwNames, NULL); printf("导出表为:\n"); printf("RVA_地址\t函数名称\t\n");
for (DWORD i = 0; i < NumberOfNames; i++) { printf("%0.8x\t%s\n", *ppdwAddr, szFunction); szFunction = szFunction + strlen(szFunction) + 1; ppdwAddr++; } }
void main() {
HANDLE 基地址 = NULL; 基地址 = OpenPe("C:\\Users\\test\\Desktop\\menuedit.dll");
if (isPE(基地址) == TRUE) { 读取PE文件头(基地址); 读取PE可选头(基地址); 读取节表(基地址); 读取导入表(基地址); 读取导出表(基地址); } else { printf("不是PE结构\n"); }
system("pause"); }
|