Kernel level using common hook function method to detect process

Source: Internet
Author: User
Tags count printf strcmp thread

A little thought about general hook:

In the system kernel level, much of MS Information is not disclosed, including the number of parameters of the function, the type of each parameter, and so on. In the system kernel, a large number of registers are accessed, while the values of many registers are provided by the upper caller. If the value changes the system will become unstable. There are likely to be unimaginable consequences. In addition, sometimes you do not know the parameters of the function that you need to hook, so you can't just change its stack, if you are careless, it may lead to a blue screen. So the best principle of hook is to call the original function in its own hook function, all register value, the value inside the stack and the information before the hook. This ensures that there is no error in the original function. Generally our own hook functions are written in the C file. For example, the target function of a hook is kireadythread.

Then you usually implement one yourself:

Mykireadythread (.....) )
{
  ...
  Call Kireadythread ...
}

But code compiled with the C compiler will show a stack frame:

Push EBP
mov ebp,esp

This is not our intention to change the number of registers violated, so we can use the assembly to achieve mykireadythread.

_func@0 proc
  Pushad     ; Save the Universal register call
  _cfunc@0; This is some of the processing done before entering the original function.
  popad       Restore Universal Register
  push EAX   
  mov eax,[esp+4]; Get the return address of the system on the stack when the call objective function is used.
  mov ds:_orgret,eax; save in a temporary variable
  pop eax
  mov [esp],retaddr; change the return address of the target function to its own code space return address so that it can take over
the processing after it returns
  jmp _orgdestfunction to the original target function
retaddr:
  pushad       ; Save the Register call _hookdestfunction@0 after the original function is processed;
  Re
  -process Popad     , reply register
  jmp Ds:_orgret, and skip to the next instruction of the system call target function.
_func@0 ENDP

When we want to intercept the target API, just modify the first 5 bytes of the original function of the machine as a jmp_func on the line. Then save the original 5 bytes, and when you jump into the original function, restore the 5 bytes.

The process in the Hook kireadythread detection system:

When the thread scheduler is preempted, the kireadythread is invoked, its prototype is void Fastcall kireadythread (in Prkthread thread), and when it enters the Kireadythread, the ECX points to thread. So you can hook Kireadythread and then use the ECX process information that is worth it. Kireadythread is not exported by Ntosknrl.exe, so it's hard to encode. The address in 2000SP4 is 0x8043141f.

Specific implementation:

1.cpp////////////////////////////////#ifdef __cplusplus extern "C" {#endif #inclu De "ntddk.h" #include "string.h" #include "ntifs.h" #include "stdio.h" #define File_device_event 0x8000 #define IOCTL_PA SSBUF \ Ctl_code (file_device_event, 0x802, method_buffered, file_any_access) void Driverunload (in PDRIVER_OBJECT pDriv

Erobject);

NTSTATUS DriverEntry (in Pdriver_object driverobject, in punicode_string Registrypath);

void Cfunc ();
void Hookdestfunction ();
NTSTATUS Deviceiocontroldispatch (in Pdevice_object deviceobject, in Pirp pirp);

extern void Func ();

void Resumedestfunction (); Const WCHAR devlink[] = L "\??
\\MyEvent ";
Const WCHAR devname[] = L "\\Device\\MyEvent";
Unicode_string Devnameunicd;   

Unicode_string Devlinkunicd; ULONG orgdestfunction = (ULONG) 0x8043141f;
Kireadythread char Jmpmycode [] = {0xe9,0x00,0x00,0x00,0x00};

Char Orgcode [5];

Char outbuf[128][16];

