Skip to content

Commit fc3994f

Browse files
[IIS] Manually parse exe bitness (#61894)
1 parent e26a16c commit fc3994f

File tree

3 files changed

+62
-12
lines changed

3 files changed

+62
-12
lines changed

src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolver.cpp

Lines changed: 59 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ HostFxrResolver::TryGetHostFxrPath(
197197
size_t size = MAX_PATH * 2;
198198
hostfxrPath.resize(size);
199199

200-
get_hostfxr_parameters params;
200+
get_hostfxr_parameters params{};
201201
params.size = sizeof(get_hostfxr_parameters);
202202
params.assembly_path = applicationPath.c_str();
203203
params.dotnet_root = dotnetRoot.c_str();
@@ -393,7 +393,7 @@ HostFxrResolver::GetAbsolutePathToDotnetFromHostfxr(const fs::path& hostfxrPath)
393393
// Tries to call where.exe to find the location of dotnet.exe.
394394
// Will check that the bitness of dotnet matches the current
395395
// worker process bitness.
396-
// Returns true if a valid dotnet was found, else false.R
396+
// Returns true if a valid dotnet was found, else false.
397397
//
398398
std::optional<fs::path>
399399
HostFxrResolver::InvokeWhereToFindDotnet()
@@ -416,7 +416,6 @@ HostFxrResolver::InvokeWhereToFindDotnet()
416416
STRU struDotnetSubstring;
417417
STRU struDotnetLocationsString;
418418
DWORD dwNumBytesRead = 0;
419-
DWORD dwBinaryType = 0;
420419
INT index = 0;
421420
INT prevIndex = 0;
422421
std::optional<fs::path> result;
@@ -521,14 +520,7 @@ HostFxrResolver::InvokeWhereToFindDotnet()
521520

522521
LOG_INFOF(L"Processing entry '%ls'", struDotnetSubstring.QueryStr());
523522

524-
if (LOG_LAST_ERROR_IF(!GetBinaryTypeW(struDotnetSubstring.QueryStr(), &dwBinaryType)))
525-
{
526-
continue;
527-
}
528-
529-
LOG_INFOF(L"Binary type %d", dwBinaryType);
530-
531-
if (fIsCurrentProcess64Bit == (dwBinaryType == SCS_64BIT_BINARY))
523+
if (fIsCurrentProcess64Bit == IsX64(struDotnetSubstring.QueryStr()))
532524
{
533525
// The bitness of dotnet matched with the current worker process bitness.
534526
return std::make_optional(struDotnetSubstring.QueryStr());
@@ -539,6 +531,62 @@ HostFxrResolver::InvokeWhereToFindDotnet()
539531
return result;
540532
}
541533

534+
BOOL HostFxrResolver::IsX64(const WCHAR* dotnetPath)
535+
{
536+
// Errors while reading from the file shouldn't throw unless
537+
// file.exception(bits) is set
538+
std::ifstream file(dotnetPath, std::ios::binary);
539+
if (!file.is_open())
540+
{
541+
LOG_TRACEF(L"Failed to open file %ls", dotnetPath);
542+
return false;
543+
}
544+
545+
// Read the DOS header
546+
IMAGE_DOS_HEADER dosHeader{};
547+
file.read(reinterpret_cast<char*>(&dosHeader), sizeof(dosHeader));
548+
if (dosHeader.e_magic != IMAGE_DOS_SIGNATURE) // 'MZ'
549+
{
550+
LOG_TRACEF(L"%ls is not a valid executable file (missing MZ header).", dotnetPath);
551+
return false;
552+
}
553+
554+
// Seek to the PE header
555+
file.seekg(dosHeader.e_lfanew, std::ios::beg);
556+
557+
// Read the PE header
558+
DWORD peSignature{};
559+
file.read(reinterpret_cast<char*>(&peSignature), sizeof(peSignature));
560+
if (peSignature != IMAGE_NT_SIGNATURE) // 'PE\0\0'
561+
{
562+
LOG_TRACEF(L"%ls is not a valid PE file (missing PE header).", dotnetPath);
563+
return false;
564+
}
565+
566+
// Read the file header
567+
IMAGE_FILE_HEADER fileHeader{};
568+
file.read(reinterpret_cast<char*>(&fileHeader), sizeof(fileHeader));
569+
570+
// Read the optional header magic field
571+
WORD magic{};
572+
file.read(reinterpret_cast<char*>(&magic), sizeof(magic));
573+
574+
// Determine the architecture based on the magic value
575+
if (magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC)
576+
{
577+
LOG_INFOF(L"%ls is 32-bit", dotnetPath);
578+
return false;
579+
}
580+
else if (magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC)
581+
{
582+
LOG_INFOF(L"%ls is 64-bit", dotnetPath);
583+
return true;
584+
}
585+
586+
LOG_INFOF(L"%ls is unknown architecture %i", dotnetPath, fileHeader.Machine);
587+
return false;
588+
}
589+
542590
std::optional<fs::path>
543591
HostFxrResolver::GetAbsolutePathToDotnetFromProgramFiles()
544592
{

src/Servers/IIS/AspNetCoreModuleV2/CommonLib/HostFxrResolver.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ class HostFxrResolver
7474
const std::filesystem::path & requestedPath
7575
);
7676

77+
static BOOL IsX64(const WCHAR* dotnetPath);
78+
7779
struct LocalFreeDeleter
7880
{
7981
void operator ()(_In_ LPWSTR* ptr) const

src/Servers/IIS/build/Build.Lib.Settings

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
<ItemDefinitionGroup>
1111
<ClCompile>
12-
<SDLCheck>false</SDLCheck>
12+
<SDLCheck>true</SDLCheck>
1313
<PreprocessorDefinitions>_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
1414
<ConformanceMode>true</ConformanceMode>
1515
</ClCompile>

0 commit comments

Comments
 (0)