////////////////////////////////////////////////////////////////////////////////// // // 功能实现:获取指定PE文件中指定函数的导出地址 // 输入参数:Base为PE文件加载的基地址 // FindFunName为要查找的函数名 // NameLength为函数名长度 // 输出参数:返回指定函数名的函数首地址 // /////////////////////////////////////////////////////////////////////////////////// DWORD FindFunAddress(DWORD Base,PCHAR FindFunName,DWORD NameLength) { TRACE0("查找指定函数的地址"); PCHAR pImageBase=(PCHAR)Base; DWORD ImageBase=0x0000000; PIMAGE_FILE_HEADER pfh = NULL; PIMAGE_OPTIONAL_HEADER poh = NULL; PIMAGE_SECTION_HEADER psh =NULL; PIMAGE_EXPORT_DIRECTORY pExpDir = NULL; DWORD NumOfName=0x00000000; PDWORD pNameArray=NULL; PWORD pOrdNameArray=NULL; PDWORD pFuncArray=NULL; DWORD NumOfNativeFun=0x00000000; DWORD FunAddress=0x00000000; if(!GetHeaders(pImageBase,&pfh,&poh,&psh)) { TRACE0("[FindFunAddress] 获取PE头信息失败\n"); return 0x00000000; } ImageBase=poh->ImageBase; //获取导出表 pExpDir=(PIMAGE_EXPORT_DIRECTORY)((DWORD)pImageBase+RVAToFileOffset(pImageBase,poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress)); //获取导出函数名个数 NumOfName=pExpDir->NumberOfNames; //获取名字地址数组 pNameArray=(PDWORD)((DWORD)pImageBase+RVAToFileOffset(pImageBase,pExpDir->AddressOfNames)); //获取名字序数表 pOrdNameArray=(PWORD)((DWORD)pImageBase+RVAToFileOffset(pImageBase,pExpDir->AddressOfNameOrdinals)); //函数地址表 pFuncArray=(PDWORD)((DWORD)pImageBase+RVAToFileOffset(pImageBase,pExpDir->AddressOfFunctions)); for(DWORD iCount=0;iCount<NumOfName;iCount++) { PCSTR pName=(PCSTR)((DWORD)pImageBase+RVAToFileOffset(pImageBase,pNameArray[iCount])); if (!stricmp(pName,FindFunName)) { TRACE0("[FindFunAddress] 找到指定函数\n"); LPCVOID pFunc=(LPCVOID)((DWORD)pImageBase+RVAToFileOffset(pImageBase,pFuncArray[pOrdNameArray[iCount]])); FunAddress=(DWORD)pFunc; return FunAddress; } } TRACE0("[FindFunAddress] 没有找到指定函数\n"); return 0x00000000; }
CAppProtector::CAppProtector(const char *lpszProtectedFileName,const char *lpszOriginalPEImageName, CAppSecureDlg* t) { ui=t; /* lpszProtectedFileName is the output filename, which is "SecureFile.EXE" by default lpszOriginalPEImageName is the PE File to protect. This file will NOT be modified in anyway. */ szProtectedFileName=new char[lstrlen(lpszProtectedFileName)+1]; lstrcpy(szProtectedFileName,lpszProtectedFileName); szMyFileName=new char[lstrlen(lpszOriginalPEImageName)+1]; lstrcpy(szMyFileName,lpszOriginalPEImageName); ///////////////////////////////////////////////////////////////////////// LOADED_IMAGE li; if(MapAndLoad(szMyFileName,0,&li,FALSE,TRUE)) RVAToFileOffset(li.FileHeader,li.FileHeader->OptionalHeader.AddressOfEntryPoint,li.FileHeader->FileHeader.NumberOfSections); else { AfxMessageBox("Load Failed !"); exit(1); } UnMapAndLoad(&li); ///////////////////////////////////////////////////////////////////////// }
/** * @brief Initializes the given `ZydisPEContext` struct. * * @param context A pointer to the `ZydisPEContext` struct. * @param base A pointer to the memory that contains the mapped PE-file. * @param size The size of the memory mapped PE-file. * * @return A zycore status code. */ static ZyanStatus ZydisPEContextInit(ZydisPEContext* context, const void* base, ZyanUSize size) { ZYAN_ASSERT(context); ZYAN_ASSERT(base); ZYAN_ASSERT(size); context->base = base; context->size = size; ZyanStatus status; ZYAN_CHECK(status = ZyanVectorInit(&context->symbols, sizeof(ZydisPESymbol), 256)); if (!ZYAN_SUCCESS(status = ZyanVectorInit(&context->unique_strings, sizeof(ZyanString), 256))) { ZyanVectorDestroy(&context->symbols); return status; } const IMAGE_DOS_HEADER* dos_header = (const IMAGE_DOS_HEADER*)base; ZYAN_ASSERT(dos_header->e_magic == IMAGE_DOS_SIGNATURE); const IMAGE_NT_HEADERS32* nt_headers_temp = (const IMAGE_NT_HEADERS32*)((ZyanU8*)dos_header + dos_header->e_lfanew); ZYAN_ASSERT(nt_headers_temp->Signature == IMAGE_NT_SIGNATURE); // Parse symbols switch (nt_headers_temp->OptionalHeader.Magic) { case IMAGE_NT_OPTIONAL_HDR32_MAGIC: { const IMAGE_NT_HEADERS32* nt_headers = (const IMAGE_NT_HEADERS32*)((ZyanU8*)dos_header + dos_header->e_lfanew); context->image_base = nt_headers->OptionalHeader.ImageBase; // Exports ZydisPESymbol element; if (nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress) { const IMAGE_EXPORT_DIRECTORY* export_directory = (const IMAGE_EXPORT_DIRECTORY*)RVAToFileOffset(base, nt_headers->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress); ZyanString module_name; if (!ZYAN_SUCCESS(status = ZyanStringWrap(&module_name, (char*)RVAToFileOffset(base, export_directory->Name))) || !ZYAN_SUCCESS(status = ZyanStringDuplicate(&element.module_name, &module_name, 0))) { goto FatalError; } // Remove file-extension ZyanISize index; if (!ZYAN_SUCCESS(status = ZyanStringRPos(&module_name, &STR_DOT, &index))) { goto FatalError; } if (index >= 0) { if (!ZYAN_SUCCESS(status = ZyanStringTruncate(&element.module_name, index)) || !ZYAN_SUCCESS(status = ZyanVectorPush(&context->unique_strings, &element.module_name))) { goto FatalError; } } else if (!ZYAN_SUCCESS(status = ZyanVectorPush(&context->unique_strings, &element.module_name))) { goto FatalError; } const ZyanUPointer entry_point = nt_headers->OptionalHeader.AddressOfEntryPoint; element.address = entry_point; if (!ZYAN_SUCCESS((status = ZyanStringWrap(&element.symbol_name, (char*)"EntryPoint"))) || !ZYAN_SUCCESS((status = ZyanVectorPush(&context->symbols, &element)))) { goto FatalError; } const ZyanU32* export_addresses = (const ZyanU32*)RVAToFileOffset(base, export_directory->AddressOfFunctions); const ZyanU32* export_names = (const ZyanU32*)RVAToFileOffset(base, export_directory->AddressOfNames); for (ZyanU32 i = 0; i < export_directory->NumberOfFunctions; ++i) { element.address = export_addresses[i]; if (!ZYAN_SUCCESS((status = ZyanStringWrap(&element.symbol_name, (char*)RVAToFileOffset(base, export_names[i]))))) { goto FatalError; } ZyanUSize found_index; if (!ZYAN_SUCCESS((status = ZyanVectorBinarySearch(&context->symbols, &element, &found_index, (ZyanComparison)&CompareSymbol))) || !ZYAN_SUCCESS((status = ZyanVectorInsert(&context->symbols, found_index, &element)))) { goto FatalError; } } } // Imports if (nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress) { const IMAGE_IMPORT_DESCRIPTOR* descriptor = (const IMAGE_IMPORT_DESCRIPTOR*)RVAToFileOffset(base, nt_headers->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress); while (descriptor->u1.OriginalFirstThunk) { ZyanString module_name; if (!ZYAN_SUCCESS(status = ZyanStringWrap(&module_name, (char*)RVAToFileOffset(base, descriptor->Name))) || !ZYAN_SUCCESS(status = ZyanStringDuplicate(&element.module_name, &module_name, 0))) { goto FatalError; } // Remove file-extension ZyanISize index; if (!ZYAN_SUCCESS(status = ZyanStringRPos(&module_name, &STR_DOT, &index))) { goto FatalError; } if (index >= 0) { if (!ZYAN_SUCCESS(status = ZyanStringTruncate(&element.module_name, index)) || !ZYAN_SUCCESS(status = ZyanVectorPush(&context->unique_strings, &element.module_name))) { goto FatalError; } } else if (!ZYAN_SUCCESS(status = ZyanVectorPush(&context->unique_strings, &element.module_name))) { goto FatalError; } const IMAGE_THUNK_DATA32* original_thunk = (const IMAGE_THUNK_DATA32*)RVAToFileOffset(base, descriptor->u1.OriginalFirstThunk); element.address = descriptor->FirstThunk; ZyanUSize found_index; if (!ZYAN_SUCCESS((status = ZyanVectorBinarySearch(&context->symbols, &element, &found_index, (ZyanComparison)&CompareSymbol)))) { goto FatalError; } ZYAN_ASSERT(status == ZYAN_STATUS_FALSE); while (original_thunk->u1.ForwarderString) { if (!(original_thunk->u1.Ordinal & IMAGE_IMPORT_BY_ORDINAL32)) { const IMAGE_IMPORT_BY_NAME* by_name = (const IMAGE_IMPORT_BY_NAME*)RVAToFileOffset(base, original_thunk->u1.AddressOfData); if (!ZYAN_SUCCESS((status = ZyanStringWrap(&element.symbol_name, (char*)by_name->Name)))) { goto FatalError; } } if (!ZYAN_SUCCESS((status = ZyanVectorInsert(&context->symbols, found_index, &element)))) { goto FatalError; } element.address += sizeof(IMAGE_THUNK_DATA32); ++original_thunk; ++found_index; } ++descriptor; } } break; } case IMAGE_NT_OPTIONAL_HDR64_MAGIC: { const IMAGE_NT_HEADERS64* nt_headers = (const IMAGE_NT_HEADERS64*)((ZyanU8*)dos_header + dos_header->e_lfanew); context->image_base = nt_headers->OptionalHeader.ImageBase; // Exports ZydisPESymbol element; if (nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress) { const IMAGE_EXPORT_DIRECTORY* export_directory = (const IMAGE_EXPORT_DIRECTORY*)RVAToFileOffset(base, nt_headers->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress); if (!ZYAN_SUCCESS(ZyanStringWrap(&element.module_name, (char*)RVAToFileOffset(base, export_directory->Name)))) { goto FatalError; } // TODO: Implement /*for (ZyanUSize i = element.module_name.length - 1; i >= 0; --i) { if (element.module_name.buffer[i] == '.') { element.module_name.length = i; break; } }*/ const ZyanUPointer entry_point = nt_headers->OptionalHeader.AddressOfEntryPoint; element.address = entry_point; if (!ZYAN_SUCCESS((status = ZyanStringWrap(&element.symbol_name, (char*)"EntryPoint"))) || !ZYAN_SUCCESS((status = ZyanVectorPush(&context->symbols, &element)))) { goto FatalError; } const ZyanU32* export_addresses = (const ZyanU32*)RVAToFileOffset(base, export_directory->AddressOfFunctions); const ZyanU32* export_names = (const ZyanU32*)RVAToFileOffset(base, export_directory->AddressOfNames); for (ZyanU32 i = 0; i < export_directory->NumberOfFunctions; ++i) { element.address = export_addresses[i]; if (!ZYAN_SUCCESS((status = ZyanStringWrap(&element.symbol_name, (char*)RVAToFileOffset(base, export_names[i]))))) { goto FatalError; } ZyanUSize found_index; if (!ZYAN_SUCCESS((status = ZyanVectorBinarySearch(&context->symbols, &element, &found_index, (ZyanComparison)&CompareSymbol))) || !ZYAN_SUCCESS((status = ZyanVectorInsert(&context->symbols, found_index, &element)))) { goto FatalError; } } } // Imports if (nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress) { const IMAGE_IMPORT_DESCRIPTOR* descriptor = (const IMAGE_IMPORT_DESCRIPTOR*)RVAToFileOffset(base, nt_headers->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress); while (descriptor->u1.OriginalFirstThunk) { if (!ZYAN_SUCCESS((status = ZyanStringWrap(&element.module_name, (char*)RVAToFileOffset(base, descriptor->Name))))) { goto FatalError; } // TODO: Implement /*for (ZyanUSize i = element.module_name.length - 1; i >= 0; --i) { if (element.module_name.buffer[i] == '.') { element.module_name.length = i; break; } }*/ const IMAGE_THUNK_DATA64* original_thunk = (const IMAGE_THUNK_DATA64*)RVAToFileOffset(base, descriptor->u1.OriginalFirstThunk); element.address = descriptor->FirstThunk; ZyanUSize found_index; if (!ZYAN_SUCCESS((status = ZyanVectorBinarySearch(&context->symbols, &element, &found_index, (ZyanComparison)&CompareSymbol)))) { goto FatalError; } ZYAN_ASSERT(status == ZYAN_STATUS_FALSE); while (original_thunk->u1.ForwarderString) { if (!(original_thunk->u1.Ordinal & IMAGE_IMPORT_BY_ORDINAL64)) { const IMAGE_IMPORT_BY_NAME* by_name = (const IMAGE_IMPORT_BY_NAME*)RVAToFileOffset(base, original_thunk->u1.AddressOfData); if (!ZYAN_SUCCESS((status = ZyanStringWrap(&element.symbol_name, (char*)by_name->Name)))) { goto FatalError; } } if (!ZYAN_SUCCESS((status = ZyanVectorInsert(&context->symbols, found_index, &element)))) { goto FatalError; } element.address += sizeof(IMAGE_THUNK_DATA64); ++original_thunk; ++found_index; } ++descriptor; } } break; } default: ZYAN_UNREACHABLE; } return ZYAN_STATUS_SUCCESS; FatalError: ZydisPEContextFinalize(context); return status; }