(27)TLB番外篇——ShadowWalker
一、全代碼校驗(yàn)、CRC檢測
很多程序會(huì)對自己的代碼做CRC檢測,當(dāng)有人修改了代碼,就會(huì)被CRC檢測線程發(fā)現(xiàn)。下面我編寫一個(gè)小程序演示這個(gè)操作:
我的代碼沒有真的用CRC,我只是將函數(shù)代碼所在的頁拷貝了一份,然后用一個(gè)線程不停地 memcmp,效果和CRC是類似的。
// GameWithCRC.cpp : Defines the entry point for the console application. //#include "stdafx.h" #include <Windows.h> #include <time.h>void attack() {srand(time(0));while (1){int damage = rand() % 1000;printf("attack(%p): 造成了 %4d 點(diǎn)傷害.\n", attack, damage);Sleep(1000);} }// 代碼拷貝 BYTE record[0x1000];// 檢測代碼是否被修改 DWORD WINAPI CheckModify() {while (1){if (memcmp(record, attack, 0x1000) != 0){printf("有壞人HOOK了attack函數(shù)!!!\n");}Sleep(1000);}return 0; }int _tmain(int argc, _TCHAR* argv[]) {memcpy(record, (LPVOID)attack, 0x1000);CreateThread(0,0,(LPTHREAD_START_ROUTINE)CheckModify,0,0,0);attack();return 0; }當(dāng)我試圖在函數(shù)內(nèi)下斷點(diǎn)的時(shí)候,就會(huì)被校驗(yàn)線程發(fā)現(xiàn):
二、ShadowWalker 簡介
這篇博客是中級課程的番外,學(xué)習(xí)TLB時(shí),老師提到了一種利用TLB機(jī)制實(shí)現(xiàn)內(nèi)存隱藏的方式——ShadowWalker。這種技術(shù)利用了TLB會(huì)緩存線性地址到物理地址映射的特性,當(dāng)CRC線程檢查某段代碼時(shí),它使用的線性地址會(huì)緩存到TLB的數(shù)據(jù)頁表緩存(Data-TLB)中。而當(dāng)EIP運(yùn)行到這段代碼時(shí),又會(huì)把代碼的線性地址緩存到TLB的指令頁表緩存(Instruction-TLB)中。這樣CPU中就緩存了同一個(gè)地址的兩份記錄,CRC線程從數(shù)據(jù)頁表緩存中讀取物理地址,EIP執(zhí)行流從指令頁表緩存中讀取物理地址,這兩個(gè)物理地址是相同的。
ShadowWalker技術(shù)的核心就在于修改指令頁表緩存中的物理地址,讓CRC線程讀取原來的代碼,而程序真正執(zhí)行的時(shí)候則跳轉(zhuǎn)到其他代碼。
這種方式在3環(huán)是不穩(wěn)定的,原因是TLB經(jīng)常刷新。
總結(jié)
以上是生活随笔為你收集整理的(27)TLB番外篇——ShadowWalker的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。