win32asm导入表

非IAT , 没用的代码,反编译用

用c32asm, petools验证

2个版本

 

masm版本:

.386
.model flat, stdcall
option casemap:none

include		windows.inc
include		user32.inc
includelib	user32.lib
include		kernel32.inc
includelib	kernel32.lib
include msvcrt.inc
includelib msvcrt.lib

.const 
szFilePath db 'C:\\code\\win32\\Project3\\Debug\\peTest_new.exe',0
szError db '出错了',0
szMsgImport	db	0dh,0ah
		db	'------------------------------------------------',0dh,0ah
		db	'导入库名: %s',0dh,0ah
		db	'------------------------------------------------',0dh,0ah
		db	'OriginalFirstThunk %08X',0dh,0ah
		db	'TimeDateStamp      %08X',0dh,0ah
		db	'ForwarderChain     %08X',0dh,0ah
		db	'FirstThunk         %08X',0dh,0ah
		db	'------------------------------------------------',0dh,0ah
		db	'导入序号  导入函数名称',0dh,0ah
		db	'------------------------------------------------',0dh,0ah,0
szMsgName	db	'%8u  %s',0dh,0ah,0
szMsgOrdinal	db	'%8u  (按序号导入)',0dh,0ah,0
szMsgSectionName		db	'导入表所处的节:%s',0dh,0ah,0
.code

GetSectionName proc pMem,dwRVA
	local dwName
	mov dwName,0
	pushad
	mov esi,pMem
	assume esi:ptr IMAGE_DOS_HEADER
	add esi,[esi].e_lfanew
	assume esi:ptr IMAGE_NT_HEADERS
	movzx ecx, [esi].FileHeader.NumberOfSections
	mov edi,esi
	add edi,IMAGE_NT_HEADERS.OptionalHeader	
	movzx  edx, [esi].FileHeader.SizeOfOptionalHeader 
	add edi,edx
	assume edi : ptr IMAGE_SECTION_HEADER

	xor edx,edx
	mov ebx,dwRVA
	.while ecx != 0
		mov edx, [edi].VirtualAddress
		add edx,[edi].SizeOfRawData
		.if  ebx>= [edi].VirtualAddress && ebx < edx
			lea eax,[edi].Name1
			mov dwName,eax
			.break
		.endif
		dec ecx
		add edi,sizeof IMAGE_SECTION_HEADER
	.endw

	popad
	assume esi:nothing
	assume edi:nothing
	mov eax,dwName
	ret
GetSectionName endp
 
RVA2FOA proc pMem, dwRVA
	local dwOffset:dword
	pushad

	mov dwOffset,0
	mov esi,pMem
	assume esi:ptr IMAGE_DOS_HEADER
	add esi,[esi].e_lfanew
	assume esi:ptr IMAGE_NT_HEADERS
	movzx ecx, [esi].FileHeader.NumberOfSections
	mov edi,esi
	add edi,IMAGE_NT_HEADERS.OptionalHeader
	movzx edx, [esi].FileHeader.SizeOfOptionalHeader 
	add edi,edx
	assume edi:ptr IMAGE_SECTION_HEADER

	xor edx,edx
	xor eax,eax
	mov ebx,dwRVA
	.while ecx != 0
		mov edx,[edi].VirtualAddress
		add edx, [edi].SizeOfRawData
		.if	 ebx >= [edi].VirtualAddress &&  ebx < edx
			mov eax,[edi].VirtualAddress
			mov edx,ebx
			sub edx,eax
			add edx, [edi].PointerToRawData
			mov dwOffset,edx
			.break
		.endif
		add edi,sizeof IMAGE_SECTION_HEADER
		dec ecx
	.endw


	assume esi:nothing
	assume edi:nothing
	popad
	mov eax,dwOffset
	ret
RVA2FOA endp



