汇编解析pe文件

主要是为了练习一下汇编语言编成和pe文件结构。

#include
#include
//winnt.h
char   *OutputDebug="OutputDebugStringA\0";//length=0x12
DWORD   KernelBase=0x7c800000;//方便试验,直接用工具读的一个值

WORD   dMZ=0;
WORD   dNumberOfSections=0;
DWORD  e_lfanew=0;
DWORD  dSignature=0;
WORD   wSizeOfOptionalHeader=0;
DWORD  DataDirExport=0;
DWORD  SectionVA=0,SectionVS=0,SectionHeaderPTRD;
DWORD  NumberOfNames=0;
DWORD  FuncIndex=0;
DWORD  FuncAddr=0;

DWORD sell()
{
	_asm
	{
		mov    eax,KernelBase
		mov    bx,word ptr [eax]
		mov    dMZ,bx
		cmp    bx,0x5a4d;MZ标示
		jnz    retu
		mov    ebx,dword ptr [eax+0x3c];获取PE头偏移
		mov    e_lfanew,ebx
		test   ebx,ebx
		jz     retu
		mov    ecx,dword ptr [eax+ebx]
		mov    dSignature,ecx
		cmp    ecx,0x4550;PE标示
		jnz    retu
		mov    cx,word ptr [eax+ebx+4+16]
		mov    wSizeOfOptionalHeader,cx
        ;直接读的结构体里面的偏移,这个用winDbg看可能比较直观一点 
		mov    edx,dword ptr [eax+ebx+0x78];nt_headers.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EPORT].VirtualAddress
		mov    DataDirExport,edx

		mov     dx,word ptr [eax+ebx+4+2];ImageNtHeaders.ImageFileHeader.NumberOfSection
		mov     dNumberOfSections,dx
find_sec:
		mov    ecx,dword ptr [eax+ebx+0xf8+0xc];SectionHeader.VirtualAddress
		mov    SectionVA,ecx
		cmp    dword ptr [eax+ebx+0x78],ecx
		jl     next_sec
		add    ecx,dword ptr [eax+ebx+0xf8+0x8];SectionHeader.Misc.VirtualSize
        cmp    dword ptr [eax+ebx+0x78],ecx
		jl     find
next_sec:
		dec    dx
		jnz    find_sec
		jmp    retu
find:
		mov     edx,dword ptr [eax+ebx+0x78];因为模块已经加载到内存,这里可以直接用这个偏移加模块基址,和从本地文件读取有点差别
		mov     ecx,dword ptr [eax+edx+0x18];ImageExportDirectory.NumberOfNames
		mov     NumberOfNames,ecx

		mov     edx,dword ptr [eax+edx+0x20];ImageExportDirectory.AddressOfNames;存函数名称字符串的偏移,这里相当于一个数组
		push    ebx
		push    ecx
		add     edx,eax;加上基址
		mov     ebx,OutputDebug;要找的函数名称
		mov     esi,ebx
		xor     ebx,ebx
		;int     3
find_func_name:
		mov     ecx,18
		push    esi
		mov     edi,dword ptr [edx+4*ebx];从字符串数组中取值比较
		add     edi,eax
		repe    cmps   ;字符串循环比较,ecx为0或不等,结束比较
		test    ecx,ecx
		jz      get_func
		pop     esi
		inc     ebx
		pop     ecx
		cmp     ebx,ecx
		push    ecx
		jl      find_func_name
		jmp     search_done
get_func:
		mov     FuncIndex,ebx;保存函数标号
		mov     edi,ebx
		pop     esi
		pop     ecx
		pop     ebx
		
		mov     edx,dword ptr [eax+ebx+0x78];
		mov     edx,dword ptr [eax+edx+0x1c];ImageExportDirectory.AddressofFunctions
		add     edx,eax
		mov     ecx,dword ptr [edx+edi*4];从函数地址数组中取值(是偏移)
		mov     FuncAddr,ecx
		add     ecx,eax
		mov     edx,OutputDebug
		mov     esi,edx
		push    esi
		call    ecx;call OutputDebguStringA,可以用DbgView看到字符串'OutputDebugStringA'
		jmp     retu
search_done:
		pop    ecx
		pop    ebx
retu:
		xor    eax,eax
		;ret
	}
}

int main()
{
	sell();
	printf("dMZ:0x%x\n",dMZ);
	printf("e_lfanew:0x%x\n",e_lfanew);
	printf("dSignature:0x%x\n",dSignature);
	printf("dNumberOfSections:0x%x\n",dNumberOfSections);
	printf("wSizeOfOptionalHeader:0x%x\n",wSizeOfOptionalHeader);
	printf("DataDirExport:0x%x\n",DataDirExport);
	printf("SectionVA:0x%x\n",SectionVA);
	printf("SectionHeaderPTRD:0x%x\n",SectionHeaderPTRD);
	printf("NumberOfNames;0x%x\n",NumberOfNames);
	printf("FuncIndex:0x%x,..%d\n",FuncIndex,FuncIndex);
	printf("FuncAddr:0x%x\n",FuncAddr);
	getchar();
	return 0;
}

DbgView的截图:

汇编解析pe文件_第1张图片

你可能感兴趣的:(汇编语言)