Skip to content

Commit 3ce7bdc

Browse files
committed
DotNetTools: Add .NET6 auxiliary provider support
1 parent 9d65d58 commit 3ce7bdc

File tree

2 files changed

+169
-27
lines changed

2 files changed

+169
-27
lines changed

plugins/DotNetTools/clrsup.c

Lines changed: 168 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -84,13 +84,10 @@ VOID FreeClrProcessSupport(
8484
_In_ PCLR_PROCESS_SUPPORT Support
8585
)
8686
{
87-
if (Support->DataProcess)
88-
IXCLRDataProcess_Release(Support->DataProcess);
89-
if (Support->DataTarget)
90-
ICLRDataTarget_Release(Support->DataTarget);
91-
92-
if (Support->DacDllBase)
93-
FreeLibrary(Support->DacDllBase);
87+
if (Support->DataProcess) IXCLRDataProcess_Release(Support->DataProcess);
88+
// Free the library here so we can cleanup in ICLRDataTarget_Release. (dmex)
89+
if (Support->DacDllBase) FreeLibrary(Support->DacDllBase);
90+
if (Support->DataTarget) ICLRDataTarget_Release(Support->DataTarget);
9491

9592
PhFree(Support);
9693
}
@@ -1127,11 +1124,11 @@ BOOLEAN DnGetProcessCoreClrPath(
11271124

11281125
if (!context.FileName)
11291126
{
1130-
PPH_PROCESS_ITEM processItem;
1131-
11321127
// This image is probably 'SelfContained' since we couldn't find coreclr.dll,
11331128
// return the path to the executable so we can check the embedded CLRDEBUGINFO. (dmex)
1134-
1129+
#ifdef _WIN64
1130+
PPH_PROCESS_ITEM processItem;
1131+
11351132
if (processItem = PhReferenceProcessItem(ProcessId))
11361133
{
11371134
if (!PhIsNullOrEmptyString(processItem->FileName))
@@ -1144,7 +1141,16 @@ BOOLEAN DnGetProcessCoreClrPath(
11441141

11451142
PhDereferenceObject(processItem);
11461143
}
1147-
1144+
#else
1145+
PPH_STRING fileName;
1146+
1147+
if (NT_SUCCESS(PhGetProcessImageFileNameByProcessId(ProcessId, &fileName)))
1148+
{
1149+
*FileName = fileName;
1150+
dataTarget->SelfContained = TRUE;
1151+
return TRUE;
1152+
}
1153+
#endif
11481154
return FALSE;
11491155
}
11501156

@@ -1157,6 +1163,30 @@ BOOLEAN DnGetProcessCoreClrPath(
11571163
return TRUE;
11581164
}
11591165

1166+
static VOID DnCleanupDacAuxiliaryProvider(
1167+
_In_ ICLRDataTarget* DataTarget
1168+
)
1169+
{
1170+
DnCLRDataTarget* dataTarget = (DnCLRDataTarget*)DataTarget;
1171+
1172+
if (dataTarget->SelfContained && dataTarget->DaccorePath)
1173+
{
1174+
PPH_STRING directoryPath;
1175+
1176+
if (directoryPath = PhGetBaseDirectory(dataTarget->DaccorePath))
1177+
{
1178+
PhDeleteDirectory(directoryPath);
1179+
PhDereferenceObject(directoryPath);
1180+
}
1181+
else
1182+
{
1183+
PhDeleteFileWin32(PhGetString(dataTarget->DaccorePath));
1184+
}
1185+
}
1186+
1187+
PhClearReference(&dataTarget->DaccorePath);
1188+
}
1189+
11601190
static BOOLEAN DnpMscordaccoreDirectoryCallback(
11611191
_In_ PFILE_DIRECTORY_INFORMATION Information,
11621192
_In_ PPH_LIST DirectoryList
@@ -1180,12 +1210,13 @@ static BOOLEAN DnpMscordaccoreDirectoryCallback(
11801210

11811211
PVOID DnLoadMscordaccore(
11821212
_In_ HANDLE ProcessId,
1183-
_In_ ICLRDataTarget *Target
1213+
_In_ ICLRDataTarget *DataTarget
11841214
)
11851215
{
11861216
// \dotnet\shared\Microsoft.NETCore.App\ is the same path used by the CLR for DAC detection. (dmex)
11871217
static PH_STRINGREF mscordaccorePathSr = PH_STRINGREF_INIT(L"%ProgramFiles%\\dotnet\\shared\\Microsoft.NETCore.App\\");
11881218
static PH_STRINGREF mscordaccoreNameSr = PH_STRINGREF_INIT(L"\\mscordaccore.dll");
1219+
DnCLRDataTarget* dataTarget = (DnCLRDataTarget*)DataTarget;
11891220
PVOID mscordacBaseAddress = NULL;
11901221
HANDLE directoryHandle;
11911222
PPH_LIST directoryList;
@@ -1195,14 +1226,13 @@ PVOID DnLoadMscordaccore(
11951226
ULONG dataTargetTimeStamp = 0;
11961227
ULONG dataTargetSizeOfImage = 0;
11971228

1198-
if (DnGetProcessCoreClrPath(ProcessId, Target, &dataTargetFileName))
1229+
if (DnGetProcessCoreClrPath(ProcessId, DataTarget, &dataTargetFileName))
11991230
{
12001231
PVOID imageBaseAddress;
12011232

12021233
if (NT_SUCCESS(PhLoadLibraryAsImageResource(dataTargetFileName, &imageBaseAddress)))
12031234
{
12041235
PCLR_DEBUG_RESOURCE debugVersionInfo;
1205-
//PVOID mscordaccoreDllAddress;
12061236

12071237
if (PhLoadResource(
12081238
imageBaseAddress,
@@ -1222,23 +1252,10 @@ PVOID DnLoadMscordaccore(
12221252
}
12231253
}
12241254

1225-
//if (PhLoadResource(
1226-
// imageBaseAddress,
1227-
// L"MINIDUMP_EMBEDDED_AUXILIARY_PROVIDER",
1228-
// RT_RCDATA,
1229-
// NULL,
1230-
// &mscordaccoreDllAddress
1231-
// ))
1232-
//{
1233-
// // TODO: Extract mscordaccore.dll from resource and PhVerifyFile. (dmex)
1234-
//}
1235-
12361255
PhFreeLibraryAsImageResource(imageBaseAddress);
12371256
}
12381257

12391258
dataTargetDirectory = PhGetBaseDirectory(dataTargetFileName);
1240-
1241-
PhDereferenceObject(dataTargetFileName);
12421259
}
12431260

12441261
if (!(directoryPath = PhExpandEnvironmentStrings(&mscordaccorePathSr)))
@@ -1334,7 +1351,105 @@ PVOID DnLoadMscordaccore(
13341351
PhClearReference(&fileName);
13351352
}
13361353

1354+
if (!mscordacBaseAddress && dataTargetFileName && dataTarget->SelfContained)
1355+
{
1356+
PVOID imageBaseAddress;
1357+
PVOID mscordacResourceBuffer;
1358+
ULONG mscordacResourceLength;
1359+
1360+
if (NT_SUCCESS(PhLoadLibraryAsImageResource(dataTargetFileName, &imageBaseAddress)))
1361+
{
1362+
if (PhLoadResource(
1363+
imageBaseAddress,
1364+
L"MINIDUMP_EMBEDDED_AUXILIARY_PROVIDER",
1365+
RT_RCDATA,
1366+
&mscordacResourceLength,
1367+
&mscordacResourceBuffer
1368+
))
1369+
{
1370+
static PH_STRINGREF tempFilePath = PH_STRINGREF_INIT(L"%TEMP%\\");
1371+
NTSTATUS status;
1372+
HANDLE fileHandle = NULL;
1373+
LARGE_INTEGER allocationSize;
1374+
PPH_STRING tempFileName;
1375+
WCHAR alphaString[32] = L"";
1376+
1377+
PhGenerateRandomAlphaString(alphaString, RTL_NUMBER_OF(alphaString));
1378+
tempFileName = PhExpandEnvironmentStrings(&tempFilePath);
1379+
tempFileName = PhConcatStringRefZ(&tempFileName->sr, alphaString);
1380+
1381+
if (NT_SUCCESS(status = PhCreateDirectory(tempFileName)))
1382+
{
1383+
PhMoveReference(&tempFileName, PhConcatStringRef2(&tempFileName->sr, &mscordaccoreNameSr));
1384+
1385+
allocationSize.QuadPart = mscordacResourceLength;
1386+
status = PhCreateFileWin32Ex(
1387+
&fileHandle,
1388+
PhGetString(tempFileName),
1389+
FILE_GENERIC_WRITE,
1390+
&allocationSize,
1391+
FILE_ATTRIBUTE_NORMAL,
1392+
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
1393+
FILE_CREATE,
1394+
FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY,
1395+
NULL
1396+
);
1397+
}
1398+
1399+
if (NT_SUCCESS(status) && fileHandle)
1400+
{
1401+
IO_STATUS_BLOCK isb;
1402+
1403+
status = NtWriteFile(
1404+
fileHandle,
1405+
NULL,
1406+
NULL,
1407+
NULL,
1408+
&isb,
1409+
mscordacResourceBuffer,
1410+
mscordacResourceLength,
1411+
NULL,
1412+
NULL
1413+
);
1414+
1415+
NtClose(fileHandle);
1416+
}
1417+
1418+
if (NT_SUCCESS(status))
1419+
{
1420+
VERIFY_RESULT verifyResult;
1421+
PPH_STRING signerName;
1422+
1423+
verifyResult = PhVerifyFile(
1424+
PhGetString(tempFileName),
1425+
&signerName
1426+
);
1427+
1428+
if (
1429+
verifyResult == VrTrusted &&
1430+
signerName && PhEqualString2(signerName, L"Microsoft Corporation", TRUE)
1431+
)
1432+
{
1433+
mscordacBaseAddress = PhLoadLibrary(PhGetString(tempFileName));
1434+
}
1435+
1436+
if (mscordacBaseAddress)
1437+
PhSetReference(&dataTarget->DaccorePath, tempFileName);
1438+
else
1439+
PhDeleteFileWin32(PhGetString(tempFileName));
1440+
1441+
PhClearReference(&signerName);
1442+
}
1443+
1444+
PhClearReference(&tempFileName);
1445+
}
1446+
1447+
PhFreeLibraryAsImageResource(imageBaseAddress);
1448+
}
1449+
}
1450+
13371451
PhClearReference(&dataTargetDirectory);
1452+
PhClearReference(&dataTargetFileName);
13381453

13391454
return mscordacBaseAddress;
13401455
}
@@ -1510,6 +1625,8 @@ ULONG STDMETHODCALLTYPE DnCLRDataTarget_Release(
15101625
{
15111626
NtClose(this->ProcessHandle);
15121627

1628+
DnCleanupDacAuxiliaryProvider(This);
1629+
15131630
PhFree(this);
15141631

15151632
return 0;
@@ -1615,6 +1732,7 @@ HRESULT STDMETHODCALLTYPE DnCLRDataTarget_GetImageBase(
16151732
{
16161733
if (this->SelfContained)
16171734
{
1735+
#ifdef _WIN64
16181736
PPH_PROCESS_ITEM processItem;
16191737
PPH_STRING baseName;
16201738

@@ -1639,6 +1757,29 @@ HRESULT STDMETHODCALLTYPE DnCLRDataTarget_GetImageBase(
16391757

16401758
PhDereferenceObject(processItem);
16411759
}
1760+
#else
1761+
PPH_STRING fileName;
1762+
PPH_STRING baseName;
1763+
1764+
if (NT_SUCCESS(PhGetProcessImageFileNameByProcessId(this->ProcessId, &fileName)))
1765+
{
1766+
if (baseName = PhGetBaseName(fileName))
1767+
{
1768+
context.ImagePath = baseName->sr;
1769+
PhEnumProcessModules(this->ProcessHandle, PhpGetImageBaseCallback, &context);
1770+
PhDereferenceObject(baseName);
1771+
1772+
if (context.BaseAddress)
1773+
{
1774+
*baseAddress = (CLRDATA_ADDRESS)context.BaseAddress;
1775+
PhDereferenceObject(fileName);
1776+
return S_OK;
1777+
}
1778+
}
1779+
1780+
PhDereferenceObject(fileName);
1781+
}
1782+
#endif
16421783
}
16431784

16441785
return E_FAIL;

plugins/DotNetTools/clrsup.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ typedef struct _DnCLRDataTarget
151151
BOOLEAN IsWow64;
152152
BOOLEAN SelfContained;
153153
PVOID DataTargetDllBase;
154+
PPH_STRING DaccorePath;
154155
} DnCLRDataTarget;
155156

156157
#define MAX_LONGPATH 1024

0 commit comments

Comments
 (0)