滴水三期逆向基础系列(六)-解析导入表

附上VS对IMPORT的一系列原装定义

typedef struct _IMAGE_IMPORT_DESCRIPTOR {
	union {
		DWORD   Characteristics;            // 0 for terminating null import descriptor
		DWORD   OriginalFirstThunk;         // RVA to original unbound IAT (PIMAGE_THUNK_DATA)
	} DUMMYUNIONNAME;
	DWORD   TimeDateStamp;                  // 0 if not bound,
	DWORD   ForwarderChain;                 // -1 if no forwarders
	DWORD   Name;
	DWORD   FirstThunk;                     // RVA to IAT (if bound this IAT has actual addresses)
} IMAGE_IMPORT_DESCRIPTOR;

typedef struct _IMAGE_THUNK_DATA64 {
	union {
		ULONGLONG ForwarderString;  // PBYTE 
		ULONGLONG Function;         // PDWORD
		ULONGLONG Ordinal;
		ULONGLONG AddressOfData;    // PIMAGE_IMPORT_BY_NAME
	} u1;
} IMAGE_THUNK_DATA64;
typedef struct _IMAGE_IMPORT_BY_NAME {
	WORD    Hint;
	CHAR   Name[1];
} IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME;

 

导入表解析没有什么难点,重点是绑定导入表的一系列操作,要牢记

