summaryrefslogtreecommitdiffhomepage
path: root/src/ldr
diff options
context:
space:
mode:
authormidipix <writeonce@midipix.org>2015-07-27 04:01:18 -0400
committermidipix <writeonce@midipix.org>2015-07-27 04:01:18 -0400
commitdd89bb8ad4fe184a34b5dbdda237e640fc82121b (patch)
tree5e80d2da35f5892f92be29f57982b2708e6bd99b /src/ldr
parentdcdadc2702712fa750ed255ed1dfa354522797a0 (diff)
downloadntapi-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.c69
-rw-r--r--src/ldr/ntapi_ldr_load_system_dll.c44
-rw-r--r--src/ldr/ntapi_ldr_revert_state_to_snapshot.c104
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;
+}