printImportSeciton proc pMem
	local buffer[1024]:byte
	pushad
	mov esi,pMem
	assume esi:ptr IMAGE_DOS_HEADER
	add esi,[esi].e_lfanew
	assume esi:ptr IMAGE_NT_HEADERS
	mov edx, [esi].OptionalHeader.DataDirectory[8].VirtualAddress
	.if !edx
		invoke MessageBox,0,addr szError,addr szError, MB_OK
		jmp done
	.endif
	invoke RVA2FOA,pMem,edx
	add eax,pMem
	mov edi,eax

	assume edi: ptr IMAGE_IMPORT_DESCRIPTOR
	assume esi:ptr IMAGE_IMPORT_BY_NAME
	xor esi,esi
	invoke GetSectionName,pMem,[edi].OriginalFirstThunk
	invoke 	wsprintf,addr buffer,addr szMsgSectionName,eax
		invoke  crt_printf , addr buffer


	.while [edi].OriginalFirstThunk
		invoke RVA2FOA,pMem,[edi].Name1
		add eax,pMem
		mov ebx,eax
		invoke 	wsprintf,addr buffer,addr szMsgImport,ebx,\
				[edi].OriginalFirstThunk,[edi].TimeDateStamp,\
				[edi].ForwarderChain,[edi].FirstThunk
		lea eax, buffer
		invoke  crt_printf , addr buffer

		invoke RVA2FOA , pMem,[edi].OriginalFirstThunk
		add eax,pMem
		mov edx,eax
		
		.while dword ptr [edx]
			.if dword ptr [edx] & IMAGE_ORDINAL_FLAG32
				mov ax,word ptr [edx]
				invoke	wsprintf,addr buffer,addr szMsgOrdinal,ax
				invoke  crt_printf , addr buffer
			.else
				invoke RVA2FOA,pMem,dword ptr [edx] 
				add eax,pMem
				mov esi,eax
				movzx ebx,[esi].Hint
				invoke	wsprintf,addr buffer,\
						addr szMsgName,ebx,addr [esi].Name1
				invoke  crt_printf,addr buffer
			.endif
			add edx,sizeof IMAGE_THUNK_DATA
		.endw

		add edi,sizeof IMAGE_IMPORT_DESCRIPTOR
	.endw





done:
	assume edi:nothing
	assume esi:nothing
	popad
	ret
printImportSeciton endp


exception_handler proc C _lpExceptionRecord,_lpSEH,_lpContext,_lpDispatcherContext
	pushad
	assume edi:ptr CONTEXT
	mov edx,_lpSEH
	push [edx+0ch]
	pop [edi].regEbp
	push [edx+8]
	pop [edi].regEip
	push edx
	pop [edi].regEsp
	assume edi:nothing
	popad
	mov eax,ExceptionContinueExecution
	ret
exception_handler endp

isPeFile proc pMem
	local ok
	pushad

	mov ok,0
	mov esi, pMem
	.if esi == 0
		jmp done
	.endif
	assume esi:ptr IMAGE_DOS_HEADER
	.if [esi].e_magic != IMAGE_DOS_SIGNATURE
		jmp done
	.endif
	add esi, [esi].e_lfanew
	assume esi:ptr IMAGE_NT_HEADERS
	.if [esi].Signature != IMAGE_NT_SIGNATURE
		jmp done
	.endif
	mov ok,1
done:
	assume esi:nothing
	popad
	mov eax,ok
	ret
isPeFile endp


openFileFunc proc filepath:dword
	local hFile , dwFileSize, hMap, pMap
	assume fs:nothing
	pushad
	push ebp
	push offset error
	push offset exception_handler
	push fs:[0]
	mov fs:[0],esp

	invoke CreateFile,filepath,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_ARCHIVE,NULL
	.if eax == INVALID_HANDLE_VALUE
		jmp error
	.endif
	mov hFile, eax
	invoke GetFileSize,eax,0
	mov dwFileSize, eax
	invoke CreateFileMapping,hFile,NULL,PAGE_READONLY,0,0,NULL
	.if  eax == 0
		jmp error
	.endif
	mov hMap,eax
	invoke MapViewOfFile,eax,FILE_MAP_READ,0,0,0
	.if eax == 0
		jmp error
	.endif
	mov pMap, eax
	invoke isPeFile,eax
	.if	eax == 0
		jmp error
	.endif 
	invoke printImportSeciton, pMap
	invoke UnmapViewOfFile,pMap
	invoke CloseHandle,hMap
	invoke CloseHandle,hFile
	jmp done



error:
		invoke MessageBox,0,addr szError,addr szError, MB_OK
done:
	pop fs:[0]
	add esp,0ch
	popad
	ret
openFileFunc endp


main proc
	call AllocConsole

	invoke openFileFunc,addr szFilePath
	invoke ExitProcess,0
	ret
main endp
end main

 

 

C版本:

// ConsoleApplication1.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <Windows.h>
#include <iostream>
using std::cout;
using std::endl;

char szSectionName[] = " 导入表所处的节:%s\n";
char szMsgImport[] = "\n导入库: %s\nOriginalFirstThunk RVA:%08X FOA:%08X\nFirstThunk         RVA:%08X FOA:%08X\n导入序号  导入函数名称\n";
char szMsgName[] = "%8u  %s\n";
char szMsgOrdinal[] = "%8u  (按序号导入)\n";
char szError[] = "这个文件不使用任何导入函数\n";
char szMsgSection[] = "节区名称  节区大小  虚拟地址  Raw_尺寸  Raw_偏移  节区属性\n";
char szSection[] = "%s\t%08X  %08X  %08X  %08X  %08X\n";

