资源简介
用了几天时间开发的一个源代码函数库,
函数库提供了一种在驱动里执行用户层代码的途径,
具体实现了调用LoadLibrary来在某个现有的进程中加载一个DLL,调用WinExec来启动一个进程。
测试能在winXP 32, WIN7 32位 和WIN7 64位等系统中运行。
在DriverEntry中调用 cbk_init初始化。
在卸载函数中调用 cbk_deinit清除。
在某个进程上下文执行环境调用cbk_execute。
如果要在某个现有进程中加载DLL,调用 cbkInsertLoadLibraryA/W
如果要在某个现有进程调用WinExec来启动另外一个进程,调用 cbkInsertWinExec
函数库有为木马开发者提供一点点后门之嫌疑,慎用。
对应的博客文章 http://blog.csdn.net/fanxiushu/article/details/38141219
代码片段和文件信息
/// By Fanxiushu 2014-06-25
//http://thisissecurity.net/2014/04/08/how-to-run-userland-code-from-the-kernel-on-windows/
#include “callback.h“
/////////////////////////////////////在用户应用程序里执行
struct SHELLCODE_PARAMS
{
PVOID pfunc;
PVOID param;
BOOLEAN bWinExec;
};
static ULONG ShellCode_Start(PVOID data ULONG data_len)
{
SHELLCODE_PARAMS* params = (SHELLCODE_PARAMS*)data;
if (params->bWinExec){ // WinExec
///
((ULONG(_stdcall*)(PVOID int))(params->pfunc))(params->param 1 );
}
else{
///
((ULONG(_stdcall*)(PVOID))(params->pfunc))(params->param);
}
//// 这个返回值等于 KeUserModeCallback 返回值
return STATUS_SUCCESS;
}
static VOID ShellCode_End(){}
//////////////////////////////////////////////////////////
//分配内存KeUserModeCallback 第一个参数是 ULONG, 所以 64位系统的分配策略从基址开始寻找 4G范围内的空闲空间
static NTSTATUS getProcessMemory(HANDLE proc_handlePVOID baseAddr PVOID* ppMem SIZE_T* pSize)
{
NTSTATUS status = STATUS_UNSUCCESSFUL;
#ifdef _WIN64
const ULONG COUNT = 1000; const ULONG SepSize = 1024 * 1024 * 3 / 2; const ULONG_PTR base = 1024 * 1024 * 50;
ULONG i;
for (i = 0; i < COUNT; ++i){
ULONG_PTR pMem = (ULONG_PTR)baseAddr + base + i*SepSize;
SIZE_T size = *pSize;
status = ZwAllocateVirtualMemory(proc_handle (PVOID*)&pMem 0 &size MEM_COMMIT | MEM_RESERVE PAGE_EXECUTE_READWRITE);
if (NT_SUCCESS(status)){
*pSize = size;
*ppMem = (PVOID)pMem;
break;
}
}
#else
status = ZwAllocateVirtualMemory(proc_handle ppMem 0 pSize MEM_COMMIT | MEM_RESERVE | MEM_TOP_DOWN PAGE_EXECUTE_READWRITE);
#endif
return status;
}
//// KeUserModeCallback 一定要在当前进程的当前用户线程环境下调用才成功
static NTSTATUS CallKeUserModeCallback(HANDLE proc_handle PVOID KernelCallbackTable
PVOID func_addr PVOID lpParam ULONG ParamSize BOOLEAN bWinExec )
{
NTSTATUS status = STATUS_SUCCESS;
//
PVOID pMem = NULL;
SIZE_T size = ParamSize;
size = (size / PAGE_SIZE + 1)*PAGE_SIZE + PAGE_SIZE; ///计算占用进程的空间
status = getProcessMemory(proc_handle KernelCallbackTable &pMem &size);
if (!NT_SUCCESS(status)){
DPT(“ZwAllocateVirtualMemory Err=0x%X\n“ status);
return status;
}
DPT(“pMem Addr=%p; KernelCallbackTable=%p\n“ pMem KernelCallbackTable);
__try{
////
ULONG TableIndex = (((ULONG_PTR)pMem - (ULONG_PTR)KernelCallbackTable) / sizeof(ULONG_PTR)); //获取索引
PVOID ShellCodeAddr = (PVOID)((ULONG_PTR)pMem + sizeof(ULONG_PTR));
ULONG ShellCodeSize = (ULONG_PTR)ShellCode_End - (ULONG_PTR)ShellCode_Start;
PVOID ParamAddr = (PVOID)((ULONG_PTR)ShellCodeAddr + ShellCodeSize);
*(ULONG_PTR*)pMem = (ULONG_PTR)ShellCodeAddr; /// 把开头地址内容写成下ShellCode执行的真正地址 KernelCallbackTable[TableIndex] = ShellCodeAddr;
RtlCopyMemory(ShellCodeAddr ShellCode_Start ShellCodeSize);
RtlCopyMemory(ParamAddr lpParam ParamSize);
SHELLCODE_PARAMS sp; RtlZeroMemory(&sp sizeof(SHELLCODE_PARAMS));
sp.pfunc = func_addr;
sp.param = ParamAddr;
属性 大小 日期 时间 名称
----------- --------- ---------- ----- ----
文件 530 2014-07-26 20:11 说明.txt
文件 15883 2014-07-26 18:01 callback.cpp
文件 3712 2014-07-01 11:11 callback.h
文件 4232 2014-07-07 15:50 common.cpp
文件 3053 2014-07-15 15:53 common.h
文件 55858 2014-06-25 14:50 pedef.h
----------- --------- ---------- ----- ----
83268 6
评论
共有 条评论