int Count = 0; ULONGORGCR0;

  #ifdef __cplusplus} #endif VOID disablewriteprotect (Pulong poldattr) {ULONG uattr;
      _asm {push eax;
      mov eax, CR0;
      mov uattr, eax; and eax, 0FFFEFFFFh;
      CR0 BIT = 0 mov cr0, eax;
  Pop eax;

  }; *poldattr = uattr;
    Save the original CRO attribute} VOID enablewriteprotect (ULONG uoldattr) {_asm {push eax; mov eax, uoldattr;
    Restore the original CR0 properties mov cr0, eax;
Pop eax;

};
  } NTSTATUS DriverEntry (in Pdriver_object pdriverobject, in punicode_string registrypath) {NTSTATUS Status;

  Pdevice_object pdevice;
  Dbgprint ("DriverEntry called!\n");
  Rtlinitunicodestring (&devnameunicd, devname);
  Rtlinitunicodestring (&devlinkunicd, DevLink); Status = IoCreateDevice (pdriverobject, 0, &devnameunicd, file_device_unknown, 0, TRUE, &PD
    Evice); if (!
    Nt_success (Status)) {dbgprint ("Can not create device.\n");
  return Status; Status = IocreatesymbolicliNK (&devlinkunicd, &DEVNAMEUNICD); if (!
      Nt_success (Status)) {Dbgprint ("Cannot create link.\n");
    return Status; 
    } pdriverobject->driverunload = Driverunload; Pdriverobject->majorfunction[irp_mj_create] = Pdriverobject->majorfunction[irp_mj_close] = pDriverObject-
    
  >majorfunction[irp_mj_device_control] = Deviceiocontroldispatch;
  Pdriverobject->driverunload = Driverunload;
  * ((ulong*) (jmpmycode+1)) = (ULONG) func-(ULONG) OrgDestFunction-5;
  memcpy (Orgcode, (char*) orgdestfunction,5);
  
  Hookdestfunction ();
return status_success;
  } void Driverunload (in Pdriver_object pdriverobject) {NTSTATUS status;
  Resumedestfunction ();
    if (Pdriverobject->deviceobject!= NULL) {status=iodeletesymboliclink (&DEVLINKUNICD); if (!
        Nt_success (status)) {Dbgprint (("Iodeletesymboliclink () failed\n")); } iodeletedevice (Pdriverobject->deviceobject);
    } void DisplayName (Pkthread Thread) {pkprocess Process = thread->apcstate.process;
  Peprocess peprocess = (peprocess) Process;
  Dbgprint ("Imagefilename =%s \ n", peprocess->imagefilename);
sprintf (outbuf[count++], "%s", peprocess->imagefilename);
  } void Cfunc (void) {ULONG pkheader=0;
  
  __asm {mov pkheader,ecx//ecx registers are prkthread parameters in Kireadythread} resumedestfunction ();   
  if (pkheader!= 0 && Count < 128) {DisplayName ((pkthread) pkheader);
  } void Hookdestfunction () {disablewriteprotect (&AMP;ORGCR0);
  memcpy ((char*) orgdestfunction,jmpmycode,5);   
Enablewriteprotect (ORGCR0);
  } void Resumedestfunction () {disablewriteprotect (&AMP;ORGCR0);
  memcpy ((char*) orgdestfunction,orgcode,5);
Enablewriteprotect (ORGCR0);         } NTSTATUS Deviceiocontroldispatch (in Pdevice_object deviceobject, in Pirp
  PIRP) {pio_stack_location irpstack; NtstATUs status;
  PVOID InputBuffer;
  ULONG inputlength;
  PVOID OutputBuffer;
  ULONG outputlength;

  Object_handle_information Objhandleinfo;
  status = Status_success;

  Remove IOCTL request Code Irpstack = Iogetcurrentirpstacklocation (PIRP);
    Switch (irpstack->majorfunction) {case Irp_mj_create:dbgprint (' Call irp_mj_create\n ');
  Break
    Case Irp_mj_close:dbgprint ("Call irp_mj_close\n");
  Break
    Case Irp_mj_device_control:dbgprint ("irp_mj_device_control\n");
    inputlength=irpstack->parameters.deviceiocontrol.inputbufferlength;
    outputlength=irpstack->parameters.deviceiocontrol.outputbufferlength; Switch (irpstack->parameters.deviceiocontrol.iocontrolcode) {case IOCTL_PASSBUF: {Rt
          
          Lcopymemory (Pirp->userbuffer, Outbuf, 20*16);
          memset (OUTBUF,0,128*16);
          Count = 0;
      Break  } Default:break;
    } default:dbgprint ("Call irp_mj_unknown\n");
  Break 
  } pirp->iostatus.status = Status; 
  pirp->iostatus.information = 0;
  IoCompleteRequest (PIRP, io_no_increment);
return status; 
}//////////////////////////////////1.asm////////////////////////////////. 386. Model Small. Data _orgret DD 0 Code Public _func@0 extrn _cfunc@0:near extrn _hookdestfunction@0:near extrn _orgdestfunction:dword _func@0 proc Pushad c All _cfunc@0 popad push EAX mov eax,[esp+4] mov ds:_orgret,eax pop eax mov [esp],retaddr jmp-_orgdestfunctio n Retaddr:pushad Call _hookdestfunction@0 popad jmp ds:_orgret _func@0 ENDP End////////////////////////////////  App.cpp//////////////////////////////////////////#include
 
  
 #include
 
  
 

#define File_device_event 0x8000 #define CTL_CODE (DeviceType, Function, Method, Access) (\ (DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) |         (method) \) #define FILE_ANY_ACCESS 0 #define METHOD_BUFFERED 0 #define File_device_unknown
    0x00000022 #define IOCTL_PASSBUF \ Ctl_code (file_device_event, 0x802, method_buffered, file_any_access) int main () {   
    HANDLE Hdevice; 
    BOOL status;
    ULONG Dwreturn;
    Char outbuf[129][16];
    Hdevice = NULL;
    M_hcommevent = NULL; Hdevice = CreateFile ("\\\\.\\myevent", generic_read| Generic_write, File_share_read |
    File_share_write, NULL, open_existing, file_attribute_normal, NULL);
      if (Hdevice = = Invalid_handle_value) {printf ("CreateFile wrong\n");
      GetChar ();
    return 0;
    while (1) {memset (outbuf,0,129*16); Status =deviceiocoNtrol (Hdevice, Ioctl_passbuf, NULL, 0, &outbuf, 128*16,
    &dwreturn,null);
        if (!status) {printf ("IO wrong+%d\n", GetLastError ());
        GetChar ();
    return 0;
    int c=0;
        while (* (char*) (&AMP;OUTBUF) +c*16) {//skips Csrss.exe and its own process information because it produces a lot of information.
          if (strcmp (char*) (&AMP;OUTBUF) +c*16, "App.exe") && \ strcmp ((char*) (&AMP;OUTBUF) +c*16, "Csrss.exe"))
        printf ("%s\n", (char*) (&AMP;OUTBUF) +c*16);
    C + +;
  Sleep (1); }
}

Test results:

......
TTPlayer.exe
system
TTPlayer.exe
vrvmon.exe
TTPlayer.exe
system
System
Explorer.EXE
Explorer.EXE
Explorer.EXE
...

testing, compiling environment Windows2000 SP4, Windows2000 DDK. Did not write the thread of the hidden process code, but basically achieved almost, just to return the information, and Ring3 level of the information obtained by the timely comparison can detect abnormal process.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.