Skip to content

LoadLibrary control flow redirection POC reverse-engineered from Turla’s Kazuar v3 loader.

License

Notifications You must be signed in to change notification settings

TheEnergyStory/LoadLibraryControlFlowRedirection

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 

Repository files navigation

LoadLibraryControlFlowRedirection

This is a Proof of Concept (POC) of a control-flow redirection trick for a DLL loaded via LoadLibraryA. While theoretically possible whenever a DLL is loaded via LoadLibrary, this specific technique was observed in the Turla Kazuar v3 loader during its abuse of MFC satellite DLL loading. It's also possible to use the technique for a DLL loaded via LoadLibraryW or LoadLibraryExA/W with some modificat ions.

When the DLL loader invokes LoadLibraryA, the malware initiates a sequence to "hook" the return path by first locating a proximal reference address to resolve the final target address to redirect to within its code. It then performs a stack walk to identify the return address of the LoadLibraryExW caller (within LoadLibraryExA as LoadLibraryA -> LoadLibraryExA -> LoadLibraryExW). After preserving the original instructions at this address for later restoration, the malware patches them with a call to its target address.

When the DLL execution seems to have ended and control is passed back to the original DLL loader, it triggers the hook and "jumps" back to the DLL for further code execution. Once the execution flow is successfully captured, the malware immediately restores the original bytes in LoadLibraryExA, erasing evidence of the hook and allowing the DLL to proceed with its execution.

The POC was tested on Windows 10 Version 22H2 (Build 19045.6691)

Details

The technique, in case the DLL was called via LoadLibraryA by the loader, works as follows:

  1. Locate Proximal Address: Get a proximal address as a reference that is near the final target address.
  2. Resolve Final Target: Use the near target address to search for the actual target address to which the control flow will be redirected.
  3. Stack Walk for Return Address: Walk the stack to find the return address of the LoadLibraryExW caller (located in LoadLibraryExA). This return address is pushed to the stack during the sequence: LoadLibraryA (called by the DLL loader) -> LoadLibraryExA -> LoadLibraryExW.
  4. State Preservation: Backup the original instructions at the identified return address in LoadLibraryExA to ensure the code can be restored later.
  5. Control Flow Hijack (Hook): Patch the bytes at the return address with a call to the target address. When the system thinks the DLL loading is finished and tries to return to LoadLibraryA, it instead triggers a "second run" of the target code.
  6. Restoration (Unhook): Once the redirection has successfully captured the execution flow, write the saved original bytes back to LoadLibraryExA to remove the evidence of the hook and restore original functionality.
  7. Payload Execution: With the control flow successfully hijacked and the hooks cleaned up, the DLL can proceed to run its logic.

When the execution of the DLL seems to have already ended and control is passed back to the DLL loader, or more precisely LoadLibraryA, it jumps back to the DLL's code.

Usage

To execute the POC DLL, we utilize the legitimate printer driver installer hpbprndi.exe (SHA-256: 34b7df7919dbbe031b5d802accb566ce6e91df4155b1858c3c81e4c003f1168c) from Hewlett-Packard (MFC application) as the loader. By renaming the POC DLL to hpbprndiLOC.dll and placing it in the same directory as hpbprndi.exe, we abuse the MFC satellite DLL loading mechanism.

To observe the successful hijack and subsequent execution of the redirection trick, DebugView is used to capture the POC's debug output.

Finally, we execute hpbprndi.exe and get the following output:

[17636] 1. Get address near target address
[17636] 2. Search for target address
[17636] [*] Making memory snapshot...
[17636] [*] Scanning memory snapshot for opcode sequence 0x50 0x56 (PUSH RAX, PUSH RSI)...
[17636] [+] Signature 0x50 0x56 found in snapshot.
[17636] [*] Target address: 0x7FFB5D9422F1
[17636] 3. Get return address of LoadLibrary... call for hooking
[17636] [*] Resolving debug helper addresses...
[17636] [+] Resolved functions SymFunctionTableAccess64 and SymGetModuleBase64.
[17636] [*] Capturing execution context...
[17636] [+] RtlCaptureContext succeeded.
[17636] [*] Initializing symbol handler...
[17636] [+] SymInitialize succeeded.
[17636] [*] Walking the stack...
[17636] [*] RetAddr: 0x7FFB5D942030 -> Symbol: <Unknown>
[17636] [*] RetAddr: 0x7FFB5D9425FB -> Symbol: <Unknown>
[17636] [*] RetAddr: 0x7FFB94A49A1D -> Symbol: <Unknown>
[17636] [*] RetAddr: 0x7FFB94A9D2F7 -> Symbol: RtlActivateActivationContextUnsafeFast
[17636] [*] RetAddr: 0x7FFB94A9D08A -> Symbol: LdrGetProcedureAddressEx
[17636] [*] RetAddr: 0x7FFB94A6D947 -> Symbol: LdrGetProcedureAddressEx
[17636] [*] RetAddr: 0x7FFB94A4FBAE -> Symbol: RtlSwitchedVVI
[17636] [*] RetAddr: 0x7FFB94A473E4 -> Symbol: RtlGetFullPathName_UstrEx
[17636] [*] RetAddr: 0x7FFB94A46AF4 -> Symbol: RtlDosPathNameToNtPathName_U
[17636] [*] RetAddr: 0x7FFB9277DB72 -> Symbol: LdrLoadDll
[17636] [*] RetAddr: 0x7FFB92776AF1 -> Symbol: LoadLibraryExW
[17636] [+] Found target LoadLibrary return address.
[17636] [*] Cleanup symbol handler...
[17636] [+] SymCleanup succeeded.
[17636] 4. Save original bytes at return address of LoadLibrary... call
[17636] [*] Allocating temporary and final buffers...
[17636] [*] Saving original bytes to temporary buffer...
[17636] [*] Saving original bytes to final buffer...
[17636] [+] Successfully saved original bytes.
[17636] 5. Hook bytes at return address of LoadLibrary... call
[17636] [+] Successfully patched bytes at target address.
[17636] 6. Unhook bytes at return address of LoadLibrary... call
[17636] [+] Successfully restored original saved bytes.
[17636] [!] Hello from main redirect function!

While this specific scenario uses a legitimate application that uses LoadLibraryA to load the DLL, the technique is universally applicable to any DLL loader that utilizes the same API function.

Background

This POC is based on an in-depth analysis of the Turla Kazuar v3 loader, the details of which can be found here: https://r136a1.dev/2026/01/14/command-and-evade-turlas-kazuar-v3-loader/

Disclaimer

This project is for educational and authorized security research purposes only. The techniques demonstrated are intended to help defenders understand advanced evasion tactics and improve detection telemetry. Use against unauthorized systems is strictly prohibited.

About

LoadLibrary control flow redirection POC reverse-engineered from Turla’s Kazuar v3 loader.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published