IMAGE_SECTION_HEADER * find_section(void * mem, DWORD rva) {
	IMAGE_DOS_HEADER * dos = (IMAGE_DOS_HEADER *)mem;
	IMAGE_NT_HEADERS * nt = (IMAGE_NT_HEADERS*)((DWORD)dos + dos->e_lfanew);
	int n = nt->FileHeader.NumberOfSections;
	IMAGE_SECTION_HEADER * sec = 0;
	IMAGE_SECTION_HEADER * header = IMAGE_FIRST_SECTION(nt);


	for (int i = 0; i < n; ++i) {
		if (rva >= header->VirtualAddress && rva < header->VirtualAddress + header->SizeOfRawData) {
			sec = header;
			break;
		}
		header++;
	}

	return sec;
}


DWORD rva2foa(void * mem , DWORD rva) {
	DWORD offset = 0;
	IMAGE_SECTION_HEADER  * sec= find_section(mem, rva);
	if (sec) {
		offset = rva - sec->VirtualAddress;
		offset += sec->PointerToRawData;
	}

	return offset;
}

char * get_section_name(void * mem, DWORD rva) {
	char * name = 0;
	IMAGE_SECTION_HEADER * sec = find_section(mem, rva);
	if (sec) {
		name = (char*)sec->Name;
	}
	return name;
}

void printImport(void * mem) {
	IMAGE_DOS_HEADER * dos = (IMAGE_DOS_HEADER *)mem;
	IMAGE_NT_HEADERS * nt = (IMAGE_NT_HEADERS*)((DWORD)dos + dos->e_lfanew);
	DWORD importRVA = nt->OptionalHeader.DataDirectory[1].VirtualAddress;
	DWORD importFOA = rva2foa(mem, importRVA);
	IMAGE_IMPORT_DESCRIPTOR * pDLL = (IMAGE_IMPORT_DESCRIPTOR*)((DWORD)mem + importFOA);
	char * pDllName = 0;
	IMAGE_THUNK_DATA * pFunction = 0;
	IMAGE_IMPORT_BY_NAME * pName = 0;


	printf(szSectionName , get_section_name(mem, importRVA));
	while (pDLL->OriginalFirstThunk) {
		pDllName =(char*) (rva2foa(mem, pDLL->Name) + (DWORD)mem);
		printf(szMsgImport, pDllName, pDLL->OriginalFirstThunk,rva2foa(mem, pDLL->OriginalFirstThunk), pDLL->FirstThunk,rva2foa(mem, pDLL->FirstThunk));
		pFunction = (IMAGE_THUNK_DATA*)(rva2foa(mem, pDLL->OriginalFirstThunk) + (DWORD)mem);

		while (pFunction->u1.AddressOfData) {
			if (pFunction->u1.AddressOfData & IMAGE_ORDINAL_FLAG32) {
				printf(szMsgOrdinal,LOWORD(pFunction));
			}
			else {
				pName = (IMAGE_IMPORT_BY_NAME *)(rva2foa(mem, pFunction->u1.AddressOfData) +(DWORD)mem);
				printf(szMsgName, pName->Hint, pName->Name);
			}

			pFunction++;
		}
		pDLL++;
	}
}

void printSection(void * mem) {
	IMAGE_DOS_HEADER * dos = (IMAGE_DOS_HEADER *)mem;
	IMAGE_NT_HEADERS * nt = (IMAGE_NT_HEADERS*)((DWORD)dos + dos->e_lfanew);
	int n = nt->FileHeader.NumberOfSections;
	IMAGE_SECTION_HEADER * header = IMAGE_FIRST_SECTION(nt);
	printf(szMsgSection);
	for (int i = 0; i < n; ++i) {
		printf(szSection, header->Name, header->Misc.VirtualSize, header->VirtualAddress,
			header->SizeOfRawData, header->PointerToRawData, header->Characteristics);
		header++;
	}
}

void createFileMapAndPrint(TCHAR * szFileName) {
	//没做异常处理
	HANDLE hFile = CreateFile(szFileName, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_ARCHIVE, 0);
	DWORD dwFileSize = 0;
	if (INVALID_HANDLE_VALUE == hFile) {
		cout << "create file failed" << endl;
		return;
	}
	HANDLE hMap = CreateFileMapping(hFile, 0, PAGE_READONLY, 0, 0, 0);
	if (0 == hMap) {
		cout << "CreateFileMapping failed" << endl;
		return;
	}
	void * mem  = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0);
	if (0 == mem) {
		cout << "MapViewOfFile failed" << endl;
		return;
	}
	printImport(mem);
	printSection(mem);

	UnmapViewOfFile(mem);
	CloseHandle(hMap);
	CloseHandle(hFile);
}

int main()
{
	TCHAR szFileName[] =L"C:\\Windows\\System32\\notepad.exe";
	createFileMapAndPrint(szFileName);
	getchar();
    return 0;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值