@@ -5673,7 +5673,7 @@ NTSTATUS PhGetLoaderEntryImageEntryPoint(
5673
5673
)
5674
5674
{
5675
5675
if (ImageNtHeader -> OptionalHeader .AddressOfEntryPoint == 0 )
5676
- return STATUS_FAIL_CHECK ; // STATUS_ENTRYPOINT_NOT_FOUND
5676
+ return STATUS_ENTRYPOINT_NOT_FOUND ;
5677
5677
5678
5678
* ImageEntryPoint = PTR_ADD_OFFSET (BaseAddress , ImageNtHeader -> OptionalHeader .AddressOfEntryPoint );
5679
5679
return STATUS_SUCCESS ;
@@ -5877,6 +5877,7 @@ static NTSTATUS PhpFixupLoaderEntryImageImports(
5877
5877
if (PhEqualBytesZ (importName , "ProcessHacker.exe" , FALSE))
5878
5878
{
5879
5879
importBaseAddress = PhInstanceHandle ;
5880
+ status = STATUS_SUCCESS ;
5880
5881
}
5881
5882
else
5882
5883
{
@@ -5998,7 +5999,8 @@ static NTSTATUS PhpFixupLoaderEntryImageImports(
5998
5999
5999
6000
static NTSTATUS PhpFixupLoaderEntryImageDelayImports (
6000
6001
_In_ PVOID BaseAddress ,
6001
- _In_ PIMAGE_NT_HEADERS ImageNtHeader
6002
+ _In_ PIMAGE_NT_HEADERS ImageNtHeaders ,
6003
+ _In_ PSTR ImportDllName
6002
6004
)
6003
6005
{
6004
6006
NTSTATUS status ;
@@ -6010,7 +6012,7 @@ static NTSTATUS PhpFixupLoaderEntryImageDelayImports(
6010
6012
6011
6013
status = PhGetLoaderEntryImageDirectory (
6012
6014
BaseAddress ,
6013
- ImageNtHeader ,
6015
+ ImageNtHeaders ,
6014
6016
IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT ,
6015
6017
& dataDirectory ,
6016
6018
& delayImportDirectory ,
@@ -6027,7 +6029,7 @@ static NTSTATUS PhpFixupLoaderEntryImageDelayImports(
6027
6029
6028
6030
status = PhGetLoaderEntryImageSection (
6029
6031
BaseAddress ,
6030
- ImageNtHeader ,
6032
+ ImageNtHeaders ,
6031
6033
delayImportDirectory ,
6032
6034
& importDirectorySection ,
6033
6035
& importDirectorySize
@@ -6050,15 +6052,54 @@ static NTSTATUS PhpFixupLoaderEntryImageDelayImports(
6050
6052
for (delayImportDirectory = delayImportDirectory ; delayImportDirectory -> DllNameRVA ; delayImportDirectory ++ )
6051
6053
{
6052
6054
PSTR importName ;
6055
+ PVOID * importHandle ;
6053
6056
PIMAGE_THUNK_DATA importThunk ;
6054
6057
PIMAGE_THUNK_DATA originalThunk ;
6058
+ PVOID importBaseAddress ;
6059
+ BOOLEAN importNeedsFree = FALSE;
6055
6060
6056
6061
importName = PTR_ADD_OFFSET (BaseAddress , delayImportDirectory -> DllNameRVA );
6062
+ importHandle = PTR_ADD_OFFSET (BaseAddress , delayImportDirectory -> ModuleHandleRVA );
6057
6063
importThunk = PTR_ADD_OFFSET (BaseAddress , delayImportDirectory -> ImportAddressTableRVA );
6058
6064
originalThunk = PTR_ADD_OFFSET (BaseAddress , delayImportDirectory -> ImportNameTableRVA );
6059
6065
6060
- if (PhEqualBytesZ (importName , "ProcessHacker.exe" , TRUE))
6066
+ if (PhEqualBytesZ (importName , ImportDllName , TRUE))
6061
6067
{
6068
+ if (PhEqualBytesZ (importName , "ProcessHacker.exe" , FALSE))
6069
+ {
6070
+ importBaseAddress = PhInstanceHandle ;
6071
+ status = STATUS_SUCCESS ;
6072
+ }
6073
+ else if (* importHandle )
6074
+ {
6075
+ importBaseAddress = * importHandle ;
6076
+ status = STATUS_SUCCESS ;
6077
+ }
6078
+ else
6079
+ {
6080
+ PPH_STRING importNameSr ;
6081
+
6082
+ importNameSr = PhZeroExtendToUtf16 (importName );
6083
+
6084
+ if (!(importBaseAddress = PhGetLoaderEntryDllBase (importNameSr -> Buffer )))
6085
+ {
6086
+ if (importBaseAddress = LoadLibrary (importNameSr -> Buffer ))
6087
+ {
6088
+ importNeedsFree = TRUE;
6089
+ status = STATUS_SUCCESS ;
6090
+ }
6091
+ else
6092
+ {
6093
+ status = PhGetLastWin32ErrorAsNtStatus ();
6094
+ }
6095
+ }
6096
+
6097
+ PhDereferenceObject (importNameSr );
6098
+ }
6099
+
6100
+ if (!NT_SUCCESS (status ))
6101
+ break ;
6102
+
6062
6103
for (
6063
6104
originalThunk = originalThunk , importThunk = importThunk ;
6064
6105
originalThunk -> u1 .AddressOfData ;
@@ -6071,7 +6112,7 @@ static NTSTATUS PhpFixupLoaderEntryImageDelayImports(
6071
6112
PVOID procedureAddress ;
6072
6113
6073
6114
procedureOrdinal = IMAGE_ORDINAL (originalThunk -> u1 .Ordinal );
6074
- procedureAddress = PhGetDllBaseProcedureAddress (PhInstanceHandle , NULL , procedureOrdinal );
6115
+ procedureAddress = PhGetDllBaseProcedureAddress (importBaseAddress , NULL , procedureOrdinal );
6075
6116
6076
6117
importThunk -> u1 .Function = (ULONG_PTR )procedureAddress ;
6077
6118
}
@@ -6081,11 +6122,16 @@ static NTSTATUS PhpFixupLoaderEntryImageDelayImports(
6081
6122
PVOID procedureAddress ;
6082
6123
6083
6124
importByName = PTR_ADD_OFFSET (BaseAddress , originalThunk -> u1 .AddressOfData );
6084
- procedureAddress = PhGetDllBaseProcedureAddress (PhInstanceHandle , importByName -> Name , 0 );
6125
+ procedureAddress = PhGetDllBaseProcedureAddress (importBaseAddress , importByName -> Name , 0 );
6085
6126
6086
6127
importThunk -> u1 .Function = (ULONG_PTR )procedureAddress ;
6087
6128
}
6088
6129
}
6130
+
6131
+ if ((InterlockedExchangePointer (importHandle , importBaseAddress ) == importBaseAddress ) && importNeedsFree )
6132
+ {
6133
+ FreeLibrary (importBaseAddress ); // A different thread has already updated the cache.
6134
+ }
6089
6135
}
6090
6136
}
6091
6137
@@ -6104,14 +6150,49 @@ static NTSTATUS PhpFixupLoaderEntryImageDelayImports(
6104
6150
return status ;
6105
6151
}
6106
6152
6153
+ NTSTATUS PhLoaderEntryLoadAllImportsForDll (
6154
+ _In_ PVOID BaseAddress ,
6155
+ _In_ PSTR ImportDllName
6156
+ )
6157
+ {
6158
+ NTSTATUS status ;
6159
+ PIMAGE_NT_HEADERS imageNtHeaders ;
6160
+
6161
+ status = PhGetLoaderEntryImageNtHeaders (
6162
+ BaseAddress ,
6163
+ & imageNtHeaders
6164
+ );
6165
+
6166
+ if (!NT_SUCCESS (status ))
6167
+ return status ;
6168
+
6169
+ status = PhpFixupLoaderEntryImageDelayImports (
6170
+ BaseAddress ,
6171
+ imageNtHeaders ,
6172
+ ImportDllName
6173
+ );
6174
+
6175
+ return status ;
6176
+ }
6177
+
6178
+ NTSTATUS PhLoadAllImportsForDll (
6179
+ _In_ PWSTR TargetDllName ,
6180
+ _In_ PSTR ImportDllName
6181
+ )
6182
+ {
6183
+ PVOID imageBaseAddress ;
6184
+
6185
+ if (!(imageBaseAddress = PhGetLoaderEntryDllBase (TargetDllName )))
6186
+ return STATUS_INVALID_PARAMETER ;
6187
+
6188
+ return PhLoaderEntryLoadAllImportsForDll (
6189
+ imageBaseAddress ,
6190
+ ImportDllName
6191
+ );
6192
+ }
6193
+
6107
6194
// dmex: This function and the other LoaderEntryImage functions don't belong in this file
6108
6195
// and should be moved into mapimg.c at some stage.
6109
- //
6110
- // We use this function to load plugins since we can 'fixup' the import table at runtime which is required when
6111
- // users have renamed the main executable to avoid malware, spyware and other software that targets Process Hacker.
6112
- // This function can only fixup images that have static imports from processhacker.exe,
6113
- // plugins that use LoadLibrary/GetProcAddress will continue to fail when the main executable is renamed.
6114
- // Note: This functionality is a WIP and not be used for anything other than plugins.
6115
6196
NTSTATUS PhLoadPluginImage (
6116
6197
_In_ PPH_STRING FileName ,
6117
6198
_Out_opt_ PVOID * BaseAddress
@@ -6153,9 +6234,11 @@ NTSTATUS PhLoadPluginImage(
6153
6234
if (!NT_SUCCESS (status ))
6154
6235
goto CleanupExit ;
6155
6236
6237
+ //status = PhLoaderEntryLoadAllImportsForDll(imageBaseAddress, "ProcessHacker.exe");
6156
6238
status = PhpFixupLoaderEntryImageDelayImports (
6157
6239
imageBaseAddress ,
6158
- imageHeaders
6240
+ imageHeaders ,
6241
+ "ProcessHacker.exe"
6159
6242
);
6160
6243
6161
6244
if (!NT_SUCCESS (status ))
0 commit comments