关于进程内的API钩子

xthmpro_cn 2005-03-13 09:18:35
我的应用程序或VCL本身调用了API函数,但是我想在不改变VCL源码或本身应用程序的情况下,写一个钩子,这个钩子只对我这个应用程序有效。
如我想我的程序在调用:CreateBitmap API函数时先调用我的函数。
谢谢各位高手。
...全文
230 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
xthmpro_cn 2005-03-19
  • 打赏
  • 举报
回复
任务完成!
导入表HOOK
内存修改HOOK 空间无效
内存修改HOOK 控件有效
xthmpro_cn 2005-03-18
  • 打赏
  • 举报
回复
基本思路是按照这个文章,但是这个文章是错误的,文章是不完整的。
http://www.xfocus.net/articles/200205/392.html
xthmpro_cn 2005-03-18
  • 打赏
  • 举报
回复
谢谢:ly_liuyang(Liu Yang)
目前我不使用Import Table,直接修改内存@MessageBoxA内存可以HOOK了,不受ASPACK等加壳软件的影响,但是,我HOOK不住控件对该API函数的调用,请指点一下,如果有源代码更好!
amitabha 2005-03-17
  • 打赏
  • 举报
回复
up
ly_liuyang 2005-03-16
  • 打赏
  • 举报
回复
原贴内容:
关于API的钩子,我已经可以在进程内钩住了,但是如果将Exe文件用Aspack压缩后就又钩不住了,不知有没有高招?谢谢!

Re:可以通过动态挂接技术,不使用Import Table的,直接就LoadLibrary后,修改由GetProcAddress获得的地址的前5Bytes为JMP XXX

流程为:
复制前+5Bytes(可能是6Bytes等,需要代码对齐)到某区域(可执行可写的区域)
修改为JMP到地址
新建立的区域中Call你的Hook过程,然后JMP到API入口+5后的地址

http://lysoft.7u7.net
LittleStar 2005-03-15
  • 打赏
  • 举报
回复
mark
xthmpro_cn 2005-03-14
  • 打赏
  • 举报
回复
按照楼上提供的地址,改了,但是没有Hook成功。
代码如下:
unit uHook;

interface
uses
Windows, Messages, SysUtils, Classes;
type
TlmportCode =
packed record
Jumplnstruction: Word; //是$25FF,JUMP指令
AddressOfPointerToFunction: PPointer;//真正开始的地址
end;
PlmportCode = ^TlmportCode;

var
FuncMessageboxA, FuncMessageboxW: PlmportCode;
//静态挂接
procedure API_Hookup;
procedure Un_API_Hook;

implementation
type
TmessageA = function(hWnd: HWND; lpText, lpCaption: PAnsiChar; uType: UINT): integer; stdcall;
TmessageW = function(hWnd: HWND; lpText, lpCaption: PAnsiChar; uType: UINT): integer; stdcall;

var
OldMessageBoxA: TmessageA;
OldMessageBoxW: TmessageW;

function TrueFunctionAddress(func: Pointer): Pointer;
var
Code: PlmportCode;
Begin
//返回指定函数的真正地址
Result:= func;
if func = nil then exit;

try
Code := func;
if (Code.jumplnstruction = $25FF) then
Result := Code.AddressOfPointerToFunction^;
except
Result :=nil;
end;
end;

Procedure PermuteFunction(OldFunc: pointer; NewFunc: pointer);
var
Written: DWORD;
begin
//写地址函数
WriteProcessMemory(GetCurrentProcess, @OldFunc, @NewFunc, 4, Written)
// raise Exception.Create('Hook OK');
end;

function MyBoxA(hWnd: HWND; lpText, lpCaption: PAnsiChar; uType: UINT): integer; stdcall;
begin
//新函数
result :=OldMessageBoxA(hWnd, 'Succes Hook MessageBoxA!', lpCaption, uType);
end;

