diff options
author | midipix <writeonce@midipix.org> | 2015-07-27 04:01:18 -0400 |
---|---|---|
committer | midipix <writeonce@midipix.org> | 2015-07-27 04:01:18 -0400 |
commit | dd89bb8ad4fe184a34b5dbdda237e640fc82121b (patch) | |
tree | 5e80d2da35f5892f92be29f57982b2708e6bd99b /src/ldr | |
parent | dcdadc2702712fa750ed255ed1dfa354522797a0 (diff) | |
download | ntapi-dd89bb8ad4fe184a34b5dbdda237e640fc82121b.tar.bz2 ntapi-dd89bb8ad4fe184a34b5dbdda237e640fc82121b.tar.xz |
entered advanced internal development stage.
Diffstat (limited to 'src/ldr')
-rw-r--r-- | src/ldr/ntapi_ldr_create_state_snapshot.c | 69 | ||||
-rw-r--r-- | src/ldr/ntapi_ldr_load_system_dll.c | 44 | ||||
-rw-r--r-- | src/ldr/ntapi_ldr_revert_state_to_snapshot.c | 104 |
3 files changed, 217 insertions, 0 deletions
diff --git a/src/ldr/ntapi_ldr_create_state_snapshot.c b/src/ldr/ntapi_ldr_create_state_snapshot.c new file mode 100644 index 0000000..74a916c --- /dev/null +++ b/src/ldr/ntapi_ldr_create_state_snapshot.c @@ -0,0 +1,69 @@ +/********************************************************/ +/* 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 <dalist/dalist.h> +#include <ntapi/ntapi.h> + +struct callback_ctx { + struct dalist_ex * ldr_state_snapshot; + int32_t status; +}; + +static int __cdecl __add_module_base_address_to_list( + struct pe_ldr_tbl_entry * ldr_tbl_entry, + enum pe_callback_reason int_callback_reason, + void * context) +{ + struct dalist_node * node; + struct callback_ctx * ctx; + + ctx = (struct callback_ctx *)context; + + if (int_callback_reason == PE_CALLBACK_REASON_ERROR) { + ctx->status = NT_STATUS_UNSUCCESSFUL; + return ctx->status; + } else if (int_callback_reason != PE_CALLBACK_REASON_ITEM) { + ctx->status = NT_STATUS_SUCCESS; + return 1; + } else if (!ldr_tbl_entry->dll_base) { + ctx->status = NT_STATUS_SUCCESS; + return 1; + } + + ctx->status = dalist_get_node_by_key( + ctx->ldr_state_snapshot, + (struct dalist_node_ex **)&node, + (uintptr_t)ldr_tbl_entry->dll_base, + DALIST_NODE_TYPE_NEW, + 0); + + if (ctx->status != DALIST_OK) + return -1; + else + return 1; +} + + +int __cdecl __ntapi_ldr_create_state_snapshot( + __out struct dalist_ex * ldr_state_snapshot) +{ + struct callback_ctx ctx; + + if (!ldr_state_snapshot->free && !ldr_state_snapshot->memfn_ptr) + return NT_STATUS_BUFFER_TOO_SMALL; + else if (ldr_state_snapshot->info.list_nodes) + return NT_STATUS_INVALID_USER_BUFFER; + + ctx.ldr_state_snapshot = ldr_state_snapshot; + + pe_enum_modules_in_load_order( + __add_module_base_address_to_list, + &ctx); + + return ctx.status; +} diff --git a/src/ldr/ntapi_ldr_load_system_dll.c b/src/ldr/ntapi_ldr_load_system_dll.c new file mode 100644 index 0000000..d417590 --- /dev/null +++ b/src/ldr/ntapi_ldr_load_system_dll.c @@ -0,0 +1,44 @@ +/********************************************************/ +/* 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_ldr.h> +#include <ntapi/ntapi.h> +#include "ntapi_impl.h" + +int32_t __stdcall __ntapi_ldr_load_system_dll( + __in void * hsysdir __optional, + __in wchar16_t * base_name, + __in uint32_t base_name_size, + __in uint32_t * image_flags __optional, + __out void ** image_base) +{ + int32_t status; + nt_unicode_string nt_image_name; + uintptr_t buffer[0x80]; + + /* stack buffer */ + __ntapi->tt_aligned_block_memset(buffer,0,sizeof(buffer)); + + status = __ntapi->tt_get_system_directory_dos_path( + hsysdir, + (wchar16_t *)buffer, + sizeof(buffer), + base_name, + base_name_size, + &nt_image_name); + + if (status != NT_STATUS_SUCCESS) + return status; + + status = __ntapi->ldr_load_dll( + 0, + 0, + &nt_image_name, + image_base); + + return status; +} diff --git a/src/ldr/ntapi_ldr_revert_state_to_snapshot.c b/src/ldr/ntapi_ldr_revert_state_to_snapshot.c new file mode 100644 index 0000000..2ca5087 --- /dev/null +++ b/src/ldr/ntapi_ldr_revert_state_to_snapshot.c @@ -0,0 +1,104 @@ +/********************************************************/ +/* 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 <dalist/dalist.h> +#include <ntapi/ntapi.h> +#include "ntapi_impl.h" + +struct callback_ctx { + struct dalist_ex * ldr_state_snapshot; + struct pe_ldr_tbl_entry * ldr_tbl_entry; + void * image_base; + uint32_t load_count; + int32_t status; +}; + +static int __cdecl __find_next_module_to_unload( + struct pe_ldr_tbl_entry * ldr_tbl_entry, + enum pe_callback_reason int_callback_reason, + void * context) +{ + struct dalist_node * node; + struct callback_ctx * ctx; + + ctx = (struct callback_ctx *)context; + + if (int_callback_reason == PE_CALLBACK_REASON_ERROR) { + ctx->status = NT_STATUS_UNSUCCESSFUL; + return ctx->status; + } else if (int_callback_reason != PE_CALLBACK_REASON_ITEM) { + ctx->status = NT_STATUS_SUCCESS; + return 1; + } else if (!ldr_tbl_entry->dll_base) { + ctx->status = NT_STATUS_SUCCESS; + return 1; + } + + + ctx->status = dalist_get_node_by_key( + ctx->ldr_state_snapshot, + (struct dalist_node_ex **)&node, + (uintptr_t)ldr_tbl_entry->dll_base, + DALIST_NODE_TYPE_EXISTING, + 0); + + if (ctx->status != DALIST_OK) + return -1; + else if (node) + return 1; + else if (!ctx->image_base || (ldr_tbl_entry->load_count < ctx->load_count)) { + ctx->image_base = ldr_tbl_entry->dll_base; + ctx->load_count = ldr_tbl_entry->load_count; + ctx->ldr_tbl_entry = ldr_tbl_entry; + } + + return 1; +} + + +int __cdecl __ntapi_ldr_revert_state_to_snapshot( + __in struct dalist_ex * ldr_state_snapshot) +{ + struct callback_ctx ctx; + uint32_t i; + + if (!ldr_state_snapshot->free && !ldr_state_snapshot->memfn_ptr) + return NT_STATUS_BUFFER_TOO_SMALL; + + ctx.ldr_state_snapshot = ldr_state_snapshot; + ctx.image_base = (void *)0; + ctx.load_count = 0; + + pe_enum_modules_in_load_order( + __find_next_module_to_unload, + &ctx); + + while ((ctx.image_base) && (ctx.status == NT_STATUS_SUCCESS)) { + if (ctx.load_count == 0xffff) { + ctx.load_count = 1; + ctx.ldr_tbl_entry->load_count = 1; + ctx.ldr_tbl_entry->entry_point = (void *)0; + ctx.ldr_tbl_entry->flags = 0; + } + + for (i=0; i<ctx.load_count; i++) + __ntapi->ldr_unload_dll(ctx.image_base); + + __ntapi->zw_unmap_view_of_section( + NT_CURRENT_PROCESS_HANDLE, + ctx.image_base); + ctx.image_base = (void *)0; + ctx.load_count = 0; + + pe_enum_modules_in_load_order( + __find_next_module_to_unload, + &ctx); + } + + return ctx.status; +} |