View Single Post
  #1  
Old 05-18-2026, 13:58
1ST 1ST is offline
Family
 
Join Date: Apr 2010
Location: Jordan
Posts: 99
Rept. Given: 47
Rept. Rcvd 225 Times in 24 Posts
Thanks Given: 6
Thanks Rcvd at 4 Times in 4 Posts
1ST Reputation: 200-299 1ST Reputation: 200-299 1ST Reputation: 200-299
Need help unpacking Themida 3.x x64

Hey everyone,

It's been quite a few years since I last did any serious RE work and wow, things have moved on. I've been banging my head against a Themida 3.x target for a couple weeks now and figured it's time to ask for help before I lose my mind.

The thing that surprised me most coming back is how little current material there is on Themida 3.x unpacking for x64. The n0pex3 and LCF-AT articles are solid foundations but they're from a while back, written against 32-bit targets and older Themida versions. Everything else I've found is either dead forum threads where OP never posts the solution, or YouTube videos with no commentary that skip the hard parts. If anyone knows of tutorials, writeups, or even Discord servers where this stuff gets discussed more actively, I'd owe you one.

Anyway, here's what I've tried, what worked, and where I'm completely stuck. Writing this out partly to organize my own thoughts and partly hoping someone spots what I'm doing wrong.

---

THE TARGET

The main EXE, 31 MB, x64. Themida/WinLicense 3.x is what Detect It Easy tells me. There's a 15 MB .themida section and from what I can tell, a decent chunk of the original code got virtualized — I counted about 647 calls and jumps from .text back into the .themida section.

Packed entry point is at RVA 0x528A058, in the .boot section.

---

WHAT I TRIED #1 — MANUAL UNPACK WITH x64DBG

Setup: latest x64dbg snapshot, ScyllaHide with the "Themida x64" profile. Had to pass sti exceptions through with Shift+F9 or the debugger chokes.

Finding the OEP:

I used the LCF-AT approach — hardware breakpoint on write to the last IAT entry, restart, run until it hits, then memory breakpoint on access to the .text section. Run again and it lands you near the OEP. After some poking around I confirmed the OEP at RVA 0x2A866C0.

So far so good. The real pain started with the IAT.

Themida 3.x IAT Obfuscation:

From what I can tell (mostly from those n0pex3 articles), Themida messes with IAT calls in a few ways. In my binary I found three patterns:

Pattern A (6 bytes): 90 E8 xx xx xx xx
The "nop" followed by a call. The call goes to one of those multijump thunks.
Since it's 6 bytes, in theory you can replace it with FF 15 [new_IAT_entry].

Pattern B (6 bytes): E8 xx xx xx xx 90
Same idea, nop just sits after the call instead of before.

Pattern C (5 bytes): E8 xx xx xx xx
Plain E8 call, no nop. The target is still a thunk but now you've only got 5 bytes,
and FF 15 [addr] needs 6. Can't be done in-place without shifting everything
that comes after.

Scale of the wreckage:

- 35 calls using Pattern A or B (patchable in theory)
- 877 calls using Pattern C (5 bytes, not patchable in-place)
- 1242 total thunks (621 pairs of FF 25 + push rdx/lea rdx)

IAT sits at RVA 0x32EA320 and the import descriptors are at RVA 0x4326390.

I dumped the process with Scylla, fixed the OEP in the PE header, fixed the import directory pointer (was pointing at the IAT instead of the descriptors), and patched those 35 calls. The dump doesn't start.

Two problems:

1. ASLR. Every IAT entry in the dump contains a resolved address (0x7FFD...) from the original run. On restart, different base addresses, every single entry is wrong. The import table needs to be descriptor-based so the Windows loader fills it, but I don't know how to convert a resolved IAT back to descriptor form when the thunks are all mixed in.

2. Those 877 E8 calls. Even if I fix the IAT, those calls point at thunks that reference the old IAT addresses. Broken either way.

I thought about building a trampoline section — leave the old thunks in place but redirect them to new IAT entries — but 877 of them manually is not happening, and I don't know of a tool that automates this for Themida's pattern.

Scylla's IAT autosearch finds nothing at the OEP. I gather that's expected for Themida but I'm not sure what the standard workaround is.

---

WHAT I TRIED THAT DIDN'T PAN OUT

- Magicmida: got a partial dump that shows the splash screen then crashes. 647 VM references left unresolved and one IAT entry broken. Half-working isn't useful when you can't debug the other half.

- Manual byte patching of all 877 calls: obviously impractical by hand, and even if I could, the 5→6 byte expansion shifts every relative offset in the binary.

- Scylla IAT autosearch at various points during execution: never finds anything. The OEP simply doesn't have a normal IAT structure nearby.

---

WHERE I COULD REALLY USE SOME HELP

1. What's the standard approach for bulk-converting the 5-byte E8 calls when you can't do it in-place? Is building a trampoline section the way to go, and if so, is there a script or tool that handles this for Themida targets? I can't be the first person to hit this.

2. How do people handle DLLs packed with Themida? Every tutorial and tool I've found assumes an EXE target. Are there Unicorn-based DLL unpackers out there, or is the approach completely different?

3. Are there any Themida 3.x x64 unpacking tutorials or writeups I've missed? I've searched exhaustively (or at least it feels that way) and come up nearly empty. Discord servers, obscure blogs, Russian forums, anything — happy to translate if needed.

4. Or, on a more practical level — is there a better tool than what I've been using? Something that handles the full pipeline for modern Themida on x64? Even commercial tools, I'm willing to pay if something actually works.

Thanks for reading this far. Any pointers at all would be massively appreciated — even just "hey I ran into this too, here's what eventually worked" would make my week.

Cheers.
Reply With Quote