Skip to content

Commit ab6c3fc

Browse files
author
icex2
committed
fix(hook): Add missing hook_table_revert impl
Allow hooks to cleanup when they are shut down.
1 parent 7a56fab commit ab6c3fc

1 file changed

Lines changed: 82 additions & 0 deletions

File tree

src/main/hook/table.c

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,21 @@ static const size_t apiset_prefix_len = sizeof(apiset_prefix) - 1;
1515
static void hook_table_apply_to_all(
1616
const char *depname, const struct hook_symbol *syms, size_t nsyms);
1717

18+
static void hook_table_revert_to_all(
19+
const char *depname, const struct hook_symbol *syms, size_t nsyms);
20+
1821
static void hook_table_apply_to_iid(
1922
HMODULE target,
2023
const pe_iid_t *iid,
2124
const struct hook_symbol *syms,
2225
size_t nsyms);
2326

27+
static void hook_table_revert_to_iid(
28+
HMODULE target,
29+
const pe_iid_t *iid,
30+
const struct hook_symbol *syms,
31+
size_t nsyms);
32+
2433
static bool hook_table_match_module(
2534
HMODULE target, const char *iid_name, const char *depname);
2635

@@ -44,6 +53,23 @@ static void hook_table_apply_to_all(
4453
}
4554
}
4655

56+
static void hook_table_revert_to_all(
57+
const char *depname, const struct hook_symbol *syms, size_t nsyms)
58+
{
59+
const peb_dll_t *dll;
60+
HMODULE pe;
61+
62+
for (dll = peb_dll_get_first(); dll != NULL; dll = peb_dll_get_next(dll)) {
63+
pe = peb_dll_get_base(dll);
64+
65+
if (pe == NULL) {
66+
continue; /* ?? Happens sometimes. */
67+
}
68+
69+
hook_table_revert(pe, depname, syms, nsyms);
70+
}
71+
}
72+
4773
void hook_table_apply(
4874
HMODULE target,
4975
const char *depname,
@@ -73,6 +99,35 @@ void hook_table_apply(
7399
}
74100
}
75101

102+
void hook_table_revert(
103+
HMODULE target,
104+
const char *depname,
105+
const struct hook_symbol *syms,
106+
size_t nsyms)
107+
{
108+
const pe_iid_t *iid;
109+
const char *iid_name;
110+
111+
assert(depname != NULL);
112+
assert(syms != NULL || nsyms == 0);
113+
114+
if (target == NULL) {
115+
/* Call out, which will then call us back repeatedly. Awkward, but
116+
viewed from the outside it's good for usability. */
117+
118+
hook_table_revert_to_all(depname, syms, nsyms);
119+
} else {
120+
for (iid = pe_iid_get_first(target); iid != NULL;
121+
iid = pe_iid_get_next(target, iid)) {
122+
iid_name = pe_iid_get_name(target, iid);
123+
124+
if (hook_table_match_module(target, iid_name, depname)) {
125+
hook_table_revert_to_iid(target, iid, syms, nsyms);
126+
}
127+
}
128+
}
129+
}
130+
76131
static void hook_table_apply_to_iid(
77132
HMODULE target,
78133
const pe_iid_t *iid,
@@ -101,6 +156,33 @@ static void hook_table_apply_to_iid(
101156
}
102157
}
103158

159+
static void hook_table_revert_to_iid(
160+
HMODULE target,
161+
const pe_iid_t *iid,
162+
const struct hook_symbol *syms,
163+
size_t nsyms)
164+
{
165+
struct pe_iat_entry iate;
166+
size_t i;
167+
size_t j;
168+
const struct hook_symbol *sym;
169+
170+
i = 0;
171+
172+
while (pe_iid_get_iat_entry(target, iid, i++, &iate) == S_OK) {
173+
for (j = 0; j < nsyms; j++) {
174+
sym = &syms[j];
175+
176+
if (hook_table_match_proc(&iate, sym)) {
177+
// Only revert-able if the original pointer was stored previously
178+
if (sym->link != NULL && *sym->link != NULL) {
179+
pe_patch(iate.ppointer, sym->link, sizeof(*sym->link));
180+
}
181+
}
182+
}
183+
}
184+
}
185+
104186
static bool hook_table_match_module(
105187
HMODULE target, const char *iid_name, const char *depname)
106188
{

0 commit comments

Comments
 (0)