免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項超值服

開通VIP
幽默人講解R3通過IAT修改HOOK目標(biāo)進(jìn)程API
大家好,我們又見面啦,今天我將為各位講述一個新故事,那就是IAT HOOK。再觀看這個故事之前,需要觀眾確定具備兩個基本能力:
1.對簡單的數(shù)據(jù)結(jié)構(gòu)在內(nèi)存中的樣子能有個宏觀的理解。
2.理解運(yùn)行在windows環(huán)境程序的工作原理。

導(dǎo)入地址表(IAT):Import Address Table 由于導(dǎo)入函數(shù)就是被程序調(diào)用但其執(zhí)行代碼又不在程序中的函數(shù),這些函數(shù)的代碼位于一個或者多個DLL 中.當(dāng)PE 文件被裝入內(nèi)存的時候,Windows 裝載器才將DLL 裝入,并將調(diào)用導(dǎo)入函數(shù)的指令和函數(shù)實際所處的地址聯(lián)系起來(動態(tài)連接),這操作就需要導(dǎo)入表完成.其中導(dǎo)入地址表就指示函數(shù)實際地址。


比如我們想對目標(biāo)程序的PeekMessage這個API函數(shù)進(jìn)行HOOK,那么只需要找到他的IAT表,并把這個API的實際地址修改,這就完成了一個API HOOK。按常理,想執(zhí)行此過程需要對PE格式有一定的理解,但是我認(rèn)為并沒有這個必要,畢竟這是一個很簡單的工作。接下來我將用我的方法帶領(lǐng)大家來實現(xiàn)它,那就是角色扮演。

首先幻想自己是30年代,藍(lán)衣社的一名特務(wù)。今天接到上級的任務(wù),去某地殺掉一名為敵對勢力工作的人,然后經(jīng)過易容,偽裝成他來執(zhí)行潛伏。那么目標(biāo)是誰呢?他又住在哪里呢?拿起MSDN情報科送來的文件看看吧,目標(biāo)叫PeekMessage,是姓“USER32.dll”家族的成員,它住在:

xxx.exe市
IMAGE_DOS_HEADER區(qū)
IMAGE_OPTIONAL_HEADER街
IMAGE_IMPORT_DESCRIPTOR小區(qū)
還有一張目標(biāo)的相片
BOOL PeekMessage
(LPMSG lpMsg,
HWND hWnd,
UINT wMsgFilterMin,
UINT wMsgFilterMax,
UINT wRemoveMsg
)

