下面代码是我从一段C语言代码转换过来的,却运行结果与C的不相同,请前辈们指点。谢谢!
unit Unit1; {$mode Delphi}{$H+}interfaceuses
  Classes, Windows, Messages, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
  StdCtrls;type  { TForm1 }  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end; var
  Form1: TForm1;
const
  FLATJMPCODE_LENGTH=5;
  function HookApi(ApiFun:LPVOID; HookFun:LPVOID):Bool;
  function MyHookFn(hwnd:HWND;sztext:pchar;szTitle:pchar;stly:LongInt):LongInt;stdcall;
implementation
function HookApi(ApiFun:LPVOID; HookFun:LPVOID):Bool;
var
   IsSuccess:Bool;
   TempVar:DWORD; //临时变量
   MemInfo:MEMORY_BASIC_INFORMATION; //内存分页属性信息
begin
   IsSuccess:=False;
   VirtualQuery(ApiFun,@MemInfo,SizeOf(MEMORY_BASIC_INFORMATION));  //查询信息
   if(VirtualProtect(MemInfo.BaseAddress,MemInfo.RegionSize,
      PAGE_READWRITE,@MemInfo.Protect)) then begin //修改页面为可写
      asm
          mov eax,ApiFun
          mov byte ptr[eax],$e9
          mov edx,HookFun
          sub edx,eax
          sub edx,FLATJMPCODE_LENGTH
          mov dword ptr[eax + 1],edx
      end;
        VirtualProtect(MemInfo.BaseAddress,MemInfo.RegionSize,MemInfo.Protect,@TempVar);//改回原属性
        IsSuccess:=True;
    end;
    Result:=IsSuccess;
end;{ TForm1 }procedure TForm1.Button1Click(Sender: TObject);
var
   hDll:HMODULE;
   OldFun:LPVOID;
begin
    hDll:=GetModuleHandle('User32.dll');
    OldFun:=GetProcAddress(hDll,'MessageBoxA');  //要HOOK的对象
    if(OldFun<>nil) then begin
        if(HookApi(@OldFun,@MyHookFn)=True) then  //如果HOOK成功
            MessageBoxA(0,'call Api MessageBox','Is Hookd?',MB_OK); //调用原API
    end;
    if(hDll<>0) then
        FreeLibrary(hDll);
end;
//我的新函数
function MyHookFn(hwnd:HWND;sztext:pchar;szTitle:pchar;stly:LongInt):LongInt;stdcall;
const
     szHookTxt = '原函数已被HOOKD!'; //用来替换原显示内容
begin
     Result:=MessageBoxEx(hwnd,szHookTxt,szTitle,stly,0);   //调用另外的API
end;initialization
  {$I Unit1.lrs}end.C语言代码:// apihook.cpp : Defines the entry point for the console application.
//#include "stdafx.h"#include <stdlib.h>
#include <windows.h>#define FLATJMPCODE_LENGTH 5//我的新函数
int __stdcall MyHookFn(HWND hwnd,char* sztext,char* szTitle,int stly)
{
    const char* szHookTxt = "原函数已被HOOKD!";         //用来替换原显示内容    return MessageBoxEx(hwnd,szHookTxt,szTitle,stly,0);   //调用另外的API
}//HOOK函数
BOOL HookApi(LPVOID ApiFun,LPVOID HookFun)
{
    BOOL    IsSuccess = FALSE;
    DWORD   TempVar;                     //临时变量
    MEMORY_BASIC_INFORMATION MemInfo;    //内存分页属性信息    VirtualQuery(ApiFun,&MemInfo,sizeof(MEMORY_BASIC_INFORMATION));  //查询信息
    if(VirtualProtect(MemInfo.BaseAddress,MemInfo.RegionSize,
        PAGE_READWRITE,&MemInfo.Protect))                            //修改页面为可写 
    {
        __asm
        {
            mov eax,ApiFun
            mov byte ptr[eax],0xe9
            mov edx,HookFun
            sub edx,eax
            sub edx,FLATJMPCODE_LENGTH
            mov dword ptr[eax + 1],edx
        }
        VirtualProtect(MemInfo.BaseAddress,MemInfo.RegionSize,
            MemInfo.Protect,&TempVar);                               //改回原属性        IsSuccess = TRUE;
    }    return IsSuccess;
}int main(int argc,char** argv)
{
    HMODULE hDll;
    LPVOID  OldFun;    hDll = GetModuleHandle("User32.dll");
    OldFun = GetProcAddress(hDll,"MessageBoxA");  //要HOOK的对象    if(OldFun)
    {
        if(HookApi(OldFun,MyHookFn))  //如果HOOK成功
            MessageBoxA(0,"call Api MessageBox","Is Hookd?",MB_OK); //调用原API
    }    if(hDll)
        FreeLibrary(hDll);    return 0;
}

解决方案 »

  1.   

    你的代码就一点小问题
    procedure TForm1.Button1Click(Sender: TObject);
    var
       hDll:HMODULE;
       OldFun:LPVOID;
    begin
        hDll:=GetModuleHandle('User32.dll');
        OldFun:=GetProcAddress(hDll,'MessageBoxA');  //要HOOK的对象
        if(OldFun<>nil) then begin
            if(HookApi(@OldFun,@MyHookFn)=True) then  //如果HOOK成功
                MessageBoxA(0,'call Api MessageBox','Is Hookd?',MB_OK); //调用原API
        end;
        if(hDll<>0) then
            FreeLibrary(hDll);
    end;改成 
      if(HookApi(OldFun,@MyHookFn)=True) then  //如果HOOK成功这样就可以了 
      

  2.   

    OldFun:LPVOID;
    这里oldfun已经是地址了,就是API的地址
    @OldFun 表示oldFun自身的地址,不是API的地址
    给分吧 哈哈
      

  3.   

    那段不用汇编也可以的
    就是在原MessageBoxA的地址处先写一个指令,用$E9来代替系统的指令
    另外再写 新函数地址 
    新函数地址 := DWORD(@MyHookFn) - DWORD(MessageBoxA的地址) - 5;
      

  4.   

    if(HookApi(OldFun,@MyHookFn)=True) then if(HookApi(@OldFun,@MyHookFn)=True) then 
    請區分此時@OldFun和OldFun的意義...
      

  5.   

    那如果hook了以后,想卸载怎么用