【转】日服巫术online过驱动保护分析(纯工具)(工具+自写驱动)
前言:
最近在學外掛編程,基本都是利用CE,OD調試分析游戲數據,但現在游戲公司用各種保護手段防止我們調試游戲,雖然我們有CE,OD這樣的利器但是仍然被游戲驅動保護擋在門外i,真可謂巧婦也難為無米之炊啊。
?不得已只好暫停學習各種找CALL技術,先了解下游戲驅動保護的門門道道。經過幾天的學習,有所收獲,特記錄下來,以備日后查詢。本貼為純工具過掉保護,下面將用工具+自寫驅動過掉它,算是最近學習驅動編程的一次實踐吧,
希望本文對?跟同我一樣剛入門的菜鳥有所幫助,歡迎菜鳥一起交流,與君共勉!?
這次用的游戲是日服目前仍然比較火爆的《巫術online》?記得沒學驅動保護之前也分析過這個游戲,但被這個游戲保護搞的藍屏N次,懷恨在心,這次就拿它開刀,廢話不說啦,進入正題:
使用工具:Kernel_Detective_1.4.1?,XueTr_0.45,?郁金香OD2010,VE修改器漢化版(核心也是CE,原版CE掛上進游戲就出錯)
打開游戲后,用OD附加,提示錯誤。
用XueTr看看這個游戲都動了什么手腳吧,讓我們的利器都用不上,哼哼。
這個GPP.dll就是游戲的驅動保護文件,萬惡啊。。。不過我們不能直接卸載,否則就是藍屏或者游戲退出。。
看看內核:
有2個系統回調,在未知模塊,很可疑,干掉它。
其他里沒有什么異常了,看看內核鉤子:
果然有hook。。。?ssdt里4個hook,經測試NtAllocateVirtualMemory就是阻止我們OD附加的罪魁禍首。右鍵恢復一下看看,恢復掉后,OD?可以附加,但游戲直接就掉了。將NtReradVirtualMemory?NtWriteVirtualMemory恢復后,游戲也跟著掉了,而且再上就上不去了,只能重啟在上。現在這驅動還溫和了很多,記得以前版本?一恢復直接就藍屏了。。。
看看ShadowSSDT
看來直接恢復是不行的,想想別的辦法吧。
具體看一下它是怎么HOOK的吧,在Kernel_Detective的SSDT里找到
NtWriteVirtualMemory,右鍵反匯編當前地址
看到以下代碼:
jmp?895B6FB0
dec?ebp
sub?al,?8
js?short?805B53CF
jmp?dword?ptr?[ecx+24]
add?dword?ptr?[eax],?eax
add?byte?ptr?[ebx+40878AF8],?cl
add?dword?ptr?[eax],?eax
add?byte?ptr?[eax+758BE045],?cl
adc?al,?84
Invalid?Command
退掉游戲,看看沒有HOOK過的代碼是怎么樣的
push?1C
push?804DAF08
call?8053CBE0
mov?eax,?dword?ptr?fs:[124]
mov?edi,?eax
可以看出?jmp?895B6FB0?這里就跳轉到游戲的驅動保護里執行了。但是簡單的jmp?0x805B53CC?是不行的,直接就藍屏了,
在用Kernel_Detective看看別的。
?
?
找到可疑的東東,有4個線程在未知模塊運行,估計他們就是驅動的監測線程,右鍵?暫停它們。?
在KD的SSDT里直看到NtQuerySystemInformation這個SSDT?HOOK??那些重要的inline?hook都看不到,而線程中這些可疑線程,xt也看不到
看來不管怎么的,有什么工具全給它招呼上還是對滴。
現在用xt恢復ssdt和shadow?ssdt試試看會發生什么吧。
游戲沒有掉,恢復的HOOK,也沒有再被HOOK,用OD附近試試看。
?果然可以附加啦!!經測試?VE查找數據,OD下斷均沒問題,可以繼續我們找CALL事業了?HOHO。
?
?
注:OD要將StrongOD插件選項里的?Anti?Anti_Attach?勾選上,否則掛上游戲仍然退出
?
?
用XT可以看到NTReadVirtualMemory??NTWRiteVirtualMemory??NTAllocateVirtualMemory?被inline?hook了,以下為函數源代碼。也就是需要恢復的代碼。
NTReadVirtualMemory??0x805B52C2
push?1C
push?804DAEF0
call?8053CBE0
mov?eax,?dword?ptr?fs:[124]
mov?edi,?eax
mov?al,?byte?ptr?[edi+140]
mov?byte?ptr?[ebp-20],?al
mov?esi,?dword?ptr?[ebp+14]
test?al,?al
je?short?805B534C?應跳轉至0X805B52E4繼續執行?HOOK?32字節NTReadVirtualMemory?+0x22
--------------------
NTReadVirtualMemory??HOOK后
jmp?88E52C20
dec?ebp
sub?al,?12
jns?short?805B52C5
jmp?dword?ptr?[ecx+24]
add?dword?ptr?[eax],?eax
add?byte?ptr?[ebx+40878AF8],?cl
add?dword?ptr?[eax],?eax
add?byte?ptr?[eax+758BE045],?cl
adc?al,?84
Invalid?Command
je?short?805B534C
-------------------------
NTWRiteVirtualMemory??0x805B53CC
push?1C
push?804DAF08
call?8053CBE0
mov?eax,?dword?ptr?fs:[124]
mov?edi,?eax
mov?al,?byte?ptr?[edi+140]
mov?byte?ptr?[ebp-20],?al
mov?esi,?dword?ptr?[ebp+14]
test?al,?al
je?short?80565456應跳轉到0x805B53EE繼續執行?NTWRiteVirtualMemory+0x22?
-------------------
NTWRiteVirtualMemory??HOOK后
jmp?88E52FB0
dec?ebp
sub?al,?8
js?short?805B53CF
jmp?dword?ptr?[ecx+24]
add?dword?ptr?[eax],?eax
add?byte?ptr?[ebx+40878AF8],?cl
add?dword?ptr?[eax],?eax
add?byte?ptr?[eax+758BE045],?cl
adc?al,?84
Invalid?Command
je?short?805B5456?
---------------------------------
NTAllocateVirtualMemory??0x805A9ABA
push?118
push?804DACB8?應跳轉到0x805A9ABF?hook5字節?NTAllocateVirtualMemory?+5
----------------
NTAllocateVirtualMemory??HOOK?后
jmp?88E53070
push?804DACB8
?
?
?
?
?
首先感謝論壇的crazyearl?本文代碼根據他發表的過HS保護中的源碼?分析編寫注釋?十分感謝為我們新手提供那么好的文章!
本篇文章適用于菜鳥級新手查看,分析。
該代碼是我學習過程中一個實踐,關于寫驅動框架結構,驅動層inline?hook,分析,繞過游戲驅動保護HOOK函數方法。
也是學習郁金香驅動保護部分課程的一個實踐。
希望給像我一樣零編程基礎學驅動的菜鳥們一些分享,幫助。?期待喜歡這方面的朋友交流?^_^??與君共勉!
前篇寫了通過KD?XT工具過日服巫術驅動保護?使OD?CE?正常加載教程,上篇寫了被驅動保護HOOK的函數具體分析,找到恢復位置,這篇寫下如何寫代碼恢復被HOOK的函數。
思路:?找到被HOOK函數的地址,然后HOOK它前5個字節,寫個jmp?自寫函數???讓它按照函數正常流程運行,跳過游戲檢測call。
首先要做的仍然是用工具?掛起檢測線程,干掉系統回調。然后加載我們自己的驅動。
加載驅動軟件:DriverMonitor???????調試信息查看:DebugView?
??
注意!!(本驅動在xp?32位win7?32位ddk編譯通過。xp32位"系統下載吧GhostXP?SP3?2011裝機版V8.0"測試通過,因匯編部分有些硬編碼,不同系統可能會有所不同,請加載驅動前先用Kernel_Detective或xuetr查看相關代碼,適當修改,否則藍屏是跑不了的啦?^_^)
驅動代碼中注釋掉一些關于進程比較的代碼,思路是如果游戲訪問關鍵函數,讓它執行自己的檢測代碼,其他執行我們HOOK的代碼。
具體實現代碼以后在補充。
?
驅動代碼見下文:??
/********************************************************************
*?創建時間:??2012/03/16
*?文件名稱:??ByPass.c
*?文件作者:??月夜翔龍*?===================================================================
*?功能說明:??入口文件
*?-------------------------------------------------------------------
*?其他說明:??
*********************************************************************/
#include?<ntddk.h>
#include?"ddk_proc.h"
#include?"GetAddrs.h"
#define?INITCODE?code_seg("INIT")
#define?PAGECODE?code_seg("PAGE")
#pragma?INITCODE?
NTSTATUS?DriverEntry(PDRIVER_OBJECT?pDriverObject,PUNICODE_STRING?B)
{?
????hookWriteMemory();?//調用自寫hook函數,恢復系統原函數,跳過游戲檢測CALL
?HookReadVirtualMemory();
?HookAllocateVirtualMemory();
????//注冊派遣例程?
pDriverObject->MajorFunction[IRP_MJ_CREATE]=ddk_DispatchRoutine_CONTROL;?//IRP_MJ_CREATE相關IRP處理函數
pDriverObject->MajorFunction[IRP_MJ_CLOSE]=ddk_DispatchRoutine_CONTROL;?//IRP_MJ_CREATE相關IRP處理函數
pDriverObject->MajorFunction[IRP_MJ_READ]=ddk_DispatchRoutine_CONTROL;?//IRP_MJ_CREATE相關IRP處理函數
pDriverObject->MajorFunction[IRP_MJ_CLOSE]=ddk_DispatchRoutine_CONTROL;?//IRP_MJ_CREATE相關IRP處理函數
pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]=ddk_DispatchRoutine_CONTROL;?//IRP_MJ_CREATE相關IRP處理函數
?CreatMyDevice(pDriverObject);?//創建驅動設備?
?pDriverObject->DriverUnload=ddk_unload;??//驅動卸載例程
????//return?(1);
?return?STATUS_SUCCESS;
}
#pragma?PAGECODE
NTSTATUS?ddk_DispatchRoutine_CONTROL(IN?PDEVICE_OBJECT?pDevobj,IN?PIRP?pIrp?)
{
?//對相應的IPR進行處理
?pIrp->IoStatus.Information=0;//設置操作的字節數為0,這里無實際意義
?pIrp->IoStatus.Status=STATUS_SUCCESS;//返回成功
?IoCompleteRequest(pIrp,IO_NO_INCREMENT);//指示完成此IRP
?KdPrint(("離開派遣函數\n"));//調試信息
?return?STATUS_SUCCESS;?//返回成功
}
void?ddk_unload(IN?PDRIVER_OBJECT?pDriverObject)
{
?UNICODE_STRING??symboName;
?PDEVICE_OBJECT?pdev;?//用來卸載設備
?uninstall();??//恢復HOOK
?RtlInitUnicodeString(&symboName,L"\\??\\ByPass_symlink");
????pdev=pDriverObject->DeviceObject;?
?IoDeleteSymbolicLink(&symboName);//刪除符號鏈接
?IoDeleteDevice(pdev);?//刪除設備對象
?KdPrint(("驅動卸載成功。。。。。。OK\n\n"));
}
---------------------------------------------------------------------------------------
/********************************************************************
*?創建時間:??2012/03/16
*?文件名稱:??ddk_proc.h?頭文件
*?文件作者:??月夜翔龍
*?===================================================================
*?功能說明:??變量定義,函數聲明部分
*?-------------------------------------------------------------------
*?其他說明:??
*********************************************************************/
#include?<windef.h>
#include?<ntddk.h>
/************************************************
***??????????????函數前置聲明部分??????????????******
************************************************/
NTSTATUS?ddk_DispatchRoutine_CONTROL(IN?PDEVICE_OBJECT?pDevobj,IN?PIRP?pIrp?);?//派遣函數
extern?long?KeServiceDescriptorTable?;?//導出SSDT表
void?ddk_unload?(IN?PDRIVER_OBJECT?pDriverObject);?//前置說明?卸載歷程
void?wpoff();?//關閉頁面保護?具體實現過程在下面
void?wpon();?//開啟頁面保護??具體實現過程在下面
NTKERNELAPI?UCHAR?*?PsGetProcessImageFileName(PEPROCESS?Process);
NTKERNELAPI?NTSTATUS?PsLookupProcessByProcessId(__in???HANDLE?ProcessId,__out??PEPROCESS?*Process);
/**************************************************
**********?????????全局變量???????*****************
**************************************************/
ULONG?WriteMemoryAddr,writeMemory_22,writeMemory_7;?//HOOK?writeMemory使用
ULONG?ReadMemoryAddr,readMemory_22;?//HOOK?readmemory?使用
ULONG?AllocateMemoryAddr,AllocateMemory_5;?//HOOK?AllocateMemory使用
#define?NAKED?__declspec(naked)??//定義裸體函數
//*******************************************************************
//PEPROCESS?WriteMemoryEPROCESS?=?NULL;??//進程比較使用?該游戲不需要?
//?ULONG?WriteMemoryEPROCESS_174;??//
//ANSI_STRING?wm_str1,wm_str2;???//保存進程名稱
//#define?APPNAME?"WizardryOnline"
/**********************************************************
***???????????????函數實現部分??????????????????????????***
**********************************************************/
//
//?名稱:?CreatMyDevice?
//?功能:?創建設備
//?參數:?驅動對象?在入口函數傳遞
//?返回:?status?
//
NTSTATUS?CreatMyDevice(IN?PDRIVER_OBJECT?pDriverObject)
{
?NTSTATUS?status;
?PDEVICE_OBJECT?pDevObj;?//用來返回設備
?UNICODE_STRING?devName;?//設備名稱
?UNICODE_STRING?symlinkname;
?RtlInitUnicodeString(&devName,L"\\Device\\ByPass_Devcice");?//初始化設備名稱
?//創建設備
?status=IoCreateDevice(pDriverObject,0,&devName,FILE_DEVICE_UNKNOWN,0,TRUE,&pDevObj);
????if(!NT_SUCCESS(status))?//如果創建設備失敗
?{
??if?(status==STATUS_INSUFFICIENT_RESOURCES)
??{
???KdPrint(("驅動資源不足.....++++++++++++"));
???
??}
??if?(status==STATUS_OBJECT_NAME_EXISTS)
??{
???KdPrint(("驅動對象名已存在.....++++++++++++"));
???
??}
??if?(status==STATUS_OBJECT_NAME_COLLISION)
??{
???KdPrint(("驅動對象名有沖突....++++++++++++"));
???
??}
??KdPrint(("設備創建失敗..........+++++++"));
??return?status;
?}
?pDevObj->Flags?|=?DO_BUFFERED_IO?;
?//創建符號鏈接
????RtlInitUnicodeString(&symlinkname,L"\\??\\ByPass_symlink");
?status=IoCreateSymbolicLink(&symlinkname,&devName);
?if?(!NT_SUCCESS(status))
?{
??IoDeleteDevice(pDevObj);?//如果創建設備符號鏈接不成功則刪除
??return?status;
?}
?KdPrint(("設備創建成功...............++\n"));
?????return?STATUS_SUCCESS;
}
//
//?名稱:?WPOFF
//?功能:?關閉頁面保護
//?參數:?
//?返回:?
//
void?wpoff()
{
?__asm?
?{
??cli
??mov?eax,cr0
??and?eax,not?10000h
??mov?cr0,eax
?}
}
//
//?名稱:?WPON
//?功能:?開啟頁面保護
//?參數:?
//?返回:?
//
void?wpon()
{
?__asm?
?{
??mov?eax,cr0
??or?eax,10000h
??mov?cr0,eax
??sti
?}
}
//
//?名稱:?卸載函數
//?功能:?處理卸載驅動要做的事情,恢復自寫HOOK
//?參數:?
//?返回:?
//
void?uninstall()
{
?KIRQL?Irql;
?//WriteMemoryAddr=CurNTWriteVirtualMemory();
?BYTE?byWriteVirtualMemory[7]?=?{0x6A,0x1C,0x68,0x08,0xAF,0x4D,0x80};??//系統原WriteVirtualMemory前7字節?硬編碼?請適當修改?
????BYTE?byReadVirtualMemory[7]??=?{0x6A,0x1C,0x68,0xF0,0xAE,0x4D,0x80};?//系統原ReadVirtualMemory前7字節?硬編碼?請適當修改
?BYTE?byAllocateVirtualMemory[5]?=?{0x68,0x18,0x01,0,0};?//系統原AllocateVirtualMemory前5字節?硬編碼?請適當修改
?wpoff();?//關閉頁面保護
?Irql=KeRaiseIrqlToDpcLevel();?//提升IRQ等級
?恢復WriteVirtualMemory
?RtlCopyMemory((BYTE*)WriteMemoryAddr,byWriteVirtualMemory,7);
?恢復ReadVirtualMemory
?RtlCopyMemory((BYTE*)ReadMemoryAddr,byReadVirtualMemory,7);
?恢復AllocateVirtualMemory
?RtlCopyMemory((BYTE*)AllocateMemoryAddr,byAllocateVirtualMemory,5);
?//恢復IRQ中斷等級
?KeLowerIrql(Irql);
?//開啟頁面保護
?wpon();
}
?
---------------------------------------------------------------------------------------------------------
?
/********************************************************************
*?創建時間:??2012/03/16
*?文件名稱:??GetAddrs.h?頭文件
*?文件作者:??月夜翔龍
*?===================================================================
*?功能說明:??獲得函數首地址,自寫HOOK,跳過游戲檢測CALL
*?-------------------------------------------------------------------
*?其他說明:??
*********************************************************************/
/*********************************************************
**********功能:?獲得當前ReadVirtualMemory地址?************
**********參數:????無??***********************************
*********返回值:?函數地址?********************************
*********公式:?函數地址=SSDT表基地址+函數標號*4?**********
*********************************************************/
ULONG?CurNTReadVirtualMemory()?
{
?ULONG?ReadMemoryBase;
?__asm
?{?
??push?eax?//存放ssdt地址?
?????push?ebx?//存放函數在SSDT表索引號?ReadVirtualMemory?十進制186?十六進制0XBA?不同系統索引號可能不同?KD查看SSDT表?
??mov?eax,KeServiceDescriptorTable
??mov?eax,[eax]?//取出ssdt基地址
??mov?ebx,0xBA?//存放索引號
??shl?ebx,2?//0xBA*4?shl?ebx,2?==?imul?ebx,ebx,4
??add?eax,ebx?//KeServiceDescriptorTable+0xBA*4??
??mov?eax,[eax]?//取出函數地址
????????mov?ReadMemoryBase,eax?//保存到ReadMemoryBase?
??pop?eax
??pop?ebx
?}
?KdPrint(("curReadMemory值為%x?+++++++\n",ReadMemoryBase));
?return?ReadMemoryBase;
}
/*********************************************************
**********功能:?獲得當前WriteVirtualMemory地址?************
**********參數:????無??***********************************
*********返回值:?函數地址?********************************
*********公式:?函數地址=SSDT表基地址+函數標號*4?**********
*********************************************************/
ULONG?CurNTWriteVirtualMemory()?
{
?ULONG?WriteMemoryBase;
?__asm
?{?
??push?eax?//存放ssdt地址?
?????push?ebx?//存放函數在SSDT表索引號?WriteVirtualMemory?十進制277?十六進制0X115?不同系統索引號可能不同?KD查看SSDT表
??mov?eax,KeServiceDescriptorTable
??mov?eax,[eax]?//取出ssdt基地址
??mov?ebx,0x115?//存放索引號
??shl?ebx,2?//0xBA*4?shl?ebx,2?==?imul?ebx,ebx,4
??add?eax,ebx?//KeServiceDescriptorTable+0x115*4??
??mov?eax,[eax]?//取出函數地址
????????mov?WriteMemoryBase,eax?//保存到WriteMemoryBase?
??pop?eax
??pop?ebx
?}
?KdPrint(("curWriteMemory值為%x?+++++++\n",WriteMemoryBase));
?return?WriteMemoryBase;
}
/*********************************************************
**********功能:?獲得當前NTAllocateVirtualMemory地址?******
**********參數:????無??***********************************
*********返回值:?函數地址?********************************
*********公式:?函數地址=SSDT表基地址+函數索引號*4?********
*********************************************************/
ULONG?CurNTAllocateVirtualMemory()?
{
?ULONG?AllocateMemoryBase;
?__asm
?{?
??push?eax?//存放ssdt地址?
?????push?ebx?//存放函數在SSDT表索引號?AllocateMemory??十進制17十六進制0X11?不同系統索引號可能不同?KD查看SSDT表
??mov?eax,KeServiceDescriptorTable
??mov?eax,[eax]?//取出ssdt基地址
??mov?ebx,0x11?//存放索引號
??shl?ebx,2?//0x11*4????shl?ebx,2?==?imul?ebx,ebx,4
??add?eax,ebx?//KeServiceDescriptorTable+0x11*4??
??mov?eax,[eax]?//取出函數地址
????????mov?AllocateMemoryBase,eax?//保存到AllocateMemoryBase?
??pop?eax
??pop?ebx
?}
?KdPrint(("curAllocateMemory值為%x?+++++++\n",AllocateMemoryBase));
?return?AllocateMemoryBase;
}
/*********************************************************
**********功能:?通過MmGetSystemRoutineAddress()獲取地址***
****************?????????演示,功能同上?????????????******
**********參數:????無???????????????????????????????******
*********返回值:?函數地址???????????????????????????******
*********公式:?無???????????????????????????????????******
**********************************************************
ULONG?OldNTAllocateVirtualMemory()?
{
??????ULONG?OldAllocateMemoryBase;
???UNICODE_STRING?S_AllocateMemory;
???RtlInitUnicodeString(&S_AllocateMemory,L"NtAllocateVirtualMemory");//初始化字串
???OldAllocateMemoryBase=(ULONG)MmGetSystemRoutineAddress(&S_AllocateMemory);//獲得地址
???KdPrint(("OldAllocateMemory值為%x?+++\n",OldAllocateMemoryBase));
???return?OldAllocateMemoryBase;
}
*/
/*********************************************************
**********功能:?恢復WriteVirtualMemory正常流程??????******
****************??????跳過游戲檢測CALL??????????????******
**********參數:????無???????????????????????????????******
*********返回值:?無?????????????????????????????????******
*********公式:?無???????????????????????????????????******
*********************************************************/
static?NAKED?void?MyWriteVirtualMemory()
{
?/*進程比較代碼實現,該游戲不需要
?獲得調用者的EPROCESS
?WriteMemoryEPROCESS?=?IoGetCurrentProcess();
?KdPrint(("WriteMemoryEPROCESS值為%x?++++\n",WriteMemoryEPROCESS));
?WriteMemoryEPROCESS_174=(ULONG)WriteMemoryEPROCESS+0x174;
?KdPrint(("WriteMemoryEPROCESS+0x174值為%x?++++\n",WriteMemoryEPROCESS_174));
?將調用者的進程名保存到str1中
?RtlInitAnsiString(&wm_str1,(PCSZ)WriteMemoryEPROCESS_174);???
?將我們要比對的進程名放入str2
?RtlInitAnsiString(&wm_str2,APPNAME);
?KdPrint(("當前進程名稱值為:%x?++++\n",&wm_str1));
?KdPrint(("APPNAME值為:%x?++++\n",&wm_str2));
?if?(RtlCompareString(&wm_str1,&wm_str2,FALSE)?==?0)
?*/
?__asm?
?{
??//0x805B53CC?
??push?0x1C
??push?0x804DAF08??//硬編碼,不同系統可能有所不同,請按實際修改
??mov?eax,0x8053CBE0??//硬編碼,不同系統可能有所不同,請按實際修改
??call?eax
????????mov?eax,?dword?ptr?fs:[0x124]
????????mov?edi,?eax
????????mov?al,?byte?ptr?[edi+0x140]
????????mov?byte?ptr?[ebp-0x20],?al
????????mov?esi,?dword?ptr?[ebp+0x14]
????????test?al,?al
??mov?eax,writeMemory_22?
??jmp?eax??//恢復writememory前32字節然后跳轉到writememory+0x22正常執行,跳過游戲檢測call
?}?//end?asm?
}
/*********************************************************
**********功能:?恢復ReadVirtual?Memory正常流程??????******
****************??????跳過游戲檢測CALL??????????????******
**********參數:????無???????????????????????????????******
*********返回值:?無?????????????????????????????????******
*********公式:?無???????????????????????????????????******
*********************************************************/
static?NAKED??void?MyReadVirtualMemory()
{
?__asm?
?{
??//0x805B52C2
????????push?0x1C
????????push?0x804DAEF0?//硬編碼,不同系統可能有所不同,請按實際修改
????????mov??eax,0x8053CBE0?//硬編碼,不同系統可能有所不同,請按實際修改
????????call?eax
????????mov?eax,?dword?ptr?fs:[0x124]
????????mov?edi,?eax
????????mov?al,?byte?ptr?[edi+0x140]
????????mov?byte?ptr?[ebp-0x20],?al
????????mov?esi,?dword?ptr?[ebp+0x14]
????????test?al,?al
??mov?eax,readMemory_22?//恢復readmemory前32字節然后跳轉到readmemory+0x22正常執行,跳過游戲檢測call
??jmp?eax
?}
}
/*********************************************************
**********功能:?恢復AllocateVirtualMemory正常流程???******
****************??????跳過游戲檢測CALL??????????????******
**********參數:????無???????????????????????????????******
*********返回值:?無?????????????????????????????????******
*********公式:?無???????????????????????????????????******
*********************************************************/
static?NAKED??void?MyAllocateVirtualMemory()
{
?__asm?
?{
????????//0x805A9ABA?
????????push?0x118??//硬編碼,不同系統可能有所不同,請按實際修改
????????mov?eax,AllocateMemory_5//恢復前5字節然后跳轉到allocatememory+0x5正常執行,跳過游戲檢測call
????????jmp?eax
?}
}
/*********************************************************
**********功能:hook原函數頭5個字節跳轉到自寫函數執行******
****************????????????????????????????????????******
**********參數:????無???????????????????????????????******
*********返回值:?無?????????????????????????????????******
*********公式:jmp?jmpaddr??jmp機器碼E9??????????????******
*********jmpaddr公式:新地址-(原地址+5)或-原地址-5???******
*********************************************************/
void?hookWriteMemory()
{
?BYTE??JmpAddress[7]?=?{0xE9,0,0,0,0,0x90,0x90};
?//該數組首字節為E9,即是jmp指令,后四字節為跳轉字節,故為0,
?//0x90為NOP指令,因WriteMemory匯編代碼頭部是兩條指令7字節?故后2字節用nop填充
?KIRQL?Irql;
?WriteMemoryAddr=CurNTWriteVirtualMemory();//獲得當前WriteVirtualMemory地址?即原地址??
?writeMemory_22=WriteMemoryAddr+0x22;?//WriteVirtualMemory+0x22?恢復前32字節然后跳轉到這里繼續執行??
?*(ULONG?*)(JmpAddress+1)=(ULONG)MyWriteVirtualMemory?-?(WriteMemoryAddr+5);?
?//將jmpaddr?寫入數組E9之后4字節?
?wpoff();?//關閉CR0
?Irql=KeRaiseIrqlToDpcLevel();?//提升IRQ中斷等級
?//向WriteVirtualMemory首地址寫入7字節,實現HOOK
?RtlCopyMemory((BYTE*)WriteMemoryAddr,JmpAddress,7);
?KeLowerIrql(Irql);?//恢復Irql
?wpon();??//開啟cr0
}
/*********************************************************
**********功能:hook原函數頭5個字節跳轉到自寫函數執行******
****************????????????????????????????????????******
**********參數:????無???????????????????????????????******
*********返回值:?無?????????????????????????????????******
*********公式:jmp?jmpaddr??jmp機器碼E9??????????????******
*********jmpaddr公式:新地址-(原地址+5)或-原地址-5???******
*********************************************************/
void?HookReadVirtualMemory()
{
?BYTE?JmpAddress[7]?=?{0xE9,0,0,0,0,0x90,0x90};
?KIRQL?Irql;
?ReadMemoryAddr=CurNTReadVirtualMemory();
?readMemory_22=ReadMemoryAddr+0x22;
?*(ULONG*)(JmpAddress+1)=(ULONG)MyReadVirtualMemory??-?(ReadMemoryAddr+5);
?wpoff();
?Irql=KeRaiseIrqlToDpcLevel();
?RtlCopyMemory((BYTE*)ReadMemoryAddr,JmpAddress,7);
?KeLowerIrql(Irql);
?wpon();
}
/*********************************************************
**********功能:hook原函數頭5個字節跳轉到自寫函數執行******
****************????????????????????????????????????******
**********參數:????無???????????????????????????????******
*********返回值:?無?????????????????????????????????******
*********公式:jmp?jmpaddr??jmp機器碼E9??????????????******
*********jmpaddr公式:新地址-(原地址+5)或-原地址-5???******
*********************************************************/
void?HookAllocateVirtualMemory()
{
????BYTE?Jmpaddress[5]?=?{0xE9,0,0,0,0};?
?//因AllocateVirtualMemory匯編頭部為push?118占5字節?與jmp?xxxx?相同?故只需hook一條指令即可?
?KIRQL?Irql;
?AllocateMemoryAddr=CurNTAllocateVirtualMemory();
?AllocateMemory_5=AllocateMemoryAddr+0x5;
?*(ULONG*)(Jmpaddress+1)=(ULONG)MyAllocateVirtualMemory?-?(AllocateMemoryAddr+5);
?wpoff();
?Irql=KeRaiseIrqlToDpcLevel();
?RtlCopyMemory((BYTE*)AllocateMemoryAddr,Jmpaddress,5);
?KeLowerIrql(Irql);
?wpon();
}
該驅動代碼?可根據自己系統改變硬編碼后?用XT?KD?可以看到加載后和卸載?HOOK的幾個函數代碼變化,無需使用游戲。
相信新手會對inline?hook有所了解
?
?
?
轉載于:https://www.cnblogs.com/zhangdongsheng/archive/2012/11/29/2795483.html
總結
以上是生活随笔為你收集整理的【转】日服巫术online过驱动保护分析(纯工具)(工具+自写驱动)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: chm帮助文档出现乱码
- 下一篇: 地表地形对地下温度及地表热流的影响