>_
The Fuzz.
← /blog
Malware Analysis

Inside a 2026 ValleyRAT drop: Squirrel, Unity, Rust, and a 1-second password crack

Walking one Silver Fox sample from MalwareBazaar through every stage. Encrypted SFX, two signed-binary sideload hops, an 111 MB Rust loader with obfstr-style string XOR, a hardware-breakpoint VEH that finds 0F 05 opcodes for direct syscalls, and a custom-base64 carrier disguised as a Windows MUI.

$ author 0xFuzz·Apr 28, 2026·20 min read
valleyratsilver-foxmalware-analysisrustdll-sideloadingdfiranti-analysis

I grabbed a fresh ValleyRAT sample off MalwareBazaar last week and it turned out to be one of the more elegant Silver Fox builds I've taken apart this year. The shipping container is an encrypted self-extracting RAR. What's inside is a tiny masterclass in abusing legitimacy: a signed launcher from a famous Electron toolchain, a signed binary from one of China's biggest game studios, and a 111 megabyte Rust DLL that does direct syscalls through a hardware-breakpoint exception handler.

Here's how it all clicks together, plus a few RE tricks worth stealing.

AttributeValue
Samplerenamed to sample.exe from the SHA256-named MalwareBazaar drop
SourceMalwareBazaar (password infected)
SHA-2566847e6a295e8312a990752c9a0662f5757e096d3ecde43776caa2943f016da11
File typePE32 (i386) GUI, 3,947,694 bytes. Stock WinRAR SFX with a RAR5 encrypted-headers overlay starting at 0x5fc00.
FamilyValleyRAT (a.k.a. Winos 4.0; Silver Fox / Valley Thief / UTG-Q-1000 cluster)
LabKali for static work, isolated Windows 10 in a snapshotted Hyper-V box for any dynamic step. No outbound network.

TL;DR

chain.txt
sample.exe (encrypted RAR-SFX, password "123")
└── wudfhost.exe                       Squirrel.Windows StubExecutable (LetsGo Network signed)
    └── app-3.16.5/wudfhost.exe        NetEase Unity game player (NetEase signed)
        └── app-3.16.5/UnityPlayer.dll MALICIOUS Rust loader (loader_dll.dll, 111 MB)
            ├── service.exe.mui        custom-base64 + padded payload chunk
            └── (overlay) ~83 MB AES-encrypted final-stage shellcode

Persistence depends on whether you have Tencent QQ PC Manager installed. If yes, you get a quiet .lnk in Startup. Otherwise you get a system-wide scheduled task pretending to be MicrosoftEdgeUpdateHelpUpdates running on every logon as administrators. The decoy is an English-language "Professional Farm Transfer Plan.pdf" that pops up so the victim doesn't get suspicious when nothing else seems to happen.

Now the fun part.

0. Lab and rules of engagement

Before unzipping, the rules:

  • Kali for static, snapshotted Windows VM for dynamic. Static covered everything below: 7z, rar2john, hashcat, binwalk, pestudio via wine, die, radare2, LnkParse3, yara. The malicious DLL was never executed.
  • No outbound network on the analysis VM. Static analysis shouldn't need it, but ValleyRAT droppers happily kick off the chain on auto-extract or shell-handler bugs. Keep DHCP off and block the host firewall outbound for the VM's IP.
  • Defang on disk. chmod -x on the unpacked PE, store inside a directory called infected/, and resist the urge to drag-and-drop the malicious DLL into a tool that runs registered file-handlers.
  • Snapshot before the first byte. Every parser you point at this thing has a chance of triggering something. Roll back rather than clean.
i
MalwareBazaar zips and 7z

MalwareBazaar packages samples in AES-encrypted zips with the password infected. Plain unzip(1) on Linux can't decrypt AES-zip; 7z x -pinfected file.zip does. Same trick if you grab it from a mirror that re-zips the sample.

1. The outer SFX: encrypted, but not really

The file looks like an installer. PE info gives it away as a stock WinRAR self-extractor:

pe-info.txt
PDB:           D:\Projects\WinRAR\sfx\build\sfxrar32\Release\sfxrar.pdb
Resources:     Lang ID 2052 (Chinese, PRC)
Compiled:      2024-02-26

The RAR signature Rar!\x1a\x07\x01\x00 shows up at file offset 0x5fc00. Carve the overlay and feed it to unrar:

carve-and-list.sh
$ unrar l -p- payload.rar
Incorrect password for payload.rar
Archive: payload.rar
Details: RAR 5, encrypted headers
  0 files

