DLL redirection
Because the search path for the DLL is sequential, let's say that there are scenarios like this:
App1.exe uses Mydll1.0.dll, App2.exe uses Mydll2.0.dll, MyDll1.0 and MyDll2.0 are two versions of the same DLL, 1.0 for the old version, and 2.0 for the new version.
If the priority of the Mydll2.0.dll's storage path is higher, then App1.exe will load the Mydll2.0.dll, which could cause
DLL is a hell of a problem, so DLL redirection solves this problem.
The loader always checks the application directory first, and all we have to do is to do the following:
① in the application directory, the new appname.local file, the file content does not matter, such as App1.exe, the corresponding file name is App1.exe.local.
② in the application directory, the new appname.local directory, the use of DLLs are placed in this directory, such as App1.exe, the corresponding directory is App1.exe.local.
Note: This feature is turned off by default in Windows and needs to be
Hkml\software\microsoft\windowsnt\currentversionimag\image a new entry in the File execution Options Registry,DWORD Devoverrideenable, the value is 1.
Relocation of the base site of the module
Each EXE and DLL has a "preferred base address", when the system creates the process address space for EXE, the EXE is loaded into the address space of the process, the default is 0x004000000;
When the loader loads the DLL into the process address space, see DLL loaded to its preferred and address, DLL defaults to 0x10000000.
You can also set the "base Address" of the module in the project properties of VS: Project Properties--Configuration Properties--linker--advanced--base addresses;
You can use the VS command dumpbin to view it, or you can use depend to view it.
e.g.
Dumpbin/headers ADll.dll
Compilers and connectors hard-code The addresses of "global variables" and "static variables" when generating code, such as code
//Global VariablesintG_num =0;voidCuseadll2dlg::onbnclickedbutton4 () {G_num=0x04030201; //Local Variables intnum =0; Num=0x01020304; //Static Local Variables int StaticS_num =0; S_num=0x02030401;}
Its corresponding disassembly code is as follows:
You can see that the addresses of "global variables" and "Static variables" are hard-coded, while local variables are not.
The exported segment of the DLL has the RVA (relative virtual address) of the symbol (variable, function), when the DLL is loaded into the process address space,
The address of the symbol in the process address space = DLL base site + RVA;
A.DLL and B.DLL's preferred base sites are 0x10000000, So when A.DLL is loaded to this address in the process address space, B.DLL cannot be loaded to this address, at which point the B.DLL needs to be relocated, and the addresses of global variables and static variables in the DLL need to be recalculated using the new base address.
Assuming that B.DLL is loaded into 0x20000000, then the address of the global and static variables in the DLL needs to be recalculated, and the following actions are required:
The ① loader must traverse the relocation segment and modify a large amount of code in the module, which can result in a performance penalty.
② when the loader writes to the code page of the module, the system's "copy-on-write" (Copy-on-wirte) mechanism forces these pages to use the system's "paging file" as the fallback memory, which results in swap-out of memory pages, which is a loss to performance.
Create an EXE or DLL that does not contain a "relocation segment"
The "/fixed" option is performed in the connector option for VS, which can make the module smaller, but fails to load if it cannot be loaded to its preferred base address.
For a "resource DLL", which does not contain any code, it is reasonable to use the/fixed switch and embed some information in the header of the file (the book is not exactly what information, how to embed it?). ) to indicate that it is reasonable not to include a relocation segment.
Create an image that does not contain any relocation information
①/subsystem:windows or/subsystem:console
② do not specify/fixed switch
③ turn off the "image_file_relocs_stripped" flag in the file header
VS provides a tool for static relocation of DLLs used by a module, Rebase.exe
The reposition tool can also be implemented by invoking the Rebaseimage function provided by the Imagehlp API.
e.g.
Two DLLs are used in the USEDLL3 program, ADll.dll and BDll.dll
StdAfx.h of the USEDLL3 project
#pragma comment (lib, "ADll.lib") #pragma comment (lib, "BDll.lib") extern c __declspec (dllimport) int __stdcall Add (int A, int b); extern " " __declspec (dllimport) int __stdcall Multi (int A , int b);
DLL dependencies seen in depends
The preferred base address for both
Now use the Rebase tool to reposition the UseDll3 module
How to use rebase order?? Not to be continued
What the rebase does
① simulation creates a process address space
② Open all modules that should be loaded, get "size" and "preferred base address" for each module
③ simulation of the module relocation process in the simulated address space, so that the module does not overlap
④ for each relocated module, parses its "relocation segment" and modifies the module's code in the disk file
⑤ change the file header of each relocated module to update its "preferred base address"
Binding of modules
VS provides the Bind.exe tool for binding, or it can be implemented using the Bindmageex () function.
After repositioning the module, simply modifying its preferred base address, the loader also needs to write the "import symbols" virtual addresses to the "import segment" of the EXE module at run time, which also causes these pages to be "paging files" as backup memory, and also a performance penalty for memory paging.
and the module binding, is the "Export section" of each DLL "base address +rva", write the EXE module "import segment", and update the DLL header information, tell the system this module has been bound, when the EXE to create the process address space, You do not need to dynamically get the virtual address of the symbol to write to the EXE import segment, but directly from the EXE "import segment" to read.
Note:
The Bind.exe is based on two assumptions:
①dll are loaded into their "preferred base site" and can be rebase to ensure
When the ② binding is complete, the symbol position referenced in the DLL "Export segment" has not changed. The loader verifies the timestamp of each DLL by checking it.
When the loader detects that any hypothesis is not set, then the loader must follow the previous look to fix the EXE's "import segment", if the loader detects that two assumptions are set up, then no longer relocate, and no longer view the virtual address of the import function.