/********************************************************/ /* ntapi: Native API core library */ /* Copyright (C) 2013--2017 Z. Gilboa */ /* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */ /********************************************************/ #include #include #include #include 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; }