Encrypted headers means we can't even list filenames without the key. Annoying. But this is the point where the malware author and I have drastically different views on what their crypto is doing:

  • They think it's protecting the payload from AV scanning at the gateway.
  • I think it's a 16-byte salt and a single PBKDF2 round.

rar2john exports the hash, hashcat eats it instantly:

crack.sh
$ rar2john payload.rar > rar.hash
$ hashcat -m 13000 rar.hash short_pwds.txt
$rar5$16$c953d2...$15$59144421...$8$abefc909a9bd0c00:123

Password: 123. Total time-to-crack: under one second on a single CPU core.

i
RE tip: don't fight the encryption, guess the password

Silver Fox-family droppers have used 123, 888, 123456, 888888, Server8888, and the like for years. Whatever password is in their phishing email body is what's hardcoded in the crypto. The encryption is purely AV evasion at the perimeter, not confidentiality. Always start with hashcat -m 13000 against rockyou.txt and a 6-digit numeric mask.

The SFX comment script then reveals the entry point:

sfx-script.ini
Setup=wudfhost.exe
Silent=1
Overwrite=1
Update=U

Silent=1 means the SFX shows zero UI, extracts to %TEMP%\RarSFX0\, auto-runs wudfhost.exe. The user just sees a PDF open on their desktop a moment later.

2. The dropped tree

dropped-tree.txt
RarSFX0/
├── 1.bat 2.bat 3.bat auto.vbs            orchestration
├── pdf.ico  图标3.ico                    icon decoration
├── db.log                                timestamp ("2026-04-21 21:01:55")
├── service.exe.mui                       payload chunk #1 (181 KB)
├── 2026il5s.dat                          decoy PDF #2 (financial allocation)
├── 2026od8a.dat                          decoy PDF #3 (401k/IRA optimisation)
├── Professional Farm Transfer Plan.pdf   decoy PDF #1 (the visible one)
├── WUDFHost.exe                          Squirrel stub
├── WUDFHost.lnk                          persistence shortcut
└── app-3.16.5/
    ├── WUDFHost.exe                      Unity binary (signed!)
    ├── UnityPlayer.dll                   THE LOADER (111 MB!)
    ├── msvcp140.dll vcruntime140*.dll    real MS runtimes
    ├── bootfix.bat WUDFHost.lnk

The batch files are all you need to understand the orchestration:

1.bat
:: the social engineering payload
copy "Professional Farm Transfer Plan.pdf" "%USERPROFILE%\Desktop\"
start "" "%USERPROFILE%\Desktop\Professional Farm Transfer Plan.pdf"
2.bat
:: keep the implant resident
taskkill /f /im "WUDFHost.exe"
WUDFHost.exe
3.bat
:: AV-aware persistence
tasklist /FI "IMAGENAME eq QQPCTray.exe" | find "QQPCTray.exe" >nul
if %errorlevel% equ 0 (
    copy wudfhost.lnk "%APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup"
) else (
    schtasks /create /tn "MicrosoftEdgeUpdateHelpUpdates" ^
             /tr "C:\Windows\en-US\WUDFHost.exe" ^
             /sc onlogon /ru "administrators" /rl highest /f
)

That 3.bat is genuinely thoughtful tradecraft. If Tencent QQ PC Manager is running, the malware downgrades persistence to a low-noise user-Startup .lnk (which QQ tends to ignore). On clean boxes, it goes for the elevated scheduled task with a Microsoft-Edge-flavoured name. The same author shipping the same dropper to a hundred victims gets to look like two completely different threats depending on who their AV vendor is.

3. The signed-binary chain

This is where it gets clever. Three WUDFHost.exe copies, all 64-bit, all valid PEs, all signed, and only one of them is malicious. And that one isn't named WUDFHost.exe.

signed-chain.txt
WUDFHost.exe (root, 32-bit)
    Signer: LetsGo Network Incorporated   (Squirrel.Windows owners)
    PDB:    C:\Users\ani\code\squirrel\squirrel.windows\build\Release\Win32\StubExecutable.pdb
    Job:    "Find latest app-X.Y.Z folder, run the binary inside it"
 
app-3.16.5/WUDFHost.exe (64-bit)
    Signer: NetEase (Hangzhou) Network Co., Ltd
    PDB:    F:\jenkins\workspace\YaoTaiWin\artifacts\WindowsPlayer\...\WindowsPlayer_Master_il2cpp_x64.pdb
    Job:    "LoadLibrary UnityPlayer.dll, GetProcAddress UnityMain, jump"
 
