Skip to content

Commit

Permalink
Fall back to IAT detouring by pointer if OriginalFirstThunk is not av…
Browse files Browse the repository at this point in the history
…ailable.

Fixes a crash that previously occurred in this case. This is particularly likely to happen with unpacked versions of previously packed binaries (UPX decompressor, I'm looking at you).
  • Loading branch information
nmlgc committed Jan 24, 2014
1 parent 3dda945 commit f67f391
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 11 deletions.
36 changes: 25 additions & 11 deletions thcrap/src/mempatch.c
Expand Up @@ -165,29 +165,43 @@ void iat_detour_set(iat_detour_t *detour, const char *old_func, const void *old_
detour->new_ptr = new_ptr;
}

int iat_detour_func(HMODULE hMod, PIMAGE_IMPORT_DESCRIPTOR pImpDesc, const iat_detour_t *detour)
{
PIMAGE_THUNK_DATA pOT = NULL;
PIMAGE_THUNK_DATA pIT = NULL;
if(hMod && pImpDesc && detour) {
pIT = (PIMAGE_THUNK_DATA)((DWORD)hMod + pImpDesc->FirstThunk);

// We generally detour by comparing exported names. This has the
// advantage that we can override any existing patches, and that
// it works on Win9x too (as if that matters). However, in case we lack
// a pointer to the OriginalFirstThunk, this is not possible, so we have
// to detour by comparing pointers then.

if(pImpDesc->OriginalFirstThunk) {
pOT = (PIMAGE_THUNK_DATA)((DWORD)hMod + pImpDesc->OriginalFirstThunk);
return func_detour_by_name(hMod, pOT, pIT, detour);
} else {
return func_detour_by_ptr(pIT, detour);
}
}
return -1;
}

int iat_detour_funcs(HMODULE hMod, const char *dll_name, iat_detour_t *detour, const size_t detour_count)
{
PIMAGE_IMPORT_DESCRIPTOR pImpDesc;
PIMAGE_THUNK_DATA pOrigThunk;
PIMAGE_THUNK_DATA pImpThunk;
PIMAGE_IMPORT_DESCRIPTOR pImpDesc = GetDllImportDesc(hMod, dll_name);
int ret = detour_count;
UINT c;

pImpDesc = GetDllImportDesc(hMod, dll_name);
if(!pImpDesc) {
return -1;
}
pOrigThunk = (PIMAGE_THUNK_DATA)((DWORD)hMod + (DWORD)pImpDesc->OriginalFirstThunk);
pImpThunk = (PIMAGE_THUNK_DATA)((DWORD)hMod + (DWORD)pImpDesc->FirstThunk);

log_printf("Detouring DLL functions (%s)...\n", dll_name);

// We _only_ detour by comparing exported names.
// Has the advantages that we can override any existing patches,
// and that it works on Win9x too (as if that matters).

for(c = 0; c < detour_count; c++) {
int local_ret = func_detour_by_name(hMod, pOrigThunk, pImpThunk, &detour[c]);
int local_ret = iat_detour_func(hMod, pImpDesc, &detour[c]);
log_printf(
"(%2d/%2d) %s... %s\n",
c + 1, detour_count, detour[c].old_func, local_ret ? "OK" : "not found"
Expand Down
3 changes: 3 additions & 0 deletions thcrap/src/mempatch.h
Expand Up @@ -83,6 +83,9 @@ int func_detour_by_ptr(PIMAGE_THUNK_DATA pImpFirstThunk, const iat_detour_t *det
// Convenience function to set a single iat_detour_t entry
void iat_detour_set(iat_detour_t* detour, const char *old_func, const void *old_ptr, const void *new_ptr);

// Sets up [detour] using the most appropriate low-level detouring function.
int iat_detour_func(HMODULE hMod, PIMAGE_IMPORT_DESCRIPTOR pImpDesc, const iat_detour_t *detour);

// Detours [detour_count] functions in the [iat_detour] array
int iat_detour_funcs(HMODULE hMod, const char *dll_name, iat_detour_t *iat_detour, const size_t detour_count);

Expand Down

0 comments on commit f67f391

Please sign in to comment.