diff options
Diffstat (limited to 'src/hash')
-rw-r--r-- | src/hash/ntapi_tt_crc32.c | 50 | ||||
-rw-r--r-- | src/hash/ntapi_tt_populate_hashed_import_table.c | 95 |
2 files changed, 145 insertions, 0 deletions
diff --git a/src/hash/ntapi_tt_crc32.c b/src/hash/ntapi_tt_crc32.c new file mode 100644 index 0000000..7ce25d3 --- /dev/null +++ b/src/hash/ntapi_tt_crc32.c @@ -0,0 +1,50 @@ +/********************************************************/ +/* ntapi: Native API core library */ +/* Copyright (C) 2013,2014,2015 Z. Gilboa */ +/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */ +/********************************************************/ + +#include <psxtypes/psxtypes.h> +#include <ntapi/nt_crc32.h> + +static const uint32_t crc32_table[256] = NTAPI_CRC32_TABLE; + +uint32_t __ntapi_tt_buffer_crc32( + uint32_t prev_hash, + const void * buffer, + size_t size) +{ + unsigned char * ch; + uint32_t crc32; + + crc32 = prev_hash ^ 0xFFFFFFFF; + ch = (unsigned char *)buffer; + + for (; size; size--,ch++) + crc32 = (crc32 >> 8) ^ crc32_table[(crc32 ^ *ch) & 0xFF]; + + return (crc32 ^ 0xFFFFFFFF); +} + + +uint32_t __cdecl __ntapi_tt_mbstr_crc32(const void * str) +{ + uint32_t crc32; + unsigned char * ch; + + crc32 = 0 ^ 0xFFFFFFFF; + ch = (unsigned char *)str; + + while (*ch) { + crc32 = (crc32 >> 8) ^ crc32_table[(crc32 ^ *ch) & 0xFF]; + ch++; + } + + return (crc32 ^ 0xFFFFFFFF); +} + + +const uint32_t * __cdecl __ntapi_tt_crc32_table(void) +{ + return crc32_table; +} diff --git a/src/hash/ntapi_tt_populate_hashed_import_table.c b/src/hash/ntapi_tt_populate_hashed_import_table.c new file mode 100644 index 0000000..a36ed2f --- /dev/null +++ b/src/hash/ntapi_tt_populate_hashed_import_table.c @@ -0,0 +1,95 @@ +/********************************************************/ +/* ntapi: Native API core library */ +/* Copyright (C) 2013,2014,2015 Z. Gilboa */ +/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */ +/********************************************************/ + +#include <psxtypes/psxtypes.h> +#include <pemagine/pemagine.h> +#include <ntapi/nt_object.h> +#include <ntapi/nt_crc32.h> +#include <ntapi/ntapi.h> +#include "ntapi_impl.h" + +struct callback_ctx { + void * import_table; + ntapi_hashed_symbol * hash_table; + uint32_t hash_table_array_size; +}; + + +static int __process_exported_symbol( + const void * base, + struct pe_export_hdr * exp_hdr, + struct pe_export_sym * exp_item, + enum pe_callback_reason reason, + void * context) +{ + uint32_t hash_value; + struct callback_ctx * ctx; + ntapi_hashed_symbol * hashed_symbol; + uintptr_t * fnptr; + + /* binary search variables */ + uint32_t lower; + uint32_t upper; + uint32_t idx; + + if (reason != PE_CALLBACK_REASON_ITEM) + return 1; + + ctx = (struct callback_ctx *)context; + hash_value = __ntapi_tt_mbstr_crc32(exp_item->name); + + /* zero-based array, binary search, idx < upper is guaranteed */ + lower = 0; + upper = ctx->hash_table_array_size; + + /* binary search */ + while (lower < upper) { + idx = (lower + upper) / 2; + hashed_symbol = (ntapi_hashed_symbol *) + ((uintptr_t)ctx->hash_table + + idx * sizeof(ntapi_hashed_symbol)); + + if (hash_value == hashed_symbol->crc32_hash) { + fnptr = (uintptr_t *)( + (uintptr_t)ctx->import_table + + (sizeof(uintptr_t) + * hashed_symbol->ordinal)); + *fnptr = (uintptr_t)exp_item->addr; + return 1; + } + + else { + if (hash_value > hashed_symbol->crc32_hash) + lower = idx + 1; + else + upper = idx; + } + } + + return 1; +} + +int32_t __cdecl __ntapi_tt_populate_hashed_import_table( + __in void * image_base, + __in void * import_table, + __in ntapi_hashed_symbol * hash_table, + __in uint32_t hash_table_array_size) +{ + struct pe_export_sym exp_item; + struct callback_ctx ctx; + + ctx.import_table = import_table; + ctx.hash_table = hash_table; + ctx.hash_table_array_size = hash_table_array_size; + + pe_enum_image_exports( + image_base, + &__process_exported_symbol, + &exp_item, + &ctx); + + return 0; +} |