Vault7: CIA Hacking Tools Revealed
Navigation: » Latest version
Inject Dll From Memory Into A Remote Process (InjectLibraryFromMemory_HYPD - Hyperdermic)
SECRET//NOFORN
OSB Library: Payload Deployment
Module Name: All name information regarding the module to include file name, crypt name, etc.
Module Description: Describe how the technique works. All the cool things it does. Describe how cool the module writer is, etc.
PSP/OS Issues: Any PSP/OS issues associated with the technique.
('excerpt' missing)
Sharing Level: Unilateral, Liaison, Intelligence Community (Default: Unilateral - until otherwise noted)
Technique Origin: In-house, internet/open-source, reversed malware, stolen, etc.
Notes: Any information that could be useful to anyone maintaining the code or using the code. i.e. This module uses Alternate Data Streams which are only available on NTFSNT filesystem (Windows) volumes.
Module Specific Structures: Any module specific data structures. (Any PVOID pvStructs).
Example Code:
INCLUDE DESCRIPTIVE LABELS FOR EACH MODULE
If Miscellaneous Modules were used in the creation of this module, include the tool list excerpt from this page inside the tool list excerpt of each Miscellaneous Module used. For example, if the CreateDirectoryWithAttributes Misc. Module was used, add an "Excerpt Include" macro inside of the Tool List Excerpt on the documentation page for the CreateDirectoryWithAttributes module. The tool list for this module should now always show up in the list of tools that use the CreateDirectoryWithAttributes.
Notes:
InjectLibraryFromMemory and InjectFireAndForgetFromMemory: Since CreateRemoteThread can only be used to call thread functions (i.e., functions that have signatures matching that of THREAD_START_ROUTINE), a workaround was needed to call DLLMain in the remote process in order to implement processAttach() and processDetach(). The loader contains the static, extern "C" function CallDllMain , which is a thread function that accepts a pointer to the CallDllMainArgs struct. The loader fills the fields of the struct with the base address of the remote DLL, the remote address of the entrypoint (DllMain) and the reason for call, then allocates memory and copies both the struct and the function itself into the remote process before calling CreateRemoteThread with pointers to the injected function and injected arguments structure. In order for this technique to work successfully, several compile/link time tricks are used to ensure that the functions are capable of being injected without causing undesirable side effects in the remote process.
In order to calculate the size of the injected function, an empty function (CallDllMain_end) is declared immediately after the actual function, and the size of CallDllMain is calculated by subtracting CallDllMain from CallDllMain_end. To help avoid function reordering, the two functions are stored in their own code segment .text$A.
Additionally, if certain build settings are enabled, the linker may generate a jump table rather than a direct call, which means that the pointers are not to the actual functions but to the entries in the jump table. To avoid this situation, incremental linking must be turned off. Optimizations are also turned off, as are runtime checks, as runtime checks add an additional call to _RTC_CheckEsp at an absolute address to the end of the function that will crash the remote process.
The voodoo required to get these functions to work looks like this:
- // turn off incremental linking -- should force this to *not* use a jump table #pragma comment(linker, "/incremental:no") // turn off optimizations #pragma optimize( "", off ) // turn off pesky runtime checks that add an extra call to _RTC_CheckEsp to the end of our function #pragma runtime_checks( "", off) // put both functions in the same section. as long as there are only two, they should be in order #pragma code_seg( ".text$A" ) extern "C" { // no optimization static DWORD WINAPIWindows Application Programming Interface CallDllMain(PCallDllMainArgs pArgs) { return pArgs->dllMain(pArgs->dllBaseAddress, pArgs->dwReasonForCall, NULL); } static void __stdcall CallDllMain_end() { } }; #pragma code_seg() #pragma runtime_checks ("", restore) #pragma optimize ("", restore)
PSP/OS Issues: List all known issues the technique has with OSs or PSPs
List Of Tools Using This Code:
- ItinerantInterloper v1.0
SECRET//NOFORN