.code GetExportTableAddr proc @lpMem:dword ;取得导出表的地址 LOCAL @lpExportTableAddr:dword pushad mov esi, dword ptr[@lpMem] assume esi:ptr IMAGE_DOS_HEADER add esi, [esi].e_lfanew assume esi:ptr IMAGE_NT_HEADERS lea eax, [esi].OptionalHeader.DataDirectory mov @lpExportTableAddr, eax assume esi:nothing popad mov eax, @lpExportTableAddr ret GetExportTableAddr endp AnalysisExportTable proc @lpMem:dword LOCAL @lpOffsetAddressOfFunctions:dword LOCAL @lpOffsetAddressOfNames:dword LOCAL @lpOffsetAddressOfNameOrdinals:dword pushad invoke GetExportTableAddr, @lpMem mov esi, eax assume esi:ptr IMAGE_DATA_DIRECTORY mov eax, [esi].VirtualAddress PrintHex eax mov eax, [esi].isize PrintHex eax invoke RvaToOffset, @lpMem, [esi].VirtualAddress add eax, @lpMem PrintHex eax mov esi, eax assume esi:ptr IMAGE_EXPORT_DIRECTORY invoke RvaToOffset, @lpMem,[esi].nName ;得到指向DLL名字的RVA在PE文件中的偏移 add eax, @lpMem PrintStringByAddr eax invoke RvaToOffset, @lpMem, [esi].AddressOfFunctions ;导出函数地址数组地址(RVA),转换成PE文件中的偏移 add eax, @lpMem mov @lpOffsetAddressOfFunctions, eax invoke RvaToOffset, @lpMem, [esi].AddressOfNames add eax, @lpMem mov @lpOffsetAddressOfNames, eax ;导出函数名字数组地址 invoke RvaToOffset, @lpMem, [esi].AddressOfNameOrdinals add eax, @lpMem mov @lpOffsetAddressOfNameOrdinals, eax ;名字序号数组地址RVA在PE文件中的偏移 invoke AnalysisAddressOfNames, @lpMem, @lpOffsetAddressOfFunctions, @lpOffsetAddressOfNames,/ @lpOffsetAddressOfNameOrdinals, [esi].NumberOfFunctions, [esi].nBase assume esi:nothing popad ret AnalysisExportTable endp AnalysisAddressOfNames proc @lpMem:dword, @lpOffsetAddressOfFunctions:dword, @lpOffsetAddressOfNames:dword, @lpOffsetAddressOfNameOrdinals:dword,/ @dwNumberOfFunctions:dword, @dwBase:dword LOCAL @dwIndex:dword pushad mov @dwIndex, 0 xor ebx, ebx .while ebx < @dwNumberOfFunctions mov edi, dword ptr[@lpOffsetAddressOfFunctions] mov eax, dword ptr[edi + ebx * 4] PrintText "函数地址:" PrintHex eax mov edi, dword ptr[@lpOffsetAddressOfNameOrdinals] mov eax, @dwIndex mov ecx, @dwNumberOfFunctions cld repnz scasw .if ZERO? mov esi, edi sub esi, @lpOffsetAddressOfNameOrdinals ;如果指定索引在函数名序号表中能找到,则必定有一个函数名字符串与之对应 sub esi, 2 shl esi, 1 add esi, @lpOffsetAddressOfNames invoke RvaToOffset, @lpMem, dword ptr[esi] add eax, @lpMem PrintText "函数名称:" PrintStringByAddr eax .endif mov eax, ebx add eax, @dwBase PrintText "函数序号:" PrintHex eax inc ebx inc @dwIndex .endw popad ret AnalysisAddressOfNames endp