Skip to content

Latest commit

 

History

History
65 lines (44 loc) · 2.68 KB

File metadata and controls

65 lines (44 loc) · 2.68 KB

binaryshield-devirtualizer PoC

This project is a static devirtualizer designed to analyze and solve a crackme protected by the open-source code virtualizer BinaryShield.

This VM has no mutation or extra obfuscation in it. It can be analyzed without recovering the whole function and with only architechture-specific disassembly.

I wanted to go further than just obtaining the flags. My goal was to push my skills, learn deobfuscation/devirtualization techniques better and compare LLVM and VTIL to see which one is better for the job.

Article : https://medium.com/@mmert_11/devirtualizing-a-vm-based-protection-with-llvm-a8b5ef9634b5

Update

After a long time, I've got a chance to take a look at this sample again, because I wasnt satisfied by the results. I've worked on it again by using symbolic execution and lifting the assembly, I'm leaving the final devirtualized result here:

; ModuleID = 'vexa'
source_filename = "vexa"

; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
define range(i64 0, 2) i64 @vexa_lifted(i64 %rax, i64 %rbx, i64 %rcx, i64 %rdx, i64 %rsi, i64 %rdi, i64 %rbp, i64 %rsp, i64 %r8, i64 %r9, i64 %r10, i64 %r11, i64 %r12, i64 %r13, i64 %r14, i64 %r15, i64 %rflags) local_unnamed_addr #0 {
entry:
  %stack162895.sroa.1404.1680.extract.trunc = trunc i64 %rcx to i32
  switch i32 %stack162895.sroa.1404.1680.extract.trunc, label %common.ret [
    i32 1859, label %"14001678299496"
    i32 2418, label %"14001678299496"
    i32 1638, label %"14001678299496"
    i32 299902, label %"14001678299496"
    i32 29763, label %"14001678299496"
  ]

common.ret:                                       ; preds = %entry, %"14001678299496"
  %common.ret.op = phi i64 [ 1, %"14001678299496" ], [ 0, %entry ]
  ret i64 %common.ret.op

"14001678299496":                                 ; preds = %entry, %entry, %entry, %entry, %entry
  br label %common.ret
}

attributes #0 = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }

  

If you are interested in this method, I recommend you take a look at NaC-L/Mergen

Technologies Used

  • LLVM for lifting and analysis
  • Experimental support for VTIL (results were not satisfactory)
  • Zydis as disassembly engine
  • LIEF for binary operations

Results

  • LLVM successfully devirtualized the function, allowed us to recover the flags and analyze the logic. It was able to recompile back to x64.
  • VTIL failed to produce acceptable results due to its outdated state. Unable for proper recompilation.

Note

This project is for research and educational purposes only.

Screenshots