原理:遍历进程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. AJAX使用说明书 基础

    AJAX简介 什么是AJAX AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步Javascript和XML”.即使用Javascript语言与服务器进行异 ...

  2. 牛客Professional Manager(并查集)

    t’s universally acknowledged that there’re innumerable trees in the campus of HUST.  Thus a professi ...

  3. 毕业设计 python opencv实现车牌识别 颜色判断

    主要代码参考https://blog.csdn.net/wzh191920/article/details/79589506 GitHub:https://github.com/yinghualuow ...

  4. hive复杂格式array,map,struct使用

    -- 创建数据库表,以array作为数据类型 drop table if exists person; create table person( name string ,work_locations ...

  5. python模块之HTMLParser简介

    html.parser是一个非常简单和实用的库,它的核心是HTMLParser类. 工作的流程是:当你feed给它一个类似HTML格式的字符串时,它会调用goahead方法向前迭代各个标签,并调用对应 ...

  6. 问题:eclipse中线程编程编译报错,undefined reference to 'pthread_create'的解决方法(已解决)

    问题描述: 在Ubuntu系统中,使用eclipse CDT集成开发环境编写pthread程序,编译时,pthread_create不通过,报错信息是: undefined reference to ...

  7. Java学习笔记day04_数组

    1.switch case switch语句中表达式的数据类型是有要求的: JDK 1.0 ~ 1.4 , 数据类型接受byte, short, int, char JDK 1.5 , 数据类型接受b ...

  8. Spring集成Quartz的3种方式

    1.使用xml配置方式 Maven依赖 <properties> <!-- spring版本号 --> <spring.version>4.2.2.RELEASE& ...

  9. 3d Max 2012安装失败怎样卸载3dsmax?错误提示某些产品无法安装

    AUTODESK系列软件着实令人头疼,安装失败之后不能完全卸载!!!(比如maya,cad,3dsmax等).有时手动删除注册表重装之后还是会出现各种问题,每个版本的C++Runtime和.NET f ...

  10. Sqlite操作的一些关键类的官方说明与Intent的startactivityforresult方法

    Intent: 该功能可以用于通过intent来跳转界面时候传递信号给原理的页面,以便做出一些处理: sqlite的使用: 该方法得到的sqlitedatabase可读可写,而getreadabled ...