Thank you for the very fast reply! :)
You are correct, it still compiles without the "64" struct name suffix, I will remember that. (I am compiling 64-bit, Windows 10.)
From your suggestion, have now tried:
1 2
|
IMAGE_LOAD_CONFIG_DIRECTORY image_config_info = {};
image_config_info.Size = sizeof(image_config_info);
|
1 2
|
IMAGE_LOAD_CONFIG_DIRECTORY image_config_info = {};
image_config_info.Size = 64;
|
and
1 2
|
IMAGE_LOAD_CONFIG_DIRECTORY image_config_info = {};
image_config_info.Size = 32;
|
but all still cause the error code to be 13.
Edit:
Also, this fails as well, same error code.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
|
int main()
{
std::string image_name = "accesschk64.exe"; //"main.exe";
PLOADED_IMAGE p_loaded_image = ImageLoad(image_name.c_str(), nullptr);
if (!p_loaded_image)
{
std::cout << "ImageLoad error " << GetLastError() << std::endl;
return 1;
}
IMAGE_LOAD_CONFIG_DIRECTORY image_config_info;
//image_config_info.Size = 64 ;//sizeof(image_config_info);
bool win_ret = GetImageConfigInformation(p_loaded_image, &image_config_info);
if (!win_ret)
{
int err = GetLastError();
std::cout << "GetImageConfigInformation failed, error " << err << '\n';
return 2;
}
else
{
std::cout << "Image Config Information loaded\n";
}
// TODO: Cleanup resources
return 0;
}
|
Note that I also found this "example" in a search,
https://elogeel.wordpress.com/2010/11/07/thread-scheduling-priorities-and-affinities/
In this example, .Size is not set. But of course that doesn't mean it shouldn't be set... but it seems to make no difference whether it is or isn't.
Edit 2:
I'm starting to think this is some sort of version compatibility issue.
You can see what's currently on the MSDN page,
https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-_image_load_config_directory64
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
|
typedef struct _IMAGE_LOAD_CONFIG_DIRECTORY64 {
DWORD Size;
DWORD TimeDateStamp;
WORD MajorVersion;
WORD MinorVersion;
DWORD GlobalFlagsClear;
DWORD GlobalFlagsSet;
DWORD CriticalSectionDefaultTimeout;
ULONGLONG DeCommitFreeBlockThreshold;
ULONGLONG DeCommitTotalFreeThreshold;
ULONGLONG LockPrefixTable;
ULONGLONG MaximumAllocationSize;
ULONGLONG VirtualMemoryThreshold;
ULONGLONG ProcessAffinityMask;
DWORD ProcessHeapFlags;
WORD CSDVersion;
WORD DependentLoadFlags;
ULONGLONG EditList;
ULONGLONG SecurityCookie;
ULONGLONG SEHandlerTable;
ULONGLONG SEHandlerCount;
ULONGLONG GuardCFCheckFunctionPointer;
ULONGLONG GuardCFDispatchFunctionPointer;
ULONGLONG GuardCFFunctionTable;
ULONGLONG GuardCFFunctionCount;
DWORD GuardFlags;
IMAGE_LOAD_CONFIG_CODE_INTEGRITY CodeIntegrity;
ULONGLONG GuardAddressTakenIatEntryTable;
ULONGLONG GuardAddressTakenIatEntryCount;
ULONGLONG GuardLongJumpTargetTable;
ULONGLONG GuardLongJumpTargetCount;
ULONGLONG DynamicValueRelocTable;
ULONGLONG CHPEMetadataPointer;
ULONGLONG GuardRFFailureRoutine;
ULONGLONG GuardRFFailureRoutineFunctionPointer;
DWORD DynamicValueRelocTableOffset;
WORD DynamicValueRelocTableSection;
WORD Reserved2;
ULONGLONG GuardRFVerifyStackPointerFunctionPointer;
DWORD HotPatchTableOffset;
DWORD Reserved3;
ULONGLONG EnclaveConfigurationPointer;
ULONGLONG VolatileMetadataPointer;
} IMAGE_LOAD_CONFIG_DIRECTORY64, *PIMAGE_LOAD_CONFIG_DIRECTORY64;
|
In my winnt.h file, however, it looks like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
typedef struct {
DWORD Size;
DWORD TimeDateStamp;
WORD MajorVersion;
WORD MinorVersion;
DWORD GlobalFlagsClear;
DWORD GlobalFlagsSet;
DWORD CriticalSectionDefaultTimeout;
ULONGLONG DeCommitFreeBlockThreshold;
ULONGLONG DeCommitTotalFreeThreshold;
ULONGLONG LockPrefixTable;
ULONGLONG MaximumAllocationSize;
ULONGLONG VirtualMemoryThreshold;
ULONGLONG ProcessAffinityMask;
DWORD ProcessHeapFlags;
WORD CSDVersion;
WORD Reserved1;
ULONGLONG EditList;
ULONGLONG SecurityCookie;
ULONGLONG SEHandlerTable;
ULONGLONG SEHandlerCount;
} IMAGE_LOAD_CONFIG_DIRECTORY64,*PIMAGE_LOAD_CONFIG_DIRECTORY64;
|
So I perhaps do need to fill in Size with something, but nothing I've tried so far as worked.
Edit 3: Actually, I wrote a program to try all .Size values between 0 and sizeof(IMAGE_LOAD_CONFIG_DIRECTORY) * 10, and none of those values worked. So it's not just an issue with size.
Edit 4: I can't read Chinese, but the same error happens in the program from this link:
https://bbs.csdn.net/topics/200087305 (fixed for modern C++ below)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
|
#include <iostream>
#include <windows.h>
#include <imagehlp.h>
#include <time.h>
using std::cout;
int main() {
OPENFILENAME ofn;
TCHAR szFileName[MAX_PATH];
LOADED_IMAGE loadedImage;
BOOL bRet;
IMAGE_LOAD_CONFIG_DIRECTORY imageLoadedConfig;
memset(&ofn, 0, sizeof(ofn));
memset(szFileName, 0, sizeof(szFileName));
ofn.lStructSize = sizeof(ofn);
ofn.lpstrFilter = TEXT("Executable Files(*.exe)\0*.exe\0DLL Files(*.dll)\0*.dllAll Files(*.*)\0*.*\0\0");
ofn.lpstrFile = szFileName;
ofn.nMaxFile = MAX_PATH;
GetOpenFileName(&ofn);
bRet = MapAndLoad(szFileName, NULL, &loadedImage, FALSE, TRUE);
if(bRet == FALSE) {
cout << "Error Ocuure in MapAndLoad\n";
}
bRet = GetImageConfigInformation(&loadedImage, &imageLoadedConfig);
if(bRet == FALSE) {
cout << "error ocuure in GetImageConfigInformation: " << GetLastError() << '\n';
}
UnMapAndLoad(&loadedImage);
return 0;
}
|
g++ -Wall main2.cpp -limagehlp -lcomdlg32 -o main2.exe |
Edit 5: To top it off, the following program produces error 87 (invalid parameter) in Visual Studio 2017, but error 13 if compiled with g++.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
|
#pragma comment(lib, "Imagehlp.lib")
#include <iostream>
#include <windows.h>
#include <imagehlp.h>
#include <time.h>
using std::cout;
int main() {
LOADED_IMAGE loadedImage;
BOOL bRet;
IMAGE_LOAD_CONFIG_DIRECTORY imageLoadedConfig;
const char* filename = "test.exe";
bRet = MapAndLoad(filename, NULL, &loadedImage, FALSE, TRUE);
if (bRet == FALSE) {
cout << "Error Ocuure in MapAndLoad\n";
}
bRet = GetImageConfigInformation(&loadedImage, &imageLoadedConfig);
if (bRet == FALSE) {
cout << "error ocuure in GetImageConfigInformation: " << GetLastError() << '\n';
}
UnMapAndLoad(&loadedImage);
return 0;
}
|
And apparently MapAndLoad isn't compatible with Unicode so that's funny too.