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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

用SSDT方法恢复冒险岛的部分函数

發(fā)布時間:2024/4/11 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 用SSDT方法恢复冒险岛的部分函数 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

?看了那么多文章、視頻,現(xiàn)在自己跟著做下恢復的驅動程序吧。今天拿冒險島的HS驅動做為例子吧。冒險島游戲對Xuetr進行檢測了,打開XueTr不久就會游戲發(fā)現(xiàn)非法模塊,最終游戲關閉。就拿上了一款叫Kernel Detective的ARK工具進行檢測冒險島的驅動吧。

??因為Kernel Detective這款工具不能檢測到有任何SSDT函數(shù)的掛鉤,而使用一般的打開進程工具卻不能打開它的進程,可知道,這款游戲驅動對NtOpenProcess函數(shù)進行了InlineHook,InlineHook如果比較簡單的,用XueTr可以檢測到的,我們用Kernel Detective工具轉到NtOpenProcess的原始地址看看前15個字節(jié)是否有存在JMP XXXXXXXX之類的不如真實的指令,我們就知道它是否對NtOpenProcess進行了簡單的InlineHook,如此分析

最終分析出:HS這個游戲保護對SSDT表的函數(shù)HOOK了三個函數(shù)。NtOpenProcess,NtReadVirtualMemory,NtWriteVirtualMemory。

NtOpenProcess的原指令:

NtOpenProcess的HOOK后指令:


NtReadVirtualMemory的原指令:

NtReadVirtualMemory的Hook后指令:

NtWriteVirtualMemory的原指令:

NtWriteVirtualMemory 的Hook后指令


跟住上面幾幅圖片已經可以看到,冒險島的驅動保護并不是很強。我們編寫代碼恢復這幾個被HOOK的函數(shù)

?

