原理:遍历进程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 暴力枚举进程的更多相关文章

  1. ZwQueryVirtualMemory暴力枚举进程模块

    0x01 前言 同学问过我进程体中EPROCESS的三条链断了怎么枚举模块,这也是也腾讯面试题.我当时听到也是懵逼的. 后来在网上看到了一些内存暴力枚举的方法ZwQueryVirtualMemory. ...

  2. HookSSDT 通过HookOpenProcess函数阻止暴力枚举进程

    首先要知道Ring3层调用OpenProcess的流程 //当Ring3调用OpenProcess //1从自己的模块(.exe)的导入表中取值 //2Ntdll.dll模块的导出表中执行ZwOpen ...

  3. 枚举进程——暴力搜索内存(Ring0)

    上面说过了隐藏进程,这篇博客我们就简单描述一下暴力搜索进程. 一个进程要运行,必然会加载到内存中,断链隐藏进程只是把EPROCESS从链表上摘除了,但它还是驻留在内存中的.这样我们就有了找到它的方法. ...

  4. 由枚举模块到ring0内存结构 (分析NtQueryVirtualMemory)

    是由获得进程模块而引发的一系列的问题,首先,在ring3层下枚举进程模块有ToolHelp,Psapi,还可以通过在ntdll中获得ZwQuerySystemInformation的函数地址来枚举,其 ...

  5. zone.js - 暴力之美

    在ng2的开发过程中,Angular团队为我们带来了一个新的库 – zone.js.zone.js的设计灵感来源于Dart语言,它描述JavaScript执行过程的上下文,可以在异步任务之间进行持久性 ...

  6. [bzoj3123][sdoi2013森林] (树上主席树+lca+并查集启发式合并+暴力重构森林)

    Description Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数 ...

  7. HDU 5944 Fxx and string(暴力/枚举)

    传送门 Fxx and string Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Othe ...

  8. 1250 Super Fast Fourier Transform(湘潭邀请赛 暴力 思维)

    湘潭邀请赛的一题,名字叫"超级FFT"最终暴力就行,还是思维不够灵活,要吸取教训. 由于每组数据总量只有1e5这个级别,和不超过1e6,故先预处理再暴力即可. #include&l ...

  9. fragment+viepager 的简单暴力的切换方式

    这里是自定义了一个方法来获取viewpager private static ViewPager viewPager; public static ViewPager getMyViewPager() ...

随机推荐

  1. 解决浏览器location.href重定向失效问题

    在[location.href]赋值语句后,添加页面刷新代码[location.reload(true)],参数为[true]这样就等价于F5刷新页面了. 需要注意的是:不能把[location.re ...

  2. GitLab 遇到的坑

    Job for postfix.service failed because the control process exited with error [zbb@storage1 ~]$ sudo ...

  3. Linux网络编程基础

    1. Linux网络模型 ① OSI七层模型和Linux四层模型 ② 各种协议之间的关系及在Linux模型中的位置 ③ 协议封装:各种协议处于一种层层封装的关系 (1)Ethernet (2)IP * ...

  4. 2.Servlet(一)

    1.Servlet的编写.访问过程: (1)编写部署Servlet程序: 编写源文件->编译类文件->部署程序->运行->Servlet处理请求,返回响应. (2)Eclips ...

  5. github访问慢解决

    参考:https://github.com/chenxuhua/issues-blog/issues/3 hosts文件: # GitHub Start 192.30.253.112 github.c ...

  6. 绿豆蛙的归宿(Java)

    Description 随着新版百度空间的上线,Blog宠物绿豆蛙完成了它的使命,去寻找它新的归宿. 给出一个有向无环图,起点为1终点为N,每条边都有一个长度,并且从起点出发能够到达所有的点,所有的点 ...

  7. STL 部分学习 未整理

    https://www.cnblogs.com/pugang/archive/2012/02/10/2345942.html

  8. C++学习笔记:

    一 友元函数:友元函数没有this指针,不是类的成员,在外部定义无需类标识符,引用全局或者静态对象不需要类对象标识符,而访问非静态对象则需要. 二 类继承:如果不指定继承方式,默认是私有继承.但私有继 ...

  9. 正则表达式获取多个img src的值

    /** * 得到网页中图片的地址 */public static Set<String> getImgStr(String htmlStr) { Set<String> pic ...

  10. (转)老男孩:Linux企业运维人员最常用150个命令汇总

    近来老男孩发现新手学习Linux记不住命令,不会分类.不会筛选重点,胡子眉毛一把抓当然记不住了. 特别整理Linux运维最常用150个命令和大家分享,大家学习命令不用在盲目了,根据分类,然后逐步学习! ...