[C] 纯文本查看 复制代码
#include<Windows.h>
#include<stdio.h>
#define FILE_ANALY_WRAP printf("\n\n");
#define SINGAL_WRAP printf("\n\n");
PIMAGE_SECTION_HEADER nodeArr;
int nodeLength;
int SectionAlignment;
int getFoa(DWORD RVA) {
int FOA = 0;
if (SectionAlignment > RVA) {
return RVA;
}
for (int i = 0;i < nodeLength;i++) {
if (nodeArr[i].VirtualAddress < RVA &&
(nodeArr[i].VirtualAddress + nodeArr[i].Misc.VirtualSize) > RVA) {
FOA = nodeArr[i].PointerToRawData + (RVA - nodeArr[i].VirtualAddress);
}
}
return FOA;
}
void AnalyEntryImportFile(int offset, LPVOID pFile) {
printf("IMAGE_DIRECTORY_ENTRY_IMPORT FOA【%X】\n", offset);
int count = 0;
UINT fileStart = (UINT)pFile;
do {
PIMAGE_IMPORT_DESCRIPTOR pImport = (PIMAGE_IMPORT_DESCRIPTOR)(fileStart + offset+count*sizeof(_IMAGE_IMPORT_DESCRIPTOR));
if (pImport->OriginalFirstThunk == NULL)
{
printf("import file total 【%d】\n", count);
break;
}
count++;
int nameAddr = getFoa(pImport->Name);
int oft = getFoa(pImport->OriginalFirstThunk);
printf("add dll file name is 【%s】 \t FOA:【%X】\n",(char *)(fileStart +nameAddr),oft);
int flag = 0;
do
{
PIMAGE_THUNK_DATA32 pThunkData = (PIMAGE_THUNK_DATA32)(fileStart + oft + flag * sizeof(_IMAGE_THUNK_DATA32));
if (pThunkData->u1.AddressOfData == 0) {
break;
}
flag++;
/*
* DWORD最高位为0,那么该数值是一个RVA,指向_IMAGE_IMPORT_BY_NAME结构,表明函数是以字符串类型的函数名导入的
* DWORD最高位为1,那么该数值的低31位就是函数的导出函数的序号
*/
int thunkAddressOfData = getFoa(pThunkData->u1.AddressOfData);
if ((pThunkData->u1.AddressOfData & 0x80000000) > 1) {
int addr = pThunkData->u1.AddressOfData & 0x7FFFFFFF;
printf("\t\t import file method NO 【%d】\n", addr,(WORD*)((UINT)pFile + addr));
}
else
{
PIMAGE_IMPORT_BY_NAME pImpotName = (PIMAGE_IMPORT_BY_NAME)((UINT)pFile + thunkAddressOfData);
printf("\t METHOD【%s】 FOA【%X】\n", pImpotName->Name, thunkAddressOfData);
}
} while (true);
SINGAL_WRAP
} while (true);
};
int main() {
printf("hello PE file.....\n");
//读取文件,返回文件句柄
HANDLE hFile = CreateFileA("C:\\Users\\dragon\\Desktop\\吾爱破解论坛学习脱壳实例_VC6.exe"
, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_DELETE | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, 0);
//根据文件句柄创建映射
HANDLE hMap = CreateFileMappingA(hFile, NULL, PAGE_READWRITE, 0, 0, 0);
//映射内容
LPVOID pFile = MapViewOfFile(hMap, FILE_SHARE_WRITE, 0, 0, 0);
//创建DOS对应的结构体指针
_IMAGE_DOS_HEADER* dos;
//类型转换,用结构体的方式来读取
//DOS 数据头
dos = (_IMAGE_DOS_HEADER*)pFile;
printf("DOS INFO MESSAGE \n");
printf("dos->e.magic:%X \n", dos->e_magic);
//输出dos->e_magic,以十六进制输出
printf("dos->e.magic:%X \n", dos->e_magic);
//PE文件开头的位置
printf("dos->PE NT header offset :\t%X", dos->e_lfanew);
FILE_ANALY_WRAP
//NT头文件
//_IMAGE_NT_HEADERS
PIMAGE_NT_HEADERS32 NT_PeHeader = (PIMAGE_NT_HEADERS32)((UINT)dos + dos->e_lfanew);
printf("PE NT Signature:%X\n", NT_PeHeader->Signature);
PIMAGE_FILE_HEADER pFileHeader = &NT_PeHeader->FileHeader;
printf("Machine 【CPU类型】%X\n", pFileHeader->Machine);
printf("NumberOfSections 【节表数量】%X\n", pFileHeader->NumberOfSections);
printf("SizeOfOptionalHeader 【扩展PE头大小】%X\n\n", pFileHeader->SizeOfOptionalHeader);
PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = &NT_PeHeader->OptionalHeader;
printf("NT MAGIC【程序类型 (32位则10B,64位则20B)】 : %X \n", pOptionalHeader->Magic);
printf("program AddressOfEntryPoint :【入口偏移地址】 %X \n", pOptionalHeader->AddressOfEntryPoint);
printf("ImageBase 【基地址】:%X \n", pOptionalHeader->ImageBase);
printf(" 【程序实际入口位置】:%X \n", pOptionalHeader->AddressOfEntryPoint + pOptionalHeader->ImageBase);
printf("SectionAlignment 【内存大小】: %X \n FileAlignment【文件偏移】: %X \n", pOptionalHeader->SectionAlignment, pOptionalHeader->FileAlignment);
SectionAlignment = pOptionalHeader->SectionAlignment;
printf("SizeOfImage 【内存大小】: %X \n SizeOfHeaders 【文件大小】: %X \n", pOptionalHeader->SizeOfImage, pOptionalHeader->SizeOfHeaders);
printf("NumberOfRvaAndSizes : 【项目表类型数量】%X \n", pOptionalHeader->NumberOfRvaAndSizes);
PIMAGE_DATA_DIRECTORY pDataDirectory = pOptionalHeader->DataDirectory;
for (int i = 0;i < pOptionalHeader->NumberOfRvaAndSizes;i++) {
printf("index 【%d】 address 【%X】 size 【%X】\n", i, pDataDirectory[i].VirtualAddress, pDataDirectory[i].Size);
}
FILE_ANALY_WRAP
/**
节表
*/
nodeLength = pFileHeader->NumberOfSections;
PIMAGE_SECTION_HEADER pNodeStart = (PIMAGE_SECTION_HEADER)((UINT)NT_PeHeader + sizeof(_IMAGE_NT_HEADERS));
nodeArr = new IMAGE_SECTION_HEADER[nodeLength];
memcpy(nodeArr, pNodeStart, nodeLength * sizeof(IMAGE_SECTION_HEADER));
for (int i = 0;i < nodeLength;i++) {
char* name = new char[sizeof(nodeArr[i].Name)];
memcpy(name, nodeArr[i].Name, sizeof(nodeArr[i].Name));
printf("PE NODE 【%s】 virtualAddress 【%X】 virtualSize:【%X】 fileAddress【%X】 fileSize【%X】\n", name,
nodeArr[i].VirtualAddress + pOptionalHeader->ImageBase,
nodeArr[i].Misc.VirtualSize,
nodeArr[i].PointerToRawData,
nodeArr[i].SizeOfRawData);
delete [] name;
}
FILE_ANALY_WRAP
/*
* 项目表信息
*/
for (int i = 0; i < pOptionalHeader->NumberOfRvaAndSizes; i++)
{
if (pDataDirectory[i].VirtualAddress == 0x0) {
continue;
}
/* int foa = 0;
for (int i = 0;i < nodelength;i++) {
if (nodearr[i].virtualaddress < pdatadirectory[i].virtualaddress &&
(nodearr[i].virtualaddress + nodearr[i].misc.virtualsize) > pdatadirectory[i].virtualaddress) {
foa = nodearr[i].pointertorawdata + (pdatadirectory[i].virtualaddress - nodearr[i].virtualaddress);
}
}*/
int FOA= getFoa(pDataDirectory[i].VirtualAddress);
switch (i) {
case IMAGE_DIRECTORY_ENTRY_EXPORT:
printf("this pe file has IMAGE_DIRECTORY_ENTRY_EXPORT\n");
break;
case IMAGE_DIRECTORY_ENTRY_IMPORT:
printf("this pe file has IMAGE_DIRECTORY_ENTRY_IMPORT\n");
AnalyEntryImportFile(FOA, pFile);
break;
case IMAGE_DIRECTORY_ENTRY_BASERELOC:
printf("this pe file has IMAGE_DIRECTORY_ENTRY_BASERELOC\n");
break;
};
}
delete[] nodeArr;
return 0;
}