#include <ntddk.h>
#include <windef.h>
typedef struct _SERVICE_DESCRIPTOR_TABLE
{
PVOID ServiceTableBase;
PULONG ServiceCounterTableBase;
ULONG NumberTableBase;
ULONG ParamTableBase;
}SERVICE_DESCRIPTOR_TABLE,*PSERVICE_DESCRIPTOR_TABLE;??//定義一個SSDT表的結構
extern PSERVICE_DESCRIPTOR_TABLE????KeServiceDescriptorTable;//這個的變量名是不能變的
typedef NTSTATUS(*NTOPENTHREAD)(OUT PHANDLE ThreadHandle,
?????????????????IN ACCESS_MASK DesiredAccess,
?????????????????IN POBJECT_ATTRIBUTES ObjectAttributes,
?????????????????IN PCLIENT_ID ClientId);
typedef NTSTATUS (*ZWOPENPROCESS)(OUT PHANDLE ProcessHandle,
?????????????????IN ACCESS_MASK AccessMask,
?????????????????IN POBJECT_ATTRIBUTES ObjectAttributes,
?????????????????IN PCLIENT_ID ClientId);
typedef NTSTATUS(*NTREADVIRTUALMEMORY)(IN HANDLE ProcessHandle,
?????????????????????IN PVOID BaseAddress,
?????????????????????OUT PVOID Buffer,
?????????????????????IN ULONG BufferLength,
?????????????????????OUT PULONG ReturnLength OPTIONAL);
typedef NTSTATUS(*NTWRITEVIRTUALMEMORY)(IN HANDLE ProcessHandle,
?????????????????????IN PVOID BaseAddress,
?????????????????????IN PVOID Buffer,
?????????????????????IN ULONG BufferLength,
?????????????????????OUT PULONG ReturnLength OPTIONAL);?????//聲明一系列被HOOK函數(shù)的原型??????
NTOPENTHREAD?????RealNtOpenThread;//接著定義這些結構的變量
ZWOPENPROCESS????RealZwOpenProcess;
NTREADVIRTUALMEMORY??RealNtReadVirtualMemory;
NTWRITEVIRTUALMEMORY RealNtWriteVirtualMemory;
VOID Hook();//掛鉤SSDT表的函數(shù),也就是恢復的過程函數(shù)
VOID UnHook();//恢復SSDT表的函數(shù)過程
VOID TD_DRIVER_UNLOAD(PDRIVER_OBJECT DriverObject);//驅動卸載例程
NTSTATUS returnvalue;
ULONG NtOpenProcess_15;
ULONG NtOpenThread_15;
ULONG NtReadVirtualMemory_12;
ULONG NtWriteVirtualMemory_12;
ULONG OldServiceAddress1,OldServiceAddress2,OldServiceAddress3,OldServiceAddress4;
__declspec(naked) NTSTATUS __stdcall My_NtReadVirtualMemory(HANDLE ProcessHandle,PVOID BaseAddress,PVOID Buffer,ULONG BufferLength,ULONG ReturnLength)//自定義的要替換的新的NtOpenProcess函數(shù)過程
{
?returnvalue =(NTSTATUS)(NTREADVIRTUALMEMORY)RealNtReadVirtualMemory(ProcessHandle,BaseAddress,Buffer,BufferLength,ReturnLength);//調用原函數(shù),
?__asm
?{
??push 1Ch
??push 804DA4E0h
??mov eax,80538FB0h
??call eax
??jmp [NtReadVirtualMemory_12]
?}//恢復原指令。。。。。。
}
__declspec(naked) NTSTATUS __stdcall My_NtWriteVirtualMemory(HANDLE ProcessHandle,PVOID BaseAddress,PVOID Buffer,ULONG BufferLength,PULONG ReturnLength)//與此類推這就是恢復NtWriteVirtualMemory的自定義函數(shù)過程
{
?returnvalue =(NTSTATUS)(NTWRITEVIRTUALMEMORY)RealNtWriteVirtualMemory(ProcessHandle,BaseAddress,Buffer,BufferLength,ReturnLength);
?__asm
?{
??push 1Ch
??push 804DA4F8h
??mov eax,80538FB0h//恢復原指令
??call eax
??jmp [NtWriteVirtualMemory_12]//跳轉到恢復后的下一個地址繼續(xù)執(zhí)行
?}
}
__declspec(naked) NTSTATUS __stdcall My_NtOpenProcess(PHANDLE ProcessHandle,ACCESS_MASK AccessMask,POBJECT_ATTRIBUTES ObjectAttributes,PCLIENT_ID ClientId)
{
?returnvalue =(NTSTATUS)(ZWOPENPROCESS)RealZwOpenProcess(ProcessHandle,AccessMask,ObjectAttributes,ClientId);
?__asm
?{
??push 0C4h
??push 804DAAB0h
??mov eax,80538FB0h
??call eax
??jmp??[NtOpenProcess_15]
?}//如此類推。。。。。。
}
__declspec(naked) NTSTATUS __stdcall My_NtOpenThread(PHANDLE ThreadHandle,ACCESS_MASK AccessMask,POBJECT_ATTRIBUTES ObjectAttributes,PCLIENT_ID ClientId)
{
?returnvalue =(NTSTATUS)(NTOPENTHREAD)RealNtOpenThread(ThreadHandle,AccessMask,ObjectAttributes,ClientId);
?__asm
?{
??push 0C0h
??push 804DAAD8h
??mov eax,80538FB0h
??call eax
??jmp??[NtOpenThread_15]
?}
}//這個是多余的。我只是為了方便如果其他游戲保護HOOK了NtOpenThread的幾個字節(jié)可以恢復而已。
VOID Hook()
{
?ULONG NtOpenProcess_Cur_Addr;
?ULONG NtOpenThread_Cur_Addr;
?ULONG NtReadVirtualMemory_Cur_Addr;
?ULONG NtWriteVirtualMemory_Cur_Addr;
?NtOpenProcess_Cur_Addr = (ULONG)KeServiceDescriptorTable->ServiceTableBase + 0x7A * 4;
?NtOpenThread_Cur_Addr = (ULONG)KeServiceDescriptorTable->ServiceTableBase + 0x80 * 4;
?NtReadVirtualMemory_Cur_Addr = (ULONG)KeServiceDescriptorTable->ServiceTableBase + 0x0BA * 4;
?NtWriteVirtualMemory_Cur_Addr = (ULONG)KeServiceDescriptorTable->ServiceTableBase + 0x115 * 4;
?OldServiceAddress1=*(ULONG*)NtOpenProcess_Cur_Addr;
?OldServiceAddress2=*(ULONG*)NtOpenThread_Cur_Addr;
?OldServiceAddress3=*(ULONG*)NtReadVirtualMemory_Cur_Addr;
?OldServiceAddress4=*(ULONG*)NtWriteVirtualMemory_Cur_Addr;
?RealZwOpenProcess=(ZWOPENPROCESS)OldServiceAddress1;
?RealNtOpenThread=(NTOPENTHREAD)OldServiceAddress2;?
?RealNtReadVirtualMemory=(NTREADVIRTUALMEMORY)OldServiceAddress3;
?RealNtWriteVirtualMemory=(NTWRITEVIRTUALMEMORY)OldServiceAddress4;?
?NtOpenProcess_15 = OldServiceAddress1+15;
?NtOpenThread_15 = OldServiceAddress2+15;
?NtReadVirtualMemory_12=OldServiceAddress3+12;
?NtWriteVirtualMemory_12=OldServiceAddress4+12;
?__asm
?{
??cli
??mov eax,cr0
??and eax,not 10000h
??mov cr0,eax
?}
?*((ULONG*)NtOpenProcess_Cur_Addr) = (ULONG)My_NtOpenProcess;
?*((ULONG*)NtOpenThread_Cur_Addr) = (ULONG)My_NtOpenThread;
?*((ULONG*)NtReadVirtualMemory_Cur_Addr) = (ULONG)My_NtReadVirtualMemory;
?*((ULONG*)NtWriteVirtualMemory_Cur_Addr) = (ULONG)My_NtWriteVirtualMemory;
?__asm
?{
??mov eax,cr0
??or eax,10000h
??mov cr0,eax
??sti
?}
?KdPrint(("編程部落超級過游戲保護驅動恢復成功...\n"));

?KdPrint((URL:DangDang.5d6d.com\));
}
VOID UnHook()
{
?ULONG NtOpenProcess_Cur_Addr;
?ULONG NtOpenThread_Cur_Addr;
?ULONG NtReadVirtualMemory_Cur_Addr;
?ULONG NtWriteVirtualMemory_Cur_Addr;
?NtOpenProcess_Cur_Addr = (ULONG)KeServiceDescriptorTable->ServiceTableBase + 0x7A * 4;
?NtOpenThread_Cur_Addr = (ULONG)KeServiceDescriptorTable->ServiceTableBase + 0x80 * 4;
?NtReadVirtualMemory_Cur_Addr = (ULONG)KeServiceDescriptorTable->ServiceTableBase + 0x0BA * 4;
?NtWriteVirtualMemory_Cur_Addr = (ULONG)KeServiceDescriptorTable->ServiceTableBase + 0x115 * 4;
?__asm
?{
??cli
??mov eax,cr0
??and eax,not 10000h
??mov cr0,eax
?}
?*((ULONG*)NtOpenProcess_Cur_Addr) = (ULONG)OldServiceAddress1;
?*((ULONG*)NtOpenThread_Cur_Addr) = (ULONG)OldServiceAddress2;
?*((ULONG*)NtReadVirtualMemory_Cur_Addr) = (ULONG)OldServiceAddress3;
?*((ULONG*)NtWriteVirtualMemory_Cur_Addr) = (ULONG)OldServiceAddress4;
?__asm
?{
??mov eax,cr0
??or eax,10000h
??mov cr0,eax
??sti
?}
?KdPrint(("編程部落超級過游戲保護驅動卸載成功...\n"));

?KdPrint((URL:DangDang.5d6d.com\));
}
VOID TD_DRIVER_UNLOAD(PDRIVER_OBJECT DriverObject)
{
?KdPrint(("The Driver Ready to End...\n"));
?UnHook();
}
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject,PUNICODE_STRING Register)
{
?KdPrint(("The TDang Writting this Driver...\n"));
?Hook();
?DriverObject->DriverUnload =TD_DRIVER_UNLOAD;
?return STATUS_SUCCESS;
}
???為了方便上面就不打那么多字了。打字累啊。就這個驅動可以恢復到了冒險島HOOK的前幾個字節(jié)。但是恢復后。進程可以打開了。但是使用OD不能附加冒險島的進程,剛剛忘記了分析還有一個函數(shù)就是KeAttachProcess和KiAttachProcess這兩個函數(shù),如果這兩個函數(shù)被HOOK了,就不能正常的附加進程了,KeAttachProcess是個導出函數(shù),使用MmGetSystemRoutineAddress這個內核函數(shù)很容易地就可以讀出他的原始地址,好了。這次就分析到這里了。

做下廣告吧。。。歡迎大家來DangDang.5d6d.com編程部落前來學習于觀摩。好了。下次我們就來分析下騰訊的游戲吧。本文章是本人第一次寫的文章,累死了,真體諒那些寫那么長文章那些人了。頂你們。

總結

以上是生活随笔為你收集整理的用SSDT方法恢复冒险岛的部分函数的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。