淺談API HOOK技術(二) (轉)
在這裡我將要實現轉跳。有人說修改內容要進入Ring 0 才可以。可是本身提供了一個寫記憶體的指令WriteProcessMemory。有了這把利器,我們幾乎無所不能。如遊戲的修改等在這裡我們只談APIHOOK。
function RepointFunction(OldFunc, NewFunc: Pointer): Integer;
var
IsDone: TList;
function RepointAddrInModule(hModule: THandle; OldFunc, NewFunc: Pointer): Integer;
var
Dos: PImageDosHeader;
NT: PImageNTHeaders;
ImportDesc: PImage_Import_Entry;
RVA: D;
Func: ^Pointer;
DLL: string;
f: Pointer;
written: DWORD;
begin
Result := 0;
D:= Pointer(hModule);
if IsDone.IndexOf(Dos) >= 0 then exit;
IsDone.Add(Dos);
OldFunc := LocateFunctionAddress(OldFunc);
if IsBadReadPtr(Dos, SizeOf(TImageDosHeader)) then exit;
if Dos.e_magic <> IMAGE_DOS_SIGNATURE then exit;
NT := Pointer(Integer(Dos) + dos._lfanew);
RVA := NT^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]
.VirtualAddress;
if RVA = 0 then exit;
ImportDesc := pointer(integer(Dos) + RVA);
while (ImportDesc^.Name <> 0) do
begin
DLL := PChar(Integer(Dos) + ImportDesc^.Name);
RepointAddrInModule(GetModuleHandle(PChar(DLL)), OldFunc, NewFunc);
Func := Pointer(Integer(DOS) + ImportDesc.LookupTable);
while Func^ <> nil do
begin
f := LocateFunctionAddress(Func^);
if f = OldFunc then
begin
WriteProcessMemory(GetCurrentProcess, Func, @NewFunc, 4, written);
if Written > 0 then Inc(Result);
end;
Inc(Func);
end;
Inc(ImportDesc);
end;
end;
begin
IsDone := TList.Create;
try
Result := RepointAddrInModule(GetModuleHandle(nil), OldFunc, NewFunc);
finally
IsDone.Free;
end;
end;
有了這兩個我們幾乎可以更改任何API函式。
我們可以先寫一個DLL。我這裡以修改Text相關函式為例:
先定義幾個函式:
type
TTextOutA = function(DC: HDC; X, Y: Integer; Str: PAnsiChar; Count: Integer): BOOL; stdcall;
TTextOutW = function(DC: HDC; X, Y: Integer; Str: PWChar; Count: Integer): BOOL; stdcall;
TTextOut = function(DC: HDC; X, Y: Integer; Str: PChar; Count: Integer): BOOL; stdcall;
TDrawTextA = function(hDC: HDC; lpString: PAnsiChar; nCount: Integer; var lpRect: TRect; uFormat: UINT): Integer; stdcall;
TDrawTextW = function(hDC: HDC; lpString: PWideChar; nCount: Integer; var lpRect: TRect; uFormat: UINT): Integer; stdcall;
TDrawText = function(hDC: HDC; lpString: PChar; nCount: Integer; var lpRect: TRect; uFormat: UINT): Integer; stdcall;
var
OldTextOutA: TTextOutA;
OldTextOutW: TTextOutW;
OldTextOut: TTextOut;
OldDrawTextA: TDrawTextA;
OldDrawTextW: TDrawTextW;
OldDrawText: TDrawText;
......
function MyTextOutA(DC: HDC; X, Y: Integer; Str: PAnsiChar; Count: Integer): BOOL; stdcall;
begin
OldTextOutA(DC, X, Y, 'ABC', length('ABC'));
end;
function MyTextOutW(DC: HDC; X, Y: Integer; Str: PWideChar; Count: Integer): BOOL; stdcall;
begin
OldTextOutW(DC, X, Y, 'ABC', length('ABC'));
end;
function MyTextOut(DC: HDC; X, Y: Integer; Str: PChar; Count: Integer): BOOL; stdcall;
begin
OldTextOut(DC, X, Y, 'ABC', length('ABC'));
end;
function MyDrawTextA(hDC: HDC; lpString: PAnsiChar; nCount: Integer; var lpRect: TRect; uFormat: UINT): Integer; stdcall;
begin
OldDrawTextA(hDC, 'ABC', length('ABC'), lpRect, uFormat);
end;
function MyDrawTextW(hDC: HDC; lpString: PWideChar; nCount: Integer; var lpRect: TRect; uFormat: UINT): Integer; stdcall;
begin
OldDrawTextW(hDC, 'ABC', length('ABC'), lpRect, uFormat);
end;
function MyDrawText(hDC: HDC; lpString: PChar; nCount: Integer; var lpRect: TRect; uFormat: UINT): Integer; stdcall;
begin
OldDrawText(hDC, 'ABC', length('ABC'), lpRect, uFormat);
end;
時我們要把原來的函式地址儲存下來:
if @OldTextOutA = nil then
@OldTextOutA := LocateFunctionAddress(@TextOutA);
if @OldTextOutW = nil then
@OldTextOutW := LocateFunctionAddress(@TextOutW);
if @OldTextOut = nil then
@OldTextOut := LocateFunctionAddress(@TextOut);
if @OldDrawTextA = nil then
@OldDrawTextA := LocateFunctionAddress(@DrawTextA);
if @OldDrawTextW = nil then
@OldDrawTextW := LocateFunctionAddress(@DrawTextW);
if @OldDrawText = nil then
@OldDrawText := LocateFunctionAddress(@DrawText);
然後很順其自然的用自己的函式替換掉原來的函式
RepointFunction(@OldTextOutA, @MyTextOutA);
RepointFunction(@OldTextOutW, @MyTextOutW);
RepointFunction(@OldTextOut, @MyTextOut);
RepointFunction(@OldDrawTextA, @MyDrawTextA);
RepointFunction(@OldDrawTextW, @MyDrawTextW);
RepointFunction(@OldDrawText, @MyDrawText);
在結束時不要忘記恢復原來函式的入口,要不然你會死得很難看喲!好了我們在寫一個Demo。你會說怎麼文字沒有變成ABC呀?是呀,你要重新整理一下才行。最小化然後在最大化。看看變了沒有。
要不然你就寫程式碼重新整理一下好了。至於去攔截其他程式的API那就用SetWindowsHookEx寫一個其他的鉤子將DLL對映進去就行了,我就不再浪費口水了。
掌握了該方法你幾乎無所不能。你可以修改其它程式。你可以攔截Createwindow等視窗函式改變其他程式的視窗形狀、你還可以其它的程式,你還可以......嘿嘿。幹了壞事別招出我來就行了。
我還寫了個例子,請在CSDN上。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-991729/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Hook技術之Hook ActivityHook
- 淺談程序隱藏技術
- 淺談Api限流API
- 淺談動態追蹤技術
- IPv6轉換技術是什麼?淺談IPv6轉換的兩種技術方式
- Android so注入(inject)和Hook技術學習(二)——GAndroidHook
- 淺談mysql資料庫技術,輕鬆玩轉儲存過程MySql資料庫儲存過程
- 淺談RASP技術攻防之基礎篇
- Laikelib淺談區塊鏈技術架構AI區塊鏈架構
- 淺談LocalCache | 京東雲技術團隊
- 技術分享 | 淺談一下大頁
- Java API 操作Docker淺談JavaAPIDocker
- 【中科三方】IPv6轉換技術是什麼?淺談IPv6轉換的兩種技術方式
- 得物技術淺談深入淺出的Redis分散式鎖Redis分散式
- 技術分享| 淺談排程平臺設計
- 一文淺談“讀寫分離”技術
- 再談訊息佇列技術-轉佇列
- 淺談 React Hooks(二)ReactHook
- 淺談IPv4/IPv6地址轉換技術-中科三方
- 淺談Layer2技術的商業化落地
- 大齡碼農那些事——淺談技術變現
- 淺談資料庫防火牆技術及應用資料庫防火牆
- 淺談常見的NoSQL技術方案和選型SQL
- 淺談技術管理之日式管理的殊途同歸
- 淺談沉浸式投影的三大技術特點
- 淺談健康技術社群與微軟MVP打造之旅微軟MVP
- 淺談.NET技術公司的實習生培養
- 淺談微服務轉型微服務
- 淺談JPA二:聊聊Hibernate
- 淺談NodeJS搭建GraphQL API服務NodeJSAPI
- 愛奇藝 Android PLT hook 技術分享AndroidHook
- 淺談馬蹄鏈DAPP專案系統開發技術邏輯(技術分析)APP
- 乾貨|淺談iOS端短影片SDK技術實現iOS
- 淺談滴滴需求響應式公交背後的技術
- 淺談RASP技術攻防之實戰[環境配置篇]
- SegmentFault 思否技術徵文丨淺談 Go 語言框架Go框架
- 技術分享| 淺談IM 產品中的“縮圖”功能
- 二、淺談 JSON 處理技巧JSON
- 淺談智慧DNS雲解析(二)DNS