app-3.16.5/UnityPlayer.dll (64-bit)
    Signer: NONE
    Internal name: loader_dll.dll
    Job:    do crime

The first stage is Squirrel.Windows StubExecutable, exactly the same launcher you'll find in your %LocalAppData%\GitHubDesktop\ or %LocalAppData%\slack\. It's signed by LetsGo Network because LetsGo are the people who ship Squirrel. Valid Authenticode.

The second stage is a real Unity Player from a real NetEase game (YaoTaiWin in the PDB, NetEase's gaming platform), signed by NetEase with a now-expired DigiCert code-signing cert. Valid Authenticode.

The third stage, UnityPlayer.dll, is not signed. But of course it doesn't have to be. app-3.16.5/WUDFHost.exe does LoadLibrary("UnityPlayer.dll") with no path, and Windows resolves the DLL from the EXE's own directory. The malicious DLL drops in alongside. Forwarding DLL hijack via two different signed binaries from two different vendors.

i
RE tip: Squirrel.Windows is the new rundll32

A Squirrel StubExecutable.pdb PDB string plus an app-X.Y.Z\ sibling directory is one of the most reliable signals you have for sideload-driven malware in 2025 to 2026. Build a YARA rule for it and grep your corpus.

The app-3.16.5/ folder name is also pure misdirection. It looks like a Squirrel app version directory, but the wrapped Unity game has nothing to do with Squirrel. The version number is a coincidence the malware author engineered. The dropper places the Squirrel stub above an app-3.16.5/ it doesn't actually belong to, and Squirrel happily picks it up.

4. The 111-megabyte Rust loader

UnityPlayer.dll is 116,391,936 bytes. That's 111 MB of "DLL". The PE itself only has 280 KB worth of sections:

sections.txt
.text   0x36a00     0x37000
.data    0xa00       0x1000
.rdata  0x6c00       0x7000
...
.reloc   0x400       0x1000

So 110 MB of overlay. Whatever's in there is the actual party.

The visible code is Rust:

rust-strings.txt
library\std\src\panicking.rs
library\alloc\src\raw_vec\mod.rs
/rustc/ded5c06cf21d2b93bffd5d884aa6e96934ee4234/...
/rust/deps\gimli-0.32.0\src\read\abbrev.rs
/rust/deps\hashbrown-0.15.5\src\raw\mod.rs
/rust/deps\object-0.37.3\src\read\coff\section.rs
/rust/deps\addr2line-0.25.0\src\line.rs
obf_lit produced invalid UTF-8

That obf_lit produced invalid UTF-8 is a panic from the popular obfstr / litcrypt family of crates that XOR-decrypt string literals at runtime. So nearly every interesting string in the binary is encrypted on disk and only materialises in RAM when a particular function is called.

The exports list is the most diagnostic thing in the whole DLL:

exports.txt
1   UnityMain         the sideload hook
2   AddHwBp           installs a hardware breakpoint
3   HandlerHwBp       Vectored Exception Handler

UnityMain is what NetEase's Unity binary calls. The other two are the punchline.

The hardware-breakpoint syscall trampoline

HandlerHwBp looks like this when you skim it:

handler-hwbp.asm
cmp dword [rdx], 0xc0000005       ; EXCEPTION_ACCESS_VIOLATION ?
jne not_us
mov rax, [rdx + 0x80]             ; ContextRecord->Rip
movzx r10, byte [rax]             ; opcode byte
movzx r9,  byte [rax + 1]         ; next byte
xor r10b, 0x0f                    ; if 0x0F, r10 == 0
xor r9b,  0x05                    ; if 0x05, r9  == 0
or  r11b, r10b
je  found_syscall

It's scanning instruction bytes at the faulting address looking for 0F 05, the syscall instruction. The whole DLL's syscall dispatch goes through this VEH:

  1. Set DR0 to the address of a benign instruction inside ntdll.dll.
  2. Hit it, take a STATUS_BREAKPOINT exception.
  3. Walk forward from Rip to find the real syscall opcode.
  4. Resolve the SSN dynamically, set up registers, and let execution continue.

This pattern (sometimes called "Hell's Hall" or "HWBP syscall") is direct-syscall delivery without ever calling the Nt* stubs that EDRs hook in user space. It's a documented Silver Fox capability and it's perfectly fingerprintable. Any DLL exporting AddHwBp and HandlerHwBp is from this family. Cheap YARA win.

Anti-sandbox: waitable timers, not Sleep

The very first thing UnityMain does is not read a file or check the environment. It does this:

sleep-evasion.c
QueryPerformanceCounter(&t0);
HANDLE timer = CreateWaitableTimerExW(...);
LARGE_INTEGER due = { .QuadPart = -2000000000 };  // 200 s, relative
SetWaitableTimer(timer, &due, 0, NULL, NULL, FALSE);
WaitForSingleObject(timer, INFINITE);
Sleep(2000);
QueryPerformanceCounter(&t1);
if (delta(t1, t0) too small) ExitProcess();

A lot of sandboxes patch Sleep() to return immediately. Almost none of them patch SetWaitableTimer and QueryPerformanceCounter consistently. The QPC is a hardware tick counter, hard to lie about. So if the wallclock didn't advance, the loader noses out of the sandbox before doing anything compromising. Cute.

The custom base64

In the small clear-text region of .rdata, just before the path C:\Windows\en-US\service.exe.mui, there's an alphabet:

custom-alphabet.txt
0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-/

That's base64 with the digits moved to the front and + replaced by -. A standard base64.b64decode() will fail on it. A url-safe base64.urlsafe_b64decode() will fail on it. You have to translate the alphabet first or, easier, do the lookup table by hand.

This is the alphabet the loader uses to decode both service.exe.mui and its own 110 MB overlay. The overlay decodes to 87 MB of high-entropy ciphertext (entropy ~7.94). The plaintext is almost certainly an AES blob: the loader imports bcryptprimitives.dll!ProcessPrng which usually accompanies a BCryptDecrypt-class call lurking inside the obfuscated code path.

The fake .mui

service.exe.mui looks like this in a hex viewer:

mui-hex.txt
00000000  50 4e 50 58 50 30 30 30 30 30 30 30 30 30 30 30  PNPXP00000000000
00000010  30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30  0000000000000000
...  (1000+ bytes of '0' padding)  ...
00000408  68 63 59 6b 4d 41 76 38 68 5a 59 6b 41 41 75 4f  hcYkMAv8hZYkAAuO
00000418  68 57 59 6a 2d 41 74 65 68 54 59 6a 6f 41 73 75  hWYj-AtehTYjoAsu
...

A 5-byte magic PNPXP, runs of literal ASCII 0, then chunks of custom-base64 separated by more padding. Real Windows MUI files never look like this. It's pure cosmetic disguise. file(1) reports it as ASCII text, strings shows nothing alarming, and at a glance in Explorer it looks like an obscure localisation resource you shouldn't touch.

After stripping the magic and the 0-padding, decoding with the custom base64, and decrypting with whatever key the obfuscated Rust assembles in memory, you get the next-stage shellcode. The 110 MB overlay carries the bulk RAT (the leaked-builder ValleyRAT plugin set: keylogger, audio/screen capture, BYOVD kernelquick rootkit, etc.). I haven't fully decrypted it for this writeup. The techniques and capabilities are well documented by Check Point, Zscaler and Fortinet for the post-leak builder.

i
RE tip: carve the overlay first

When you see a "DLL" that's over 100 MB and the IMAGE_NT_HEADERS say only ~300 KB of sections, the PE structure is a fig leaf. The whole game is in the overlay. Calculate last_section.PointerToRawData + last_section.SizeOfRawData and dd skip= past it; analyse the bottom half on its own. Don't run strings on the whole 116 MB, the overlay is base64 ciphertext and you'll find nothing useful but spend minutes pretending to.

5. Pivots from the LNK

This is the part everybody forgets. WUDFHost.lnk (the persistence shortcut, dropped twice in the package) is a goldmine. LnkParse3 rips it open in three lines:

parse-lnk.py
import LnkParse3
with open("WUDFHost.lnk", "rb") as f:
    LnkParse3.lnk_file(f).print_lnk_file()

What falls out:

FieldValue
Target pathC:\Windows\en-US\WUDFHost.exe
Working directoryC:\Windows\en-US
Build host (NetBIOS)desktop-jpresuo
Build MAC OUI00:0c:29: (VMware default)
Builder SIDS-1-5-21-4148627571-40687702-2776887718-500
Volume label系统 ("System"), Chinese-locale Windows
Drive serial0x122dcedf

The 00:0c:29: MAC OUI is VMware Workstation's. The -500 RID is local Administrator. The volume label is Mandarin. The malware author was operating from a Chinese-locale Windows VM, building shortcuts as Administrator, and didn't sanitise the LNK metadata before shipping.

Hashes change every build. desktop-jpresuo and that SID don't. They pivot beautifully on VirusTotal and MalwareBazaar to find sibling samples that were built on the same machine.

i
RE tip: pull LNK metadata, always

I can't remember the last time I analysed a malicious LNK and didn't get the build host name out of it. Threat actors keep forgetting that Windows fingerprints their dev box every time they hit Save.

What it is

This is ValleyRAT, the Winos 4.0 Remote Access Trojan, distributed by the Silver Fox / UTG-Q-1000 / "Valley Thief" cluster. It's a Chinese cybercrime operation that has been distributing through trojanised installers, SEO-poisoned downloads, and tax-themed phishing since 2022. The post-March-2025 leak of their builder kicked off an explosion of variants. Check Point counted ~6,000 new samples in the year following the leak, with ~85% in the second half of that period.

What's interesting about this sample isn't the RAT itself (the leaked ValleyRAT plugin set is well documented), it's the delivery layer. Every choice is calibrated to spend AV/EDR analyst attention on something signed and legitimate. Squirrel and Unity are not exotic. They're so boring that the typical EDR triage workflow whitelists them on sight.

Stand-out fingerprints for this build:

  • Rust loader (the older Picus-documented .NET / MSBuild / 3DES delivery is gone).
  • Two-tier signed-binary sideload (Squirrel + Unity, two different vendors, both expired certs).
  • Hardware-breakpoint VEH syscall trampoline for direct syscalls.
  • AV-aware persistence branching based on Tencent QQ Manager presence.
  • Fake .mui carrier with PNPXP magic and 0-padding cosmetic.
  • Custom base64 alphabet (0-9 A-Z a-z - /).

RE tips you can steal

A summary of things that saved me time on this one and will save you time on the next:

  1. Crack first, RE second. Silver Fox uses trivial passwords for its encrypted SFXs. Don't waste an evening trying to decrypt headers or hunting for the password in the binary. rar2john + hashcat -m 13000 is faster than reading the SFX stub.
  2. PDB:squirrel.windows\...\StubExecutable.pdb is a smoking gun. Build a YARA rule on it and app-X.Y.Z\ directory siblings.
  3. Check Authenticode on every PE in the drop. Knowing what's signed by whom tells you in 30 seconds which binaries are payload and which are camouflage.
  4. .mui files in C:\Windows\en-US\ that aren't structured MUI resources are payloads. Real MUI files are tiny, structured, and never start with PNPXP.
  5. Carve the overlay before disassembling. A 116 MB DLL with 280 KB of sections is all overlay. Don't make strings slog through 110 MB of ciphertext.
  6. Rust binaries leak the toolchain, the crates, and often the obfuscation library. obf_lit produced invalid UTF-8 means they're using obfstr / litcrypt-style string XOR; that gives you the function shape to look for.
  7. AddHwBp / HandlerHwBp is a family signature. Three Silver Fox variants in 2025 ship those exact export names. If you see them, you know what you're looking at.
  8. VEH that does xor reg, 0x0f followed by xor reg, 0x05 is a syscall-finder. That's a 5-line YARA hex pattern that catches every HWBP-syscall implementation I've seen.
  9. Run LnkParse3 on every .lnk you find. Build host, MAC OUI, SID, volume label: all free pivots.
  10. Setup= and Silent= in a WinRAR SFX comment script tell you the entry point before you open Ghidra. Always read the SFX script first.

IOCs

typevaluenote
sha2566847e6a295e8312a990752c9a0662f5757e096d3ecde43776caa2943f016da11sample.exe (SFX dropper)
sha256c9e3b700e048840e1fc4d652064bc1a982c82c719cc58f3174a12bfdddf04f1dWUDFHost.exe (Squirrel stub)
sha256727d6989e0d368898aad322cd6c72c33843d37d6ff22542780414cc88685d28aapp-3.16.5/WUDFHost.exe (NetEase Unity)
sha2563701aeb70cff1e9a8185a6f60002fc24e155a43ad0fd8da748fa1ab6d4d5e579app-3.16.5/UnityPlayer.dll (malicious Rust loader)
sha2567bfdb1947b94bb76a3af36ebd164c79caab2b01ff076bf9fbdfc4271c1b3f988service.exe.mui (encrypted payload carrier)
sha2563d9db5f2b6a706f016351b4fed35568e7ebd291ba6180fd22ad8c837d7346535WUDFHost.lnk
sha25636c2667920379f6d986c97702d449079b80868f20aa339b24d9ea1f70b8dd85dProfessional Farm Transfer Plan.pdf (decoy)
sha256c866bd5187f743af03279a44c3ce678778b6cfd14501583f9454445d2f53663c2026il5s.dat (decoy PDF)
sha256d3767d048d41b02db1fe6bcc1f4693cdbce719f36c7b181048223451df71faed2026od8a.dat (decoy PDF)
pathC:\Windows\en-US\WUDFHost.exeStage 1 dropper location
pathC:\Windows\en-US\app-3.16.5\WUDFHost.exeStage 2 sideload host (NetEase signed)
pathC:\Windows\en-US\app-3.16.5\UnityPlayer.dllStage 3 malicious Rust loader
pathC:\Windows\en-US\service.exe.muiStage 4 encrypted payload carrier
lnk%APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup\WUDFHost.lnkPersistence (low-noise path, taken if QQPCTray.exe present)
schtaskMicrosoftEdgeUpdateHelpUpdatesPersistence (high-priv path, RunLevel=Highest, RunAs=administrators)
build-hostdesktop-jpresuoLNK Distributed Tracker, builder NetBIOS
builder-sidS-1-5-21-4148627571-40687702-2776887718-500LNK property store, RID 500 = local Administrator
builder-mac00:0c:29:df:a6:9eLNK Droid GUID, VMware default OUI
archive-pwd123RAR-SFX password, recoverable in <1s
alphabet0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-/Custom base64 alphabet, both stages
internal-nameloader_dll.dllStage 3 Rust DLL internal name
exportsAddHwBp, HandlerHwBp, UnityMainStage 3 Rust DLL exports, family-diagnostic

Detection

A Sigma sketch (pseudo):

valleyrat_wudfhost_sideload.yml
title: ValleyRAT WUDFHost Sideload Chain
detection:
  selection_path:
    Image|endswith: '\WUDFHost.exe'
    Image|contains:
      - '\AppData\'
      - '\Temp\RarSFX'
      - '\Windows\en-US\'
  filter_legit:
    Image|startswith: 'C:\Windows\System32\'
  schtasks_persistence:
    CommandLine|contains:
      - 'MicrosoftEdgeUpdateHelpUpdates'
      - '\Windows\en-US\WUDFHost.exe'
  condition: (selection_path and not filter_legit) or schtasks_persistence

A YARA sketch:

valleyrat_hwbp_2026.yar
rule ValleyRAT_HWBP_SyscallTrampoline_2026 {
    meta:
        author = "0xfuzz"
        family = "ValleyRAT/Winos4.0"
        tlp    = "white"
    strings:
        $alphabet  = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-/" ascii
        $hwbp_pair = { 41 80 F? 0F 4? ?? ?? 41 80 F? 05 }
        $obfstr    = "obf_lit produced invalid UTF-8" ascii
        $mui_path  = "C:\\Windows\\en-US\\service.exe.mui" ascii
        $exp1      = "AddHwBp" ascii
        $exp2      = "HandlerHwBp" ascii
    condition:
        uint16(0) == 0x5a4d
        and ($alphabet and $hwbp_pair)
        and 2 of ($obfstr, $mui_path, $exp1, $exp2)
}

EDR correlations worth wiring up:

  • Process WUDFHost.exe running outside C:\Windows\System32\, especially under C:\Windows\en-US\ or %TEMP%\RarSFX*\. The legitimate WUDFHost.exe only ever lives in System32.
  • Scheduled task creation for any task name beginning MicrosoftEdgeUpdate... whose action targets a path under C:\Windows\en-US\.
  • cmd.exe running tasklist /FI "IMAGENAME eq QQPCTray.exe" followed within seconds by schtasks /create from the same parent.
  • Process tree where signed WUDFHost.exe (NetEase signature) loads UnityPlayer.dll from a non-Unity install path.
  • The final RAT plugin set beacons over HTTP/HTTPS. Once the in-memory blobs are decrypted you'll see the standard ValleyRAT GetOnlineSize_<n> and IpDates-style traffic. Out of scope for static analysis here, but worth wiring up on a dynamic VM if you go that next step.

References

$ echo "thanks for reading" | tee /dev/null
$ next post

More in Malware Analysis