Regin: Static Analysis of Its Lightweight VFS Abstraction Layer
Regin:
Static Analysis of Its Lightweight VFS Abstraction Layer
Polymorphic Kernel Interfaces and I/O Abstraction Layer
“To
understand the immeasurable, the mind must be extraordinarily quiet, still.”
— Jiddu Krishnamurti
Seeker(李标明) · @clibm079
China · Independent Malware Analyst &
Researcher
From
2025.9.24 to 2025.10.14
Prologue: The Temple and the Kernel
Recently, I still
climbed a mountain and visited the temple again, but only a few times;
sometimes, I go hiking in the forests. Here, I keep moving on malware research.
I notice that quite sophisticated malware Regin, between 2014 and 2015,
Symantec and Kaspersky published their report of analysis.
According to a
Symantec report, “Regin is a multi-staged, modular threat, meaning that it has
a number of components, each depending on others, to perform attack
operations.”
In this report, I
would like to do and share limited analysis without getting all components. I
was very curious and interested in the VFS design uncovered by the Symantec and
Kaspersky report; it needs “stage 2” to run “stage 3,” so personally I just
tended to do simple static analysis about the driver named VMEM.sys, which is
on stage 3. Table 2 is shown as follows.
Figure
1: Table 2 from Symantec’s report.
The following limited analysis
about “Virtual file system (VFS) access manager” was done in my own way.
Sample choice: Regin
NAME: Stage 3 is internally known
as VMEM.sys
MD5:
8486ec3112e322f9f468bdea3005d7b5
Static analysis
The
Concept of VFS
I think we need to know what’s VFS first before staring
static analysis. When we say VFS (Virtual File System)
in the context of drivers or operating systems, we’re not talking about a
“virtual machine file type” like a .vmdk
or .vdi
.
Instead:
·
VFS = Virtual File System
It’s an abstraction
layer that lets
software access different storage backends (real disk, network share, encrypted
container, memory region, etc.) using the same file API.
Kernel Interface-Based
Polymorphism Design
I
did a string search and followed the value of Unit(hex), which is 006bh, and
finally went to the main function sub_2E40A and then dove deep into the
sub-branch sub_2F7C6 and found a series of similar calls that do:
push offset sub_2EBB4
push 0x12
push eax
call dword ptr [ecx+24h]
Dispatcher
pattern:
• Different handlers (sub_xxx
)
pushed but same [ecx+24h]
call → polymorphic dispatch.
• Immediate
(0x12) is likely a flag controlling logic flow or acting as a mode selector.
Figure
2: Polymorphic
interface dispatch design.
And from the above pattern of design, it’s very
convenient to do functionality extension because of its scalability. It treats
the design seriously as professional software
engineering architecture thinking and practice, which is a long-term maintenance and mature mindset.
Polymorphic Dispatch
Issue Direct Kernel I/O Calls
When diving deep into polymorphic
dispatch, different handlers are supplied to the same dispatcher, like the
pattern “push offset sub_xxx”; they issue direct kernel I/O calls
under the safety kernel environment, for which they did security initialization
and releasing with synchronization logic. Here are several different handlers
to pick to demonstrate.
1.
About “push offset sub_2EDCC”
kr_sec_init (After Function Rename):
It executes the kernel security
initialization operation API (KeGetCurrentIrql, KeEnterCriticalRegion,
ExAcquireFastMutexUnsafe, KfAcquireSpinLock, and ExAcquireFastMutex).
And in the middle part, the logic
branch operation handles routines and issues direct kernel I/O calls
(ZwQueryInformationFile, ZwWriteFile).
kr_sec_clean (After Function Rename):
And finally, it is
to release them that are related to API (ExReleaseFastMutexUnsafe,
KeLeaveCriticalRegion, KfReleaseSpinLock, and
ExReleaseFastMutex).
Figure 3: push offset sub_2EDCC logic issue direct kernel I/O calls.
In addition, it uses the standard software CRC32
algorithm implementation for integrity checks, a valid precomputed CRC with reversed polynomial 0xEDB88320 in the lookup table.
Figure 4: snippet for 256
precomputed uint32 values, including the polynomial 0xEDB88320.
2.
About “push offset sub_2EBB4”
The structure design is very similar to “push
offset sub_2EDCC,” which includes a wrapper for “ZwWriteFile” and the
part of function sub_2FD2C.
3.
About
“push offset sub_2F32A”:
The structure has more sub-branches in the logic
design. When diving deep into the function sub_30386, the logic branch
operation handles routines that issue direct kernel I/O calls
(ZwQueryInformationFile, ZwWriteFile, ZwReadFile, ZwClose). Wait on an event or
op completion (ZwWaitForSingleObject) before proceeding.
Yes, in the function sub_2F7C6, most
of the functionality is designed around I/O calls to bridge virtual objects to
real files or queries or operate on real file objects, which is polymorphism
design with the same interface and different implementations.
well-designed Kernel Synchronization Wrapper
In the function sub_2EDCC,
kr_acquire_lock and kr_release_unlock perform IRQL-aware lock/unlock routines,
including the different lock types: FastMutex Unsafe, SpinLock, and FastMutex.
The design is a kernel synchronization security layer, which, combined
with file operation, the concurrency control indicates the
feature about typical VFS-layer or filesystem object access.
Figure 5:kernel synchronization wrapper with IRQL checks.
Figure 6:perform IRQL lock/unlock routines.
The implementation's use of IRQL-aware wrappers for local
resource protection, in contrast to the complex multi-layer locking
architecture required for managing global Index Node, Directory Entry, and superblock caches in a standard VFS,
definitively characterizes it as a Light VFS-layer implementation.
According to Kernel
Theory Knowledge, Synchronization Expertise, and Security Awareness, this
synchronization wrapper indicates a highly sophisticated threat actor with
professional kernel development experience.
Conclusion
Together, these behaviors indicate that the function sub_2F7C6 implements a custom VFS (virtual
filesystem) structure, using polymorphic method tables to
abstract file access. an abstraction layer that routes all file-like operations
(read, write, query, close) through a consistent interface, guarded by a
well-designed synchronization security layer, and the code uses IRQL-aware wrappers for
local protection. The evidence indicates that it is a Lightweight
VFS layer or VFS access manager.
Epilogue: What the Regin Taught Me
1.
If you want to analyze Regin-class implants, you must
reach a high level of Windows kernel competence.
its authors deliberately used advanced kernel primitives (VFS-like storage,
IRQL-aware locking, Zw* bridging, stealthy persistence).
2.
Malware that is designed
with multiple stages and interdependent components makes analysis more
challenging and is very difficult to understand completely without all related
samples.
3.
Simply being curious and exploring gives people
positive abilities to expand on malware research or other fields.
4. Being humble is not just about
recognizing how little you know but also about facing complexity and
understanding it takes time and patience.
Annotation: In all the sentences I wrote and used the word
“you or your or yourself” in, it talked to me or “the malware sample itself,
especially in my poem I did”, not the reader. I must clarify my motivation.
References
[1]. https[:]//docs.broadcom.com/doc/regin-top-tier-espionage-tool-15-en
[2]. https[:]//media.kasperskycontenthub.com/wp-content/uploads/sites/43/2018/03/08070305/
Kaspersky_Lab_whitepaper_Regin_platform_eng.pdf
“Do or do not, there is no try.”
— Master Yoda
End of Report
──────────────────────
Seeker(李标明) · @clibm079
China · Independent Malware
Analyst & Researcher
Labels: #KernelMode, #Regin, #ReverseEngineering, #rootkit, #TopTierAPT, #VFS
0 Comments:
Post a Comment
Subscribe to Post Comments [Atom]
<< Home