日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

网上一个仿TP挂钩内核的源码

發(fā)布時間:2024/4/11 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 网上一个仿TP挂钩内核的源码 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

最近研究TESSAFE.SYS的驅(qū)動,GOOGLE搜索到微點也是一樣的手法HOOK call ObOpenObjectByPointe,把不完整的代碼給編寫實現(xiàn)了下。未實現(xiàn)檢測,應(yīng)該是有修改我的代碼或恢復(fù)HOOK call即重啟或藍(lán)屏,我為了方便沒實現(xiàn),下載我改動后驅(qū)動文件,用來保護(hù)記事本不被OPENprocess。。

然后unhook call?ObOpenObjectByPointe 的代碼從網(wǎng)上摘來,在搞虛擬機(jī)里可以過掉,但主機(jī)確是老藍(lán)屏8e代碼。原來是代碼根本不對,看雪上發(fā)的貼,有指出不對的代碼拷貝函數(shù),我做下修改為指令長度拷貝,終于可以了。反inline hook 深層call驅(qū)動文件,可以下載,源碼都在下面了,文件里就沒放。注意順序,必須先開這個驅(qū)動才有用,因為是從內(nèi)存拷貝來的,先讓inline hook 深層call驅(qū)動加載了,在拷貝內(nèi)存也是錯誤的。關(guān)閉時倒序來,否則藍(lán)了別怪我,模擬就只是模擬罷了。

//unhok call?這是SSDT hook,在深層call ObOpenObjectByPointe驅(qū)動加載前復(fù)制NtOpenThread NtOpenProcess 兩個代碼到別處SSDT。原來主機(jī)藍(lán)屏,但虛擬機(jī)也實現(xiàn)不藍(lán),反匯編下看到代碼烤過來的不對,果然是拷貝函數(shù)沒處理細(xì)節(jié),做下修改BufferCode函數(shù)加了反匯編引擎判斷指令長度,按長度來拷貝,再根據(jù)指令做重定位。

?

#include "ntddk.h"

#include <ntdef.h>

#include "LDasm.h"

#define ThreadLength 0x4f4 //要保存的 NtOpenThread 原代碼的長度

#define ProcessLength 0x28a //要保存的 NtOpenProcess 原代碼的長度


#define DeviceLink L"\\Device\\DNFCracker"

#define SymbolicLink L"\\DosDevices\\DNFCracker"

#define IOCTL_RESTORE (ULONG)CTL_CODE(FILE_DEVICE_UNKNOWN, 0x886, METHOD_BUFFERED, FILE_ANY_ACCESS)


typedef NTSTATUS (* NTOPENTHREAD)(

?OUT PHANDLE ThreadHandle,

?IN ACCESS_MASK DesiredAccess,

?IN POBJECT_ATTRIBUTES ObjectAttributes,

?IN OPTIONAL PCLIENT_ID ClientId

?);


typedef NTSTATUS (* NTOPENPROCESS)(

??OUT PHANDLE ProcessHandle,

??IN ACCESS_MASK DesiredAccess,

??IN POBJECT_ATTRIBUTES ObjectAttributes,

??IN PCLIENT_ID ClientId

??);


typedef struct _SERVICE_DESCRIPTOR_TABLE

{

PVOID ???ServiceTableBase;

PULONG ??ServiceCounterTableBase;

ULONG ???NumberOfService;

ULONG ???ParamTableBase;

}

SERVICE_DESCRIPTOR_TABLE, *PSERVICE_DESCRIPTOR_TABLE;

extern PSERVICE_DESCRIPTOR_TABLE KeServiceDescriptorTable;


VOID Hook();

VOID Unhook();

VOID BufferCode(PUCHAR pCode, ULONG TrgAddr, ULONG BufferLength);

NTOPENTHREAD OldThread;

NTOPENPROCESS OldProcess;

ULONG AddrRead, AddrWrite;

//原 NtReadVirtualMemory/NtWriteVirtualMemory 的前 16 字節(jié)代碼

ULONG OrgRead[2], OrgWrite[2];

//保存 NtOpenThread/NtOpenProcess 代碼

UCHAR MyThread[ThreadLength], MyProcess[ProcessLength];


NTSTATUS MyNtOpenThread(

PHANDLE ThreadHandle,

ACCESS_MASK DesiredAccess,

POBJECT_ATTRIBUTES ObjectAttributes,

PCLIENT_ID ClientId)?

