@@ -119,7 +119,9 @@ static int plthook_open_real(plthook_t **plthook_out, HMODULE hMod)
119
119
plthook_t * plthook ;
120
120
ULONG ulSize ;
121
121
IMAGE_IMPORT_DESCRIPTOR * desc_head , * desc ;
122
- size_t num_entries = 0 ;
122
+ PIMAGE_NT_HEADERS nt ;
123
+ PIMAGE_DELAYLOAD_DESCRIPTOR dload_head , dload ;
124
+ unsigned int num_entries = 0 ;
123
125
size_t ordinal_name_buflen = 0 ;
124
126
size_t idx ;
125
127
char * ordinal_name_buf ;
@@ -130,7 +132,7 @@ static int plthook_open_real(plthook_t **plthook_out, HMODULE hMod)
130
132
return PLTHOOK_INTERNAL_ERROR ;
131
133
}
132
134
133
- /* Calculate size to allocate memory. */
135
+ /* Calculate size to allocate memory (Import Table) */
134
136
for (desc = desc_head ; desc -> Name != 0 ; desc ++ ) {
135
137
IMAGE_THUNK_DATA * name_thunk = (IMAGE_THUNK_DATA * )((char * )hMod + desc -> OriginalFirstThunk );
136
138
IMAGE_THUNK_DATA * addr_thunk = (IMAGE_THUNK_DATA * )((char * )hMod + desc -> FirstThunk );
@@ -158,6 +160,42 @@ static int plthook_open_real(plthook_t **plthook_out, HMODULE hMod)
158
160
}
159
161
}
160
162
163
+ /* Calculate size to allocate memory (Delayed Load Import Table) */
164
+ nt = (PIMAGE_NT_HEADERS )((uintptr_t )hMod + ((PIMAGE_DOS_HEADER )hMod )-> e_lfanew );
165
+ dload_head = (PIMAGE_DELAYLOAD_DESCRIPTOR )((uintptr_t )hMod +
166
+ nt -> OptionalHeader .DataDirectory [IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT ].VirtualAddress );
167
+
168
+ for (dload = dload_head ; dload -> DllNameRVA != 0 ; dload ++ ) {
169
+ IMAGE_THUNK_DATA * name_thunk = (IMAGE_THUNK_DATA * )((uintptr_t )hMod + dload -> ImportNameTableRVA );
170
+ IMAGE_THUNK_DATA * addr_thunk = (IMAGE_THUNK_DATA * )((uintptr_t )hMod + dload -> ImportAddressTableRVA );
171
+ const char * module_name = (char * )((uintptr_t )hMod + dload -> DllNameRVA );
172
+ int is_winsock2_dll = (stricmp (module_name , "WS2_32.DLL" ) == 0 );
173
+
174
+ if (* module_name == '\0' ) {
175
+ continue ;
176
+ }
177
+
178
+ while (name_thunk -> u1 .AddressOfData ) {
179
+ if (IMAGE_SNAP_BY_ORDINAL (name_thunk -> u1 .Ordinal )) {
180
+ int ordinal = IMAGE_ORDINAL (name_thunk -> u1 .Ordinal );
181
+ const char * name = NULL ;
182
+ if (is_winsock2_dll ) {
183
+ name = winsock2_ordinal2name (ordinal );
184
+ }
185
+ if (name == NULL ) {
186
+ #ifdef __CYGWIN__
187
+ ordinal_name_buflen += snprintf (NULL , 0 , "%s:@%d" , module_name , ordinal ) + 1 ;
188
+ #else
189
+ ordinal_name_buflen += _scprintf ("%s:@%d" , module_name , ordinal ) + 1 ;
190
+ #endif
191
+ }
192
+ }
193
+ num_entries ++ ;
194
+ name_thunk ++ ;
195
+ addr_thunk ++ ;
196
+ }
197
+ }
198
+
161
199
plthook = calloc (1 , offsetof(plthook_t , entries ) + sizeof (import_address_entry_t ) * num_entries + ordinal_name_buflen );
162
200
if (plthook == NULL ) {
163
201
set_errmsg ("failed to allocate memory: %" SIZE_T_FMT " bytes" , sizeof (plthook_t ));
@@ -168,6 +206,8 @@ static int plthook_open_real(plthook_t **plthook_out, HMODULE hMod)
168
206
169
207
ordinal_name_buf = (char * )plthook + offsetof(plthook_t , entries ) + sizeof (import_address_entry_t ) * num_entries ;
170
208
idx = 0 ;
209
+
210
+ /* Import Table */
171
211
for (desc = desc_head ; desc -> Name != 0 ; desc ++ ) {
172
212
IMAGE_THUNK_DATA * name_thunk = (IMAGE_THUNK_DATA * )((char * )hMod + desc -> OriginalFirstThunk );
173
213
IMAGE_THUNK_DATA * addr_thunk = (IMAGE_THUNK_DATA * )((char * )hMod + desc -> FirstThunk );
@@ -198,6 +238,41 @@ static int plthook_open_real(plthook_t **plthook_out, HMODULE hMod)
198
238
}
199
239
}
200
240
241
+ /* Delayed Load Import Table */
242
+ for (dload = dload_head ; dload -> DllNameRVA != 0 ; dload ++ ) {
243
+ IMAGE_THUNK_DATA * name_thunk = (IMAGE_THUNK_DATA * )((uintptr_t )hMod + dload -> ImportNameTableRVA );
244
+ IMAGE_THUNK_DATA * addr_thunk = (IMAGE_THUNK_DATA * )((uintptr_t )hMod + dload -> ImportAddressTableRVA );
245
+ const char * module_name = (char * )((uintptr_t )hMod + dload -> DllNameRVA );
246
+ int is_winsock2_dll = (stricmp (module_name , "WS2_32.DLL" ) == 0 );
247
+
248
+ if (* module_name == '\0' ) {
249
+ continue ;
250
+ }
251
+
252
+ while (name_thunk -> u1 .AddressOfData ) {
253
+ const char * name = NULL ;
254
+
255
+ if (IMAGE_SNAP_BY_ORDINAL (name_thunk -> u1 .Ordinal )) {
256
+ int ordinal = IMAGE_ORDINAL (name_thunk -> u1 .Ordinal );
257
+ if (is_winsock2_dll ) {
258
+ name = winsock2_ordinal2name (ordinal );
259
+ }
260
+ if (name == NULL ) {
261
+ name = ordinal_name_buf ;
262
+ ordinal_name_buf += sprintf (ordinal_name_buf , "%s:@%d" , module_name , ordinal ) + 1 ;
263
+ }
264
+ } else {
265
+ name = (char * )((PIMAGE_IMPORT_BY_NAME )((char * )hMod + name_thunk -> u1 .AddressOfData ))-> Name ;
266
+ }
267
+ plthook -> entries [idx ].mod_name = module_name ;
268
+ plthook -> entries [idx ].name = name ;
269
+ plthook -> entries [idx ].addr = (void * * )& addr_thunk -> u1 .Function ;
270
+ idx ++ ;
271
+ name_thunk ++ ;
272
+ addr_thunk ++ ;
273
+ }
274
+ }
275
+
201
276
* plthook_out = plthook ;
202
277
return 0 ;
203
278
}
0 commit comments