Three methods for performing DLL injection
Author: cultivate (innocent)
Mail:
TAOY5178@hotmail.com
OICQ: 24149877
In Windows, each process has its own independent address space, such an application cannot enter the address space of another process without damaging the operation of another process, which makes the system more stable. But in this way, if we have to operate the process we are interested in, it makes complicated. For example, we have to create a subclass for a window created by another process or want to get some interesting information from one of the interested processes (such as the password you want to get the Win2000 user login). And DLL injection technology is just to solve these problems. The DLL injection is to insert the DLL into the address space of the process you specify, so that we can operate the process of interest.
When our DLL is injected into the specified process space, in order to make us more clearly see that it has successfully implanted the specified process space, we need to use a simple tool to view the specified process space. All modules entered in order to determine if our DLL has been successfully injected. If you have a Windows Optimization Master, you can use the process tools it provides to view, no relationship, I wrote a gadget with BCB, although it is not convenient, but you can clearly see the specified process space All load modules in the middle.
The main code of the tool is as follows:
/ / -------------------------------------------------------------------------------------------- ---------------------------
Void __fastcall tfrmmain :: btlookclick (TOBJECT * SENDER)
{
DWORD DWPROCESSID;
BOOL BRET;
ModuleEntry32 HMOD = {SizeOf (HMOD)};
Handle hthsnapshot = NULL;
Bool bmoremods = false;
Listview-> clear ();
IF (edit-> text == ")")
Return;
Else
DWPROCESSID = STRTOINT (Edit-> Text);
/ / Establish a snapshot for the process
Hthsnapshot = CreateToolhelp32Snapshot (TH32CS_SNAPMODULE,
DWProcessID);
IF (hthsnapshot == null)
{
MessageBox (Handle, "" CreateToolhelp32Snapshot Failed with Error "
INTSTOSTR (GetLastError ())). C_str (), "Error!",
MB_ICONINFORMATION MB_OK);
Return;
}
/ / Get the module in the module list
Bmoremods = module32first (hthsnapshot, & hmod);
IF (Bmoremods == False)
{
MessageBox (Handle, "" Module32First Failed with Error "
INTSTOSTR (GetLastError ())). C_str (), "Error!",
MB_ICONINFORMATION MB_OK);
Return;
}
For (; bmoremods; bmoremods = module32next (hthsnapshot, & hmod))
{
TLISTITEM * ITEM;
Item = listview-> items-> add ();
Item-> caption = string (hmod.szexepath);
Item-> imageIndex = 0;
}
// Close the handle
CloseHandle (hthsnapshot);
}
Let's start our topic next.
There are three main methods of DLL injection, namely, the application hook technology, create three types of remote threads and Troy DLL.
First, use hook technology for DLL injection
I have written a introduction about Hook. If you have read or write the Hook program before, then you have injected this DLL. It is other of the installation of a hook for the system or a thread. What to say here is that if it is a global hook, your DLL will load to any address space of any calling process when the process is called, which is a fair resource. So I only install thread hooks for a specified thread in the downloaded demo.
1. Create a DLL project with BCB (if you use VC or others, please contact yourself), enter the following code:
/ / =========================================================================================================================================================================================== ===========================
// File: unitlib.cpp
// Description: Demonstration DLL injection by hook technology.
// Inject the code in this DLL into the specified process space.
// Author: cultivate (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; // 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 ="
INTOSTR (DWTHREADID)). C_str (), "dll",
MB_ICONINFORMATION MB_OK);
/ / Install the hook of the specified thread
HHOOK = SETWINDOWSHOKEX (WH_GetMessage, (HookProc) MyProc,
Hinst, dwthreadid;
IF (hHOOK! = null)
Return True;
Else
{
MessageBox (NULL, "DLL is about to withdraw from 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 is just a demonstration of DLL injection, so there is nothing here, handed over to system processing.
Return (CallNexthooKex (HHOOK, NCODE, WPARAM, LPARAM);
}
/ / -------------------------------------------------------------------------------------------- ---------------------------
There are two functions in this DLL, one for installing the hook function (SETHOOK), and the other is a hook function (MyProc). Where the mounting hook function provides a parameter, which thread is installed by this parameter, if the parameter is 0, unload the hook.
Compile this project, that is, the generation we want to use the DLL file in the specified process.
2. Establish a test project. Establish an application engineering with BCB, add two buttons to the form, one for installing the thread hook, one for uninstall. code show as below:
/ / -------------------------------------------------------------------------------------------- ---------------------------
// sethook function prototype declaration
TypedEf Bool (WinAPI * LPSETHOK) (UNSIGNED Long Dwthread);
/ / -------------------------------------------------------------------------------------------- ---------------------------
__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 name of the DLL file to be loaded
Szpath = Application-> Exename;
szpath = szpath.substring (0, szpath.length ()
- strring (Strrscan (szpath.c_str (), '//')). Length ());
Szpath = szpath "//dllib.dll";
/ / Load DLL
HDLL = loadingLibrary (szpath.c_str ());
IF (HDLL! = NULL)
{
Lproc = (lpsethook) GetProcaddress (HDLL, "STHOK");
IF (lproc! = NULL)
{
// Because there is no appropriate tool to get the thread ID, it is also necessary to simply start, so a notepad process is created here so that its thread ID is installed, and the hook is installed, and our DLL is injected into the notepad process.
Bret = CREATEPROCESS (NULL,
"c: //winnt//system32//notepad.exe",
NULL,
NULL,
True,
0,
NULL,
NULL,
& Start,
& info);
IF (Bret! = 0)
{
IF ((* LPROC) (Info.dwthreadID) == false)
ShowMessage ("STHOOK FAILED with ERROR"
INTTOSTR (GetLastError ()));
}
Else
{
ShowMessage ("CreateProcess Failed with Error"
INTTOSTR (GetLastError ()));
}
}
}
}
/ / -------------------------------------------------------------------------------------------- ---------------------------
// Uninstall the hook
Void __fastcall tfrmmain :: Button2Click (TOBJECT * SENDER)
{
String szpath;
LPSETHOOK LPROC;
Handle HDLL;
Szpath = Application-> Exename;
szpath = szpath.substring (0, szpath.length ()
- strring (Strrscan (szpath.c_str (), '//')). Length ());
Szpath = szpath "//dllib.dll";
HDLL = loadingLibrary (szpath.c_str ());
IF (HDLL! = NULL)
{
Lproc = (lpsethook) GetProcaddress (HDLL, "STHOK");
IF (lproc! = NULL)
(* LPROC) (0);
}
}
/ / -------------------------------------------------------------------------------------------- -------------------------- Next to generate an executable, click on the first installation hook button, then you can use us to start Write the tool tool to see the tool to view, you will see the path and file name you just have DLL in the module, indicating that we have successfully inject your DLL into the memory of Notepad. After clicking the uninstall button, check the module in the notepad process, will not see the full file name of our DLL file, indicating that the injection of the notepad process has been successfully revoked.
Second, use the remote thread to perform DLL injection
This method is more complicated as compared with the previous method, and this method can only be used in Win2000 (XP, and the latest 2003 do not know). Specific steps are as follows:
1) Take the process ID of the remote process;
2) Assign a memory in the remote process space to store the DLL full path to the injected;
3), write the path to the DLL to be injected to the remote process space you just allocated;
4), get the address of LoadLibray from kernel32.dll;
5), call the CREATEREMOTETHREAD function to create a remote thread with the address of the thread function from the address of the LoadLibrary function obtained from the Kernel32.dll, and creates a remote thread;
In the second step, why should we write the file name of the DLL we have to be injected to the address space of the remote process, "Windows Core Programming" is described in this:
"(To the DLL file name to be injected) The string is in the address space of the calling process. The address of the string has been given a newly created remote thread, which transmits it to the L Oadl Ibrary A. However, when L OAD L IBRARY A Cancels the reference to the memory address, the DLL path name string will no longer exist, the thread of the remote process may cause access violations. "
As for why the LoadLibrary is called directly in the fourth step, "Windows Core Programming" is described in this:
"If you use a direct reference to L OAD L Ibrary A in the call to C Reate R Emote T Hread, this will convert the address of the Ibrary A of L OAD L Ibrary A in the input of the C Reate R Emote T Hread. The address of the replacement program is passed as the start address of the remote thread, which will cause the remote thread to start performing some inexplicable things. The result is likely to cause access to violations. "
Ok, let's start our example below.
1. To apply HOOK to DLL injection, let's create a DLL project first, this DLL can not write any code, because we just want to inject DLL to the specified process to achieve the purpose, but for the best, I still just casually Write an API function. code show as below:
Extern "C" __DECLSPEC (DLLEXPORT) __stdcall void About ();
Int WinApi DLLENTRYPOINT (Hinstance Hinst, Unsigned Long Reason, Void * LPRESERVED)
{
Return 1;
}
/ / -------------------------------------------------------------------------------------------- ---------------------------
Void __declspec (dllexport) __stdcall about () {
MessageBox (NULL, "this DLL module demonstrates the injection technology of DLL ./N"
"Inject this module into the specified" Call LoadLibrary "
"The address space of the process.", "DLL injection technology",
MB_ICONINFORMATION MB_OK);
}
Compiling it, you get the DLL file we use to be injected. Next is the test engineering.
2, write test projects. Establish an application engineering with BCB, put two buttons in the form, one to inject, one to undo, and another text box control, used to wait for the user to enter the process ID number. code show as below:
/ / -------------------------------------------------------------------------------------------- ---------------------------
// DLL injection function
Bool Winapi LoadLib (DWord DWProcessid, LPWSTR LPSZLIBNAME)
{
Handle HProcess = NULL,
hthread = null;
LPWSTR LPSZREMOTEFILE = NULL;
/ / Open a remote process
HProcess = OpenProcess (Process_create_thread
| Process_vm_operation
| Process_vm_write,
False,
DWProcessID);
IF (hprocess == null)
{
MessageBox (NULL, "" OpenProcess Failed with Error "
INTSTOSTR (GetLastError ())). C_str (), "error",
MB_ICONINFORMATION MB_OK);
Return False;
}
/ / Assign space in the remote process to store the DLL file name
Lpszremotefile = (LPWSTR) VirtualaLalkEx (HProcess, NULL,
Sizeof (Wchar) * lstrlenw (lpszlibname) 1,
MEM_COMMIT, PAGE_READWRITE
IF (lpszremotefile == NULL)
{
Messagebox (NULL, "" VirtualaLallocex Failed with Error "
INTSTOSTR (GetLastError ())). C_str (), "error",
MB_ICONINFORMATION MB_OK);
Return False;
}
/ / Copy the DLL file name to the remotely allocated process space
IF (! WriteProcessMemory (HProcess, Lpszremotefile,
(PVOID) LPSZLIBNAME, SIZEOF (WCHAR) * LSTRLENW (LPSZLIBNAME) 1,
NULL))
{
Messagebox (NULL, "" WriteProcessMemory Failed with error "
INTSTOSTR (GetLastError ())). C_str (), "error",
MB_ICONINFORMATION MB_OK);
Return False;
}
/ / Get the address of the LoadLibrary function in Kennel32.dll
Pthread_start_routine pfnthreadrtn =
(Pthread_start_routine) getProcadDress ("kernel32.dll"), "loadLibraryw";
IF (pfnthreadrtn == NULL)
{
Messagebox (NULL, "" GetProcaddress Failed with Error "
INTSTOSTR (GetLastError ())). C_str (), "error",
MB_ICONINFORMATION MB_OK);
Return False;
}
// Create a remote thread
hthread = CreateremoteThread (HProcess,
NULL,
0,
PFNTHREADRTN, / / LOADLIBRARY address
Lpszremotefile, // To load the DLL name
0,
NULL);
IF (hthread == null)
{
MessageBox (Null, "" CreateRemoteThread Failed with error "
INTSTOSTR (GetLastError ())). C_str (), "error",
MB_ICONINFORMATION MB_OK);
Return False;
}
// Waiting for the thread to return
WaitforsingleObject (hthread, infinite);
/ / Release the memory in the process space
VirtualFreeex (HProcess, Lpszremotefile, 0, MEM_RELEASE);
// Close the handle
CloseHandle (HTHREAD);
CloseHandle (HPROCESS);
Return True;
}
// Release the injected DLL in the process space
Bool WinApi Freeelib (DWord DWProcessid, LPTSTR LPSZLIBNAME)
{
Handle HProcess = NULL,
hthread = NULL,
Hthsnapshot = null;
ModuleEntry32 HMOD = {SizeOf (HMOD)};
Bool bfound;
/ / Get all module images of the specified process
Hthsnapshot = CreateToolhelp32Snapshot (TH32CS_SNAPMODULE,
DWProcessID);
IF (hthsnapshot == null)
{
MessageBox (Null, "" CreateRemoteThread Failed with error "
INTSTOSTR (GetLastError ())). C_str (), "error",
MB_ICONINFORMATION MB_OK);
Return False;
}
/ / Get the specified module in all module lists
Bool Bmoremods = Module32First (hthsnapshot, & hmod);
IF (Bmoremods == False)
{
MessageBox (NULL, "" Module32First Failed with Error "
INTSTOSTR (GetLastError ())). C_str (), "error",
MB_ICONINFORMATION MB_OK);
Return False;
}
/ / Loop to get the desired module
For (; bmoremods; bmoremods = module32next (hthsnapshot, & hmod) {
//ShowMessage (String (HMod.szeExepath) "|" string (lpszlibname);
IF ((hmod.szexepath, lpszlibname) == 0) ||
(hmod.szmodule, lpszlibname) == 0)))
Break;
}
// Open the process
HProcess = OpenProcess (Process_create_thread | Process_VM_OPERATION,
False, dwprocessid;
IF (hprocess == null)
{
MessageBox (NULL, "" OpenProcess Failed with Error "
INTSTOSTR (GetLastError ())). C_str (), "error",
MB_ICONINFORMATION MB_OK);
Return False;
}
// Get the address of the FreeELibrary function in kernel32.dll
Pthread_start_routine pfnthreadrtn =
(Pthread_start_routine) getProcAddress
GetModuleHandle ("kernel32.dll"), "freelibrary");
IF (pfnthreadrtn == NULL)
{
Messagebox (NULL, "" GetProcaddress Failed with Error "
INTSTOSTR (GetLastError ())). C_str (), "error",
MB_ICONINFORMATION MB_OK);
Return False;
}
// Create a remote thread to execute the FreElibrary function
hthread = CreateremoteThread (HProcess,
NULL,
0,
PfnthreadRTN,
HMOD.MODBASEADDR,
0,
NULL);
IF (hthread == null)
{
MessageBox (Null, "" CreateRemoteThread Failed with error "
INTSTOSTR (GetLastError ())). C_str (), "error",
MB_ICONINFORMATION MB_OK);
Return False;
}
// Waiting for the thread to return
WaitforsingleObject (hthread, infinite);
// Close the handle
CloseHandle (HTHREAD);
CloseHandle (hthsnapshot);
CloseHandle (HPROCESS);
Return True;
}
/ / -------------------------------------------------------------------------------------------- ---------------------------
Void __fastcall tfrmmain :: btloadClick (Tobject * Sender)
{
m_szdllfile = Application-> Exename;
m_szdllfile = m_szdllfile.substring (0, m_szdllfile.length ()
- String (STRRSCAN (m_szdllfile.c_str (), '//')). Length ()); m_szdllfile = m_szdllfile "//dllib.dll";
m_dwprocessid = start (edit-> text);
LoadLib (m_dwprocessid, wideString (m_szdllfile) .c_bstr ());
}
/ / -------------------------------------------------------------------------------------------- ---------------------------
Void __fastcall tfrmmain :: btunloadClick (TOBJECT * SENDER)
{
Freelib (m_dwprocessid, m_szdllfile.c_str ());
}
/ / -------------------------------------------------------------------------------------------- ---------------------------
Ok, build the above engineering to synthesize the EXE file, then we can test the DLL injection test. Open the notepad first (of course you can also open other processes, or directly in the already loaded process), find its process ID through the Windows Task Manager. Then run our test project, enter the process ID in the text box, click Inject. At this time, we can view the modules included in its process space through our most write gadgets, and you will find that our DLL has successfully loaded into its process space. Click Uninstall to cancel the DLL injection.
Third, use Troy DLL to inject
The principle of this method is to write a DLL that has the same interface function called with the original process, and replaces the original DLL with our DLL. In the replacement process, the function of the interested function is replaced by the function of interest, and the function that is not interested in, the function is called in the form of the original DLL in the form of function. There is a premise this that you must know which functions in the original DLL are written in writing, so that the corresponding API function cannot be found when the DLL is called to call the DLL, especially when replacing the system DLL file. be careful.
Let's demonstrate this way. I did this, first write a DLL as the replaced DLL, named DLLLIB.DLL (last renamed _dllib.dll), then written Troy DLL, named Troydll.dll (finally named original DLL name, That is, DlliB.dll, which has the same API function process as DllLib.dll, but makes changes to one of the API functions, because there is another API function to function forward, transfer The original DLL, ie (renamed _dllib.dll's dlliB.dll). At this time, our test program was originally called DLLLIB.dll, but because the dlliB.dll has been replaced by Troydll.dll, the test program actually calls Troydll.dll, and for forwarding functions, it passes Troydll.dll calls DLLLIB.DLL (renamed _dllib.dll) is done. At this point, our Troj DLL actually injects the process space of our test program.
1. Write the original DLL. The code of DlliB.dll (renamed after _dllib.dll) is as follows:
/ / =========================================================================================================================================================================================== =========================== // file: unitlib.cpp
// Description: Demonstrates DLL injection with Troy DLL. This is the DLL of its own, another Troy DLL will
// For function forwarding and implement additional functions.
// Author: cultivate (innocent)
/ / =========================================================================================================================================================================================== ===========================
// Function declaration
Extern "C" __DECLSPEC (DLLEXPORT) __stdcall void About ();
Extern "C" __DECLSPEC (DLLEXPORT) __stdcall Int Add (Int A, INT B);
Int WinApi DLLENTRYPOINT (Hinstance Hinst, Unsigned Long Reason, Void * LPRESERVED)
{
Return 1;
}
/ / -------------------------------------------------------------------------------------------- ---------------------------
Void __declspec (dllexport) __stdcall about ()
{
Try
{
Messagebox (null, "This is the original DLL file!", "The original DLL",
MB_ICONINFORMATION MB_OK);
} catch (Exception & E)
{
MessageBox (null, e.Message.c_str (), "dllib", mb_ok);
}
}
// Dual plus (note: here is two numbers)
INT __DECLSPEC (DLLEXPORT) __STDCALL Add (int A, int b)
{
Return (A B);
}
2. Write Troj DLL. The code of Troydll.dll is as follows:
/ / =========================================================================================================================================================================================== ============================ // file: unittroy.cpp
// Description: This is Troy DLL, and it will change its DLL file to the DLL file name to be replaced.
// Author: cultivate
/ / =========================================================================================================================================================================================== ===========================
Extern "C" __DECLSPEC (DLLEXPORT) __stdcall void About ();
Extern "C" __DECLSPEC (DLLEXPORT) __stdcall Int Add (Int A, INT B);
Int Multiply (Int A, INT B);
Progress Statement in // DLL
TypeDef void (WinAPI * about) ();
TypeDef Int (WinAPI * Add) (Int A, INT B);
STATIC STRING SZDLLNAME;
Int WinApi DLLENTRYPOINT (Hinstance Hinst, Unsigned Long Reason, Void * LPRESERVED)
{
Szdllname = Application-> Exename;
Szdllname = szdllname.substring (0, szdllname.length ()
- strrs (SZDLLNAME.C_STR (), '//')). Length ());
// Demname after DlliB.dll file name
szdllname = szdllname "//_dllib.dll";
Return 1;
}
/ / -------------------------------------------------------------------------------------------- ---------------------------
Void __declspec (dllexport) __stdcall about ()
{
/ / Direct function forwarding
Handle HDLL = NULL;
HDLL = loadingLibrary (szdllname.c_str ());
About about;
Try
{
IF (HDLL! = NULL)
{
About = (About) GetProcaddress (HDLL, "About"); if (About! = NULL)
About ();
}
Else
MessageBox (NULL, "loaded into the original DLL error!", "Troy DLL",
MB_ICONINFORMATION MB_OK);
} catch (Exception & E)
{
MessageBox (null, e.Message.c_str (), "dlltroy", MB_OK);
}
}
INT __DECLSPEC (DLLEXPORT) __STDCALL Add (int A, int b)
{
int NRET;
Handle HDLL = NULL;
Add add;
HDLL = loadingLibrary (szdllname.c_str ());
IF (HDLL! = NULL)
{
// For the convenience of demonstration, you will do a function forwarding in order to see the value that should return.
Add = (add) getProcadDress (HDLL, "Add");
IF (add! = null)
NRET = Add (a, b);
ShowMessage ("This is the call result in the DLL:" INTOSTR (NRET));
}
Else
MessageBox (NULL, "loaded from the original DLL error!", "Troy DLL", MB_OK;
// The original completion of the two additions is multiplied by two numbers, returning two numbers.
NRET = MULTIPLY (A, B);
Return nret;
}
Int Multiply (Int A, INT B)
{
Return (a * b);
}
3, write test projects. Add two buttons to the form, call two API functions in DLLLLIB.DLL, respectively. code show as below:
TYPEDEF (WinAPI * about) ();
TypeDef Int (WinAPI * Add) (Int A, INT B);
/ / -------------------------------------------------------------------------------------------- ---------------------------
__fastcall tfrmmain :: TfrmMain (Tcomponent * Owner)
: TFORM (OWNER)
{
}
/ / -------------------------------------------------------------------------------------------- ---------------------------
Void __fastcall tfrmmain :: formcreate (TOBJECT * Sender)
{
m_szdllname = Application-> Exename;
m_szdllname = m_szdllname.substring (0, m_szdllname.length ()
- Strier (STRRSCAN (m_szdllname.c_str (), '//')). Length ());
m_szdllname = m_szdllname "//dllib.dll";
}
/ / -------------------------------------------------------------------------------------------- ---------------------------
// Call the About () function
Void __fastcall tfrmmain :: Button1Click (Tobject * Sender)
{
Handle HDLL;
About about;
Try
{
HDLL = loadingLibrary (m_szdllname.c_str ());
IF (HDLL! = NULL)
{
About = (About) GetProcaddress (HDLL, "About");
IF (About! = null)
About ();
}
} catch (Exception & E)
{
MessageBox (Handle, E.MESSAGE.C_STR (), "Error", MB_OK;
}
}
/ / -------------------------------------------------------------------------------------------- ---------------------------
// Call the Add () function
Void __fastcall tfrmmain :: Button2Click (TOBJECT * SENDER)
{
Handle HDLL;
Add add;
int NRET;
HDLL = loadingLibrary (m_szdllname.c_str ());
IF (HDLL! = NULL)
{
Add = (add) getProcadDress (HDLL, "Add");
IF (add! = null)
NRET = Add (10, 2);
SHOWMESSAGE ("The result returned from Troj DLL:" INTSTOSTR (NRET));
}
}
4, test. Renamed DlliB.dll to _dllib.dll, rename the Troydll.dll to DLLLIB.DLL, which completes the DLL replacement. Let's run our test engineering below, click the button called the reference () function, because About () is forward (transfer to the original DLL, ie_dllib.dll) through DLLLIB.DLL (ie Troydll.dll). So see the information box that is played in the original DLL (ie_dllib.dll). At this point, you will find the process space with the tool to view the process module, you will find that your Troy DLL (renamed DlliB.dll) has successfully in the process space of the test program.
Click the button to call the add () function, you will see that it is completed, the result of the return is two, because we have already made a hands and feet in Troy DLL. This is the key to using it. Gina, know when Windows is logged in, do you want to get the password you log in? Then use this method, put the msgina.dll this thing to it into your own DLL, and the complex password is still sampled, and it is not a spirit, huh, huh ~. (If you want yourself? Take a look "Winlogon Login Management and Gina Introduction"
surroundings:
Win2000 Server BCB 6.0
Attached: this article related program code
Reference: "Windows Core Programming"
==============================================
I have written it for a long time, I haven't sent it out ~~~~ Hehe ~~~~, there is something wrong, welcome everyone to correct ~~