OriginalFirstThunk : 00013064
TimeDateStamp : 00000000
ForwarderChain : 00000000
Name : KERNEL32.dll
FirstThunk : 0001335c
一个目录项代表一个dll,里面可包含多个导入项。
OriginalFirstThunk为导入符号表的RVA
FirstThunk为导入地址表的RVA。
hint: 217
name: DeleteCriticalSection
address: 0000000000013654
导入地址表,动态链接器负责将dll函数的地址印射到导入地址表里面
#include<iostream>
#include<fstream>
#include<iomanip>
#include<vector>
#include<windows.h>
using namespace std;
#define Read(S) readBytes(input,&S,sizeof S)
#define ReadAddr(S,addr) readAddr(input,&S,sizeof(S),addr)
#define ReadStr(addr) readStr(input,addr);
int symposition;
int numofsym;
int NtPosition ;
#define BYSEQ 0x8000000000000000
typedef enum {
PE32,PE32plus
}PE;
PE pe=PE32;
char dataDirectories[][64]={
"Export Table",
"Import Table",
"Resource Table",
"Exception Table",
"Certificate Table",
"Base Relocation Table",
"Debug ",
"Architecture",
"Global Ptr",
"TLS Table",
"Load Config Table",
"Bound Import",
"IAT",
"Delay Import Descriptor",
"CLR Runtime Header",
"Reserved "
};
void readBytes(ifstream &input,void *p,int len){
char *t=(char *)p;
for(int i=0;i<len;i++)t[i]=input.get();
}
void readAddr(ifstream &input,void *pp,int len,int raw){
auto t=input.tellg();
input.seekg(raw);
char *p=(char*)pp;
for(int i=0;i<len;i++)p[i]=input.get();
input.seekg(t);
}
void readStr(ifstream &input,unsigned long long raw){
auto t=input.tellg();
input.seekg(raw);
char c;
do{
c=input.get();
if(c)
cout.put(c);
}while(c);
input.seekg(t);
}
//读取dos头
void readDos(ifstream &input){
IMAGE_DOS_HEADER dos;
Read(dos);
//cout<<a[0]<<a[1]<<endl;
printf("magic : %04x\n",dos.e_magic);
printf("cblp : %04x\n",dos.e_cblp);
printf("cp : %04x\n",dos.e_cp);
printf("crlc : %04x\n",dos.e_crlc);
printf("cparhdr : %04x\n",dos.e_cparhdr);
printf("minalloc : %04x\n",dos.e_minalloc);
printf("ss : %04x\n",dos.e_ss);
printf("sp : %04x\n",dos.e_sp);
printf("csum : %04x\n",dos.e_csum);
printf("ip : %04x\n",dos.e_ip);
printf("cs : %04x\n",dos.e_cs);
printf("lfarlc : %04x\n",dos.e_lfarlc);
printf("ovno : %04x\n",dos.e_ovno);
printf("res :\n");
for(int i=0;i<4;i++) printf("%04x ",dos.e_res[i]);
puts("");
printf("oemid : %04x\n",dos.e_oemid);
printf("oeminfo : %04x\n",dos.e_oeminfo);
printf("res2 :\n");
for(int i=0;i<10;i++) printf("%04x ",dos.e_res2[i]);
puts("");
printf("lfanew : %08lx\n",dos.e_lfanew);
puts("");
NtPosition = dos.e_lfanew;
}
void readNt(ifstream &input){
input.seekg(NtPosition);
DWORD Signature;
Read(Signature);
IMAGE_FILE_HEADER FileHeader;
Read(FileHeader);
printf("Signature : %08lx\n",Signature);
puts("");
printf("Machine : %04x\n",FileHeader.Machine);
printf("NumberOfSections : %04x\n",FileHeader.NumberOfSections);
printf("TimeDateStamp : %08lx\n",FileHeader.TimeDateStamp);
printf("PointerToSymbolTable : %08lx\n",FileHeader.PointerToSymbolTable);
printf("NumberOfSymbols : %08lx\n",FileHeader.NumberOfSymbols);
printf("SizeOfOptionalHeader : %04x\n",FileHeader.SizeOfOptionalHeader);
printf("Characteristics : %04x\n",FileHeader.Characteristics);
puts("");
symposition=FileHeader.PointerToSymbolTable;
numofsym=FileHeader.NumberOfSymbols;
union {
IMAGE_OPTIONAL_HEADER64 a;
IMAGE_OPTIONAL_HEADER32 b;
}OH;
char *p=(char *)&OH;
int dircnt=0;
//判断是PE32 还是 PE32+
if (FileHeader.Machine != 0x014c) {
pe=PE32plus;
Read(OH.a);
IMAGE_OPTIONAL_HEADER64 &OptionalHeader = OH.a;
printf("magic : %04x\n", OptionalHeader.Magic);
printf("MajorLinkerVersion : %02x\n", OptionalHeader.MajorLinkerVersion);
printf("MinorLinkerVersion : %02x\n", OptionalHeader.MinorLinkerVersion);
printf("SizeOfCode : %08lx\n", OptionalHeader.SizeOfCode);
printf("SizeOfInitializedData : %08lx\n", OptionalHeader.SizeOfInitializedData);
printf("SizeOfUninitializedData : %08lx\n", OptionalHeader.SizeOfUninitializedData);
printf("AddressOfEntryPoint : %08lx\n", OptionalHeader.AddressOfEntryPoint);
printf("BaseOfCode : %08lx\n", OptionalHeader.BaseOfCode);
//printf("BaseOfData : %08lx\n",OptionalHeader.BaseOfData);
printf("ImageBase : %016llx\n", OptionalHeader.ImageBase);
printf("SectionAlignment : %08lx\n", OptionalHeader.SectionAlignment);
printf("FileAlignment : %08lx\n", OptionalHeader.FileAlignment);
printf("MajorOperatingSystemVersion : %04x\n", OptionalHeader.MajorOperatingSystemVersion);
printf("MinorOperatingSystemVersion : %04x\n", OptionalHeader.MinorOperatingSystemVersion);
printf("MajorImageVersion : %04x\n", OptionalHeader.MajorImageVersion);
printf("MinorImageVersion : %04x\n", OptionalHeader.MinorImageVersion);
printf("MajorSubsystemVersion : %04x\n", OptionalHeader.MajorSubsystemVersion);
printf("MinorSubsystemVersion : %04x\n", OptionalHeader.MinorSubsystemVersion);
printf("Win32VersionValue : %08lx\n", OptionalHeader.Win32VersionValue);
printf("SizeOfImage : %08lx\n", OptionalHeader.SizeOfImage);
printf("SizeOfHeaders : %08lx\n", OptionalHeader.SizeOfHeaders);
printf("CheckSum : %08lx\n", OptionalHeader.CheckSum);
printf("Subsystem : %04x\n", OptionalHeader.Subsystem);
printf("DllCharacteristics : %04x\n", OptionalHeader.DllCharacteristics);
printf("SizeOfStackReserve : %016llx\n", OptionalHeader.SizeOfStackReserve);
printf("SizeOfStackCommit : %016llx\n", OptionalHeader.SizeOfStackCommit);
printf("SizeOfHeapReserve : %016llx\n", OptionalHeader.SizeOfHeapReserve);
printf("SizeOfHeapCommit : %016llx\n", OptionalHeader.SizeOfHeapCommit);
printf("LoaderFlags : %08lx\n", OptionalHeader.LoaderFlags);
printf("NumberOfRvaAndSizes : %08lx\n", OptionalHeader.NumberOfRvaAndSizes);
printf("DataDirectory:\n");
for (int i = 0; i < OptionalHeader.NumberOfRvaAndSizes; i++) {
printf("%24s :",dataDirectories[i]);
printf("%02d : Size:%08lx VirtualAddress:%016lx\n", i, OptionalHeader.DataDirectory[i].Size,
OptionalHeader.DataDirectory[i].VirtualAddress);
}
}else{
Read(OH.b);
IMAGE_OPTIONAL_HEADER32 OptionalHeader=OH.b;
printf("magic : %04x\n",OptionalHeader.Magic);
printf("MajorLinkerVersion : %02x\n",OptionalHeader.MajorLinkerVersion);
printf("MinorLinkerVersion : %02x\n",OptionalHeader.MinorLinkerVersion);
printf("SizeOfCode : %08lx\n",OptionalHeader.SizeOfCode);
printf("SizeOfInitializedData : %08lx\n",OptionalHeader.SizeOfInitializedData);
printf("SizeOfUninitializedData : %08lx\n",OptionalHeader.SizeOfUninitializedData);
printf("AddressOfEntryPoint : %08lx\n",OptionalHeader.AddressOfEntryPoint);
printf("BaseOfCode : %08lx\n",OptionalHeader.BaseOfCode);
printf("BaseOfData : %08lx\n",OptionalHeader.BaseOfData);
printf("ImageBase : %08lx\n",OptionalHeader.ImageBase);
printf("SectionAlignment : %08lx\n",OptionalHeader.SectionAlignment);
printf("FileAlignment : %08lx\n",OptionalHeader.FileAlignment);
printf("MajorOperatingSystemVersion : %04x\n",OptionalHeader.MajorOperatingSystemVersion);
printf("MinorOperatingSystemVersion : %04x\n",OptionalHeader.MinorOperatingSystemVersion);
printf("MajorImageVersion : %04x\n",OptionalHeader.MajorImageVersion);
printf("MinorImageVersion : %04x\n",OptionalHeader.MinorImageVersion);
printf("MajorSubsystemVersion : %04x\n",OptionalHeader.MajorSubsystemVersion);
printf("MinorSubsystemVersion : %04x\n",OptionalHeader.MinorSubsystemVersion);
printf("Win32VersionValue : %08lx\n",OptionalHeader.Win32VersionValue);
printf("SizeOfImage : %08lx\n",OptionalHeader.SizeOfImage);
printf("SizeOfHeaders : %08lx\n",OptionalHeader.SizeOfHeaders);
printf("CheckSum : %08lx\n",OptionalHeader.CheckSum);
printf("Subsystem : %04x\n",OptionalHeader.Subsystem);
printf("DllCharacteristics : %04x\n",OptionalHeader.DllCharacteristics);
printf("SizeOfStackReserve : %08lx\n",OptionalHeader.SizeOfStackReserve);
printf("SizeOfStackCommit : %08lx\n",OptionalHeader.SizeOfStackCommit);
printf("SizeOfHeapReserve : %08lx\n",OptionalHeader.SizeOfHeapReserve);
printf("SizeOfHeapCommit : %08lx\n",OptionalHeader.SizeOfHeapCommit);
printf("LoaderFlags : %08lx\n",OptionalHeader.LoaderFlags);
printf("NumberOfRvaAndSizes : %08lx\n",OptionalHeader.NumberOfRvaAndSizes);
for (int i = 0; i < OptionalHeader.NumberOfRvaAndSizes; i++) {
printf("%24s :",dataDirectories[i]);
printf("%02d : Size:%08lx VirtualAddress:%016lx\n", i, OptionalHeader.DataDirectory[i].Size,
OptionalHeader.DataDirectory[i].VirtualAddress);
}
}
//读取section header
IMAGE_SECTION_HEADER sh;
for(int i=0;i< FileHeader.NumberOfSections;i++){
Read(sh);
printf("Name : ");
if(sh.Name[0]!='/'){
for (int i = 0; i < 8; i++) {
if (sh.Name[i] != '\0')putchar(sh.Name[i]);
else break;
}puts("");
}else{
int off = atoi((char*)sh.Name+1);
auto t=input.tellg();
input.seekg(symposition+18*numofsym+off);
while(true){
char c=input.get();
if(c!='\0')cout.put(c);
else break;
}
input.seekg(t);
}
printf("VirtualSize :%08lx\n", sh.Misc.VirtualSize);
printf("VirtualAddress :%08lx\n", sh.VirtualAddress);
printf("SizeOfRawData :%08lx\n", sh.SizeOfRawData);
printf("PointerToRawData :%08lx\n", sh.PointerToRawData);
printf("PointerToRelocations :%08lx\n", sh.PointerToRelocations);
printf("PointerToLinenumbers :%08lx\n", sh.PointerToLinenumbers);
printf("NumberOfRelocations :%04x\n", sh.NumberOfRelocations);
printf("NumberOfLinenumbers :%04x\n", sh.NumberOfLinenumbers);
printf("Characteristics :%08lx\n", sh.Characteristics);
puts("");
auto idatastart =sh.VirtualAddress;
auto secheaderaddr=input.tellg();
//保存节头表位置并查找节所对应的数据
input.seekg(sh.PointerToRawData);
int cnt=16;
if(!strcmp((char*)sh.Name,".rdata")){
for(int i=0;i<sh.SizeOfRawData&&i<500;i++){
unsigned char c=input.get();
if(c>=32&&c<126){
printf("%c",c);
}else if(c=='\n')puts("");
else printf("%02x ",c);
cnt--;
if(cnt==0){
//puts("");
cnt=16;
}
}
}else if(!strcmp((char *)sh.Name,".idata")){
int len=sh.SizeOfRawData;
IMAGE_IMPORT_DESCRIPTOR iid;
vector<IMAGE_IMPORT_DESCRIPTOR> IID;
do{
Read(iid);
IID.push_back(iid);
}while(iid.OriginalFirstThunk!=0);
for(int i=0;i<IID.size()-1;i++){
IMAGE_IMPORT_DESCRIPTOR iid=IID[i];
printf("OriginalFirstThunk : %08lx\n",iid.OriginalFirstThunk);
printf("TimeDateStamp : %08lx\n",iid.TimeDateStamp);
printf("ForwarderChain : %08lx\n",iid.ForwarderChain);
//求在idata中的偏移
input.seekg(sh.PointerToRawData+iid.Name - idatastart);
char c;
printf("Name : ");
while(c=input.get(),c != '\0'){
cout.put(c);
}
puts("");
printf("FirstThunk : %08lx\n",iid.FirstThunk);
puts("");
if(pe==PE32){
}else{
unsigned long long ist;
vector<unsigned long long> INT;
auto t=iid.OriginalFirstThunk-idatastart
+sh.PointerToRawData;
input.seekg(t);
do{
Read(ist);
INT.push_back(ist);
}while(ist);
t=iid.FirstThunk-idatastart
+sh.PointerToRawData;
input.seekg(t);
vector<unsigned long long > IAT;
do{
Read(ist);
IAT.push_back(ist);
}while(ist);
for(int i=0;i<INT.size()-1;i++){
auto ist=INT[i];
auto iat=IAT[i];
auto raw=sh.PointerToRawData+ist-idatastart;
WORD hint;
ReadAddr(hint,raw);
printf("hint: %d \nname: ",hint);
ReadStr(raw+2);
puts("");
printf("address: %016llx\n",iat);
}
cout<<"end"<<endl;
}
}
}else{
for(int i=0;i<sh.SizeOfRawData&&i<500;i++){
unsigned char c=input.get();
printf("%02x ",c);
cnt--;
if(cnt==0){
puts("");
cnt=16;
}
}
}
puts("");
input.seekg(secheaderaddr);
}
}
void readSym(ifstream &input){
IMAGE_SYMBOL sym;
input.seekg(symposition);
for(int i=0;i<numofsym;i++){
char *p=(char *)&sym;
for(int j=0;j<sizeof (sym);j++){
p[j]=input.get();
}
printf("Name : ");
if(sym.N.Name.Short==0){
auto t=input.tellg();
input.seekg(symposition+18*numofsym+sym.N.Name.Long);
while(true){
char c=input.get();
if(c!='\0')cout.put(c);
else break;
}
input.seekg(t);
}else{
for(int j=0;j<8;j++){
if(sym.N.ShortName[j]!='\0')cout.put(sym.N.ShortName[j]);
else break;
}
}puts("");
printf("Value : %08lx\n",sym.Value);
printf("SectionNumber : %04x\n",sym.SectionNumber);
printf("Type : %04x\n",sym.Type);
printf("StorageClass : %02x\n",sym.StorageClass);
printf("NumberOfAuxSymbols : %02x\n",sym.NumberOfAuxSymbols);
puts("");
}
}
void readSt(ifstream &input){
puts("");
puts("strings :");
DWORD len ;
input.seekg(symposition+18*numofsym);
char *a=(char *)&len;
for(int i=0;i<4;i++)a[i]=input.get();
for(int i=0;i<len-4;i++){
unsigned char c=input.get();
if(c>=32&&c<126){
printf("%c",c);
}else if(c=='\n')puts("");
else printf("%02x ",c);
}
}
int main(int argc,char **argv){
if(argc<2){
cout<<"need file name"<<endl;
}
ifstream input(argv[1],ios::binary);
if(input.is_open()){
//cout<<"open success"<<endl;
}else{
cout<<"open failed"<<endl;
}
readDos(input);
readNt(input);
readSym(input);
readSt(input);
}