@@ -954,9 +954,56 @@ VOID SeiBuildInclExclList(PDB pdb, TAGID ShimTag, PSHIMINFO pShimInfo)
954954 SeiReadInExclude (pdb , ShimTag , & pShimInfo -> InExclude );
955955}
956956
957+ DWORD SeiPatchImportsByName (PIMAGE_THUNK_DATA OriginalThunk , PIMAGE_THUNK_DATA FirstThunk , PHOOKAPIEX HookApi , PLDR_DATA_TABLE_ENTRY LdrEntry )
958+ {
959+ DWORD dwFound = 0 ;
960+
961+ for (; OriginalThunk -> u1 .AddressOfData && FirstThunk -> u1 .Function ; OriginalThunk ++ , FirstThunk ++ )
962+ {
963+ if (!IMAGE_SNAP_BY_ORDINAL (OriginalThunk -> u1 .Function ) && !SeiIsOrdinalName (HookApi -> FunctionName ))
964+ {
965+ PIMAGE_IMPORT_BY_NAME ImportName ;
966+
967+ ImportName = (PIMAGE_IMPORT_BY_NAME )((PBYTE )LdrEntry -> DllBase + OriginalThunk -> u1 .Function );
968+ if (!strcmp ((PCSTR )ImportName -> Name , HookApi -> FunctionName ))
969+ {
970+ SeiPatchNewImport (FirstThunk , HookApi , LdrEntry );
971+ dwFound ++ ;
972+ }
973+ }
974+ else
975+ {
976+ if (SeiIsOrdinalName (HookApi -> FunctionName ) && ((PCSTR )IMAGE_ORDINAL (OriginalThunk -> u1 .Function ) == HookApi -> FunctionName ))
977+ {
978+ SeiPatchNewImport (FirstThunk , HookApi , LdrEntry );
979+ dwFound ++ ;
980+ }
981+ }
982+ }
983+
984+ return dwFound ;
985+ }
986+
987+ DWORD SeiPatchImportsByAddress (PIMAGE_THUNK_DATA FirstThunk , PHOOKAPIEX HookApi , PLDR_DATA_TABLE_ENTRY LdrEntry )
988+ {
989+ DWORD dwFound = 0 ;
990+
991+ for (; FirstThunk -> u1 .Function ; FirstThunk ++ )
992+ {
993+ if ((PULONG_PTR )FirstThunk -> u1 .Function == HookApi -> OriginalFunction )
994+ {
995+ SeiPatchNewImport (FirstThunk , HookApi , LdrEntry );
996+ dwFound ++ ;
997+ }
998+ }
999+
1000+ return dwFound ;
1001+ }
1002+
9571003/* Given one loaded module, redirect (hook) all functions from the iat that are registered by shims */
9581004VOID SeiHookImports (PLDR_DATA_TABLE_ENTRY LdrEntry )
9591005{
1006+ BOOLEAN HasImportNameTable ;
9601007 ULONG Size ;
9611008 PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor ;
9621009 PBYTE DllBase = LdrEntry -> DllBase ;
@@ -984,7 +1031,15 @@ VOID SeiHookImports(PLDR_DATA_TABLE_ENTRY LdrEntry)
9841031
9851032 SHIMENG_INFO ("Hooking module 0x%p \"%wZ\"\n" , LdrEntry -> DllBase , & LdrEntry -> BaseDllName );
9861033
987- for ( ;ImportDescriptor -> Name && ImportDescriptor -> OriginalFirstThunk ; ImportDescriptor ++ )
1034+ HasImportNameTable = ImportDescriptor -> OriginalFirstThunk ;
1035+ if (!HasImportNameTable )
1036+ {
1037+ /* Some PEs (eg. built with Borland toolchain or compressed with UPX) may not have an import name table.
1038+ * In that case we have to rely solely on an import address table. */
1039+ SHIMENG_INFO ("Module 0x%p \"%wZ\" does not have an import name table\n" , LdrEntry -> DllBase , & LdrEntry -> BaseDllName );
1040+ }
1041+
1042+ for ( ;ImportDescriptor -> Name && (HasImportNameTable ? ImportDescriptor -> OriginalFirstThunk : ImportDescriptor -> FirstThunk ); ImportDescriptor ++ )
9881043 {
9891044 PHOOKMODULEINFO HookModuleInfo ;
9901045
@@ -998,7 +1053,7 @@ VOID SeiHookImports(PLDR_DATA_TABLE_ENTRY LdrEntry)
9981053
9991054 for (n = 0 ; n < ARRAY_Size (& HookModuleInfo -> HookApis ); ++ n )
10001055 {
1001- DWORD dwFound = 0 ;
1056+ DWORD dwFound ;
10021057 PHOOKAPIEX HookApi = * ARRAY_At (& HookModuleInfo -> HookApis , PHOOKAPIEX , n );
10031058
10041059 /* Check if this module should be excluded from being hooked (system32/winsxs, global or shim exclude) */
@@ -1007,41 +1062,19 @@ VOID SeiHookImports(PLDR_DATA_TABLE_ENTRY LdrEntry)
10071062 continue ;
10081063 }
10091064
1010- OriginalThunk = (PIMAGE_THUNK_DATA )(DllBase + ImportDescriptor -> OriginalFirstThunk );
10111065 FirstThunk = (PIMAGE_THUNK_DATA )(DllBase + ImportDescriptor -> FirstThunk );
10121066
1013- /* Walk all imports */
1014- for (;OriginalThunk -> u1 .AddressOfData && FirstThunk -> u1 .Function ; OriginalThunk ++ , FirstThunk ++ )
1067+ if (HasImportNameTable )
10151068 {
1016- if (!IMAGE_SNAP_BY_ORDINAL (OriginalThunk -> u1 .Function ))
1017- {
1018- if (!SeiIsOrdinalName (HookApi -> FunctionName ))
1019- {
1020- PIMAGE_IMPORT_BY_NAME ImportName ;
1021-
1022- ImportName = (PIMAGE_IMPORT_BY_NAME )(DllBase + OriginalThunk -> u1 .Function );
1023- if (!strcmp ((PCSTR )ImportName -> Name , HookApi -> FunctionName ))
1024- {
1025- SeiPatchNewImport (FirstThunk , HookApi , LdrEntry );
1026-
1027- /* Sadly, iat does not have to be sorted, and can even contain duplicate entries. */
1028- dwFound ++ ;
1029- }
1030- }
1031- }
1032- else
1033- {
1034- if (SeiIsOrdinalName (HookApi -> FunctionName ))
1035- {
1036- if ((PCSTR )IMAGE_ORDINAL (OriginalThunk -> u1 .Function ) == HookApi -> FunctionName )
1037- {
1038- SeiPatchNewImport (FirstThunk , HookApi , LdrEntry );
1039- dwFound ++ ;
1040- }
1041- }
1042- }
1069+ OriginalThunk = (PIMAGE_THUNK_DATA )(DllBase + ImportDescriptor -> OriginalFirstThunk );
1070+ dwFound = SeiPatchImportsByName (OriginalThunk , FirstThunk , HookApi , LdrEntry );
1071+ }
1072+ else
1073+ {
1074+ dwFound = SeiPatchImportsByAddress (FirstThunk , HookApi , LdrEntry );
10431075 }
10441076
1077+ /* Sadly, IAT does not have to be sorted, and can even contain duplicate entries. */
10451078 if (dwFound != 1 )
10461079 {
10471080 char szOrdProcFmt [10 ];
0 commit comments