{

ACCESS_MASK oDA;

OBJECT_ATTRIBUTES oOA;

CLIENT_ID oCID;

NTSTATUS statusF, statusT;


oDA = DesiredAccess;

oOA = *ObjectAttributes;

oCID = *ClientId;


statusF = OldThread(ThreadHandle, oDA, &oOA, &oCID);

statusT = ((NTOPENTHREAD)MyThread)(ThreadHandle, DesiredAccess, ObjectAttributes, ClientId);

return statusT;

}


NTSTATUS MyNtOpenProcess(

PHANDLE ProcessHandle,

ACCESS_MASK DesiredAccess,

POBJECT_ATTRIBUTES ObjectAttributes,

PCLIENT_ID ClientId)?

{

ACCESS_MASK oDA;

OBJECT_ATTRIBUTES oOA;

CLIENT_ID oCID;

NTSTATUS statusF, statusT;


oDA = DesiredAccess;

oOA = *ObjectAttributes;

oCID = *ClientId;


statusF = OldProcess(ProcessHandle, oDA, &oOA, &oCID);

statusT = ((NTOPENPROCESS)MyProcess)(ProcessHandle, DesiredAccess, ObjectAttributes, ClientId);

return statusT;

}



VOID OnUnload(IN PDRIVER_OBJECT DriverObject)

{

//UNICODE_STRING usLink;

Unhook();

DbgPrint("DNF Cracker Unloaded!");

}


VOID Hook()

{

ULONG AddrProcess, AddrThread;

KIRQL Irql;

AddrRead = (ULONG)KeServiceDescriptorTable->ServiceTableBase + 0xBA * 4;

AddrWrite = (ULONG)KeServiceDescriptorTable->ServiceTableBase + 0x115 * 4;

AddrThread = (ULONG)KeServiceDescriptorTable->ServiceTableBase + 0x80 * 4;

AddrProcess = (ULONG)KeServiceDescriptorTable->ServiceTableBase + 0x7A * 4;


OldThread = (NTOPENTHREAD)(*(PULONG)AddrThread);

OldProcess = (NTOPENPROCESS)(*(PULONG)AddrProcess);

//DbgPrint("MyThread:0xX OldThread:0xX", MyThread, OldThread);

//DbgPrint("MyProcess:0xX OldProcess:0xX", MyProcess, OldProcess);


__asm

{

cli

mov eax,cr0

and eax,not 10000h

mov cr0,eax

}

Irql=KeRaiseIrqlToDpcLevel();

//記錄 NtReadVirtualMemory/NtWriteVirtualMemory 前 16 字節(jié)


//保存原代碼

BufferCode(MyThread, (ULONG)OldThread, ThreadLength);

BufferCode(MyProcess, (ULONG)OldProcess, ProcessLength);


//SSDT Hook

*(PULONG)AddrThread = (ULONG)MyNtOpenThread;

*(PULONG)AddrProcess = (ULONG)MyNtOpenProcess;

KeLowerIrql(Irql);

__asm

{

mov eax,cr0

or eax,10000h

mov cr0,eax

sti

}

DbgPrint("OldThread!:X\n",(ULONG)OldThread);

DbgPrint("OldProcess!:X\n",(ULONG)OldProcess);

DbgPrint("MyThread!:X\n",(ULONG)MyThread);

DbgPrint("MyProcess!:X\n",(ULONG)MyProcess);

}


VOID Unhook()

{

ULONG AddrProcess, AddrThread;KIRQL Irql;

AddrThread = (ULONG)KeServiceDescriptorTable->ServiceTableBase + 0x80 * 4;

AddrProcess = (ULONG)KeServiceDescriptorTable->ServiceTableBase + 0x7A * 4;


__asm

{

cli

mov eax,cr0

and eax,not 10000h

mov cr0,eax

}

Irql=KeRaiseIrqlToDpcLevel();

//恢復(fù) SSDT

*(PULONG)AddrThread = (ULONG)OldThread;

*(PULONG)AddrProcess = (ULONG)OldProcess;

KeLowerIrql(Irql);

__asm

{?

mov eax,cr0

or eax,10000h

mov cr0,eax

sti

}

}

NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)

{

DbgPrint("DNF Cracker Loaded!");

DriverObject->DriverUnload = OnUnload;


Hook();


return STATUS_SUCCESS;

}