資料就這么多啦,但是并沒有說明目標(biāo)住在幾號樓幾層幾號啊。不過沒有關(guān)系我們是特務(wù)嘛。這難不倒我們的,Let's begin
坐著藍(lán)衣社為我們準(zhǔn)備的專機(jī)SetWindowsHookEx把我們(DLL)注入到xxx.exe市,哈哈~下了飛機(jī)來到一個陌生的城市真是倆眼一摸黑呀,怎么找我們的目的地呢?最簡單的辦法:打車,于是我們攔了一輛GetModuleHandle(NULL)牌的出租車,誰知道一上車。司機(jī)看到我給他的地址后告訴我要去的地方需要過海,沒辦法直接到,只能先送我到IMAGE_DOS_HEADER區(qū),然后再換船過海才行。聽得我暈頭轉(zhuǎn)向的,沒辦法,走吧。。。閑來打量一下這個城市,滿眼盡是一些由0和1搭建黑白2色的高樓大廈,顏色和款式是多么的單調(diào)枯燥哇,算了,還是閉目養(yǎng)神吧。不一會我們來到了IMAGE_DOS_HEADER區(qū)的水路碼頭,該下車換乘船過海啦。于是買了(ModuleAddress+ImageDosHearderPointer->e_lfanew+24)號渡輪的船票,繼續(xù)這次無聊的旅程。暈船從頭吐到尾,好不容易熬到了地方,原來一出了碼頭就來到了IMAGE_OPTIONAL_HEADER街,抬頭一望在我們12點鐘方向,有個小巴站臺,走過去這么一看才知道原來坐
ModuleAddress+ImageOptionalHeaderPointer->DataDirectory
[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress線小巴,可以直達(dá)我們的終點:IMAGE_IMPORT_DESCRIPTOR小區(qū)。二話不說,走著您嘚~~~~~馬上要到目的地啦。趁坐小巴的這段時間我們先來整理下思緒,因為不知道具體的樓號和門牌號,所以我們要先想個什么辦法,于是找同車的一位美麗小姐打聽得知,IMAGE_IMPORT_DESCRIPTOR小區(qū)的每座樓都是同一樣式的,那就是ImageImportDescriptorPointer->FirstThunk風(fēng)格,又知道一樓大廳有個收信箱,上面登記著住戶的姓名。有了這些線索我們就下車一棟樓,一棟樓的找吧,雖然這個方案毫無創(chuàng)意,但是記得有位大師曾經(jīng)說過:往往通過復(fù)雜的數(shù)據(jù)結(jié)構(gòu)和華麗的算法并不是解決問題的好方法,因為它加大了維護(hù)和調(diào)試的難度。所以我們就用這種直接而有效的土辦法來老老實實的找吧:先逐樓搜索
while(ImageImportDescriptorPointer->FirstThunk!=0),然后找到一樓大廳的收信箱
TargetName=(LPCTSTR)((DWORD)ModuleAddress+ImageImportDescriptorPointer->Name),再逐戶的查找姓“USER32.dll”的家族
if(TargetName.Compare(_T("USER32.dll"))==0),沒過多久我們終于找到了,登記簿上寫明了具體的門牌號,哈哈~這表示我們離成功只有一步之遙,于是迫不及待的走進(jìn)ModuleAddress+ImageImportDescriptorPointer->FirstThunk號電梯,走向“USER32.dll”家,來到門口,我停住啦,靜靜地站在那里平復(fù)一下心緒,10秒后我飛起一腳踹開了大門走了進(jìn)去,映入眼簾的是:坐在屋里男女老少,大大小小10幾口子,全部一臉驚愕的盯著我這位不速之客。我拿出相片while(ImageThunkDataPointer->u1.Function)迅速搜索,
FunctionAddress=(PDWORD)&(ImageThunkDataPointer->u1.Function)定位目標(biāo),
if(*FunctionAddress==(DWORD)PeekMessageAddress)經(jīng)過一輪的搜索,我找到了目標(biāo),他正傻傻的坐在角落里的電腦桌前,我走到它面前
VirtualQuery(FunctionAddress, &InforMation, sizeof(InforMation))細(xì)細(xì)的打量著他:凌亂的頭發(fā)如同雜草,一架高度數(shù)眼鏡戴在蒼白消瘦的臉頰上,駝背,纖細(xì)卻小腹異常隆起的身材,套著10幾年前流行的服飾,HOHO~做技術(shù)典型的形象,我冷漠的從懷中掏出了槍:
VirtualProtect(FunctionAddress, sizeof(DWORD),PAGE_READWRITE,&BeforeProtect)頂在目標(biāo)的眉心。此時此刻,在場的所有人都清楚了我的來意。死亡的恐懼籠罩在每個人的心頭,我不在多做停留,無情的勾動了扳機(jī),這就是一個特務(wù)的專業(yè)操守。嘿嘿
::WriteProcessMemory((HANDLE)-1,FunctionAddress,&FunctionOfSelf,sizeof(DWORD), NULL)目標(biāo)應(yīng)聲倒地。在手槍的淫威下,其他人也只好無奈的接受這痛苦的事實,我也就成功的完成了此次任務(wù)。開始潛伏。

接下來換種語言再來講述一下這個故事:C++

#include <winternl.h>
#include "DialogMain.h"

typedef BOOL (WINAPI* PEEKMESSAGE)(LPMSG lpMsg,HWND hWnd,UINT wMsgFilterMin,UINT wMsgFilterMax,UINT wRemoveMsg);

PEEKMESSAGE FakePeekMessage=(PEEKMESSAGE)PeekMessage;
BOOL WINAPI MinePeekMessage(LPMSG lpMsg,HWND hWnd, UINT wMsgFilterMin,UINT wMsgFilterMax,UINT wRemoveMsg)
{
  AfxMessageBox(_T("你TM是不是調(diào)用我啦?"));
  return ((PEEKMESSAGE)FakePeekMessage)(lpMsg,hWnd,wMsgFilterMin,wMsgFilterMax,wRemoveMsg);
}

BOOL CDialogMain::ImportAddressTableHook(HMODULE ModuleAddress,LPCTSTR Library,LPCVOID TargetAddress,LPCVOID ReplaceAddress)
{
  IMAGE_DOS_HEADER* ImageDosHearderPointer=NULL;
  IMAGE_OPTIONAL_HEADER* ImageOptionalHeaderPointer=NULL;  
  IMAGE_IMPORT_DESCRIPTOR* ImageImportDescriptorPointer=NULL;
  IMAGE_THUNK_DATA* ImageThunkDataPointer=NULL;
  CString TargetName;
  DWORD Value=0;
  LPDWORD FunctionAddress=NULL;
  MEMORY_BASIC_INFORMATION InforMation;
  DWORD BeforeProtect=0;

  ImageDosHearderPointer=(IMAGE_DOS_HEADER*)ModuleAddress;
  ImageOptionalHeaderPointer=(IMAGE_OPTIONAL_HEADER*)((DWORD)ModuleAddress+ImageDosHearderPointer->e_lfanew+24);
  ImageImportDescriptorPointer=(IMAGE_IMPORT_DESCRIPTOR*)
                 ((DWORD)ModuleAddress+ImageOptionalHeaderPointer->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
  while(ImageImportDescriptorPointer->FirstThunk!=0)   
  {   
    TargetName=(LPCTSTR)((DWORD)ModuleAddress+ImageImportDescriptorPointer->Name);
    if(TargetName.Compare(Library)==0)
    {   
      Value=(DWORD)ModuleAddress+ImageImportDescriptorPointer->FirstThunk;
      break;
    }
    ImageImportDescriptorPointer++;   
  }  
  if (Value==0)
  {
    AfxMessageBox(_T("獲取導(dǎo)入地址表失敗!"));
    return FALSE;
  }
  else
  {
    ImageThunkDataPointer=(IMAGE_THUNK_DATA*)Value;
    while(ImageThunkDataPointer->u1.Function)   
    {   
      FunctionAddress=(LPDWORD)&(ImageThunkDataPointer->u1.Function);

      if(*FunctionAddress==(DWORD)TargetAddress)
      {   
        DebugInfo.Format(_T("%x"),*FunctionAddress);
        EditHeroBlood.SetWindowText(DebugInfo);
        VirtualQuery(FunctionAddress,&InforMation,sizeof(InforMation));   
        VirtualProtect(FunctionAddress, sizeof(DWORD),PAGE_READWRITE,&BeforeProtect);   
        if (::WriteProcessMemory((HANDLE)-1,FunctionAddress,&ReplaceAddress,sizeof(DWORD),NULL)==FALSE)
        {
          AfxMessageBox(_T("修改導(dǎo)入地址表失敗!"));
          return FALSE;
        }
        else
        {
          VirtualProtect(FunctionAddress,sizeof(DWORD),BeforeProtect,0);   
          return TRUE;
        }
      }   
      ImageThunkDataPointer++;   
    }
  }
  return FALSE;
}
我再換一種語言來講述:

大家都知道其實我上述我說地名都是一些結(jié)構(gòu)體,而Windows就是靠無數(shù)個這樣的結(jié)構(gòu)體連接搭建起來的,你中有我,我中有你,這就好比一個生物由無數(shù)個細(xì)胞組成的一樣。因為今天我們不是講述windows體系,所以我也不做過多解釋。


那么通過IAT修改來實現(xiàn)API HOOK的實現(xiàn)原理是什么呢?關(guān)鍵就在于如何在茫茫的內(nèi)存中找到我們的目標(biāo),聽起來好像很恐怖,像大海撈針,其實沒那么難,因為windows就是通過那些結(jié)構(gòu)體把數(shù)據(jù)在內(nèi)存中全部線形連接起來啦。這就像玩大富翁,或者一種挖寶藏游戲,從起點出發(fā)走幾步就會得到一個提示,告訴我們下一步該怎么走?,F(xiàn)在我就帶領(lǐng)大家來玩一次這種游戲

先來說明游戲規(guī)則
WORD=2步
DWORD=4步
指針=進(jìn)入下一房間
數(shù)組=翻卡片得到答案
RVA=地圖寶箱
IMAGE_DOS_HEADER STRUCT
{
這里就是我們的起點,可以通過GetModuleHandle(NULL)獲得,比如起點地址是0x00000000,我們得到的第一個提示
(ModuleAddress+ImageDosHearderPointer->e_lfanew+24),怎么理解這個提示呢?就是從起點開始走36步,找到一個叫e_lfanew的門(因為它是指針,所以他就是通往下一個房間的大門),然后推門進(jìn)去后再走24步,我們就找到了第二個將要給我們提示的地方

e_magic           WORD
e_cblp            WORD
e_cp              WORD
e_crlc            WORD
e_cparhdr         WORD
e_minalloc        WORD
e_maxalloc        WORD
e_ss              WORD
e_sp              WORD
e_csum            WORD
e_ip              WORD
e_cs              WORD
e_lfarlc          WORD
e_ovno            WORD
e_res             WORD
e_oemid           WORD
e_oeminfo         WORD
e_res2            WORD
e_lfanew          DWORD

}
IMAGE_DOS_HEADER ENDS

typedef struct _IMAGE_OPTIONAL_HEADER
{  
我們通過上一個提示來到了這個房間,同樣我們得到了又一個提示
ModuleAddress+ImageOptionalHeaderPointer->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress)
理解下這個提示。這代表我們從起點走到e_lfanew大門進(jìn)入這個房間再走96步找到DataDirectory開始翻卡片(他是一個結(jié)構(gòu)體形數(shù)組),來找答案,而答案就在第IMAGE_DIRECTORY_ENTRY_IMPORT(表示1,也就是DataDirectory[1])張卡片內(nèi)

WORD Magic;  
BYTE MajorLinkerVersion;  
BYTE MinorLinkerVersion;  
DWORD SizeOfCode;
DWORD SizeOfInitializedData;  
DWORD SizeOfUninitializedData;  
DWORD AddressOfEntryPoint;  
DWORD BaseOfCode;  
DWORD BaseOfData;  
DWORD ImageBase;  
DWORD SectionAlignment;  
DWORD FileAlignment;  
WORD MajorOperatingSystemVersion;  
WORD MinorOperatingSystemVersion;  
WORD MajorImageVersion;  
WORD MinorImageVersion;  
WORD MajorSubsystemVersion;  
WORD MinorSubsystemVersion;  
DWORD Win32VersionValue;  
DWORD SizeOfImage;  
DWORD SizeOfHeaders;  
DWORD CheckSum;  
WORD Subsystem;  
WORD DllCharacteristics;  
DWORD SizeOfStackReserve;  
DWORD SizeOfStackCommit;  
DWORD SizeOfHeapReserve;  
DWORD SizeOfHeapCommit;  
DWORD LoaderFlags;  
DWORD NumberOfRvaAndSizes;  
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
}
IMAGE_OPTIONAL_HEADER,

IMAGE_IMPORT_DESCRIPTOR STRUCT
{
通過上面的提示,我們來到了這個房間,那么下一個提示是什么呢?那就是while(ImageImportDescriptorPointer->FirstThunk!=0),再來理解下這個提示。它是說讓我們找到FirstThunk這個地圖寶箱(RAV)在里面找到我們需要的地圖才能找到下一個房間,那我們就一張一張的翻看吧
我們要找的地圖名就是“USER32.dll”
  union
    Characteristics
    OriginalFirstThunk
  ends
  TimeDateStamp
  ForwarderChain
  Name1
  FirstThunk
}
IMAGE_IMPORT_DESCRIPTOR ENDS

有了地圖我們就來到了下一個房間
IMAGE_THUNK_DATA32 STRUCT
哈哈。這就使傳說中的IAT表啦,就差一步就找到寶藏啦。我們看一下這次的提示while(ImageThunkDataPointer->u1.Function),它是說讓后找到u1.Function這個卡片商來得到寶藏位置的答案,只是這次我們不知道第幾張卡片里有我們要的答案。沒辦法挨個翻吧。指導(dǎo)找到
PeekMessage
    union u1
        ForwarderString
        Function
        Ordinal
        AddressOfData
    ends
IMAGE_THUNK_DATA32 ENDS

找到后,還用我教嗎?關(guān)閉他的保護(hù)屬性,然后改寫他的地址吧。。。


【小結(jié)】

這里我鉤了一個目標(biāo)程序接收消息的函數(shù)PeekMessage,然后把它傳進(jìn)來的參數(shù)輸出出來??纯此麜粫约航o自己發(fā)消息。HOHO。。挺無聊的
但是如果你想鉤點別的。比如目標(biāo)程序的socket,哈哈~那你覺得這像什么呢?
本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
利用word將PDF轉(zhuǎn)換DOC文件的方法 --電腦高手
深入剖析PE文件
PE文件結(jié)構(gòu)
深入剖析Win32可移植可執(zhí)行文件格式(第二部分)
Windows下動態(tài)鏈接之一:DLL插件機(jī)制的裝載和使用
PE文件結(jié)構(gòu)詳解(四)PE導(dǎo)入表
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服