紧跟着上一篇,自己写了个简单的分析OBJ的源代码,知道了基本的COFF结构以后其实分析起来不难,但是要以比较整齐的方式输入比较麻烦,于是乎...代码变得很难看...将就一下吧,以实现功能为主...争取下次写PE分析代码的时候好好重构一下...
"pch.cpp"是一个预编译头文件:cl pch.cpp /Yc
pch.h:
#include <afxwin.h>
#include <afxext.h>
#include <afxdisp.h>
#include <afxdtctl.h>
#include <afxcmn.h>
#include "pch.h" #include <iostream> #include <fstream> #include <iomanip> using namespace std; #define C(X) ((unsigned char)(fileHeader[X]) + 0) #define D(X) ((unsigned char)(sectionHeader[X]) + 0) #define E(X) ((unsigned char)(pSymbolData[X]) + 0) #define PRINT_ADDRESS(X) (cout<<right<<"0x"<<setfill('0')<<setw(8)<<address(X)<<" "<<setw(2)) // Get current address int address(int size) { static int presize = 0; static int address = 0; address += presize; presize = size; return address; } int main(int argc, char *agrv[]) { if(argc != 2) { cout<<"Usage: objview.exe C://sample.obj"<<endl; return 0; } fstream file(agrv[1], ios_base::in | ios::binary); if(!file.is_open()) { cout<<"ERROR: Invalid File Name!"<<endl; return 0; } cout<<setiosflags(ios::uppercase); cout.setf(ios_base::hex, ios_base::basefield); /* -----COFF File Header - 20byte----- typedef struct _IMAGE_FILE_HEADER { WORD Machine; WORD NumberOfSections; DWORD TimeDateStamp; DWORD PointerToSymbolTable; DWORD NumberOfSymbols; WORD SizeOfOptionalHeader; WORD Characteristics; } IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER; */ IMAGE_FILE_HEADER File_Header; char fileHeader[sizeof(File_Header)] = {0}; file.read(fileHeader, sizeof(fileHeader)); memcpy(&File_Header, fileHeader, sizeof(File_Header)); cout<<"---------------------------COFF FILE HEAD---------------------------"<<endl; PRINT_ADDRESS(2)<<C(0)<<" "<<setw(2)<<C(1) <<setfill(' ')<<setw(30)<<" "<<"// Machine"<<endl; PRINT_ADDRESS(2)<<C(2)<<" "<<setw(2)<<C(3) <<setfill(' ')<<setw(30)<<" "<<"// NumberOfSections"<<endl; PRINT_ADDRESS(4)<<C(4)<<" "<<setw(2)<<C(5)<<" "<<setw(2)<<C(6)<<" "<<setw(2)<<C(7) <<setfill(' ')<<setw(24)<<" "<<"// TimeDateStamp"<<endl; PRINT_ADDRESS(4)<<C(8)<<" "<<setw(2)<<C(9)<<" "<<setw(2)<<C(10)<<" "<<setw(2)<<C(11) <<setfill(' ')<<setw(24)<<" "<<"// PointerTosymbolTable"<<endl; PRINT_ADDRESS(4)<<C(12)<<" "<<setw(2)<<C(13)<<" "<<setw(2)<<C(14)<<" "<<setw(2)<<C(15) <<setfill(' ')<<setw(24)<<" "<<"// NumberOfSymbols"<<endl; PRINT_ADDRESS(2)<<C(16)<<" "<<setw(2)<<C(17) <<setfill(' ')<<setw(30)<<" "<<"// SizeOfOptionalHeader"<<endl; PRINT_ADDRESS(2)<<C(18)<<" "<<setw(2)<<C(19) <<setfill(' ')<<setw(30)<<" "<<"// Characteristics"<<endl; cout<<"------------------------END: COFF FILE HEAD------------------------"<<endl<<endl; cout<<"Press any key to show section table!"<<endl; cin.get(); /* -----------------Section Table----------------- #define IMAGE_SIZEOF_SHORT_NAME 8 typedef struct _IMAGE_SECTION_HEADER { BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; union { DWORD PhysicalAddress; DWORD VirtualSize; } Misc; DWORD VirtualAddress; DWORD SizeOfRawData; DWORD PointerToRawData; DWORD PointerToRelocations; DWORD PointerToLinenumbers; WORD NumberOfRelocations; WORD NumberOfLinenumbers; DWORD Characteristics; } IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER; #define IMAGE_SIZEOF_SECTION_HEADER 40 */ cout<<"----------------------------SECTION HEAD----------------------------"<<endl; IMAGE_SECTION_HEADER *Section_Header_Array = new IMAGE_SECTION_HEADER[File_Header.NumberOfSections]; for(int i = 0; i < File_Header.NumberOfSections; i++) { char sectionHeader[sizeof(IMAGE_SECTION_HEADER)] = {0}; file.read(sectionHeader, sizeof(sectionHeader)); memcpy(&Section_Header_Array[i], sectionHeader, sizeof(IMAGE_SECTION_HEADER)); cout<<"section name: "<<(char*)(Section_Header_Array[i].Name)<<endl; PRINT_ADDRESS(8)<<D(0)<<" "<<setw(2)<<D(1)<<" "<<setw(2)<<D(2)<<" "<<setw(2)<<D(3)<<" " <<setw(2)<<D(4)<<" "<<setw(2)<<D(5)<<" "<<setw(2)<<D(6)<<" "<<setw(2)<<D(7) <<setfill(' ')<<setw(12)<<" "<<"// Name"<<endl; PRINT_ADDRESS(4)<<D(8)<<" "<<setw(2)<<D(9)<<" "<<setw(2)<<D(10)<<" "<<setw(2)<<D(11) <<setfill(' ')<<setw(24)<<" "<<"// VirtualSize"<<endl; PRINT_ADDRESS(4)<<D(12)<<" "<<setw(2)<<D(13)<<" "<<setw(2)<<D(14)<<" "<<setw(2)<<D(15) <<setfill(' ')<<setw(24)<<" "<<"// VirtualAddress"<<endl; PRINT_ADDRESS(4)<<D(16)<<" "<<setw(2)<<D(17)<<" "<<setw(2)<<D(18)<<" "<<setw(2)<<D(19) <<setfill(' ')<<setw(24)<<" "<<"// SizeOfRawData"<<endl; PRINT_ADDRESS(4)<<D(20)<<" "<<setw(2)<<D(21)<<" "<<setw(2)<<D(22)<<" "<<setw(2)<<D(23) <<setfill(' ')<<setw(24)<<" "<<"// PointerToRawData"<<endl; PRINT_ADDRESS(4)<<D(24)<<" "<<setw(2)<<D(25)<<" "<<setw(2)<<D(26)<<" "<<setw(2)<<D(27) <<setfill(' ')<<setw(24)<<" "<<"// PointerToRelocations"<<endl; PRINT_ADDRESS(4)<<D(28)<<" "<<setw(2)<<D(29)<<" "<<setw(2)<<D(30)<<" "<<setw(2)<<D(31) <<setfill(' ')<<setw(24)<<" "<<"// PointerToLinenumbers"<<endl; PRINT_ADDRESS(2)<<D(32)<<" "<<setw(2)<<D(33) <<setfill(' ')<<setw(30)<<" "<<"// NumberOfRelocations"<<endl; PRINT_ADDRESS(2)<<D(34)<<" "<<setw(2)<<D(35) <<setfill(' ')<<setw(30)<<" "<<"// NumberOfLinenumbers"<<endl; PRINT_ADDRESS(4)<<D(36)<<" "<<setw(2)<<D(37)<<" "<<setw(2)<<D(38)<<" "<<setw(2)<<D(39) <<setfill(' ')<<setw(24)<<" "<<"// Characteristics"<<endl; } cout<<"--------------------------END: SECTION HEAD-------------------------"<<endl<<endl; cout<<"Press any key to show each sections!"<<endl; cin.get(); for(int i = 0; i < File_Header.NumberOfSections; i++) { DWORD dAddr = Section_Header_Array[i].PointerToRawData; DWORD dSize = Section_Header_Array[i].SizeOfRawData; DWORD dEndr = (dAddr == 0) ? 0 : (dAddr + dSize); cout<<"---------------SECTION DATA: "<<(char*)(Section_Header_Array[i].Name)<<"----------------"<<endl; cout<<left<<setfill(' ')<<setw(20)<<"section name: "<<(char*)(Section_Header_Array[i].Name)<<endl; cout<<left<<setfill(' ')<<setw(20)<<"start address: "<<"0x"<<right<<setfill('0')<<setw(8)<<dAddr<<endl; cout<<left<<setfill(' ')<<setw(20)<<"data size: "<<Section_Header_Array[i].SizeOfRawData<<endl; cout<<left<<setfill(' ')<<setw(20)<<"end address: "<<"0x"<<right<<setfill('0')<<setw(8)<<dEndr<<endl; // .bbs setction doesn't have any data if(dAddr != 0) { file.seekg(dAddr, ios::beg); char* pData = new char[dSize]; file.read(pData, dSize); cout<<left<<setfill(' ')<<setw(20)<<"data: "; for(int j = 0; j < dSize; j++) { cout<<right<<setw(2)<<setfill('0')<<(unsigned char)(pData[j]) + 0<<" "; } address(Section_Header_Array[i].SizeOfRawData); cout<<endl; // relocation data in .text section if(Section_Header_Array[i].NumberOfRelocations != 0) { /*typedef struct _IMAGE_RELOCATION { union { DWORD VirtualAddress; DWORD RelocCount; } DUMMYUNIONNAME; DWORD SymbolTableIndex; WORD Type; } IMAGE_RELOCATION; typedef IMAGE_RELOCATION UNALIGNED *PIMAGE_RELOCATION; */ DWORD dRelocationNum = Section_Header_Array[i].NumberOfRelocations; DWORD dImageSize = sizeof(IMAGE_RELOCATION); char* pRelocationData = new char[dRelocationNum * dImageSize]; file.seekg(Section_Header_Array[i].PointerToRelocations, ios::beg); file.read(pRelocationData, dRelocationNum * dImageSize); cout<<left<<setfill(' ')<<setw(20)<<"relacation: " <<"VirtualAddress "<<"SymbolTableIndex "<<"Type"<<endl; for(int k = 0; k < dRelocationNum; k++) { PRINT_ADDRESS(dImageSize)<<" "; for(int n = 0; n < dImageSize; n++) { cout<<right<<setw(2)<<setfill('0') <<(unsigned char)(pRelocationData[n+k*dImageSize]) + 0<<" "; if((n+1)%4 == 0) cout<<" "; } cout<<endl; } delete[] pRelocationData; } delete[] pData; } cout<<"-------------SECTION DATA END: "<<(char*)(Section_Header_Array[i].Name)<<"--------------"<<endl<<endl; } /* typedef struct _IMAGE_SYMBOL { union { BYTE ShortName[8]; struct { DWORD Short; // if 0, use LongName DWORD Long; // offset into string table } Name; DWORD LongName[2]; } N; DWORD Value; SHORT SectionNumber; WORD Type; BYTE StorageClass; BYTE NumberOfAuxSymbols; } IMAGE_SYMBOL; typedef IMAGE_SYMBOL UNALIGNED *PIMAGE_SYMBOL; #define IMAGE_SIZEOF_SYMBOL 18 */ cout<<"Press any key to show symbol table!"<<endl; cin.get(); cout<<"----------------------------SYMBOL TABLE----------------------------"<<endl; DWORD dSymbolTableSize = sizeof(IMAGE_SYMBOL); for(int i = 0; i < File_Header.NumberOfSymbols; i++) { IMAGE_SYMBOL Symbol_Data; char* pSymbolData = new char[dSymbolTableSize]; memcpy(&Symbol_Data, pSymbolData, sizeof(IMAGE_SYMBOL)); file.seekg(File_Header.PointerToSymbolTable + i*dSymbolTableSize, ios::beg); file.read(pSymbolData, dSymbolTableSize); static bool bHasAppendedTablePrevious = false; if(bHasAppendedTablePrevious) cout<<"symbol name: APPENDED TABLE"<<endl; else cout<<"symbol name: "<<pSymbolData<<endl; if(pSymbolData[dSymbolTableSize - 1] != 0) bHasAppendedTablePrevious = true; else bHasAppendedTablePrevious = false; PRINT_ADDRESS(8)<<E(0)<<" "<<setw(2)<<E(1)<<" "<<setw(2)<<E(2)<<" "<<setw(2)<<E(3)<<" " <<setw(2)<<E(4)<<" "<<setw(2)<<E(5)<<" "<<setw(2)<<E(6)<<" "<<setw(2)<<E(7) <<setfill(' ')<<setw(12)<<" "<<"// Name"<<endl; PRINT_ADDRESS(4)<<E(8)<<" "<<setw(2)<<E(9)<<" "<<setw(2)<<E(10)<<" "<<setw(2)<<E(11) <<setfill(' ')<<setw(24)<<" "<<"// Value"<<endl; PRINT_ADDRESS(2)<<E(12)<<" "<<setw(2)<<E(13) <<setfill(' ')<<setw(30)<<" "<<"// SectionNumber"<<endl; PRINT_ADDRESS(2)<<E(14)<<" "<<setw(2)<<E(15) <<setfill(' ')<<setw(30)<<" "<<"// Type"<<endl; PRINT_ADDRESS(1)<<E(16)<<" "<<setfill(' ')<<setw(32)<<" "<<"// StorageClass"<<endl; PRINT_ADDRESS(1)<<E(17)<<" "<<setfill(' ')<<setw(32)<<" "<<"// NumberOfAuxSymbols"<<endl; delete[] pSymbolData; } cout<<"-------------------------END: SYMBOL TABLE-------------------------"<<endl<<endl; cout<<"Press any key to show string table!"<<endl; cin.get(); cout<<"----------------------------STRING TABLE----------------------------"<<endl; int iStringTableSize = 0; file.read((char*)(&iStringTableSize), 4); cout<<"SIZE OF STRING TABLE: "<<iStringTableSize<<endl; while(true) { static int iOffset = 4; char ch = file.get(); if(iOffset == 4) cout<<left<<"OFFSET FROM STRING TABLE: "<<right<<setw(8)<<setfill('0')<<iOffset<<" "; iOffset++; if(ch == EOF || iOffset == iStringTableSize) break; else if(ch == 0) cout<<endl<<left<<"OFFSET FROM STRING TABLE: "<<right<<setw(8)<<setfill('0')<<iOffset<<" "; else cout<<ch; } cout<<endl<<"-------------------------END OF STRING TABLE-------------------------"<<endl; cout<<endl<<"THE END!"<<endl; file.close(); }