;made by correy
;made in 16.08.2009
;Email:leguanyuan@126.com
;QQ:112426112
;rc me.rc
;ml /coff test.asm /link /subsystem:windows me.res
;此文件我花了半个月的时间才完成,
;用十天的时间完成rvatooffset子程序
;用三天的时间完成遍历dll文件
;用三天的时间完成遍历api函数。
;此文件没有加入seh异常处理,对一些文件不能查询。
;本文件完全用汇编语言编成,没有汇编语言的高级语法。
;此文件没有考虑pe+的情况
.386
.model flat,stdcall
option casemap:none
include windows.inc
include kernel32.inc
include user32.inc
include comdlg32.inc
includelib user32.lib
includelib kernel32.lib
includelib comdlg32.lib
.data
correy db "made by correy",0
wrong db "will over!",0
FilterString db "pe File (*.exe, *.dll)",0,"*.exe;*.dll",0,0
h db "%8x",0
.data?
ofn OPENFILENAME <>
buffer db 256 DUP (?)
mz dd ?
pe dd ?
OptionalHeader dd ?
header dd ?
magic word ?
sizeOfOptionalHeader dd ?
sections dd ?
v dd ?
.code
rvatooffset proc sectionsn,head,rva
push esi
push edi
push ecx
mov edi,rva
mov esi,head
mov ecx,sectionsn
again:cmp ecx,0
jna show
cmp edi,[esi+12]
jb add40
mov eax,[esi+12]
add eax,[esi+16]
cmp edi,eax
jnb add40
mov eax,[esi+12]
sub edi,eax
mov eax,[esi+20]
add eax,edi
jmp show
add40:add esi,40
dec ecx
jmp again
show:pop ecx
pop edi
pop esi
ret
rvatooffset endp
start:
mov ofn.lStructSize,SIZEOF ofn
mov ofn.lpstrFilter, OFFSET FilterString
mov ofn.lpstrFile, OFFSET buffer
mov ofn.nMaxFile,512
mov ofn.Flags, OFN_FILEMUSTEXIST or OFN_PATHMUSTEXIST or OFN_LONGNAMES or OFN_EXPLORER or OFN_HIDEREADONLY
invoke GetOpenFileName, ADDR ofn
cmp eax,0
je exit
invoke CreateFile, addr buffer, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL
cmp eax,INVALID_HANDLE_VALUE
je exit
invoke CreateFileMapping,eax, NULL, PAGE_READONLY,0,0,0
cmp eax,0
je exit
invoke MapViewOfFile,eax,FILE_MAP_READ,0,0,0
cmp eax,0
je exit
mov mz,eax
mov esi,mz
add esi,3ch
mov esi,[esi]
mov eax,mz
add esi,eax
mov pe,esi
mov esi,pe
add esi,6
mov dx,word ptr [esi]
movsx edx,dx
mov sections,edx
mov esi,pe
add esi,24
mov OptionalHeader,esi ;保存可选头的地址。
mov esi,pe
add esi,20
mov dx,word ptr [esi]
movsx edx,dx
mov sizeOfOptionalHeader,edx
mov esi,OptionalHeader
add esi,sizeOfOptionalHeader
mov header,esi ;保存节头的地址。
mov esi,OptionalHeader
add esi,104
mov esi,[esi]
invoke rvatooffset,sections,header,esi
mov edi,eax
mov esi,eax
add edi,mz
again2:cmp dword ptr [edi+12],0
je exit
cmp dword ptr [edi+16],0
je exit
add eax,12
add eax,mz
mov eax,[eax]
invoke rvatooffset,sections,header,eax
add eax,mz
invoke MessageBox,0,eax,addr correy,0
mov eax,[edi+16]
invoke rvatooffset,sections,header,eax
add eax,mz
again3:push eax
cmp dword ptr [eax],0
je exit2
test dword ptr [eax],80000000h
jne exit2
invoke rvatooffset,sections,header,dword ptr [eax]
add eax,mz
add eax,2
invoke MessageBox,0,eax,addr correy,0
pop eax
add eax,4
jmp again3
exit2:
add edi,20
add esi,20
mov eax,esi
jmp again2
exit:invoke MessageBox,0,addr wrong,addr correy,0
invoke ExitProcess,NULL
end start
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
#include <Windows.h>
#include <stdio.h> // for printf
/*
写作目的:遍历一个PE文件导入的DLL及其函数。
made by correy
made at 2015.06.23
*/
unsigned int RVATOOFFSET(IN PVOID lpFileBase,IN unsigned int rva)
/*
返回0表示失败,其他的是在文件中的偏移。
*/
{
unsigned int offset = 0;//返回值。
IMAGE_DOS_HEADER * p_image_dos_header = (IMAGE_DOS_HEADER * )lpFileBase;
ULONG ntSignature = (ULONG)p_image_dos_header + p_image_dos_header->e_lfanew;
ntSignature = * (ULONG *)ntSignature;
DWORD CoffHeaderOffset = (ULONG)p_image_dos_header + p_image_dos_header->e_lfanew + sizeof(ULONG);
IMAGE_FILE_HEADER * p_image_file_header = (IMAGE_FILE_HEADER *)CoffHeaderOffset;
//注意这里用的永远是:IMAGE_OPTIONAL_HEADER32.
//要分析IMAGE_OPTIONAL_HEADER64的一个办法是:强制定义一个,载赋值转换.
//其实这个结构的大小是固定的,只不过32位的和64位的不一样.但还是用规范建议的.IMAGE_FILE_HEADER的成员访问好.
IMAGE_OPTIONAL_HEADER * p_image_optional_header = (IMAGE_OPTIONAL_HEADER *)((ULONG)p_image_file_header + sizeof(IMAGE_FILE_HEADER));
IMAGE_SECTION_HEADER * p_image_section_header = (IMAGE_SECTION_HEADER *)((ULONG)p_image_optional_header + p_image_file_header->SizeOfOptionalHeader);//必须加(ULONG),不然出错.
for (int i = 0;i < p_image_file_header->NumberOfSections;i++) //规范规定是从1开始的.
{
if (rva >= p_image_section_header[i].VirtualAddress && rva <= (p_image_section_header[i].VirtualAddress + p_image_section_header[i].Misc.VirtualSize))
{
offset = rva - p_image_section_header[i].VirtualAddress + p_image_section_header[i].PointerToRawData;
break;
}
}
return offset;
}
void DumpFile(LPCWSTR filename)
/*
摘自:Peering Inside the PE: A Tour of the Win32 Portable Executable File Format.有改动。
*/
{
HANDLE hFile = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if ( hFile == INVALID_HANDLE_VALUE )
{
printf("Couldn't open file with CreateFile()\n");
return;
}
HANDLE hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
if ( hFileMapping == 0 )
{
CloseHandle(hFile);
printf("Couldn't open file mapping with CreateFileMapping()\n");
return;
}
LPVOID lpFileBase = MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0);
if ( lpFileBase == 0 )
{
CloseHandle(hFileMapping);
CloseHandle(hFile);
printf("Couldn't map view of file with MapViewOfFile()\n");
return;
}
PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)lpFileBase;
if ( dosHeader->e_magic != IMAGE_DOS_SIGNATURE )
{
printf("dosHeader->e_magic != IMAGE_DOS_SIGNATURE\n");
UnmapViewOfFile(lpFileBase);
CloseHandle(hFileMapping);
CloseHandle(hFile);
return;
}
LONG e_lfanew = dosHeader->e_lfanew;
PIMAGE_NT_HEADERS ntHeader = (PIMAGE_NT_HEADERS)((PCHAR)dosHeader + e_lfanew);
if (ntHeader->Signature != IMAGE_NT_SIGNATURE)
{
printf("ntHeader->Signature != IMAGE_NT_SIGNATURE\n");
UnmapViewOfFile(lpFileBase);
CloseHandle(hFileMapping);
CloseHandle(hFile);
return;
}
//if (FlagOn(ntHeader->FileHeader.Characteristics, IMAGE_FILE_DLL) || FlagOn(ntHeader->FileHeader.Characteristics, IMAGE_FILE_SYSTEM))
//{
// return;
//}
PIMAGE_IMPORT_DESCRIPTOR InportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)(ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress + (SIZE_T)lpFileBase);
ULONG InportSize = ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size;
//IMPORT_DESCRIPTOR = (PIMAGE_IMPORT_DESCRIPTOR)RtlImageDirectoryEntryToData ((SIZE_T)lpFileBase, TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &InportSize);//经测试二者相等。这一行等于上面的两行。
if (InportDescriptor == NULL)
{
//没有导出表。
//__debugbreak();
printf("InportDescriptor == NULL\n");
UnmapViewOfFile(lpFileBase);
CloseHandle(hFileMapping);
CloseHandle(hFile);
return;
}
InportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)(RVATOOFFSET(lpFileBase, (SIZE_T)InportDescriptor - (SIZE_T)lpFileBase) + (SIZE_T)lpFileBase);
int dll_count = 0;//
for ( ; ;dll_count++ )
{
//if (InportDescriptor->Characteristics == 0 && InportDescriptor->FirstThunk == 0 && InportDescriptor->ForwarderChain == 0 &&
// InportDescriptor->Name == 0 && InportDescriptor->OriginalFirstThunk && InportDescriptor->TimeDateStamp == 0)
//{
// break;
//}
//结束标志。
if (InportDescriptor->Name == 0)
{
break;
}
//printf("Characteristics == 0x%x\n", InportDescriptor->Characteristics);
//printf("OriginalFirstThunk == 0x%x\n", InportDescriptor->OriginalFirstThunk);//这个不打印,原因是和Characteristics一样。
//printf("TimeDateStamp == 0x%x\n", InportDescriptor->TimeDateStamp);//这个域一直被设置为 0,直到映像被绑定。当映像被绑定之后,这个域被设置为这个 DLL 的日期/时间戳。
//printf("ForwarderChain == 0x%x\n", InportDescriptor->ForwarderChain);
char * name = (char *)(RVATOOFFSET(lpFileBase, InportDescriptor->Name) + (SIZE_T)lpFileBase);
printf("\n\n\nDllName:%s\n", name);
//printf("FirstThunk == 0x%x\n", InportDescriptor->FirstThunk);//注意这个成员是有值的,值是地址,地址的内容是没初始化的。必须有值的。
//PIMAGE_IMPORT_BY_NAME import_by_name = (PIMAGE_IMPORT_BY_NAME)InportDescriptor->Characteristics;
//PIMAGE_THUNK_DATA thunk_data = (PIMAGE_THUNK_DATA)InportDescriptor->FirstThunk;
//PIMAGE_IMPORT_BY_NAME import_by_name = (PIMAGE_IMPORT_BY_NAME)(RVATOOFFSET(lpFileBase, InportDescriptor->Characteristics) + (SIZE_T)lpFileBase);
//PIMAGE_THUNK_DATA thunk_data = (PIMAGE_THUNK_DATA)(RVATOOFFSET(lpFileBase, InportDescriptor->FirstThunk) + (SIZE_T)lpFileBase);
PIMAGE_THUNK_DATA thunk_data = (PIMAGE_THUNK_DATA)(RVATOOFFSET(lpFileBase, InportDescriptor->Characteristics) + (SIZE_T)lpFileBase);
//PIMAGE_IMPORT_BY_NAME import_by_name = (PIMAGE_IMPORT_BY_NAME)(RVATOOFFSET(lpFileBase, thunk_data->u1.AddressOfData) + (SIZE_T)lpFileBase);
int api_count = 0;
for ( ; ;api_count++ )
{
//结束标志。
if (*(SIZE_T *)thunk_data == 0)
{
break;
}
PIMAGE_IMPORT_BY_NAME import_by_name = (PIMAGE_IMPORT_BY_NAME)(RVATOOFFSET(lpFileBase, thunk_data->u1.AddressOfData) + (SIZE_T)lpFileBase);
printf("\tAPIName:%s\n", import_by_name->Name);
thunk_data++;
}
InportDescriptor++;
}
UnmapViewOfFile(lpFileBase);
CloseHandle(hFileMapping);
CloseHandle(hFile);
}
int wmain(int argc, wchar_t *argv[])
{
if ( argc != 2 )
{
return 1;
}
DumpFile(argv[1]);
return 0;
}
没有评论:
发表评论