In the previous article Windows callback monitoring < A > summed up some usage of Createprocessnotify,createprocessnotifyex and loadimagenotify, and then produced a thought that Since loading the. exe file while the process is being created will execute our callback function, if we add an item to the import table of the in-memory. exe file in our callback function, the process will not load our prepared. dll file, and if it successfully loads our DLL, it will be injected successfully.
#pragmaOnce#include<ntifs.h>#include<ntimage.h>#include<windef. H>VOID Wpoff (); VOID Wpon (); VOID unloaddriver (Pdriver_object driverobject); VOID loadimagenotifyroutine (punicode_string fullimagename,handle processid,pimage_info ImageInfor);externchar*psgetprocessimagefilename (peprocess eprocess); VOID Unicodetochar (punicode_string unisource, CHAR*szdest); #include"LoadImage.h"Pimage_import_descriptor G_oldimportdesc; KIRQL IRQL; Peprocess g_targetprocess; HANDLE G_targetprocessid; NTSTATUS DriverEntry (in Pdriver_object driverobject, in punicode_string registerpath) {dbgprint ("driver loading \ r \ n"); DriverObject->driverunload =Unloaddriver; Pssetloadimagenotifyroutine ((pload_image_notify_routine) loadimagenotifyroutine); returnstatus_success;} VOID unloaddriver (Pdriver_object driverobject) {psremoveloadimagenotifyroutine (pload_image_notify_routine) Loadimagenotifyroutine); Dbgprint ("drive uninstall \ r \ n");} VOID loadimagenotifyroutine (punicode_string fullimagename,handle processid,pimage_info ImageInfor) {NTSTATUS Status; PVOID driverentryaddress=NULL; Charszfullimagename[260]={0}; Peprocess tatgetprocess=NULL; Kapc_state apcstate; BOOLEAN battached=FALSE; HANDLE hprocess; Status= Pslookupprocessbyprocessid (processid,&tatgetprocess); if(!nt_success (Status)) { return ; } if(Strstr (Psgetprocessimagefilename (tatgetprocess),"CC.exe"))//the current process is CC.exe{Unicodetochar (fullimagename,szfullimagename); if(Strstr (Szfullimagename,"CC.exe"))//the CC.exe is loaded.{G_targetprocessid=ProcessId; Status=Obopenobjectbypointer (tatgetprocess, Obj_kernel_handle|obj_case_insensitive, NULL, Generic_all,*Psprocesstype, KernelMode,&hprocess); if(!nt_success (Status)) {Obdereferenceobject (tatgetprocess); return; } g_targetprocess=tatgetprocess; __try {//kestackattachprocess (tatgetprocess,&apcstate); if(Mmisaddressvalid (imageinfor->ImageBase)) {Pimage_dos_header PDos; Pimage_nt_headers Pheader=NULL; Pimage_import_descriptor Pimportdesc; //zwunmapviewofsection (hprocess,imageinfor->imagebase);ULONG Nimportdllcount; PVOID Ulimagebase= imageinfor->ImageBase; ULONG nnewimportsize; ULONG nnewdllnamesize=0x20; Pimage_import_descriptor Lpnewimportdesc=NULL; PVOID Lpdllname=NULL; Image_import_descriptor Add_importdesc; Pimage_thunk_data Lpnewthunkdata=NULL; ULONG nnewthunkdatasize=0x20; Pimage_import_by_name Lpimportapi=NULL; ULONG nnewimportapisize=0x20; PDos=(Pimage_dos_header) ulimagebase; Pheader= (pimage_nt_headers) ((ULONG) ulimagebase+ (ULONG) pdos->e_lfanew); Pimportdesc= (Pimage_import_descriptor) ((ULONG) pheader->Optionalheader.datadirectory[image_directory_entry_import]. Virtualaddress+(ULONG) ulimagebase); //number of imported table itemsNimportdllcount = Pheader->optionalheader.datadirectory[image_directory_entry_import]. Size/sizeof(Image_import_descriptor); G_oldimportdesc= Pimportdesc;//The original import tablennewimportsize=sizeof(image_import_descriptor) * (nimportdllcount+1);//Add your ownStatus= Zwallocatevirtualmemory (Ntcurrentprocess (), &lpnewimportdesc,0, &nnewimportsize, Mem_commit, page_execute_readwrite); if(!nt_success (Status)) {Obdereferenceobject (tatgetprocess); Obdereferenceobject (tatgetprocess); return; } rtlzeromemory (Lpnewimportdesc,nnewimportsize); Status= Zwallocatevirtualmemory (hprocess, &lpdllname,0, &nnewdllnamesize, Mem_commit, page_execute_readwrite); if(!nt_success (Status)) {zwfreevirtualmemory (hprocess,&lpnewimportdesc,0, mem_release); Obdereferenceobject (tatgetprocess); Obdereferenceobject (tatgetprocess); return; } rtlzeromemory (Lpdllname,nnewdllnamesize); //ThunkdataStatus = Zwallocatevirtualmemory (hprocess, &lpnewthunkdata,0, &nnewthunkdatasize, Mem_commit, page_execute_readwrite); if(!nt_success (Status)) {zwfreevirtualmemory (hprocess,&lpnewimportdesc,0, mem_release); Zwfreevirtualmemory (hprocess,&lpdllname,0, mem_release); Obdereferenceobject (tatgetprocess); Obdereferenceobject (tatgetprocess); return; } rtlzeromemory (Lpnewthunkdata,nnewthunkdatasize); //Image_import_by_nameStatus = Zwallocatevirtualmemory (hprocess, &lpimportapi,0, &nnewimportapisize, Mem_commit|Mem_top_down, Page_execute_readwrite); if(!nt_success (Status)) {zwfreevirtualmemory (hprocess,&lpnewimportdesc,0, mem_release); Zwfreevirtualmemory (hprocess,&lpdllname,0, mem_release); Zwfreevirtualmemory (hprocess,&lpnewthunkdata,0, mem_release); Obdereferenceobject (tatgetprocess); Obdereferenceobject (tatgetprocess); return; } rtlzeromemory (Lpimportapi,nnewimportapisize); //The original import table, leaving a table entryRtlcopymemory (lpnewimportdesc+1, Pimportdesc,sizeof(image_import_descriptor) *nimportdllcount); Lpimportapi->hint =0; Rtlcopymemory (Lpimportapi->name,"DllMain",0x20); Lpnewthunkdata->u1. Addressofdata = (ULONG) lpimportapi-(ULONG) ulimagebase; Add_importdesc.originalfirstthunk= (ULONG) lpnewthunkdata-(ULONG) ulimagebase; Add_importdesc.timedatestamp=0; Add_importdesc.forwarderchain=0; Rtlcopymemory (Lpdllname,"Test.dll",0x20); Add_importdesc.name= (ULONG) lpdllname-(ULONG) ulimagebase; Add_importdesc.firstthunk=Add_importdesc.originalfirstthunk; Rtlcopymemory (Lpnewimportdesc,&add_importdesc,sizeof(Image_import_descriptor)); Wpoff (); //Modify DescriptorPheader->optionalheader.datadirectory[image_directory_entry_import]. Size + =sizeof(Image_import_descriptor); Pheader->optionalheader.datadirectory[image_directory_entry_import]. Virtualaddress = (ulong_ptr) Lpnewimportdesc-(ULONG_PTR) ulimagebase; Wpon (); } //keunstackdetachprocess (&apcstate);}__except (exception_execute_handler) {} obdereferenceobject (tatgetprocess); }} obdereferenceobject (tatgetprocess);} VOID Wpoff () {ulong_ptr CR0=0; IRQL=Keraiseirqltodpclevel (); CR0=__readcr0 (); CR0&=0xfffffffffffeffff; __WRITECR0 (CR0);} VOID Wpon () {ulong_ptr CR0=__readcr0 (); CR0|=0x10000; __WRITECR0 (CR0); KELOWERIRQL (IRQL);} VOID Unicodetochar (punicode_string unisource, CHAR*szdest) {ansi_string ansitemp; Rtlunicodestringtoansistring (&ansitemp,unisource,true); strcpy (Szdest,ansitemp.buffer); Rtlfreeansistring (&ansitemp);}
However, there is no egg, inject success, but do not know why, and finally show the program initialization error.
Hope to have the understanding of the hero pointing.
Windows callback monitoring < two >