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() ...
随机推荐
- Codeforces Round #335 (Div. 2) C
C. Sorting Railway Cars time limit pe ...
- GIL 线程池 进程池 同步 异步 阻塞 非阻塞
1.GIL 是一个全局解释器锁,是一种互斥锁 为什么需要GIL锁:因为一个python.exe进程中只有一份解释器,如果这个进程开启了多个线程都要执行代码 多线程之间要竞争解释器,一旦竞争就有可能出现 ...
- 提取SQL中用到的表
dos2unix * for i in `ls` do :}` awk '{print tolower($0)}' "${i}"|grep -Eiw "from" ...
- java thread start到run:C++源码分析
转:https://hunterzhao.io/post/2018/06/11/hotspot-explore-inside-java-thread-run/ 整体流程 java new Thread ...
- oracle序列的缓存
在高并发的数据库系统中,序列的缓存也要相应的调大.现在看看数据库自己的一个高并发序列的定义. 当我们向数据库发送一个请求时,监听接待,然后oracle会启动一个后台进程(这个进程就是通常所说的数据库并 ...
- leetcode 925. 长按键入
题目描述: 你的朋友正在使用键盘输入他的名字 name.偶尔,在键入字符 c 时,按键可能会被长按,而字符可能被输入 1 次或多次. 你将会检查键盘输入的字符 typed.如果它对应的可能是你的朋友的 ...
- c++中 重载 覆盖 隐藏的区别 附加 mutable笔记
成员函数被重载的特征有: 1) 相同的范围(在同一个类中): //2) 函数名字相同: 3) 参数不同: 4) virtual关键字可有可无. 覆盖的特征有: 1) 不同的范围(分别位于派生类与基类) ...
- SteamVR手柄震动控制实现
SteamVR手柄震动控制实现 public class handCtrl : MonoBehaviour { public SteamVR_TrackedObject _TrackedObject; ...
- (转)AIX修改系统时区的3种方法和AIX 时间问题(夏令时)
原文:http://blog.csdn.net/fuwencaho/article/details/28267283 http://www.wo81.com/tec/os/aix/2014-04-30 ...
- 《nginx 三》实现nginx的动态负载均衡——实战
Http动态负载均衡 什么是动态负载均衡 传统的负载均衡,如果Upstream参数发生变化,每次都需要重新加载nginx.conf文件, 因此扩展性不是很高,所以我们可以采用动态负载均衡,实现Upst ...