|
|
dd89bb |
/********************************************************/
|
|
|
dd89bb |
/* ntapi: Native API core library */
|
|
|
dd89bb |
/* Copyright (C) 2013,2014,2015 Z. Gilboa */
|
|
|
dd89bb |
/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */
|
|
|
dd89bb |
/********************************************************/
|
|
|
dd89bb |
|
|
|
dd89bb |
#include <psxtypes/psxtypes.h>
|
|
|
dd89bb |
#include <pemagine/pemagine.h>
|
|
|
dd89bb |
#include <ntapi/nt_object.h>
|
|
|
dd89bb |
#include <ntapi/nt_crc32.h>
|
|
|
dd89bb |
#include <ntapi/ntapi.h>
|
|
|
dd89bb |
#include "ntapi_impl.h"
|
|
|
dd89bb |
|
|
|
dd89bb |
struct callback_ctx {
|
|
|
dd89bb |
void * import_table;
|
|
|
dd89bb |
ntapi_hashed_symbol * hash_table;
|
|
|
dd89bb |
uint32_t hash_table_array_size;
|
|
|
dd89bb |
};
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
dd89bb |
static int __process_exported_symbol(
|
|
|
dd89bb |
const void * base,
|
|
|
dd89bb |
struct pe_export_hdr * exp_hdr,
|
|
|
dd89bb |
struct pe_export_sym * exp_item,
|
|
|
dd89bb |
enum pe_callback_reason reason,
|
|
|
dd89bb |
void * context)
|
|
|
dd89bb |
{
|
|
|
dd89bb |
uint32_t hash_value;
|
|
|
dd89bb |
struct callback_ctx * ctx;
|
|
|
dd89bb |
ntapi_hashed_symbol * hashed_symbol;
|
|
|
dd89bb |
uintptr_t * fnptr;
|
|
|
dd89bb |
|
|
|
dd89bb |
/* binary search variables */
|
|
|
dd89bb |
uint32_t lower;
|
|
|
dd89bb |
uint32_t upper;
|
|
|
dd89bb |
uint32_t idx;
|
|
|
dd89bb |
|
|
|
dd89bb |
if (reason != PE_CALLBACK_REASON_ITEM)
|
|
|
dd89bb |
return 1;
|
|
|
dd89bb |
|
|
|
dd89bb |
ctx = (struct callback_ctx *)context;
|
|
|
dd89bb |
hash_value = __ntapi_tt_mbstr_crc32(exp_item->name);
|
|
|
dd89bb |
|
|
|
dd89bb |
/* zero-based array, binary search, idx < upper is guaranteed */
|
|
|
dd89bb |
lower = 0;
|
|
|
dd89bb |
upper = ctx->hash_table_array_size;
|
|
|
dd89bb |
|
|
|
dd89bb |
/* binary search */
|
|
|
dd89bb |
while (lower < upper) {
|
|
|
dd89bb |
idx = (lower + upper) / 2;
|
|
|
dd89bb |
hashed_symbol = (ntapi_hashed_symbol *)
|
|
|
dd89bb |
((uintptr_t)ctx->hash_table
|
|
|
dd89bb |
+ idx * sizeof(ntapi_hashed_symbol));
|
|
|
dd89bb |
|
|
|
dd89bb |
if (hash_value == hashed_symbol->crc32_hash) {
|
|
|
dd89bb |
fnptr = (uintptr_t *)(
|
|
|
dd89bb |
(uintptr_t)ctx->import_table
|
|
|
dd89bb |
+ (sizeof(uintptr_t)
|
|
|
dd89bb |
* hashed_symbol->ordinal));
|
|
|
dd89bb |
*fnptr = (uintptr_t)exp_item->addr;
|
|
|
dd89bb |
return 1;
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
else {
|
|
|
dd89bb |
if (hash_value > hashed_symbol->crc32_hash)
|
|
|
dd89bb |
lower = idx + 1;
|
|
|
dd89bb |
else
|
|
|
dd89bb |
upper = idx;
|
|
|
dd89bb |
}
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
return 1;
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
int32_t __cdecl __ntapi_tt_populate_hashed_import_table(
|
|
|
dd89bb |
__in void * image_base,
|
|
|
dd89bb |
__in void * import_table,
|
|
|
dd89bb |
__in ntapi_hashed_symbol * hash_table,
|
|
|
dd89bb |
__in uint32_t hash_table_array_size)
|
|
|
dd89bb |
{
|
|
|
dd89bb |
struct pe_export_sym exp_item;
|
|
|
dd89bb |
struct callback_ctx ctx;
|
|
|
dd89bb |
|
|
|
dd89bb |
ctx.import_table = import_table;
|
|
|
dd89bb |
ctx.hash_table = hash_table;
|
|
|
dd89bb |
ctx.hash_table_array_size = hash_table_array_size;
|
|
|
dd89bb |
|
|
|
dd89bb |
pe_enum_image_exports(
|
|
|
dd89bb |
image_base,
|
|
|
dd89bb |
&__process_exported_symbol,
|
|
|
dd89bb |
&exp_item,
|
|
|
dd89bb |
&ctx;;
|
|
|
dd89bb |
|
|
|
dd89bb |
return 0;
|
|
|
dd89bb |
}
|