API hook example: capture packets (reprinted)
Sometimes we needProgramIntercept the network data sent and received, for example, analyze the HTTP header sent by IE and obtain the request address. this time we can use tools such as WPE and sniffer to achieve our goal. however, the tool features are limited. If you want to implement more powerful functions, you can do it yourself.
There are three methods to intercept network data packets. One is to set the network card to the hybrid mode. This time, all the packets on the LAN can be monitored, second, hook the API functions sent and received by the target process. The third method is to implement a proxy DLL. here we use the hook api method, which is easy to implement and won't get a lot of useless data (for example, the first method will monitor all network data ).
The following is a simplified API hook template. The principle is to use the message hookCodeInject to the target process, and use getprocaddress to get the API function entry address. Change the function entry address to the function entry defined by yourself. Then, the corresponding parameters of the API function are obtained. After processing, change back to the actual API function entry address and call it.
Hook. DLL code:
Library hook;
Uses
Sysutils,
Windows,
Messages,
Apihook in 'apihook. pa ';
Type
Pdata = ^ tdata;
Tdata = record
HOOK: thandle;
Hooked: Boolean;
End;
VaR
Dlldata: pdata;
{------------------------------------}
{Process name: hookproc
{Process function: hook Process
{Process parameter: the phase of the ncode, wparam, and lparam messages
{Off parameter
{------------------------------------}
Procedure hookproc (ncode, wparam, lparam: longword); stdcall;
Begin
If not dlldata ^. Hooked then
Begin
Hookapi;
Dlldata ^. Hooked: = true;
End;
// Call the next hook
Callnexthookex (dlldata ^. Hook, ncode, wparam, lparam );
End;
{------------------------------------}
{Function name: installhook
{Function: Install hook in a specified window
{Function parameter: swindow: the window to install the hook
{Return value: True is returned for success, and false is returned for failure.
{------------------------------------}
Function installhook (swindow: longword): Boolean; stdcall;
VaR
Threadid: longword;
Begin
Result: = false;
Dlldata ^. Hook: = 0;
Threadid: = getwindowthreadprocessid (swindow, nil );
// Hook the specified window
Dlldata ^. Hook: = setwindowshookex (wh_getmessage, @ hookproc, hinstance, threadid );
If dlldata ^. Hook> 0 then
Result: = true // whether the hook is successful
Else
Exit;
End;
{------------------------------------}
{process name: Unhook
{process function: uninstall hook
{process parameters: none
{}< br> procedure unhook; stdcall;
begin
unhookapi;
// uninstall hook
unhookwindowshookex (dlldata ^. hook);
end;
{------------------------------------}
{Process name: DLL entry function
{Process function: Initialize and release the DLL.
{Process parameter: DLL status
{------------------------------------}
Procedure mydllhandler (reason: integer );
VaR
Fhandle: longword;
Begin
Case reason
Dll_process_attach:
Begin // create a file ing to implement global variables in the DLL
Fhandle: = createfilemapping ($ ffffffff, nil, page_readwrite, 0, $ FFFF, 'mydlldata ');
If fhandle = 0 then
If getlasterror = error_already_exists then
Begin
Fhandle: = openfilemapping (file_map_all_access, false, 'mydlldata ');
If fhandle = 0 Then exit;
End else exit;
Dlldata: = mapviewoffile (fhandle, file_map_all_access, 0, 0, 0 );
If dlldata = nil then
Closehandle (fhandle );
End;
Dll_process_detach:
Begin
If assigned (dlldata) then
Begin
Unmapviewoffile (dlldata );
Dlldata: = nil;
End;
End;
End;
End;
{$ R *. Res}
Exports
Installhook, unhook, hookproc;
Begin
Dllproc: = @ mydllhandler;
Mydllhandler (dll_process_attach );
Dlldata ^. Hooked: = false;
End.
Bytes ----------------------------------------------------------------------------------------
Apihook. Pas code:
Unit apihook;
Interface
Uses
Sysutils,
Windows, Winsock;
Type
// Define the API function to be hooked
Tsockproc = function (s: tsocket; var Buf; Len, flags: integer): integer; stdcall;
Pjmpcode = ^ tjmpcode;
Tjmpcode = packed record
Jmpcode: byte;
Address: tsockproc;
Moveax: array [0 .. 2] of byte;
End;
// -------------------- Function declaration ---------------------------
Procedure hookapi;
Procedure unhookapi;
VaR
Oldsend, oldrecv: tsockproc; // original API address
Jmpcode: tjmpcode;
Oldproc: array [0 .. 1] of tjmpcode;
Addsend, addrecv: pointer; // API address
Tmpjmp: tjmpcode;
Processhandle: thandle;
Implementation
{---------------------------------------}
{Function: Send function hook
{Function parameter: Same as send
{Function return value: integer
{---------------------------------------}
Function mysend (S: tsocket; var Buf; Len, flags: integer): integer; stdcall;
VaR
Dwsize: Cardinal;
Begin
// Process the sent data here
Messagebeep (1000); // a simple response
// Call the Direct Send Function
Writeprocessmemory (processhandle, addsend, @ oldproc [0], 8, dwsize );
Result: = oldsend (S, Buf, Len, flags );
Jmpcode. Address: = @ mysend;
Writeprocessmemory (processhandle, addsend, @ jmpcode, 8, dwsize );
End;
{-------------------------------------}
{function: hook of Recv function
{function parameter: Same as Recv
{function return value: integer
{-----------------------------------}
function myrecv (S: tsocket; var Buf; Len, flags: integer): integer; stdcall;
var
dwsize: cardinal;
begin
// process the received data
messagebeep (1000 ); // a simple response
// call the direct Recv function
writeprocessmemory (processhandle, addrecv, @ oldproc [1], 8, dwsize );
result: = oldrecv (S, Buf, Len, flags);
jmpcode. address: = @ myrecv;
writeprocessmemory (processhandle, addrecv, @ jmpcode, 8, dwsize);
end;
{----------------------------------}
{process function: hookapi
{process parameter: None
{----------------------------------}
procedure hookapi;
var
dllmodule: thandle;
dwsize: Cardinal;
begin
processhandle: = getcurrentprocess;
dllmodule: = loadlibrary ('ws2 _ 32. dll ');
addsend: = getprocaddress (dllmodule, 'send'); // obtain the API address
addrecv: = getprocaddress (dllmodule, 'recv ');
jmpcode. jmpcode: = $ B8;
jmpcode. moveax [0]: = $ ff;
jmpcode. moveax [1]: = $ E0;
jmpcode. moveax [2]: = 0;
readprocessmemory (processhandle, addsend, @ oldproc [0], 8, dwsize);
jmpcode. address: = @ mysend;
writeprocessmemory (processhandle, addsend, @ jmpcode, 8, dwsize); // modify the send Entry
readprocessmemory (processhandle, addrecv, @ oldproc [1], 8, dwsize);
jmpcode. address: = @ myrecv;
writeprocessmemory (processhandle, addrecv, @ jmpcode, 8, dwsize); // modify Recv entry
oldsend: = addsend;
oldrecv: = addrecv;
end;
{------------------------------------}
{Process function: Cancel hookapi
{Process parameter: None
{------------------------------------}
Procedure unhookapi;
VaR
Dwsize: Cardinal;
Begin
Writeprocessmemory (processhandle, addsend, @ oldproc [0], 8, dwsize );
Writeprocessmemory (processhandle, addrecv, @ oldproc [1], 8, dwsize );
End;
End.
Bytes ---------------------------------------------------------------------------------------------
After compiling the DLL, create a new program to call the installhook of the DLL and input the main window handle of the target process:
Unit fmmain;
Interface
Uses
Windows, messages, sysutils, variants, classes, graphics, controls, forms,
Dialogs, stdctrls;
Type
Tform1 = Class (tform)
Button1: tbutton;
Button2: tbutton;
Edit1: tedit;
Procedure button1click (Sender: tobject );
Procedure button2click (Sender: tobject );
Private
{Private Declarations}
Public
{Public declarations}
End;
VaR
Form1: tform1;
Installhook: function (swindow: thandle): Boolean; stdcall;
Unhook: procedure; stdcall;
Implementation
{$ R *. DFM}
Procedure tform1.button1click (Sender: tobject );
VaR
Modulehandle: thandle;
Tmpwndhandle: thandle;
Begin
Tmpwndhandle: = 0;
Tmpwndhandle: = findwindow (nil, 'title of the destination Windows ');
If not iswindow (tmpwndhandle) then
Begin
MessageBox (self. Handle, 'window not found ','!!! ', Mb_ OK );
Exit;
End;
Modulehandle: = loadlibrary ('hook. dll ');
@ Installhook: = getprocaddress (modulehandle, 'installhook ');
@ Unhook: = getprocaddress (modulehandle, 'unhook ');
If installhook (findwindow (nil, 'untidled ') then
Showmessage ('hook OK ');
End;
Procedure tform1.button2click (Sender: tobject );
Begin
Unhook
End;