Win64 驱动内核编程-26.强制结束进程
強(qiáng)制結(jié)束進(jìn)程
? ? 依然已經(jīng)走到驅(qū)動(dòng)這一層了,那么通常結(jié)束掉一個(gè)進(jìn)程不是什么難的事情。同時(shí)因?yàn)?span style="font-family:Times New Roman">win64?位的各種保護(hù),導(dǎo)致大家慢慢的已經(jīng)不敢HOOK了,當(dāng)然這指的是產(chǎn)品。作為學(xué)習(xí)和破解的話當(dāng)然可以嘗試各種hook。目前來說很多殺軟進(jìn)程保護(hù)都是通過回調(diào)了保護(hù)的,簡單,穩(wěn)定,安全。So,強(qiáng)制結(jié)束進(jìn)程會(huì)比當(dāng)年簡單很多。
首先就是上一個(gè)最基本的驅(qū)動(dòng)里結(jié)束進(jìn)程的方法:
?
1.直接調(diào)用ZwTerminateProcess去結(jié)束進(jìn)程,這個(gè)是公開導(dǎo)出的函數(shù),也就是說它很穩(wěn)定。不要小看這個(gè)東西,我測(cè)試過很多殺軟。目前停不掉的只有國外的?某傘,可能有人會(huì)關(guān)心國內(nèi)的各種衛(wèi)士能不能停掉!我覺得可以嘗試一下,通常不會(huì)失望。OK不廢話,上代碼:
TerminateProcess ->NtTerminateProcess ->ZwTerminateProcessvoid ZwKillProcess(HANDLE hdPid) { __try {HANDLE hProcess = NULL;CLIENT_ID ClientId = {0};OBJECT_ATTRIBUTES oa = {0};ClientId.UniqueProcess = (HANDLE)hdPid; ClientId.UniqueThread = 0;oa.Length = sizeof(oa);oa.RootDirectory = 0;oa.ObjectName = 0;oa.Attributes = 0;oa.SecurityDescriptor = 0;oa.SecurityQualityOfService = 0;ZwOpenProcess(&hProcess, 1, &oa, &ClientId);if (hProcess){ZwTerminateProcess(hProcess, 0);ZwClose(hProcess);};}__except (EXCEPTION_EXECUTE_HANDLER){;}}2.方法2就是通過PsTerminateSystemThread找到PspTerminateThreadByPointer
?
下面是Win7?64?雙機(jī)調(diào)試?windbg獲取的信息
????然后要找到Win7?64位PspTerminateThreadByPointer結(jié)構(gòu)(注意下面的是win7?64每個(gè)系統(tǒng)要單獨(dú)去找):
typedef NTSTATUS (__fastcall *PSPTERMINATETHREADBYPOINTER) ( IN PETHREAD Thread, IN NTSTATUS ExitStatus, IN BOOLEAN DirectTerminate );? ? 然后就是定位一個(gè)特征碼,從PsTerminateSystemThread開始往下找,直接把學(xué)習(xí)資料的代碼拿過來吧,作者是定位了01e8也就是兩條匯編指令相關(guān)的部分。然后自定義了一個(gè)計(jì)算公式hash這個(gè)特征碼,代碼如下(這個(gè)地方不固定,定位的越長,越準(zhǔn)確):
if(PspTerminateThreadByPointer==NULL) {AddressOfPsTST=(ULONG64)GetFunctionAddr(L"PsTerminateSystemThread");if(AddressOfPsTST==0)return STATUS_UNSUCCESSFUL;for(i=1;i<0xff;i++){if(MmIsAddressValid((PVOID)(AddressOfPsTST+i))!=FALSE){if(*(BYTE*)(AddressOfPsTST+i)==0x01&&*(BYTE*)(AddressOfPsTST+i+1)==0xe8) //目標(biāo)地址-原始地址-5=機(jī)器碼 ==> 目標(biāo)地址=機(jī)器碼+5+原始地址{RtlMoveMemory(&callcode,(PVOID)(AddressOfPsTST+i+2),4);AddressOfPspTTBP=(ULONG64)callcode + 5 + AddressOfPsTST+i+1;}}} PspTerminateThreadByPointer=(PSPTERMINATETHREADBYPOINTER)AddressOfPspTTBP;}
? ? 找到函數(shù)位置之后,剩下的可以直接枚舉線程id,找到進(jìn)程id,通過進(jìn)程id進(jìn)行對(duì)比之后決定是否結(jié)束掉這個(gè)線程。
for(i=4;i<0x40000;i+=4) {status=PsLookupThreadByThreadId((HANDLE)i, &Thread);if(NT_SUCCESS(status)){tProcess=IoThreadToProcess(Thread);if(tProcess==Process)PspTerminateThreadByPointer(Thread,0,1);ObDereferenceObject(Thread);} }3.第三種方式就是強(qiáng)行切到對(duì)方內(nèi)存里,然后直接?進(jìn)程虛擬內(nèi)存擦除(這個(gè)自己也會(huì)退出,但是可以繼續(xù)打開新進(jìn)程鏈接服務(wù)干活,或者擦除的時(shí)候就直接啟動(dòng)一個(gè)擦除進(jìn)程):
BOOLEAN ZeroKill(ULONG PID) //X32 X64 {NTSTATUS ntStatus = STATUS_SUCCESS;int i = 0;PVOID handle;PEPROCESS Eprocess;ntStatus = PsLookupProcessByProcessId(PID, &Eprocess);if (NT_SUCCESS(ntStatus)){PKAPC_STATEpKs=(PKAPC_STATE)ExAllocatePool(NonPagedPool, sizeof(PKAPC_STATE));KeStackAttachProcess(Eprocess , pKs);//Attach進(jìn)程虛擬空間for (i = 0; i <= 0x7fffffff; i += 0x1000){if (MmIsAddressValid((PVOID)i)){_try{ProbeForWrite((PVOID)i,0x1000,sizeof(ULONG));memset((PVOID)i,0xcc,0x1000);}_except(1){continue;}}else{if (i>0x1000000) //填這么多足夠破壞進(jìn)程數(shù)據(jù)了 break;}}KeUnstackDetachProcess(pKs);if (ObOpenObjectByPointer((PVOID)Eprocess, 0, NULL, 0, NULL, KernelMode, &handle) != STATUS_SUCCESS)return FALSE;ZwTerminateProcess((HANDLE)handle, STATUS_SUCCESS);ZwClose((HANDLE)handle);return TRUE;}return FALSE; }總結(jié)
以上是生活随笔為你收集整理的Win64 驱动内核编程-26.强制结束进程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Win64 驱动内核编程-25.X64枚
- 下一篇: Win64 驱动内核编程-28.枚举消息