// OrgRel 原相對跳轉(zhuǎn)地址

// CurAbs 當(dāng)前代碼絕對地址

// MyAbs 替換代碼絕對地址

// CodeLen 跳轉(zhuǎn)代碼占據(jù)的長度

// 返回值 到替換代碼的相對地址

LONG GetRelAddr(LONG OrgRel, ULONG CurAbs, ULONG MyAbs) //, ULONG CodeLen)

{

ULONG TrgAbs;

TrgAbs = CurAbs + OrgRel; // + CodeLen; //目的地址

return TrgAbs - MyAbs;

}


// 保存原來整個函數(shù)的代碼(已修改的正確拷貝指令函數(shù))

// pCode 用來保存代碼的數(shù)組的地址

// TrgAddr 要保存的函數(shù)的地址

// BufferLength 整個函數(shù)占用的大小

VOID BufferCode(PUCHAR pCode, ULONG TrgAddr, ULONG BufferLength)

{

PUCHAR cPtr, pOpcode;

ULONG cAbs, i;

LONG oRel, cRel;

????ULONG Length;

memset(pCode, 0x90, BufferLength);

for (i = 0; i < BufferLength; i+= Length)

{

cAbs = TrgAddr + i;

pCode[i] = *(PUCHAR)cAbs;

Length = SizeOfCode((PUCHAR)cAbs, &pOpcode);//計算當(dāng)前指令長度

if(Length)

{//不為0則考過來指令, 長度:Length

memcpy(pCode + i, (PVOID)(cAbs), Length);

}//下面對這條指令重新處理,修正定位

//if (!Length) break;

switch (*(PUCHAR)cAbs)

{

case 0x0F: //JXX NEAR X

if ((*(PUCHAR)(cAbs + 1) >= 0x80)&&(*(PUCHAR)(cAbs + 1) <= 0x8F))

{

oRel = *(PLONG)(cAbs + 2);

if ((oRel + cAbs + 6 > TrgAddr + BufferLength)||

(oRel + cAbs + 6 < TrgAddr)) //判斷跳轉(zhuǎn)是否在過程范圍內(nèi)

{

pCode[i + 1] = *(PUCHAR)(cAbs + 1);

cRel = GetRelAddr(oRel, cAbs, (ULONG)pCode + i);

memcpy(pCode + i + 2, &cRel, sizeof(LONG));

//DbgPrint("JXX: 0xX -> 0xX", cAbs, (ULONG)pCode + i);

//i += sizeof(LONG) + 1;

}

}

break;

case 0xE8: //CALL

oRel = *(PLONG)(cAbs + 1);

if ((oRel + cAbs + 5 > TrgAddr + BufferLength)||

(oRel + cAbs + 5 < TrgAddr)) //判斷跳轉(zhuǎn)是否在過程范圍內(nèi)

{

cRel = GetRelAddr(oRel, cAbs, (ULONG)pCode + i);

memcpy(pCode + i + 1, &cRel, sizeof(LONG));

//DbgPrint("CALL: 0xX -> 0xX", cAbs, (ULONG)pCode + i);

}

break;

case 0x80: //CMP BYTE PTR X

if (*(PUCHAR)(cAbs + 1) == 0x7D)

{

memcpy(pCode + i + 1, (PVOID)(cAbs + 1), 3);

//i += 3;?

continue;

}

break;

case 0xC2: //RET X

if (*(PUSHORT)(cAbs +1) == 0x10)

{

memcpy(pCode + i + 1, (PVOID)(cAbs + 1), sizeof(USHORT));

//i += sizeof(USHORT);

}

break;

//default:

}

//DbgPrint("addr:X//n:X//Length!X\n",(ULONG)cAbs,*(PUCHAR)cAbs,Length);

}

}

//可惜這個代碼早已放出來很久,TX更新很快,早沒用了,開啟來游戲就它提示非法,辛虧沒缺德到藍(lán)屏重啟。然后又加個INLINE HOOK NTOPENPROCESS 頭,可惜被檢測到。

//不過學(xué)習(xí)這些還是有好處的,不經(jīng)意間注意到一個細(xì)節(jié)被我過了,哈哈。。?

?

----------------------------------------------------


總結(jié)

以上是生活随笔為你收集整理的网上一个仿TP挂钩内核的源码的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。