作為臨時解決方案,我正在實作一種通過 32 位 DLL 將一些資料獲取到 64 位應用程式的方法。
我讓它盡可能簡單,它不需要是高性能或最漂亮的解決方案。這個想法是不要在花哨的握手等上浪費太多時間。
為此,我的 64 位應用程式加載了一個我自己制作的 64 位 DLL(它具有與 32 位 DLL 相同的匯出函式)。因此,在主應用程式中,沒有任何變化。
64 位 DLL 通過在命令列上傳遞記憶體映射檔案的名稱和一些其他輸入資料來創建一個記憶體映射檔案并啟動一個 32 位幫助程式。
輔助程式可執行檔案加載 32 位 DLL,呼叫 DLL 函式,將資料復制到共享記憶體映射檔案中,然后退出,然后……Bob 是你的叔叔。也就是說..鮑勃今天過得很糟糕,它不起作用。WriteFile()記憶體映射檔案失敗并出現 Windows API 錯誤 6 ( ERROR_INVALID_HANDLE),如GetLastError().
除了寫入記憶體映射檔案外,一切正常(讀取也可能失敗,但還沒有做到這一點)。
我確定問題在于我如何創建記憶體映射檔案,我在這里完全超出了我的深度,所以我很欣賞一雙新鮮的眼睛。
64位DLL中的相關代碼:
char MemoryFileName[] = "unique_name_with_extra_random_chars";
HANDLE MemoryFile = CreateFileMapping(INVALID_HANDLE_VALUE, NULL,
PAGE_EXECUTE_READWRITE, 0, (256 * 1024), MemoryFileName) ;
if (MemoryFile)
{
void *View = MapViewOfFile(MemoryFile, FILE_MAP_ALL_ACCESS, 0, 0, 0) ;
char Exe[] = "Hlpr.exe" ;
char Cmd[2048] = "Hlpr.exe " ;
strcat(Cmd, "\"") ;
strcat(Cmd, MemoryFileName) ;
strcat(Cmd, "\" \"") ;
strcat(Cmd, "262144") ; // (256 * 1024)
strcat(Cmd, "\" \"") ;
strcat(Cmd, file_name_path_of_data_the_dll_needs_to_parse) ;
strcat(Cmd, "\"") ;
STARTUPINFO StartupInfo = {sizeof StartupInfo} ; // Init
PROCESS_INFORMATION ProcessInfo ;
if (CreateProcess(Exe, Cmd, NULL, NULL, false, 0, NULL, NULL,
&StartupInfo, &ProcessInfo))
{
if (WaitForSingleObject(ProcessInfo.hProcess, INFINITE) == WAIT_OBJECT_0)
{
DWORD ExitCode ;
if (GetExitCodeProcess(ProcessInfo.hProcess, &ExitCode))
{
Status = (ExitCode >> 24) ; // Feedback from the dll function
if (Status == DLL_FUNCTION_OK)
{
DWORD Size = (ExitCode & 0x00FFFFFF) ;
if (Size)
{
BYTE *Buffer = new BYTE[Size] ;
Dll_function_return_Data =
(Dll_function_return_Data_Type*)Buffer ;
SetFilePointer(MemoryFile, 0, 0, FILE_BEGIN) ;
DWORD BytesCopied ;
ReadFile(MemoryFile, Buffer, Size, &BytesCopied, NULL) ;
if (BytesCopied != Size)
Status = MY_ERROR ;
}
}
}
}
CloseHandle(ProcessInfo.hProcess) ;
CloseHandle(ProcessInfo.hThread) ;
}
UnmapViewOfFile(View) ;
}
CloseHandle(MemoryFile) ;
32位相關代碼Hlpr.exe:
if (ParamCount() >= 3)
{
String DllPath = StringReplace(ParamStr(0), L"Hlpr.exe",
L"the_32bit_dll.dll", TReplaceFlags() << rfReplaceAll) ;
DllHandle = LoadLibraryExW(DllPath.c_str(), NULL, 0) ;
if (DllHandle)
{
// Here the dll exported function pointers are collected (GetProcAddress())
if (dll_function_pointer)
{
MemoryFile = OpenFileMapping(FILE_MAP_ALL_ACCESS, false,
ParamStr(1).c_str()) ;
if (MemoryFile)
{
void *View = MapViewOfFile(MemoryFile, FILE_MAP_ALL_ACCESS, 0, 0, 0);
DWORD SizeOfMappedFile = ParamStr(2).ToInt() ;
if (SizeOfMappedFile)
{
AnsiString ImageFileNameA(ParamStr(3)) ;
DWORD Size ;
Dll_function_return_Data_Type *Dll_function_return_Data ;
Status = dll_function_pointer(ImageFileNameA.c_str(),
Dll_function_return_Data, Size) ;
if (Status == DLL_FUNCTION_OK)
{
if (SizeOfMappedFile >= Size)
{
SetFilePointer(MemoryFile, 0, 0, FILE_BEGIN) ;
if (WriteFile(MemoryFile, (BYTE*)Dll_function_return_Data,
Size, &BytesCopied, NULL)) // FAILS
{
if (Size != BytesCopied)
Status = MY_ERROR ;
}
else
{
LOG("Error: %u", GetLastError()) ; // Returns error 6
Status = MY_ERROR ;
}
}
else
Status = MY_ERROR ;
}
}
UnmapViewOfFile(View) ;
}
}
}
}
程式使用此退出代碼退出:
return ((Status << 24) | BytesCopied) ;
uj5u.com熱心網友回復:
根據評論,我意識到我誤解了 FileMapping 的使用HANDLE和MapViewOfFile().
而不是在記憶體映射檔案上使用ReadFile()and我可以簡單地使用回傳的指標WriteFile()memcpy()MapViewOfFile()
這是固定代碼:
64位DLL中的相關代碼:
char MemoryFileName[] = "unique_name_with_extra_random_chars";
HANDLE MemoryFile = CreateFileMapping(INVALID_HANDLE_VALUE, NULL,
PAGE_EXECUTE_READWRITE, 0, (256 * 1024), MemoryFileName) ;
if (MemoryFile)
{
void *Mem = MapViewOfFile(MemoryFile, FILE_MAP_ALL_ACCESS, 0, 0, 0) ;
char Exe[] = "Hlpr.exe" ;
char Cmd[2048] = "Hlpr.exe " ;
strcat(Cmd, "\"") ;
strcat(Cmd, MemoryFileName) ;
strcat(Cmd, "\" \"") ;
strcat(Cmd, "262144") ; // (256 * 1024)
strcat(Cmd, "\" \"") ;
strcat(Cmd, file_name_path_of_data_the_dll_needs_to_parse) ;
strcat(Cmd, "\"") ;
STARTUPINFO StartupInfo = {sizeof StartupInfo} ; // Init
PROCESS_INFORMATION ProcessInfo ;
if (Mem && CreateProcess(Exe, Cmd, NULL, NULL, false, 0, NULL, NULL,
&StartupInfo, &ProcessInfo))
{
if (WaitForSingleObject(ProcessInfo.hProcess, INFINITE) == WAIT_OBJECT_0)
{
DWORD ExitCode ;
if (GetExitCodeProcess(ProcessInfo.hProcess, &ExitCode))
{
Status = (ExitCode >> 24) ; // Feedback from the dll function
if (Status == DLL_FUNCTION_OK)
{
DWORD Size = (ExitCode & 0x00FFFFFF) ;
if (Size)
{
BYTE *Buffer = new BYTE[Size] ;
Dll_function_return_Data =
(Dll_function_return_Data_Type*)Buffer ;
memcpy(Buffer, Mem, Size) ;
}
}
}
}
CloseHandle(ProcessInfo.hProcess) ;
CloseHandle(ProcessInfo.hThread) ;
}
UnmapViewOfFile(Mem) ;
}
CloseHandle(MemoryFile) ;
32位相關代碼Hlpr.exe:
if (ParamCount() >= 3)
{
String DllPath = StringReplace(ParamStr(0), L"Hlpr.exe",
L"the_32bit_dll.dll", TReplaceFlags() << rfReplaceAll) ;
DllHandle = LoadLibraryExW(DllPath.c_str(), NULL, 0) ;
if (DllHandle)
{
// Here the dll exported function pointers are collected (GetProcAddress())
if (dll_function_pointer)
{
MemoryFile = OpenFileMapping(FILE_MAP_ALL_ACCESS, false,
ParamStr(1).c_str()) ;
if (MemoryFile)
{
void *Mem = MapViewOfFile(MemoryFile, FILE_MAP_ALL_ACCESS, 0, 0, 0) ;
DWORD SizeOfMappedFile = ParamStr(2).ToInt() ;
if (Mem && SizeOfMappedFile)
{
AnsiString ImageFileNameA(ParamStr(3)) ;
DWORD Size ;
Dll_function_return_Data_Type *Dll_function_return_Data ;
Status = dll_function_pointer(ImageFileNameA.c_str(),
Dll_function_return_Data, Size) ;
if (Status == DLL_FUNCTION_OK)
{
if (SizeOfMappedFile >= Size)
{
memcpy(Mem, (BYTE*)Dll_function_return_Data, Size) ;
BytesCopied = Size ;
}
else
Status = MY_ERROR ;
}
}
UnmapViewOfFile(Mem) ;
}
}
}
}
The program exits with this exit code:
return ((Status << 24) | BytesCopied) ;
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/442482.html
