APIHOOK instance analysis 2004-2-18 Join 9CBS Author Rivershan 0 comments Click 224 About APIHOOK's basic knowledge, such as DLL related knowledge, Hook related knowledge, contact between system processes, and threads. Specifically you can see another article: "My DLL (Dynamic Link Library) Learning Notes" and "My Hook Learning Notes". :) The following is the focus of this article, and analyzes APIHOOK according to the APIHOK source code. I. APIHOK DLL section APIHOOK_DLL.CPP // Rivers Hold written in 2002.9.23 /// # include "stdafx.h" #include "apihook_dll.h" #include
#include
#pragma comment (lib, "imagehlp") // Define global shared data segment
#pragma data_seg ("Shared")
HModule Hmoddll = NULL;
Hhook hHOOK = NULL;
#pragma data_seg ()
#pragma Comment (Linker, "/ Section: Shared, RWS") // Setting the properties of the global shared data segment
/ DLLMAIN function /
// DLL entry point
Bool Apientry Dllmain (HModule Hmodule,
DWORD UL_REASON_FOR_CALL,
LPVOID LPRESERVED
)
{
Switch (ul_reason_for_call)
{
Case DLL_Process_attach:
// if (shook)
Case DLL_PROCESS_DETACH:
Uninstallhook ();
Break;
}
HMODDLL = HMODULE;
Return True;
}
/ HookoneAPI function /
// Make the key function of IAT conversion, its parameter meanings:
// pszcalleemodulename: Module name that needs HOOK
// pfnoriginapiaddress: Address to be replaced with the address of your API function
// pfndummyfuncaddress: The address of the module name that needs HOOK
// hmodcallermodule: The module name we have to find, if it is not assigned,
// The program that will be assigned to the enumerated program all calling modules
Void WinApi HookoneApi (LPCTSTSTSTSTSTSZZCALLEMODULENAME, PROC PFNORIGINAPIADDRESS,
Proc Pfndummyfuncaddress, HModule Hmodcallermodule
{
Ulong size;
/ / Get pointers in the image_directory_descriptor array in the Import to the IMPORT in the PE file
PIMAGE_IMPORT_DESCRIPTOR PIMPORTDESC = (PIMAGE_IMPORT_DESCRIPTOR)
ImageDirectoryEntryTodata (Hmodcallermodule, True, Image_Directory_Entry_import, & size);
IF (pimportdesc == null)
Return;
/ / Find records to see if there is any DLL we want
For (; pimportdesc-> name; pimportdesc )
{
LPSTR pszdllname = (lpstr) ((pbyte) hmodcallermodule pimportdesc-> name); if (lszdllname, pszcalleemodulename) == 0)
Break;
}
IF (pimportdesc-> name == null)
{
Return;
}
// Looking for the functions we want
PIMAGE_THUNK_DATA PTHUNK =
(PIMAGE_THUNK_DATA) (PBYTE) HMODCALLERMODULE PIMPORTDESC-> firstthunk); // Iat
For (; pthunk-> u1.function; pthunk )
{
// PPFN records the address of the function corresponding to the IAT entry
PROC * PPFN = (Proc *) & pthunk-> u1.function;
IF (* ppfn == pfnoriginapiaddress)
{
// If the address is the same, it is found to find the function we want, rewrite, pointing it to the function we defined.
WriteProcessMemory (getCurrentProcess (), PPFN, & PFNDUMMYFuncaddress,
SizeOf (Pfndummyfuncaddress, NULL);
Return;
}
}
}
/ / Find the DLL module applied by the hook
Bool WinApi HookAllapi (LPCTSTR Pszcalleemodulen), Proc Pfnoriginapiaddress,
Proc Pfndummyfuncaddress, HModule Hmodcallermodule
{
IF (pszcalleemodulename == null)
{
Return False;
}
IF (pfnoriginapiaddress == null)
{
Return False;
}
// If you don't pass the module name to be hooked, enumerate all referenced modules that are hooked.
/ / Find the corresponding function name of these modules
IF (HMODCALLERMODULE == NULL)
{
Memory_basic_information minfo;
HModule HModHOKDLL;
Handle hsnapshot;
ModuleEntry32 me = {sizeof (moduleEntry32)};
// ModuleEntry32: describes the structure of the module applied by the specified process.
VirtualQuery (HookoneApi, & Minfo, SIZEOF (Minfo);
HMODHOKDLL = (hmodule) minfo.allocationbase;
Hsnapshot = CreateToolHelp32Snapshot (TH32CS_SNAPMODULE, 0);
Bool bok = module32first (hsnapshot, & me);
While (bok)
{
IF (me.hmodule! = hmodhookdll)
{
hmodcallermodule = me.hmodule; // Assignment
//me.hmodule: Point to each module currently hooked
HookoneApi (Pszcalleemodulename, Pfnoriginapiaddress,
Pfndummyfuncaddress, hmodcallermodule;
}
BOK = Module32Next (HSnapshot, & me);
}
Return True;}
// If you pass it, look for
Else
{
HookoneApi (Pszcalleemodulename, Pfnoriginapiaddress,
Pfndummyfuncaddress, hmodcallermodule;
Return True;
}
Return False;
}
UnHookAllapihooks function /
// Cancel the modification of IAT by making PfnDumMyfuncaddress and PFNORiginapiadDress
Bool WinAPI UnHookallapihook (LPCTSTSTSTSTSTSZCALLEMODULENAME, PROC PFNORIGINAPIADDRESS,
Proc Pfndummyfuncaddress, HModule Hmodcallermodule
{
PROC TEMP;
Temp = pfnoriginapiaddress;
Pfnoriginapiaddress = pfndummyfuncaddress;
Pfndummyfuncaddress = Temp;
Return HookAllapi (Pszcalleemodulen), Pfnoriginapiaddress,
Pfndummyfuncaddress, hmodcallermodule;
}
// getMSGProc function
// hook the substruction. Unlike other hooks, there is no meaningful thing, continue to call the next hook subsidy, form a cycle
LResult Callback GetMsgProc (int Code, WPARAM WPARAM, LPARAM LPARAM)
{
Return CallNexthookex (HHOOK, CODE, WPARAM, LPARAM);
}
Installhook function /
/ / Install or uninstall the hook, the BOOL ISHOOK parameter is a flag
/ / Initialize which API function hooked?
/ / We are installing the hook type is wh_getimentage
Void __Declspec (DLLEXPORT) WinAPI Installhook (Bool Ishook, DWORD DWTHREADID)
{
ISHOOK
{
HHOOK = SETWINDOWSHOKEX (WH_GetMessage, (HookProc) getMsgProc, HModdll, DWTHREADID;
//GetProcaddress ("GDi32.dll"), "ExtTextouta ": Acquisite the address of the hook in the DLL in the DLL
HookAllapi ("gdi32.dll", getProcaddress (GetModuleHandle ("gdi32.dll"),
"TextOutw"), (Proc) & h_textoutw, null;
HookAllapi ("gdi32.dll", getProcaddress (GetModuleHandle ("gdi32.dll"),
"TextOuta", (Proc) & h_textouta, null;
}
Else
{
Uninstallhook ();
UnHookallapihooks ("GDi32.dll", getProcaddress (GetModuleHandle ("gdi32.dll"),
"TextOutw"), (Proc) & h_textoutw, null;
UnHookallapihooks ("GDI32.DLL", GetProcaddress (GetModuleHandle ("gdi32.dll"), "TextOuta"), (Proc) & H_TextOuta, NULL);
}
}
/ Uninstallhook function
// Uninstall the hook
Bool WinApi Uninstallhook ()
{
UnHookWindowsHookex (HHOOK);
Return True;
}
/ H_textouta function /
// Our replacement function, you can implement the features we have to do in it.
/ / What I did here is to show a dialog, indicate which function is replaced.
Bool WinApi H_Textouta (HDC HDC, INT NXSTART, INT NYSTART, LPCSTART, INT NYSTART, LPCSTR LPSTRING, INT CBSTRING)
{
MessageBox (NULL, "Textouta", "APIHOOK_DLL --- Rivershan", MB_OK);
Textouta (HDC, NXStart, NyStart, LPString, Cbstring); // Returns the original function to display characters
Return True;
}
/ H_textoutw function /
//
Bool WinApi H_TextOutw (HDC HDC, INT NXSTART, INT NYSTART, LPCWSTART LPSTRING, INT CBSTRING)
{
MessageBox (NULL, "TextOutw", "APIHOOK_DLL --- Rivershan", MB_OK;
TextOutw (HDC, NxStart, NyStart, LPString, Cbstring); // Returns the original function to display characters
Return True;
}
*********************************************************** **************************************************
*********************************************************** **************************************************
APIHOOK_DLL.H
// rivershan is written in 2002.9.23 //
/
// DLL header file for declaration functions
Void __Declspec (DLLEXPORT) WinAPI Installhook (Bool, DWORD);
Bool WinAPI Uninstallhook ();
Lresult Callback GetMsgProc (int Code, WPARAM WPARAM, LPARAM LPARAM);
Void WinApi HookoneApi (LPCTSTSTSTSTSTSZZCALLEMODULENAME, PROC PFNORIGINAPIADDRESS,
Proc pfndummyfuncaddress, hmodule hmodcallermodule;
Bool WinApi HookAllapi (LPCTSTR Pszcalleemodulen), Proc Pfnoriginapiaddress,
Proc pfndummyfuncaddress, hmodule hmodcallermodule;
Bool WinAPI UnHookallapihook (LPCTSTSTSTSTSTSZCALLEMODULENAME, PROC PFNORIGINAPIADDRESS,
Proc Pfndummyfuncaddress, HModule Hmodcallermodule; Bool WinApi H_Textouta (HDC, INT, INT, LPCSTR, INT);
Bool WinApi H_TextOutw (HDC, INT, INT, LPCWSTR, INT);
Bool WinAPI H_ExtTextouta (HDC, INT, INT, UINT, Const Rect *, LPCSTR, UINT, Const Int *);
BOOL WINAPI H_EXTTEXTOUTW (HDC, INT, INT, UINT, Const Rect *, LPCWSTR, UINT, Const Int *);
*********************************************************** **************************************************
*********************************************************** **************************************************
APIHOOK_DLL DEF file
Library APIHOOK_DLL.DLL
Export
INSTALLHOOK
Second, the APIHOOK EXE section
APIHOK_EXEDLG.CPP /
// rivershan is written in 2002.9.23 //
/
#include "stdafx.h"
#include "APIHOK_EXE.H"
#include "apihook_exedlg.h"
#include "APIHOK_DLL.H"
#ifdef _Debug
#define new debug_new
#undef this_file
Static char this_file [] = __file__;
#ENDIF
/
// CapiHook_exedlg Dialog
Capihook_exedlg :: CapiHook_exedlg (CWND * PParent / * = NULL * /)
: Cdialog (CapiHook_exedlg :: IDD, PPARENT)
{
// {{AFX_DATA_INIT (CAPIHOOK_EXEDLG)
// Note: The classwizard will add member initialization here
//}} AFX_DATA_INIT
// Note That Loadicon Does Not Require a Subsequent Destroyicon in Win32
m_hicon = AFXGetApp () -> loadicon (iDR_mainframe);
}
Void CapiHook_exedlg :: DODATAEXCHANGE (CDataExchange * PDX)
{
CDIALOG :: DODATAEXCHANGE (PDX);
// {{AFX_DATA_MAP (CapiHook_exedlg)
// DDX_Control (PDX, IDC_EDit1, m_edit);
//}} AFX_DATA_MAP
}
Begin_MESSAGE_MAP (CapiHook_exedlg, CDIALOG)
// {{AFX_MSG_MAP (CapiHook_exedlg)
ON_WM_PAINT ()
ON_WM_QUERYDRAGICON ()
ON_BN_CLICKED (IDC_Button_OUT, ONBUTTONOUT)
ON_BN_CLICKED (IDC_Button_Begin, OnButtonbegin)
ON_BN_CLICKED (IDC_Button_Stop, OnButtonStop)
//}} AFX_MSG_MAP
END_MESSAGE_MAP ()
/
// CapiHook_exedlg Message Handlers
Bool Capihook_exedlg :: OnItDialog ()
{
CDIALOG :: OnInitdialog ();
// set the icon for this dialog. The framework does this AutomaticL
// when the application's main window is not a dialog
Seticon (M_Hicon, True); // set Big icon
Seticon (M_Hicon, False); // set small icon
// Todo: Add Extra Initialization Here
Return True; // Return True UnsS you set the focus to a control
}
// if you add a minimize button to your dialog, you will need the code below
// to draw the icon. For mfc Applications Using The Document / View Model,
// this is automatic or done for you by the framework.
Void CapiHook_exedlg :: onpaint ()
{
IF (Isiconic ())
{
CPAINTDC DC (this); // Device Context for Painting
SendMessage (WM_ICONERASEBKGND, (WPARAM) dc.getsafehdc (), 0);
// Center icon in Client Rectangle
INT CXCION = GetSystemMetrics (sm_cxicon);
INT Cyicon = GetSystemMetrics (SM_CYICON)
CRECT RECT;
GetClientRect (& RECT);
INT x = (Rect.width () - CXICON 1) / 2;
INT Y = (Rect.height () - Cyicon 1) / 2;
// Draw the icon
Dc.drawicon (X, Y, M_HICON);
}
Else
{
CDIALOG :: onpaint ();
}
}
// the system calls this to obtain the cursor to display while the user DRAGS
// the minimized window.
Hcursor capihook_exedlg :: ONQUERYDRAGICON ()
{
Return (hcursor) m_hicon;
}
/ Onbuttonout function //
// Use the TextOUT function
Void Capihook_exedlg :: OnButtonout ()
{
// Todo: Add Your Control Notification Handler Code Here
HDC HDC = :: getdc (getsafehwnd ());
:: TextOuta (HDC, 0, 0, "APIHOOK_EXE --- Rivershan, 30);
UpdateWindow ();
}
/ Onbuttonbegin function
// Start hook, here we hang this APIHOOK_EXE this program void CapiHook_exedlg :: OnbuttonBegin ()
{
DWORD DWTHREADID = GetWindowThreadProcessId (m_hwnd, null); // Get your own process ID
Installhook (True, DWTHREADID);
}
/ OnButtonStop function
/ / Cancel hook
Void Capihook_exedlg :: OnButtonStop ()
{
Installhook (false, 0);
}
Third, the integration of APIHOOK
1. Create a Win32 Dynamic-Link Library program with VC , named APIHOOK_DLL. Next, select the second A Simple DLL Project;
2. Create a new one file, named APIHOOK_DLL.H. Delete the original content in the project in the project, then copy the contents of the above APIHOOK_DLL.CPP and APIHOOK_DLL.H files to newly built projects; CPP and .H files;
3. Create a new Text file, named APIHOOK_DLL.DEF. Copy the contents of the DEF file above.
4. Compile;
5. Newly built a MFC AppWizard (EXE) program, named APIHOK_EXE. Then select the third item, the program based on the dialog, other default;
6. Delete the control on the original dialog, then create three buttons IDs are: IDC_Button_STOP, IDC_Button_Stop, IDC_Button_OUT, CAPTION: Bigin Hook, Stop Hook, Text Out. Don't let these three buttons are on the top of the dialog customer area;
7. Copy the APIHOK_DLL.H file to the APIHOOK_EXE program directory, then add it to the header folder of the APIHOK_EXE.
8. Delete the original content in the project in the project, and then copy the contents of the above APIHOOK_EXEDLG.CPP file to the newly created .CPP file;
9. Open the Project-> Setting menu, select Fourth Link, add the path to our DLL LIB file in Object / Library Moduls: ../ APIHOOK_DLL / Debug / APIHOOK_DLL.LIB;
10. Compile;
11. Place the APIHOOK_DLL.DLL file in the same folder of the APIHOOK_DLL.EXE program;
12. Run the program, click the Bigin Hook button, start hook. Then click the Text Out button to jump out of the dialog and display the words you want to display in the program. Click on the Stop Hook and then there is no dialog box that click the Text Out button.
Fourth, some explanation
1. This hookapi is an IAT of the Jeffrey Richter's overwriting program, or it can be implemented with the way of jump function entry points. This I didn't do research. :)
2, some of my experience:
The so-called hookaPi is the IAT of the rewrite program, then calls my own function to replace the original API function. In our own written API function, we can work we want. After that, you can pass the original function back, or you can't pass it, as long as you design it.
The so-called calling your own function is to pass the original function parameters to my replacement function. We can use these parameters to do things we want to do. And the system, I think the purpose of this hook set by Microsoft (I think so), so I will not check whether the replacement function is the original function, as long as the parameter, the return value meets the conditions, and will not be wrong. The return value of the replacement function is preferably the original function. Otherwise, when it is wrong, the effect of the exe program played by HOOK, injecting the DLL into the Hook program, and pass the ID or global interface to the process you want to hook Hook to query the IAT of the module you want to hook. If you don't inject it, the system will not let you query IAT. What DLL does is to determine which function to be hung and which DLL is in this DLL.