function MyBoxW(hWnd: HWND; lpText, lpCaption: PAnsiChar; uType: UINT): integer; stdcall;
begin
//新函数
result :=OldMessageBoxW(hWnd, 'Succes Hook MessageBoxW!', lpCaption, uType);
end;

procedure API_Hookup;
begin
//在旧函数的地址写上自己的函数
PermuteFunction(@FuncMessageboxA, @MyBoxA);
PermuteFunction(@FuncMessageboxW, @MyBoxW);
end;

procedure Un_API_Hook;
begin
//在旧的函数地址写旧的函数
PermuteFunction(@FuncMessageboxA, @OldMessageboxA);
PermuteFunction(@FuncMessageboxW, @OldMessageboxW);
end;

initialization
//记住旧函数的跳转的指令位置.
FuncMessageboxA:= @MessageBoxA;
FuncMessageboxW:= @MessageBoxW;
//从旧函数指针返回旧函数的真实地址,便于将来写回.
@OldMessageBoxA:= TrueFunctionAddress(@MessageBoxA);
@OldMessageBoxW:= TrueFunctionAddress(@MessageBoxW);
end.

Form
uses uhook;


procedure TForm1.btn2Click(Sender: TObject);
begin
API_Hookup;
end;

procedure TForm1.btn4Click(Sender: TObject);
begin
MessageBoxA(Form1.Handle,'NO HOOK UP A','MessageBoxA',MB_OK);
MessageBoxW(Form1.Handle,'NO HOOK UP W','MessageBoxW',MB_OK);
MessageBox (Form1.Handle,'NO HOOK UP BOX','MessageBox',MB_OK);
end;

procedure TForm1.btn3Click(Sender: TObject);
begin
Un_API_Hook;
end;
僵哥 2005-03-14
  • 打赏
  • 举报
回复
http://www.xfocus.net/articles/200205/392.html
ju1 2005-03-14
  • 打赏
  • 举报
回复
高深没看懂
xthmpro_cn 2005-03-14
  • 打赏
  • 举报
回复
请大家帮助!
xthmpro_cn 2005-03-14
  • 打赏
  • 举报
回复
另外这个代码编译的Exe文件不能用Aspack压缩,压缩后就钩不住了。还请大家帮忙!
xthmpro_cn 2005-03-14
  • 打赏
  • 举报
回复
这样即可,请大家解释一下RepointAddrInModule递归函数的意思,我具体还不是很明白。
以下主要代码来自CSDN:
unit uhook;

interface

uses
Windows, Messages, Classes;

type
TmessageA = function(hWnd: HWND; lpText, lpCaption: PAnsiChar; uType: UINT): integer; stdcall;
TmessageW = function(hWnd: HWND; lpText, lpCaption: PAnsiChar; uType: UINT): integer; stdcall;

//入口结构
Image_Import_Entry = record
Characteristics: DWORD;
TimeDateStamp: DWORD;
MajorVersion: Word;
MinorVersion: Word;
Name: DWORD;
LookupTable: DWORD;
end;
PImage_Import_Entry = ^Image_Import_Entry;

//函数跳转的结构
TImportCode = packed record
JumpInstruction: Word; //定义跳转指令jmp,是$25FF,JUMP指令
AddressOfPointerToFunction: ^Pointer; //定义要跳转到的函数,//真正开始的地址
end;
PImportCode = ^TImportCode;

procedure API_Hookup;
procedure Un_API_Hook;

implementation

var
OldMessageBoxA: TmessageA;
OldMessageBoxW: TmessageW;

function GetFunctionAddress(PFunction: PImportCode): Pointer;
begin
Result:= PFunction;
if PFunction = nil then exit;

if (PFunction.JumpInstruction = $25FF) then
Result:= PFunction.AddressOfPointerToFunction^;
end;

