zoukankan      html  css  js  c++  java
  • 截取程序的网络封包(Delphi Hook API)(该日志是转载的)

    有时候我们需要对其它应用程序发送和接收的网络数据进行拦截,比如要对IE发送的**头进行分析,得到请求的地址等.这次我们可以用一些例如WPE, Sniffer之类的工具来达到目的.但是工具功能有限,要想实现更强大的功能,还是我们自己动手来DIY吧.

    拦截网络数据封包的方法有三种,一是将网卡设为混杂模式,这次就可以监视到局域网上所有的数据包,二是HOOK目标进程的发送和接收的API函数,第三种方法是自己实现一个代理的DLL.在这里我们使用HOOK API的方法,这样易于实现,而且也不会得到大量的无用数据(如第一种方法就会监视到所有的网络数据).

    下面是一个尽量简化了的API HOOK的模版,原理是利用消息钩子将DLL中的代码注入到目标进程中,再用GetProcAddress得到API函数入口地址,将函数入口址改为自己定义的函数入口,这样就得到了API函数的相应参数,处理完后,再改回真实API函数入口地址,并调用它.

    HOOK.DLL的代码:

    1 library Hook;
    2
    3 uses
    4 SysUtils,
    5 windows,
    6 Messages,
    7 APIHook in 'APIHook.pas';
    8
    9 type
    10 PData = ^TData;
    11 TData = record
    12 Hook: THandle;
    13 Hooked: Boolean;
    14 end;
    15
    16 var
    17 DLLData: PData;
    18
    19 {------------------------------------}
    20 {过程名:HookProc
    21 {过程功能:HOOK过程
    22 {过程参数:nCode, wParam, lParam消息的相
    23 { 关参数
    24 {------------------------------------}
    25 procedure HookProc(nCode, wParam, lParam: LongWORD);stdcall;
    26 begin
    27 if not DLLData^.Hooked then
    28 begin
    29 HookAPI;
    30 DLLData^.Hooked := True;
    31 end;
    32 //调用下一个Hook
    33 CallNextHookEx(DLLData^.Hook, nCode, wParam, lParam);
    34 end;
    35
    36
    37 {------------------------------------}
    38 {函数名:InstallHook
    39 {函数功能:在指定窗口上安装HOOK
    40 {函数参数:sWindow:要安装HOOK的窗口
    41 {返回值:成功返回TRUE,失败返回FALSE
    42 {------------------------------------}
    43 function InstallHook(SWindow: LongWORD):Boolean;stdcall;
    44 var
    45 ThreadID: LongWORD;
    46 begin
    47 Result := False;
    48 DLLData^.Hook := 0;
    49 ThreadID := GetWindowThreadProcessId(sWindow, nil);
    50 //给指定窗口挂上钩子
    51 DLLData^.Hook := SetWindowsHookEx(WH_GETMESSAGE, @HookProc, Hinstance, ThreadID);
    52 if DLLData^.Hook > 0 then
    53 Result := True //是否成功HOOK
    54 else
    55 exit;
    56 end;
    57
    58 {------------------------------------}
    59 {过程名:UnHook
    60 {过程功能:卸载HOOK
    61 {过程参数:无
    62 {------------------------------------}
    63 procedure UnHook;stdcall;
    64 begin
    65 UnHookAPI;
    66 //卸载Hook
    67 UnhookWindowsHookEx(DLLData^.Hook);
    68 end;
    69
    70 {------------------------------------}
    71 {过程名:DLL入口函数
    72 {过程功能:进行DLL初始化,释放等
    73 {过程参数:DLL状态
    74 {------------------------------------}
    75 procedure MyDLLHandler(Reason: Integer);
    76 var
    77 FHandle: LongWORD;
    78 begin
    79 case Reason of
    80 DLL_PROCESS_ATTACH:
    81 begin //建立文件映射,以实现DLL中的全局变量
    82 FHandle := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0, $ffff, 'MYDLLDATA');
    83 if FHandle = 0 then
    84 if GetLastError = ERROR_ALREADY_EXISTS then
    85 begin
    86 FHandle := OpenFileMapping(FILE_MAP_ALL_ACCESS, False, 'MYDLLDATA');
    87 if FHandle = 0 then Exit;
    88 end else Exit;
    89 DLLData := MapViewOfFile(FHandle, FILE_MAP_ALL_ACCESS, 0, 0, 0);
    90 if DLLData = nil then
    91 CloseHandle(FHandle);
    92 end;
    93 DLL_PROCESS_DETACH:
    94 begin
    95 if Assigned(DLLData) then
    96 begin
    97 UnmapViewOfFile(DLLData);
    98 DLLData := nil;
    99 end;
    100 end;
    101 end;
    102 end;
    103
    104 {$R *.res}
    105 exports
    106 InstallHook, UnHook, HookProc;
    107
    108 begin
    109 DLLProc := @MyDLLHandler;
    110 MyDLLhandler(DLL_PROCESS_ATTACH);
    111 DLLData^.Hooked := False;
    112 end.
    113
    114 ----------------------------------------------------------------------------------------
    115 APIHook.Pas的代码:
    116
    117 unit APIHook;
    118
    119 interface
    120
    121 uses
    122 SysUtils,
    123 Windows, WinSock;
    124
    125 type
    126 //要HOOK的API函数定义
    127 TSockProc = function (s: TSocket; var Buf; len, flags: Integer): Integer; stdcall;
    128
    129 PJmpCode = ^TJmpCode;
    130 TJmpCode = packed record
    131 JmpCode: BYTE;
    132 Address: TSockProc;
    133 MovEAX: Array [0..2] of BYTE;
    134 end;
    135
    136 //--------------------函数声明---------------------------
    137 procedure HookAPI;
    138 procedure UnHookAPI;
    139
    140 var
    141 OldSend, OldRecv: TSockProc; //原来的API地址
    142 JmpCode: TJmpCode;
    143 OldProc: array [0..1] of TJmpCode;
    144 AddSend, AddRecv: pointer; //API地址
    145 TmpJmp: TJmpCode;
    146 ProcessHandle: THandle;
    147 implementation
    148
    149 {---------------------------------------}
    150 {函数功能:Send函数的HOOK
    151 {函数参数:同Send
    152 {函数返回值:integer
    153 {---------------------------------------}
    154 function MySend(s: TSocket; var Buf; len, flags: Integer): Integer; stdcall;
    155 var
    156 dwSize: cardinal;
    157 begin
    158 //这儿进行发送的数据处理
    159 MessageBeep(1000); //简单的响一声
    160 //调用直正的Send函数
    161 WriteProcessMemory(ProcessHandle, AddSend, @OldProc[0], 8, dwSize);
    162 Result := OldSend(S, Buf, len, flags);
    163 JmpCode.Address := @MySend;
    164 WriteProcessMemory(ProcessHandle, AddSend, @JmpCode, 8, dwSize);
    165 end;
    166
    167 {---------------------------------------}
    168 {函数功能:Recv函数的HOOK
    169 {函数参数:同Recv
    170 {函数返回值:integer
    171 {---------------------------------------}
    172 function MyRecv(s: TSocket; var Buf; len, flags: Integer): Integer; stdcall;
    173 var
    174 dwSize: cardinal;
    175 begin
    176 //这儿进行接收的数据处理
    177 MessageBeep(1000); //简单的响一声
    178 //调用直正的Recv函数
    179 WriteProcessMemory(ProcessHandle, AddRecv, @OldProc[1], 8, dwSize);
    180 Result := OldRecv(S, Buf, len, flags);
    181 JmpCode.Address := @MyRecv;
    182 WriteProcessMemory(ProcessHandle, AddRecv, @JmpCode, 8, dwSize);
    183 end;
    184
    185 {------------------------------------}
    186 {过程功能:HookAPI
    187 {过程参数:无
    188 {------------------------------------}
    189 procedure HookAPI;
    190 var
    191 DLLModule: THandle;
    192 dwSize: cardinal;
    193 begin
    194 ProcessHandle := GetCurrentProcess;
    195 DLLModule := LoadLibrary('ws2_32.dll');
    196 AddSend := GetProcAddress(DLLModule, 'send'); //取得API地址
    197 AddRecv := GetProcAddress(DLLModule, 'recv');
    198 JmpCode.JmpCode := $B8;
    199 JmpCode.MovEAX[0] := $FF;
    200 JmpCode.MovEAX[1] := $E0;
    201 JmpCode.MovEAX[2] := 0;
    202 ReadProcessMemory(ProcessHandle, AddSend, @OldProc[0], 8, dwSize);
    203 JmpCode.Address := @MySend;
    204 WriteProcessMemory(ProcessHandle, AddSend, @JmpCode, 8, dwSize); //修改Send入口
    205 ReadProcessMemory(ProcessHandle, AddRecv, @OldProc[1], 8, dwSize);
    206 JmpCode.Address := @MyRecv;
    207 WriteProcessMemory(ProcessHandle, AddRecv, @JmpCode, 8, dwSize); //修改Recv入口
    208 OldSend := AddSend;
    209 OldRecv := AddRecv;
    210 end;
    211
    212 {------------------------------------}
    213 {过程功能:取消HOOKAPI
    214 {过程参数:无
    215 {------------------------------------}
    216 procedure UnHookAPI;
    217 var
    218 dwSize: Cardinal;
    219 begin
    220 WriteProcessMemory(ProcessHandle, AddSend, @OldProc[0], 8, dwSize);
    221 WriteProcessMemory(ProcessHandle, AddRecv, @OldProc[1], 8, dwSize);
    222 end;
    223
    224 end.
    225
    226 ---------------------------------------------------------------------------------------------
    227 编译这个DLL后,再新建一个程序调用这个DLL的InstallHook并传入目标进程的主窗口句柄就可:
    228 unit fmMain;
    229
    230 interface
    231
    232 uses
    233 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
    234 Dialogs, StdCtrls;
    235
    236 type
    237 TForm1 = class(TForm)
    238 Button1: TButton;
    239 Button2: TButton;
    240 Edit1: TEdit;
    241 procedure Button1Click(Sender: TObject);
    242 procedure Button2Click(Sender: TObject);
    243 private
    244 { Private declarations }
    245 public
    246 { Public declarations }
    247 end;
    248
    249 var
    250 Form1: TForm1;
    251 InstallHook: function (SWindow: THandle):Boolean;stdcall;
    252 UnHook: procedure;stdcall;
    253 implementation
    254
    255 {$R *.dfm}
    256
    257 procedure TForm1.Button1Click(Sender: TObject);
    258 var
    259 ModuleHandle: THandle;
    260 TmpWndHandle: THandle;
    261 begin
    262 TmpWndHandle := 0;
    263 TmpWndHandle := FindWindow(nil, '目标窗口的标题');
    264 if not isWindow(TmpWndHandle) then
    265 begin
    266 MessageBox(self.Handle, '没有找到窗口', '!!!', MB_OK);
    267 exit;
    268 end;
    269 ModuleHandle := LoadLibrary('Hook.dll');
    270 @InstallHook := GetProcAddress(ModuleHandle, 'InstallHook');
    271 @UnHook := GetProcAddress(ModuleHandle, 'UnHook');
    272 if InstallHook(FindWindow(nil, 'Untitled')) then
    273 ShowMessage('Hook OK');
    274 end;
    275
    276 procedure TForm1.Button2Click(Sender: TObject);
    277 begin
    278 UnHook
    279 end;
    280
    281 end.
    282

    原文地址:http://hi.baidu.com/lzj1981/blog/item/e026663325667748ac4b5fe5.html

  • 相关阅读:
    webpack配置之代码优化
    react组件生命周期
    javascript记住用户名和登录密码
    ajax异步请求原理和过程
    深入理解ajax系列第五篇——进度事件
    ajax多次请求,只执行最后一次的方法
    CentOS6.8下MySQL MHA架构搭建笔记
    HTTP状态码
    什么是 Redis 事务?原理是什么?
    Redis 通讯协议是什么?有什么特点?
  • 原文地址:https://www.cnblogs.com/LearningC/p/1945222.html
Copyright © 2011-2022 走看看