C 从用户模式运行内核模式系统调用
我试图使用C 从用户模式运行内核模式系统调用,c,assembly,kernel,ida,C,Assembly,Kernel,Ida,我试图使用OpenProcess()读取某些进程(如csrss.exe)的内存。问题是,只要我使用PROCESS\u ALL\u ACCESS这些进程就无法打开。因此,我尝试使用PROCESS\u QUERY\u LIMITED\u INFORMATION参数,但这并不能获得有趣的结果 根据我对系统的理解,此函数最终调用ZwOpenProcess()。我目前的理解是,如果应用程序在用户模式下访问它,那么这个调用也将被视为来自用户模式而不是内核模式的调用 为了绕过此检查,我执行了以下操作: 用于打
OpenProcess()
读取某些进程(如csrss.exe)的内存。问题是,只要我使用PROCESS\u ALL\u ACCESS
这些进程就无法打开。因此,我尝试使用PROCESS\u QUERY\u LIMITED\u INFORMATION
参数,但这并不能获得有趣的结果
根据我对系统的理解,此函数最终调用ZwOpenProcess()
。我目前的理解是,如果应用程序在用户模式下访问它,那么这个调用也将被视为来自用户模式而不是内核模式的调用
为了绕过此检查,我执行了以下操作:
ntdll.dll
ZwReadVirtualMemory()也做了同样的操作:
下面是我的问题:
我是否可以直接创建一个.asm文件,并在同一个文件中编写这些过程,然后调用它们以获得对这些函数的内核模式访问
如果我使用上述方法调用这些例程,PROCESS\u ALL\u ACCESS
是否适用于这些例程
我还需要使用VirtualQueryEx()
,我找不到内核模式的替代品,在这种情况下,我计划将VirtualQueryEx()
与上述自定义调用一起使用。现在我的问题是,既然VirtualQueryEx()
不是内核模式调用(至少不是在顶部,我的意思是ReadProcessMemory()
也调用ZwReadVirtualMemory(),但如果由用户模式程序启动,则不是内核模式调用,VirtualQueryEx()
)也是如此,这会是一个问题,还是在我进行下一个自定义调用时会恢复到用户模式
我做这一切的最终目的是能够以内核级权限打开所有进程,读取它们的内存并将它们转储到文件中。这还包括在系统级别运行的进程,如csrss.exe。如果存在任何更简单的方法,请用同样的方法启发我
Code :
HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
HANDLE lProc = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid);
DWORD error = GetLastError();
if (hProc || lProc)
{
//(!hProc && lProc) ? printf("lproc") : printf("hProc"); //Testing Condition
fProc = (!hProc && lProc) ? lProc : hProc;
while (1) {
if ((VirtualQueryEx(fProc, addr1, &meminfo, sizeof(meminfo))) == 0)
{
break;
}
if ((meminfo.State == MEM_COMMIT))
{
static unsigned char display_buffer[1024 * 128];
SIZE_T bytes_left;
SIZE_T total_read;
SIZE_T bytes_to_read;
SIZE_T bytes_read;
FILE *f;
f = fopen("Dump.txt", "a");
addr = (unsigned char*)meminfo.BaseAddress;
//printf("Process Name : %ws\r\n", pName.Buffer);
fprintf(f, "Process Name : %ws\r\n", pName.Buffer);
//printf("Base Address : 0x%08x\r\n", addr);
fprintf(f, "Base Address : 0x%08x\r\n", addr);
bytes_left = meminfo.RegionSize;
//printf("Region Size : %d\r\n", bytes_left);
fprintf(f, "Region Size : %d\r\n", bytes_left);
total_read = 0;
//printf("Contents : \r\n");
fprintf(f, "Contents : \r\n");
while (bytes_left)
{
bytes_to_read = (bytes_left > sizeof(display_buffer)) ? sizeof(display_buffer) : bytes_left;
ReadProcessMemory(hProc, addr + total_read, display_buffer, bytes_to_read, &bytes_read);
if (bytes_read != bytes_to_read) break;
int j = 0;
for (j = 0; j < bytes_to_read; j++)
{
if ((display_buffer[j] > 31) && (display_buffer[j] < 127)) {
//printf("%c ", display_buffer[j]);
fprintf(f, "%c", display_buffer[j]);
}
else {
//printf(".");
fprintf(f, ".");
}
}
//printf("\r\n");
fprintf(f, "\r\n");
bytes_left -= bytes_read;
total_read += bytes_read;
}
fclose(f);
}
addr1 = (unsigned char*)meminfo.BaseAddress + meminfo.RegionSize;
}
}
else {
printf("\nFailed to open process - error - %d\r\n", error);
}
代码:
HANDLE hProc=OpenProcess(PROCESS\u ALL\u ACCESS,FALSE,pid);
HANDLE lProc=OpenProcess(PROCESS\u QUERY\u LIMITED\u INFORMATION,FALSE,pid);
DWORD error=GetLastError();
if(hProc | | lProc)
{
//(!hProc&&lProc)?printf(“lProc”):printf(“hProc”);//测试条件
fProc=(!hProc&&lProc)?lProc:hProc;
而(1){
if((VirtualQueryEx(fProc、addr1和meminfo、sizeof(meminfo)))==0)
{
打破
}
if((meminfo.State==MEM_COMMIT))
{
静态无符号字符显示缓冲区[1024*128];
剩余字节的大小;
总读数的大小;
读取字节的大小;
读取的字节大小;
文件*f;
f=fopen(“Dump.txt”,“a”);
addr=(无符号字符*)meminfo.BaseAddress;
//printf(“进程名称:%ws\r\n”,pName.Buffer);
fprintf(f,“进程名称:%ws\r\n”,pName.Buffer);
//printf(“基址:0x%08x\r\n”,地址);
fprintf(f,“基址:0x%08x\r\n”,地址);
bytes_left=meminfo.RegionSize;
//printf(“区域大小:%d\r\n”,剩余字节);
fprintf(f,“区域大小:%d\r\n”,剩余字节);
总读数=0;
//printf(“内容:\r\n”);
fprintf(f,“内容:\r\n”);
while(剩余字节)
{
bytes_to_read=(bytes_left>sizeof(display_buffer))?sizeof(display_buffer):bytes_left;
ReadProcessMemory(hProc、addr+总读取、显示缓冲区、字节到字节读取和字节读取);
如果(字节读取!=字节读取)中断;
int j=0;
对于(j=0;j31)和&(显示缓冲区[j]<127)){
//printf(“%c”,显示缓冲区[j]);
fprintf(f,“%c”,显示缓冲区[j]);
}
否则{
//printf(“.”);
fprintf(f,“.”);
}
}
//printf(“\r\n”);
fprintf(f,“\r\n”);
字节\左-=字节\读取;
读取的总字节数+=读取的字节数;
}
fclose(f);
}
addr1=(无符号字符*)meminfo.BaseAddress+meminfo.RegionSize;
}
}
否则{
printf(“\n无法打开进程-错误-%d\r\n”,错误);
}
因此,在这里,我试图将所有内存信息保存到给定进程的DUMP.txt文件中。Windows Vista-Windows 10
感谢您指出,自Windows 10以来,情况发生了变化。
事实上,他们从WindowsVista开始改变
Windows Vista将
强制将DRM应用于媒体内容。
正常进程无法读取或修改受保护的进程(除其他限制外)。
受保护的进程只有在经过签名且仅执行一组受限制的
行动
在Windows 8.1中,Microsoft重新访问了受保护的进程,并引入了受保护的进程指示灯
(PPL)工艺等级。
一个PPL只能由另一个PPL启动;有了安全引导或安全保护,关键系统进程是PPL。
这意味着它们无法打开,即使是通过管理员/系统帐户
csrss.exe
也是一个PPL,因为Windows 8.1:
注
PsProtectedSignerNone = 0n0
PsProtectedSignerAuthenticode = 0n1
PsProtectedSignerCodeGen = 0n2
PsProtectedSignerAntimalware = 0n3
PsProtectedSignerLsa = 0n4
PsProtectedSignerWindows = 0n5
PsProtectedSignerWinTcb = 0n6
PsProtectedSignerMax/PsProtectedSignerWinSystem = 0n7
PROCESS_QUERY_LIMITED_INFORMATION
PROCESS_SUSPEND_RESUME
PROCESS_TERMINATE (excluding WinTcb, Antimalware and Lsa)
PROCESS_SET_LIMITED_INFORMATION
#include <windows.h>
int CALLBACK WinMain(
_In_ HINSTANCE hInstance,
_In_ HINSTANCE hPrevInstance,
_In_ LPSTR lpCmdLine,
_In_ int nCmdShow
)
{
HANDLE thisProcess = GetCurrentProcess();
HANDLE thisToken;
TOKEN_PRIVILEGES newPrivileges;
HANDLE thatProcess;
newPrivileges.PrivilegeCount = 1;
newPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if (LookupPrivilegeValue(NULL, "SeDebugPrivilege", &newPrivileges.Privileges[0].Luid) == 0)
{
MessageBox(NULL, "LookupPrivilegeValue", "Cannot find privilege", MB_ICONEXCLAMATION);
ExitProcess(1);
}
if (OpenProcessToken(thisProcess, TOKEN_ADJUST_PRIVILEGES, &thisToken) == 0)
{
MessageBox(NULL, "OpenProcessToken", "Cannot open token", MB_ICONEXCLAMATION);
ExitProcess(2);
}
AdjustTokenPrivileges(thisToken, FALSE, &newPrivileges, 0, NULL, NULL);
if (GetLastError() != ERROR_SUCCESS)
{
MessageBox(NULL, "AdjustTokenPrivileges", "Cannot adjust privileges", MB_ICONEXCLAMATION);
ExitProcess(3);
}
thatProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, 1080);
if (thatProcess == NULL)
{
MessageBox(NULL, "OpenProcess", "Cannot open that process", MB_ICONEXCLAMATION);
ExitProcess(4);
}
MessageBox(NULL, "Done", "Opened", MB_ICONINFORMATION);
}
mov r10, rcx
mov eax, 26h
syscall