function RepointFunction(OldFunc, NewFunc: Pointer): Integer;
var
ProcessList: TList;
function RepointAddrInModule(hModule: THandle; OldFunc, NewFunc: Pointer): Integer;
var
f: Pointer;
RVA: DWORD;
InportDLL: string;
written: DWORD;
Func: ^Pointer;
NT: PImageNTHeaders;
Dos: PImageDosHeader;
ImportDesc: PImage_Import_Entry;
begin
//HOOK的数量
Result:= 0;

//判断当前Module是否已经处理过
Dos:= Pointer(hModule);
if ProcessList.IndexOf(Dos) >= 0 then exit;
ProcessList.Add(Dos);

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) + Integer(RVA));

//取旧的函数地址
OldFunc:= GetFunctionAddress(OldFunc);
while (ImportDesc^.Name <> 0) do
begin
//递归处理函数包含的所有InprotDll
InportDLL:= PChar(Integer(Dos) + Integer(ImportDesc^.Name));
RepointAddrInModule(GetModuleHandle(PChar(InportDLL)), OldFunc, NewFunc);
//处理当前Dll导入的函数
Func:= Pointer(Integer(DOS) + Integer(ImportDesc.LookupTable));
while Func^ <> nil do
begin
f:= GetFunctionAddress(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
ProcessList:= TList.Create;
try
Result:= RepointAddrInModule(GetModuleHandle(nil), OldFunc, NewFunc); //这可以HOOK到“我的程序的代码”
finally
ProcessList.Free;
end;
end;

function MyBoxA(hWnd: HWND; lpText, lpCaption: PAnsiChar; uType: UINT): Integer; stdcall;
begin
//新函数
result:=OldMessageBoxA(hWnd, 'Succes Hook MessageBoxA!', lpCaption, uType);
end;

function MyBoxW(hWnd: HWND; lpText, lpCaption: PAnsiChar; uType: UINT): Integer; stdcall;
begin
//新函数
// result:=OldMessageBoxW(hWnd, '成功HOOK!', lpCaption, uType);
result:=OldMessageBoxA(hWnd, 'Succes Hook MessageBoxW!', lpCaption, uType);
end;

procedure API_Hookup;
begin
if @OldMessageBoxA = nil then
@OldMessageBoxA:= GetFunctionAddress(@MessageBoxA);
RepointFunction(@OldMessageBoxA, @MyBoxA);

if @OldMessageBoxW = nil then
@OldMessageBoxW:= GetFunctionAddress(@MessageBoxW);
RepointFunction(@OldMessageBoxW, @MyBoxW);
end;

procedure Un_API_Hook;
begin
if @OldMessageBoxA <> nil then
RepointFunction(@MyBoxA, @OldMessageBoxA);

if @OldMessageBoxW <> nil then
RepointFunction(@MyBoxW, @OldMessageBoxW);
end;


end.
xthmpro_cn 2005-03-14
  • 打赏
  • 举报
回复
请大家推荐一个行的.!
ju1 2005-03-14
  • 打赏
  • 举报
回复
确实不行 我看了 这个 逻辑 就 不太象行的样子很多写 文章的 都是 随便一写
没有真实的把 源代码 放再那里给大家下载
ju1 2005-03-14
  • 打赏
  • 举报
回复
sephil老大 那个 统计个数 问题还没帮我呢!
xthmpro_cn 2005-03-14
  • 打赏
  • 举报
回复
测试了是不行的。
Sephil 2005-03-14
  • 打赏
  • 举报
回复
xthmpro_cn(安徽农民*在外打工) 的可以
xthmpro_cn 2005-03-14
  • 打赏
  • 举报
回复
但是我的不成功,帮忙看看。
ly_liuyang 2005-03-14
  • 打赏
  • 举报
回复
呵呵,就是API Hook了
例子很多的:)

http://lysoft.7u7.net
caiso 2005-03-13
  • 打赏
  • 举报
回复
顶一下

1,183

社区成员

发帖
与我相关
我的任务
社区描述
Delphi Windows SDK/API
社区管理员
  • Windows SDK/API社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