Author: edification (innocent)
MAIL: taoy5178@hotmail.com
OICQ: 24149877 from: Network Technology
In WINDOWS, each process has its own address space, so that an application cannot enter the address space of another process without disrupting the running of another process, this makes the system more stable. However, in this case, operations on processes we are interested in become more complex. For example, we want to create a subclass for the window created by another process or retrieve interesting information from one of the processes that interest us (for example, you want to get the WIN2000 User Logon password ). The DLL injection technology can solve these problems. DLL injection is to insert the DLL into the address space of other processes you specified, so that we can operate on the processes that are interested in.
When our DLL is injected into the specified process space, in order to make it clearer that it has successfully injected to the specified process space, therefore, we need to use a simple tool to view all modules loaded in the specified process space to determine whether our DLL has been successfully injected. If you have a Windows optimization master installed in your system, you can use the process tool provided by it to check whether it does not matter. I wrote a small tool using BCB, although it is not very convenient, however, you can also clearly see all the Loading modules in the specified process space.
The main code of this tool is as follows:
//---------------------------------------------------------------------------
Void _ fastcall TfrmMain: btLookClick (TObject * Sender)
{
DWORD dwProcessId;
BOOL bRet;
MODULEENTRY32 hMod = {sizeof (hMod )};
HANDLE hthSnapshot = NULL;
BOOL bmoremod = FALSE;
ListView-> Clear ();
If (Edit-> Text = "")
Return;
Else
DwProcessId = StrToInt (Edit-> Text );
// Create a snapshot for the Process
HthSnapshot = createconlhelp32snapshot (TH32CS_SNAPMODULE,
DwProcessId );
If (hthSnapshot = NULL)
{
MessageBox (Handle, ("createconlhelp32snapshot failed with error"
+ IntToStr (GetLastError (). c_str (), "Error! ",
MB_ICONINFORMATION + MB_ OK );
Return;
}
// Obtain the modules in the module list
Bmoremod = Module32First (hthSnapshot, & hMod );
If (bmoremod = FALSE)
{
MessageBox (Handle, ("Module32First failed with error"
+ IntToStr (GetLastError (). c_str (), "Error! ",
MB_ICONINFORMATION + MB_ OK );
Return;
}
For (; bmoremod = Module32Next (hthSnapshot, & hMod ))
{
TListItem * Item;
Item = ListView-> Items-> Add ();
Item-> Caption = String (hMod. szExePath );
Item-> ImageIndex = 0;
}
// Close the handle
CloseHandle (hthSnapshot );
}
Next let's start our discussion.
There are three main DLL injection methods: Application HOOK technology, remote thread creation, and trojan DLL.
I. Apply HOOK Technology for DLL Injection
I have previously written an introduction to HOOK. If you have read or previously written a HOOK program, you have already injected such DLL. It installs a hook for the system or a thread. If it is a global hook, your DLL will be loaded into the address space of any called process during the process call, which is a waste of resources. Therefore, in the download demonstration, I only install thread hooks for a specified thread.
1. Use BCB to create a DLL Project (if you are using VC or another project, check it yourself) and enter the following code:
// ================================================ ============================================
// File: UnitLib. cpp
// Description: demonstrate DLL Injection Using Hook Technology.
// Inject the code in this DLL into the specified process space.
// Author: edification (innocent)
// ================================================ ============================================
// Function declaration
Extern "C" _ declspec (dllexport) _ stdcall
Bool SetHook (DWORD dwThreadId );
Extern "C" _ declspec (dllexport) _ stdcall
Lresult callback MyProc (int nCode, WPARAM wParam, LPARAM lParam );
Static HHOOK hHook = NULL; // hook handle
Static HINSTANCE hInst; // The current DLL handle
Int WINAPI DllEntryPoint (HINSTANCE hinst, unsigned long reason, void * lpReserved)
{
HInst = hinst;
Return 1;
}
//---------------------------------------------------------------------------
// Install the hook function
Bool _ declspec (dllexport) _ stdcall SetHook (DWORD dwThreadId)
{
If (dwThreadId! = 0)
{
MessageBox (NULL, ("DLL has been injected! NThreadId = "+
IntToStr (dwThreadId). c_str (), "DLL ",
MB_ICONINFORMATION + MB_ OK );
// Install the hook of the specified Thread
HHook = SetWindowsHookEx (WH_GETMESSAGE, (HOOKPROC) MyProc,
HInst, dwThreadId );
If (hHook! = NULL)
Return true;
} Else
{
MessageBox (NULL, "DLL is about to be withdrawn from the notepad process space! "," DLL ",
MB_ICONINFORMATION + MB_ OK );
Return (UnhookWindowsHookEx (hHook ));
}
Return true;
}
// Hook Function
Lresult callback _ declspec (dllexport) _ stdcall
MyProc (int nCode, WPARAM wParam, LPARAM lParam)
{
// Because it only demonstrates DLL injection, nothing will be done here and it will be handed over to the system for processing.
Return (CallNextHookEx (hHook, nCode, wParam, lParam ));
}
//---------------------------------------------------------------------------
This DLL contains two functions: SetHook and MyProc ). The installation hook function provides a parameter that specifies the thread to install. If this parameter is set to 0, the hook is uninstalled.
Compile the project to generate the DLL file we want to inject to the specified process.
2. Establish a test project. Create an application project with BCB, add two buttons in the form, one for installing thread hooks and the other for uninstalling. The Code is as follows:
//---------------------------------------------------------------------------
// SetHook function prototype Declaration
Typedef BOOL (WINAPI * LPSETHOOK) (unsigned long dwThreadId );
//---------------------------------------------------------------------------
_ Fastcall TfrmMain: TfrmMain (TComponent * Owner)
: TForm (Owner)
{
}
//---------------------------------------------------------------------------
// Install the hook
Void _ fastcall TfrmMain: Button1Click (TObject * Sender)
{
String szPath;
LPSETHOOK lproc;
HANDLE hDll;
BOOL bRet;
PROCESS_INFORMATION info;
STARTUPINFO start;
Memset (& start, 0, sizeof (start ));
// Get the DLL file name to be loaded
SzPath = Application-> ExeName;
SzPath = szPath. SubString (0, szPath. Length ()
-String (StrRScan (szPath. c_str (),). Length ());
SzPath = szPath + "DllLib. dll ";
// Load the DLL
HDll = LoadLibrary (szPath. c_str ());
If (hDll! = &