非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;
}