扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
作者:朱先忠编译 来源:天极网 2007年10月17日
关键字:
//打开设备 device=CreateFile("\\\\.\\PROTECTOR",GENERIC_READ|GENERIC_WRITE, 0,0,OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM,0); //得到NtCreateSection的索引并把它连同输出缓冲区的地址传递给设备 DWORD * addr=(DWORD *) (1+(DWORD)GetProcAddress(GetModuleHandle("ntdll.dll"),"NtCreateSection")); ZeroMemory(outputbuff,256); controlbuff[0]=addr[0]; controlbuff[1]=(DWORD)&outputbuff[0]; DeviceIoControl(device,1000,controlbuff,256,controlbuff,256,&dw,0); |
NTSTATUS DrvDispatch(IN PDEVICE_OBJECT device,IN PIRP Irp) { UCHAR*buff=0; ULONG a,base; PIO_STACK_LOCATION loc=IoGetCurrentIrpStackLocation(Irp); if(loc->Parameters.DeviceIoControl.IoControlCode==1000) { buff=(UCHAR*)Irp->AssociatedIrp.SystemBuffer; //钩住服务调度表 memmove(&Index,buff,4); a=4*Index+(ULONG)KeServiceDescriptorTable->ServiceTable; base=(ULONG)MmMapIoSpace(MmGetPhysicalAddress((void*)a),4,0); a=(ULONG)&Proxy; _asm { mov eax,base mov ebx,dword ptr[eax] mov RealCallee,ebx mov ebx,a mov dword ptr[eax],ebx } MmUnmapIoSpace(base,4); memmove(&a,&buff[4],4); output=(char*)MmMapIoSpace(MmGetPhysicalAddress((void*)a),256,0); } Irp->IoStatus.Status=0; IoCompleteRequest(Irp,IO_NO_INCREMENT); return 0; } |
//这个函数用来确定是否我们应该允许NtCreateSection()调用成功 ULONG __stdcall check(PULONG arg) { HANDLE hand=0;PFILE_OBJECT file=0; POBJECT_HANDLE_INFORMATION info;ULONG a;char*buff; ANSI_STRING str; LARGE_INTEGER li;li.QuadPart=-10000; //检查标志。如果所要求的存取方式不是PAGE_EXECUTE, //这并不要紧 if((arg[4]&0xf0)==0)return 1; if((arg[5]&0x01000000)==0)return 1; //经由文件句柄得到文件名 hand=(HANDLE)arg[6]; ObReferenceObjectByHandle(hand,0,0,KernelMode,&file,&info); if(!file)return 1; RtlUnicodeStringToAnsiString(&str,&file->FileName,1); a=str.Length;buff=str.Buffer; while(1) { if(buff[a]=='.'){a++;break;} a--; } ObDereferenceObject(file); //如果它是不可执行的,这也不要紧 //返回1 if(_stricmp(&buff[a],"exe")){RtlFreeAnsiString(&str);return 1;} //现在,我们要询问用户的选择。 //把文件名写入缓冲区,并等待直到用户显示响应 //(第一个DWORD为1意味着我们可以继续) //同步存取该缓冲区 KeWaitForSingleObject(&event,Executive,KernelMode,0,0); //把缓冲区的前两个DWORD置为0, //把字符串复制到该缓冲区中,并循环下去,直到用户把每一个 //DWORD置为1. //第二个DWORD的值指明用户的响应 strcpy(&output[8],buff); RtlFreeAnsiString(&str); a=1; memmove(&output[0],&a,4); while(1) { KeDelayExecutionThread(KernelMode,0,&li); memmove(&a,&output[0],4); if(!a)break; } memmove(&a,&output[4],4); KeSetEvent(&event,0,0); return a; } //仅保存执行上下文并调用check() _declspec(naked) Proxy() { _asm{ //保存执行上下文并调用check() //-后面的依赖于check()所返回的值 // 如果返回值是1,继续实际的调用。 //否则,返回STATUS_ACCESS_DENIED pushfd pushad mov ebx,esp add ebx,40 push ebx call check cmp eax,1 jne block //继续实际的调用 popad popfd jmp RealCallee //返回STATUS_ACCESS_DENIED block:popad mov ebx, dword ptr[esp+8] mov dword ptr[ebx],0 mov eax,0xC0000022L popfd ret 32 } } |
如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。
现场直击|2021世界人工智能大会
直击5G创新地带,就在2021MWC上海
5G已至 转型当时——服务提供商如何把握转型的绝佳时机
寻找自己的Flag
华为开发者大会2020(Cloud)- 科技行者