Skip to content

Commit 0dd10e9

Browse files
authored
Feature/delayload win32 (#1)
* First attempt. * Solve issue. * Solve issues in delay load. * Debugging. * Debugging. * Debugging. * Debugging. * Debugging. * Debugging. * Debugging. * Debugging. * Debugging. * Debug entries. * Debug entries.
1 parent 2858946 commit 0dd10e9

File tree

3 files changed

+85
-8
lines changed

3 files changed

+85
-8
lines changed

Diff for: .github/workflows/run-tests.yml

+7-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
name: tests
1+
name: Tests
2+
23
on:
34
push:
45
pull_request:
@@ -112,9 +113,10 @@ jobs:
112113
- name: arm-linux-gnueabihf with optimization
113114
run: |
114115
make relro_pie_tests TARGET_PLATFORM=arm-linux-gnueabihf
115-
- name: aarch64-linux-gnu with optimization
116-
run: |
117-
make relro_pie_tests TARGET_PLATFORM=aarch64-linux-gnu
116+
# TODO: https://github.com/kubo/plthook/issues/51
117+
# - name: aarch64-linux-gnu with optimization
118+
# run: |
119+
# make relro_pie_tests TARGET_PLATFORM=aarch64-linux-gnu
118120
- name: powerpc-linux-gnu with optimization
119121
run: |
120122
make relro_pie_tests TARGET_PLATFORM=powerpc-linux-gnu QEMU_ARCH=ppc
@@ -130,7 +132,7 @@ jobs:
130132
if: github.event.inputs.tests_on_macos == 'true' || github.event.inputs.tests_on_macos == ''
131133
strategy:
132134
matrix:
133-
os: [macos-12, macos-13, macos-14]
135+
os: [macos-13, macos-14, macos-15]
134136
runs-on: ${{ matrix.os }}
135137
defaults:
136138
run:

Diff for: .gitignore

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
*~
22
/test/android/libs/
33
/test/android/obj/
4-
4+
.vscode

Diff for: plthook_win32.c

+77-2
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,9 @@ static int plthook_open_real(plthook_t **plthook_out, HMODULE hMod)
119119
plthook_t *plthook;
120120
ULONG ulSize;
121121
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;
123125
size_t ordinal_name_buflen = 0;
124126
size_t idx;
125127
char *ordinal_name_buf;
@@ -130,7 +132,7 @@ static int plthook_open_real(plthook_t **plthook_out, HMODULE hMod)
130132
return PLTHOOK_INTERNAL_ERROR;
131133
}
132134

133-
/* Calculate size to allocate memory. */
135+
/* Calculate size to allocate memory (Import Table) */
134136
for (desc = desc_head; desc->Name != 0; desc++) {
135137
IMAGE_THUNK_DATA *name_thunk = (IMAGE_THUNK_DATA*)((char*)hMod + desc->OriginalFirstThunk);
136138
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)
158160
}
159161
}
160162

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+
161199
plthook = calloc(1, offsetof(plthook_t, entries) + sizeof(import_address_entry_t) * num_entries + ordinal_name_buflen);
162200
if (plthook == NULL) {
163201
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)
168206

169207
ordinal_name_buf = (char*)plthook + offsetof(plthook_t, entries) + sizeof(import_address_entry_t) * num_entries;
170208
idx = 0;
209+
210+
/* Import Table */
171211
for (desc = desc_head; desc->Name != 0; desc++) {
172212
IMAGE_THUNK_DATA *name_thunk = (IMAGE_THUNK_DATA*)((char*)hMod + desc->OriginalFirstThunk);
173213
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)
198238
}
199239
}
200240

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+
201276
*plthook_out = plthook;
202277
return 0;
203278
}

0 commit comments

Comments
 (0)