Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 从用户模式运行内核模式系统调用_C_Assembly_Kernel_Ida - Fatal编程技术网

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
  • 找到这个函数,下面是我找到的
  • 根据我的理解,它再次执行一个测试,然后如果它的计算结果为0,它将执行低延迟系统调用,我相信这是函数的内核模式版本

    接下来,我对
    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