ring0 暴力枚举进程
原理:遍历进程ID,然后openprocess,能打开的都枚举出来
ring0 :
#include "EnumProcessByForce.h" extern
char* PsGetProcessImageFileName(PEPROCESS EProcess);
extern
POBJECT_TYPE* PsProcessType; NTSTATUS
DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegisterPath)
{
PDEVICE_OBJECT DeviceObject;
NTSTATUS Status;
int i = ;
UNICODE_STRING DeviceName;
UNICODE_STRING LinkName; RtlInitUnicodeString(&DeviceName, DEVICE_NAME);
RtlInitUnicodeString(&LinkName, LINK_NAME); Status = IoCreateDevice(DriverObject, , &DeviceName, FILE_DEVICE_UNKNOWN, , FALSE, &DeviceObject);
if (!NT_SUCCESS(Status))
{
return Status;
} Status = IoCreateSymbolicLink(&LinkName, &DeviceName); if (!NT_SUCCESS(Status))
{
//销毁设备对象
IoDeleteDevice(DeviceObject);
DeviceObject = NULL; return Status;
} DriverObject->DriverUnload = UnloadDriver; //设置派遣函数
for (i = ; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
{
DriverObject->MajorFunction[i] = DefaultPassThrough;
} DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DeviceControlDispatch; //DeviceIoControl(DeviceObject) } NTSTATUS DefaultPassThrough(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{ Irp->IoStatus.Information = ;
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT); //将Irp返回给IO管理器,IO_NO_INCREMENT不增加优先级
return STATUS_SUCCESS; } void UnloadDriver(PDRIVER_OBJECT DriverObject)
{
PDEVICE_OBJECT DeviceObject = NULL;
PDEVICE_OBJECT v1 = NULL;
UNICODE_STRING LinkName; RtlInitUnicodeString(&LinkName, LINK_NAME);
IoDeleteSymbolicLink(&LinkName);
DeviceObject = DriverObject->DeviceObject;
v1 = DeviceObject;
while (DeviceObject != NULL)
{
v1 = DeviceObject->NextDevice;
IoDeleteDevice(DeviceObject);
DeviceObject = v1;
} } NTSTATUS DeviceControlDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
NTSTATUS Status = STATUS_SUCCESS;
ULONG IoControlCode = ;
PVOID InputBuffer = NULL;
PVOID OutputBuffer = NULL;
ULONG32 InputLength = ;
ULONG32 OutputLength = ;
char BufferData[MAX_PATH] = { };
ULONG BufferLength = MAX_PATH; PIO_STACK_LOCATION IoStackLocation = IoGetCurrentIrpStackLocation(Irp); IoControlCode = IoStackLocation->Parameters.DeviceIoControl.IoControlCode; switch (IoControlCode) //IO控制码
{
case CTL_GET_PROCESS_IMAGE_NAME_BY_PROCESSID:
{ InputBuffer = OutputBuffer = Irp->AssociatedIrp.SystemBuffer; //CopyBuffer
InputLength = IoStackLocation->Parameters.DeviceIoControl.InputBufferLength;
OutputLength = IoStackLocation->Parameters.DeviceIoControl.OutputBufferLength; //功能
if (InputLength == sizeof(ULONG) && InputBuffer != NULL&&OutputLength == MAX_PATH)
{
Status = EnumProcessByForce(*((PULONG)InputBuffer), BufferData, &BufferLength); if (NT_SUCCESS(Status))
{
memcpy((char*)OutputBuffer, BufferData, BufferLength);
} else
{
BufferLength = ;
} } }
default:
{ break;
} } Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = BufferLength; //指示有多少内存向Ring3拷贝 //最后派遣函数将IRP请求结束,通过IoCompleteRequest IoCompleteRequest(Irp, IO_NO_INCREMENT); //将Irp返回给IO管理器
return STATUS_SUCCESS; } NTSTATUS EnumProcessByForce(ULONG ProcessID, char* BufferData, ULONG* BufferLength)
{
//进程的名称存储在进程的EProcess当前 NTSTATUS Status = STATUS_UNSUCCESSFUL;
PEPROCESS EProcess = NULL;
Status = PsLookupProcessByProcessId((HANDLE)ProcessID, &EProcess); if (!NT_SUCCESS(Status))
{
return Status;
}
//判断是否有效
if (IsRealProcess(EProcess) == TRUE)
{
ObDereferenceObject(EProcess); if (strlen(PsGetProcessImageFileName(EProcess)) < *BufferLength)
{
*BufferLength = strlen(PsGetProcessImageFileName(EProcess));
}
else
{
*BufferLength = *BufferLength - ;
} memcpy(BufferData, PsGetProcessImageFileName(EProcess), *BufferLength);
return STATUS_SUCCESS;
} return Status;
} BOOLEAN IsRealProcess(PEPROCESS EProcess)
{
ULONG_PTR ObjectType;
ULONG_PTR ObjectTypeAddress;
ULONG_PTR ProcessType = ((ULONG_PTR)*PsProcessType); //系统导出的全局变量 if (ProcessType && EProcess && MmIsAddressValid((PVOID)(EProcess)))
{
ObjectType = KeGetObjectType((PVOID)EProcess); //通过EProcess 获得进程对象特征码
if (ObjectType &&
ProcessType == ObjectType)
{
return TRUE;
}
}
return FALSE;
}
ULONG_PTR KeGetObjectType(PVOID ObjectBody)
{
ULONG_PTR ObjectType = NULL; pfnObGetObjectType ObGetObjectType = NULL;
/*
kd> u ObGetObjectType
nt!ObGetObjectType:
840a8b68 8bff mov edi,edi
840a8b6a 55 push ebp
840a8b6b 8bec mov ebp,esp
840a8b6d 8b4508 mov eax,dword ptr [ebp+8]
840a8b70 0fb640f4 movzx eax,byte ptr [eax-0Ch]
840a8b74 8b04858035f983 mov eax,dword ptr nt!ObTypeIndexTable (83f93580)[eax*4]
840a8b7b 5d pop ebp
840a8b7c c20400 ret 4
*/
if (!MmIsAddressValid || !ObjectBody || !MmIsAddressValid(ObjectBody))
{
return NULL;
}
ObGetObjectType = (pfnObGetObjectType)GetFunctionAddressByName(L"ObGetObjectType");
if (ObGetObjectType)
{
ObjectType = ObGetObjectType(ObjectBody);
} return ObjectType;
} PVOID GetFunctionAddressByName(WCHAR *FunctionName)
{
UNICODE_STRING v1;
PVOID FunctionAddress = NULL; if (FunctionName && wcslen(FunctionName) > )
{
RtlInitUnicodeString(&v1, FunctionName);
FunctionAddress = MmGetSystemRoutineAddress(&v1); //在系统第一个模块ntoskrnl.exe 导出表中搜索
}
return FunctionAddress;
}
//对派遣函数的简单处理
//大部分的IRP都源于文件I / O处理的API,如CreateFile、ReadFile等。处理这些IRP最简单的方法是在相应的派遣函数中,
//将IRP的状态设置成功,然后结束IRP的请求(使用IoCompleteRequest),并让派遣函数返回成功。
ring3 :
#include "stdafx.h"
#include "EnumProcessForceRing3.h" #ifdef _DEBUG
#define new DEBUG_NEW
#endif // 唯一的应用程序对象
#include <windows.h>
#include <WinIoCtl.h>
#include <map>
CWinApp theApp; using namespace std; #define LINK_NAME L"\\\\.\\LinkName" //rdata #define CTL_CODE( DeviceType, Function, Method, Access ) ( \
((DeviceType) << ) | ((Access) << ) | ((Function) << ) | (Method) )
#define CTL_GET_PROCESS_IMAGE_NAME_BY_PROCESSID \
CTL_CODE(FILE_DEVICE_UNKNOWN,0x830,METHOD_BUFFERED,FILE_ANY_ACCESS) void EnumProcessForce(HANDLE DeviceHandle, map<ULONG, CString>& ProcessInfo);
BOOL GrantPriviledge(IN const WCHAR* PriviledgeName);
map<ULONG, CString> __ProcessInfo;
int main()
{ GrantPriviledge(L"SeDebugPrivilege");
HANDLE DeviceHandle = NULL;
DeviceHandle = CreateFile(LINK_NAME, //设备名称 不是\\Device\\ 是要使用设备对象的LinkName
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (DeviceHandle == INVALID_HANDLE_VALUE)
{
return FALSE;
}
printf("已连接");
__ProcessInfo[] = "System.exe";
EnumProcessForce(DeviceHandle, __ProcessInfo); //模块
if (DeviceHandle != NULL)
{
CloseHandle(DeviceHandle); DeviceHandle = NULL;
} map<ULONG, CString>::iterator Travel; for (Travel = __ProcessInfo.begin(); Travel != __ProcessInfo.end(); Travel++)
{
printf("%4d %S\r\n", Travel->first, Travel->second);
} printf("Input AnyKey To Exit\r\n");
getchar();
return ;
} void EnumProcessForce(HANDLE DeviceHandle, map<ULONG, CString>& ProcessInfo)
{
DWORD ReturnLength = ;
char ProcessImageName[MAX_PATH] = { };
size_t i = ;
while (i < )
{
HANDLE ProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, i);
if (ProcessHandle == NULL)
{
i += ;
continue;
}
BOOL IsOk = DeviceIoControl(DeviceHandle, CTL_GET_PROCESS_IMAGE_NAME_BY_PROCESSID, //消息码
&i, //InputData
sizeof(ULONG), //InputDataSize
ProcessImageName, //OutputData
MAX_PATH, //OutputDataSize
&ReturnLength,
NULL);
if (IsOk == TRUE&&ReturnLength != )
{
ProcessImageName[ReturnLength] = '\0';
}
ProcessInfo[i] = ProcessImageName;
i += ;
}
}
BOOL GrantPriviledge(IN const WCHAR* PriviledgeName)
{
// 打开权限令牌
HANDLE ProcessHandle = GetCurrentProcess();
HANDLE TokenHandle = NULL;
LUID uID;
if (!OpenProcessToken(ProcessHandle, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &TokenHandle))
{
return FALSE;
}
if (!LookupPrivilegeValue(NULL, PriviledgeName, &uID)) // 通过权限名称查找uID
{
CloseHandle(TokenHandle);
TokenHandle = NULL;
return FALSE;
}
TOKEN_PRIVILEGES TokenPrivileges;
TokenPrivileges.PrivilegeCount = ; // 要提升的权限个数
TokenPrivileges.Privileges[].Attributes = SE_PRIVILEGE_ENABLED; // 动态数组,数组大小根据Count的数目
TokenPrivileges.Privileges[].Luid = uID;
if (!AdjustTokenPrivileges(TokenHandle, FALSE, &TokenPrivileges,
sizeof(TOKEN_PRIVILEGES), NULL, NULL))
{
printf("%d\r\n", GetLastError());
CloseHandle(TokenHandle);
TokenHandle = NULL;
return FALSE;
}
CloseHandle(TokenHandle);
TokenHandle = NULL;
return TRUE;
}
ring0 暴力枚举进程的更多相关文章
- ZwQueryVirtualMemory暴力枚举进程模块
0x01 前言 同学问过我进程体中EPROCESS的三条链断了怎么枚举模块,这也是也腾讯面试题.我当时听到也是懵逼的. 后来在网上看到了一些内存暴力枚举的方法ZwQueryVirtualMemory. ...
- HookSSDT 通过HookOpenProcess函数阻止暴力枚举进程
首先要知道Ring3层调用OpenProcess的流程 //当Ring3调用OpenProcess //1从自己的模块(.exe)的导入表中取值 //2Ntdll.dll模块的导出表中执行ZwOpen ...
- 枚举进程——暴力搜索内存(Ring0)
上面说过了隐藏进程,这篇博客我们就简单描述一下暴力搜索进程. 一个进程要运行,必然会加载到内存中,断链隐藏进程只是把EPROCESS从链表上摘除了,但它还是驻留在内存中的.这样我们就有了找到它的方法. ...
- 由枚举模块到ring0内存结构 (分析NtQueryVirtualMemory)
是由获得进程模块而引发的一系列的问题,首先,在ring3层下枚举进程模块有ToolHelp,Psapi,还可以通过在ntdll中获得ZwQuerySystemInformation的函数地址来枚举,其 ...
- zone.js - 暴力之美
在ng2的开发过程中,Angular团队为我们带来了一个新的库 – zone.js.zone.js的设计灵感来源于Dart语言,它描述JavaScript执行过程的上下文,可以在异步任务之间进行持久性 ...
- [bzoj3123][sdoi2013森林] (树上主席树+lca+并查集启发式合并+暴力重构森林)
Description Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数 ...
- HDU 5944 Fxx and string(暴力/枚举)
传送门 Fxx and string Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Othe ...
- 1250 Super Fast Fourier Transform(湘潭邀请赛 暴力 思维)
湘潭邀请赛的一题,名字叫"超级FFT"最终暴力就行,还是思维不够灵活,要吸取教训. 由于每组数据总量只有1e5这个级别,和不超过1e6,故先预处理再暴力即可. #include&l ...
- fragment+viepager 的简单暴力的切换方式
这里是自定义了一个方法来获取viewpager private static ViewPager viewPager; public static ViewPager getMyViewPager() ...
随机推荐
- Kibana6.x.x——执行yarn build出现的警告信息记录
Running "_build:installDependencies" task Warning: Command failed: /home/kibana_git/kibana ...
- 互联网开发-web文件上传性能问题
1. 问题描述 文件大小 部署环境 平均上传速度 5M 外网 28s-36s 5M 公司局域内网 秒传,很快 2. 问题分析 在网上搜索“测速网”测试了一下公司外网的带宽情况: 上传带宽 = 1.04 ...
- Dev GridView RowCellClick事件与MouseDown事件
GridView处于可编辑状态,左键点击默认为“进入编辑”. 将GridView的OptionsColumn.AllowEdit设置为false后左键可触发RowCellClick.但有时候,既希望G ...
- Linux中的netstat命令详解
功能说明 netstat是基于Netstat这个命令行工具的指令,它可以用来查询系统上的网络套接字连接情况,包括tcp,udp以及Unix套接字:另外它还能列出路由表,接口状态和多播成员等信息. 主要 ...
- Spyder清除Variable Explorer&&手动安装protobuf3.0(为了配置windows的python接口)
输入:reset 选择:y PS:建议在windows下,安装anaconda32bit版本的,可以兼容更多第三方包. Conda使用清华镜像 配置镜像 在conda安装好之后,默认的镜像是官方的 ...
- css 断行省略号,隐藏,fixed定位
text-overflow(clip | elipsis)(显示省略号| 不显示省略号) white-space:nowrap 强制文字不断行 word-break:break-all; ...
- 转Linux 下用alias 设置命令别名快速切换常用命令
https://blog.csdn.net/u012830148/article/details/80618616 在linux下开发,经常需要切换目录,如果目录很长则切换起来非常的麻烦,针对一些常用 ...
- django-filter version 2.0 改动
今天使用django-filter时候遇到了下面这个问题: django-filter: TypeError at /goods/ init() got an unexpected keyword a ...
- 前后端分离之JWT用户认证
在前后端分离开发时为什么需要用户认证呢?原因是由于HTTP协定是不储存状态的(stateless),这意味着当我们透过帐号密码验证一个使用者时,当下一个request请求时它就把刚刚的资料忘了.于是我 ...
- python绘制动态图
1.需要注意的问题 解决 MatplotlibDeprecationWarning: Using default event loop until function specific to this ...