緊跟着上一篇,自己寫了個簡單的分析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();
}