VOID ReturnAllImport(
	IN LPVOID pFileBuffer
){
	if(pFileBuffer == NULL){
		return;
	}
	if(!is64Bit){
		PIMAGE_DOS_HEADER idh = NULL;
		PIMAGE_NT_HEADERS inh = NULL;
		PIMAGE_OPTIONAL_HEADER ioh = NULL;
		PIMAGE_SECTION_HEADER ish = NULL;
		
		idh = (PIMAGE_DOS_HEADER)pFileBuffer;
		inh = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer + idh->e_lfanew);
		ioh = &inh->OptionalHeader;
		ish = (PIMAGE_SECTION_HEADER)((DWORD)ioh + inh->FileHeader.SizeOfOptionalHeader);
	
		PIMAGE_DATA_DIRECTORY pdd = ioh->DataDirectory;
		if(pdd[1].VirtualAddress == 0){
			cout << "不存在导入表..." << endl;
			return ;
		}
		DWORD ImportVirtualAddrTemp = pdd[1].VirtualAddress;
		DWORD ImportVirtualAddr = RVAToFOA(ImportVirtualAddrTemp, pFileBuffer);
		cout << hex << "ImportVirtualAddr = " << ImportVirtualAddr << endl;
		
		PIMAGE_IMPORT_DESCRIPTOR ped = (PIMAGE_IMPORT_DESCRIPTOR)(ImportVirtualAddr + (DWORD)pFileBuffer);
		cout << hex << "-----------IMAGE_IMPORT_DESCRIPTOR---------" << endl;
		cout << hex << "-importRVA                   = " << ImportVirtualAddrTemp       << endl;
		cout << hex << "-importSize                  = " << pdd[1].Size                    << endl;
		DWORD num = 1;
		while(!(ped->FirstThunk == 0x00 && ped->OriginalFirstThunk == 0x00)){
			cout << hex << "--" << num ++ << endl;
			cout << hex << "-importName                  = " << ped->Name<< endl;
			printf(        "-importNameString            = %s\n", RVAToFOA(ped->Name, pFileBuffer) + (DWORD)pFileBuffer);
			printf(        "-importFirstThunk            = %x\n", ped->FirstThunk);
			DWORD oftRva = ped->OriginalFirstThunk;
			DWORD oftFoa = (RVAToFOA(ped->OriginalFirstThunk, pFileBuffer));
			DWORD oftFoaTemp = (RVAToFOA(ped->OriginalFirstThunk, pFileBuffer) + (DWORD)pFileBuffer);

			PIMAGE_THUNK_DATA itd = (PIMAGE_THUNK_DATA)oftFoaTemp;
			cout << hex << "-ThunkDetail------------------------" << endl;
			cout << hex << "----ThunkRVA\t\tThunkFOA\tThunkValue\tHint\t\tName" << endl;
			while(itd->u1.AddressOfData != 0){
				cout <<"\t" << oftRva <<"\t\t" << oftFoa <<"\t\t" << itd->u1.AddressOfData <<"\t\t";
				if(IMAGE_SNAP_BY_ORDINAL(itd->u1.AddressOfData)){
					 printf( "\t0x%04X\n" , itd->u1.AddressOfData & 0xFFFF);
				}else{
					PIMAGE_IMPORT_BY_NAME pib = (PIMAGE_IMPORT_BY_NAME)(RVAToFOA(itd->u1.AddressOfData, pFileBuffer) + (DWORD)pFileBuffer);
					printf( "%04X\t\t%s\n" ,pib->Hint ,pib->Name );
				}
				itd += 1;
				oftRva += sizeof(PIMAGE_IMPORT_BY_NAME);
				oftFoa += sizeof(PIMAGE_IMPORT_BY_NAME);
			}
			ped += 1;
		}
		
	}else{
		PIMAGE_DOS_HEADER idh = NULL;
		PIMAGE_NT_HEADERS64 inh = NULL;
		PIMAGE_OPTIONAL_HEADER64 ioh = NULL;
		PIMAGE_SECTION_HEADER ish = NULL;
		
		idh = (PIMAGE_DOS_HEADER)pFileBuffer;
		inh = (PIMAGE_NT_HEADERS64)((DWORD)pFileBuffer + idh->e_lfanew);
		ioh = &inh->OptionalHeader;
		ish = (PIMAGE_SECTION_HEADER)((DWORD)ioh + inh->FileHeader.SizeOfOptionalHeader);
	
		PIMAGE_DATA_DIRECTORY pdd = ioh->DataDirectory;
		if(pdd[1].VirtualAddress == 0){
			cout << "不存在导入表..." << endl;
			return ;
		}
		DWORD ImportVirtualAddrTemp = pdd[1].VirtualAddress;
		DWORD ImportVirtualAddr = RVAToFOA(ImportVirtualAddrTemp, pFileBuffer);
		cout << hex << "ImportVirtualAddr = " << ImportVirtualAddr << endl;
		
		PIMAGE_IMPORT_DESCRIPTOR ped = (PIMAGE_IMPORT_DESCRIPTOR)(ImportVirtualAddr + (DWORD)pFileBuffer);
		cout << hex << "-----------IMAGE_IMPORT_DESCRIPTOR---------" << endl;
		cout << hex << "-importRVA                   = " << ImportVirtualAddrTemp       << endl;
		cout << hex << "-importSize                  = " << pdd[1].Size                    << endl;
		DWORD num = 1;
		while(!(ped->FirstThunk == 0x00 && ped->OriginalFirstThunk == 0x00)){
			cout << hex << "--" << num ++ << endl;
			cout << hex << "-importName                  = " << ped->Name<< endl;
			printf(        "-importNameString            = %s\n", RVAToFOA(ped->Name, pFileBuffer) + (DWORD)pFileBuffer);
			printf(        "-importFirstThunk            = %x\n", ped->FirstThunk);
			DWORD oftRva = ped->OriginalFirstThunk;
			DWORD oftFoa = (RVAToFOA(ped->OriginalFirstThunk, pFileBuffer));
			DWORD oftFoaTemp = (RVAToFOA(ped->OriginalFirstThunk, pFileBuffer) + (DWORD)pFileBuffer);

			PIMAGE_THUNK_DATA64 itd = (PIMAGE_THUNK_DATA64)oftFoaTemp;
			cout << hex << "-ThunkDetail------------------------" << endl;
			cout << hex << "----ThunkRVA\t\tThunkFOA\tThunkValue\tHint\t\tName" << endl;
			while(itd->u1.AddressOfData != 0){
				cout <<"\t" << oftRva <<"\t\t" << oftFoa <<"\t\t" << itd->u1.AddressOfData <<"\t\t";
				if(IMAGE_SNAP_BY_ORDINAL64(itd->u1.AddressOfData)){
					 printf( "----no Name----\t0x%04X\n" , itd->u1.AddressOfData & 0xFFFF);
				}else{
					PIMAGE_IMPORT_BY_NAME pib = (PIMAGE_IMPORT_BY_NAME)(RVAToFOA(itd->u1.AddressOfData, pFileBuffer) + (DWORD)pFileBuffer);
					printf( "%04X\t\t%s\n" ,pib->Hint ,pib->Name );
				}
				itd += 1;
				oftRva += sizeof(PIMAGE_IMPORT_BY_NAME);
				oftFoa += sizeof(PIMAGE_IMPORT_BY_NAME);
			}
			ped += 1;
		}
	}
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值