/UnivDisasm

x86 Disassembler and Analyzer

Primary LanguagePascalMozilla Public License 2.0MPL-2.0

UnivDisasm

UnivDisasm is a powerful x86 disassembler and opcodes analyzer library for x86 architectures.

Disassembler

Features:

  • Support x86 and x86-64 architectures.
  • Support Intel and AMD instructions.
  • Support mostly all instructions found in Intel and AMD documentations, including:
    • FPU,MMX;
    • SSE,SSE2,SSE3,SSSE3,SSE4.1,SSE4.2,SSE5;
    • 3DNOW;
    • AES, MPX, F16C, TSX, VME, BMI, BMI2 …
    • FMA,FMA4;
    • AVX,AVX2;
    • AVX512F, AVX512BW, AVX512CD, AVX512DQ, AVX512ER, AVX512PF, AVX512VBMI, AVX512IFMA.
  • Support REX, DREX, VEX, EVEX and XOP instructions encoding.
  • EFlags/RFlags: UnivDisasm can recognize instructions that may affect, modify or reset EFlags/RFlags register.
  • Instructions are grouped into two order: instructions groups and instructions categories.
  • Each instruction has its own identifier make it easy to find and match decoded instructions.
  • Detect instruction's table.
  • Branch instructions: UnivDisasm recognize branch and calculate the destination address, make it easy for you to follow branch instructions.
  • Support VSIB memory addressing.
  • Support Intel enhancement syntax:
  • Masking.
  • Zeroing.
  • Rounding.
  • Broadcasting.
  • Support the compressed displacement disp8*N.
  • Reconize pseudo-ops instructions such as CMPPS.
  • Built-in analyzer to recognize warnings and errors.
  • Safe: UnivDisasm was designed to be safe, that’s mean it’s safe for multi threads (thread safe).And provides built-in mechanisms for errors and safe bytes reading.
  • Faster: Due to its coding architecture, UnivDisasm is considered to be faster to decode instructions.
  • Customized: UnivDisasm has an open architecture allowing for easy to extend for others syntax. You can have your own assembler syntax with less code writing!

Examples The left side is the instructions opcodes and the right side is the full instructions str decoded by UnivDisasm.

[$48,$8B,$04,$55,$56,$34,$12,$00] : # mov rax,qword [rdx*2+0x00123456]
[$48,$69,$C1,$05,$00,$00,$00] :     # imul rax,rcx,00000005
[$FF,$35,$23,$01,$00,$00    ] :     # push qword [rip 0x00000123]
[$D8,$C7                    ] :     # fadd st(0),st(7)
[$DC,$EF                    ] :     # fsub st(7),st(0)
[$62,$01,$95,$C7,$58,$F4                 ]  :  # vaddpd zmm30{k7}{z},zmm29,zmm28         
[$62,$01,$95,$10,$58,$F4                 ]  :  # vaddpd zmm30,zmm29,zmm28,{rn-sae}       
[$62,$01,$95,$70,$58,$F4                 ]  :  # vaddpd zmm30,zmm29,zmm28,{rz-sae}       
[$62,$91,$0C,$47,$C2,$ED,$19             ]  :  # vcmpnge_uqps k5{k7},zmm30,zmm29         
[$62,$03,$15,$00,$21,$F4,$AB             ]  :  # vinsertps xmm30,xmm29,xmm28,0xab        
[$62,$63,$15,$50,$03,$72,$7F,$7B         ]  :  # valignd zmm30,zmm29,dword disp8[rdx+0x1fc]{1to16},0x7b
[$62,$62,$95,$50,$65,$72,$80             ]  :  # vblendmpd zmm30,zmm29,qword disp8[rdx-0x400]{1to8}
[$62,$02,$FD,$41,$92,$74,$39,$20         ]  :  # vgatherdpd zmm30{k1},qword disp8[r9+ymm31*1+0x100]
[$62,$63,$95,$47,$3A,$B2,$E0,$EF,$FF,$FF,$7B]  :  # vinserti64x4 zmm30{k7},zmm29,yword [rdx-0x1020],0x7b
[$62,$63,$15,$50,$03,$B2,$00,$02,$00,$00,$7B]  :  # valignd zmm30,zmm29,dword [rdx+0x200]{1to16},0x7b
[$62,$02,$FD,$41,$92,$B4,$FE,$7B,$00,$00,$00]  :  # vgatherdpd zmm30{k1},qword [r14+ymm31*8+0x7b]
[$62,$02,$FD,$41,$92,$B4,$FE,$7B,$00,$00,$00]  :  # vgatherdpd zmm30{k1},qword [r14+ymm31*8+0x7b]
[$62,$22,$FD,$41,$92,$B4,$B9,$00,$04,$00,$00]  :  # vgatherdpd zmm30{k1},qword [rcx+ymm31*4+0x400]
[$62,$02,$7D,$41,$92,$B4,$FE,$7B,$00,$00,$00]  :  # vgatherdps zmm30{k1},dword [r14+zmm31*8+0x7b]
[$62,$02,$7D,$41,$92,$B4,$FE,$7B,$00,$00,$00]  :  # vgatherdps zmm30{k1},dword [r14+zmm31*8+0x7b]
[$62,$B1,$0C,$40,$C2,$AC,$F0,$23,$01,$00,$00,$1A]  :  # vcmpngt_uqps k5,zmm30,zword [rax+r14*8+0x123]

Sample Dump (not all features are included):

# [0x62 0x61 0x95 0x40 0x58 0x72 0x7F]
# vaddpd zmm30,zmm29,zword disp8[rdx+0x1fc0]
ins.Prefixes.EVEXPrf.Flags := PF_USED + PF_VALID
ins.Encoding := ENC_EVEX
ins.AddressMode = AM_64
ins.ModRm.Value = 0x72
ins.ModRm.Value.Mod = 1
ins.ModRm.Value.Reg = 6
ins.ModRm.Value.Rm  = 2
ins.Disp.Flags = DF_USED + DF_DISP8N
ins.Disp.N     = 64
ins.Disp.Value = 0x1FC0
ins.Disp.Size  = SIZE_WORD
ins.InstID     = INST_ID_VADDPD
ins.Mnem       = INST_MNEM_VADDPD
ins.InstGroups = INST_GRP_AVX512F + INST_GRP_VL
ins.nArg       = 3 
ins.Arg1.Flags = AF_REG
ins.Arg1.Size  = SIZE_ZWORD
ins.Arg1.Reg   = REG_ZMM30
ins.Arg2.Flags = AF_REG
ins.Arg2.Size  = SIZE_ZWORD
ins.Arg2.Reg   = REG_ZMM29
ins.Arg3.Flags = AF_MEM
ins.Arg3.Size  = SIZE_ZWORD
ins.Arg3.Mem.BaseReg = REG_RDX
...
...

Command line

UnivDisasm has a command line tool to disasm sequence of bytes of opcodes.

Usage: UnivDisasm [<Options>][<OpCodes>...]

  • Options:
  • -h : Display help.
  • -v : Vendor = <*Intel,AMD,CENTAUR>.
  • -x : Architecture = *32 or 64.
    • means default to this value if not specified.
  • OpCodes: Sequence of bytes of opcodes.
  • Note: If you are using hex format, each byte must be preceded by (0x or $) prefix.

Eg: UnivDisasm.exe -v intel -x 32 "0x62 0x02 0x95 0x40 0x65 0xF4"

Simple GUI

A simple graphical user interface (GUI) to list UnivDisasm capability.

GUI

Analyzer

UnivDisasm has a powerful analyzer, make it easy to find errors and detect for warnings.

Features:

  • Detect instructions that may cause crash if executed.
  • Detect wrong prefixes combining.
  • Detect wrong address memory.
  • Detect wrong segment registers.
  • Detect for unlockable instructions.
  • Detect instructions that doesn’t initialize BND registers.

Errors recognized by Analyzer:

 { Errors }
  ERROR_SUCCESS                     : No errors detected.
  ERROR_INVALID_OPERAND_SIZE        : Invalid J size.
  ERROR_INVALID_EFFECTIVE_ADDRESS   : Invalid memory address => May cause AV.
  ERROR_INVALID_ADDRESS_MODE        : Invalid Address mode.
  ERROR_VL_EXPECTED_UPPER           : Vector length size must be YWORD or ZWORD.
  ERROR_VL_EXPECTED_LOWER           : Vector length size must be OWORD or YWORD.
  ERROR_INVALID_SEGMENT        		: Invalid segment register.
  ERROR_INVALID_VEX_ESCAPE    		: Invalid VEX prefix escape.
  ERROR_INVALID_EVEX_ESCAPE  		: Invalid EVEX prefix escape.
  ERROR_INVALID_XOP_ESCAPE  		: Invalid XOP prefix escape.
  ERROR_EXCEEDED_SAFE_LENGTH 	    : Exceeded Safe length.
  ERROR_SIB_EXPECTED 
  ERROR_RELATIVE_ADDRESS_PROHIBITED 
  ERROR_INVALID_OPCODE 
  ERROR_INTERNAL  					: Internal Error

Warnings recognized by Analyzer:

  { Warnings }
  WARN_NIL  { No warnings }
  WARN_INST_NOT_LOCKABLE  : Instruction not lockable.
  WARN_XAQUIRE_INVALID  : Invalid XAQUIRE prefix.
  WARN_REPNE_INVALID  : Invalid REPNE prefix.
  WARN_REP_INVALID  : Invalid REP prefix.
  WARN_REPE_INVALID  : Invalid REPE prefix.
  WARN_XRELEASE_INVALID 
  WARN_SUPERFLUOUS_PREFIX  : Prefix found , but not required.
  WARN_XAQUIRE_NEED_LOCK  : XAQUIRE prefix require LOCK prefix.
  WARN_XRELEASE_NEED_LOCK  : XRELEASE prefix require LOCK prefix.
  WARN_SOURCE_OPERAND_NOT_MEM  : Source operand must be memory.
  WARN_CS_PREFIX_IGNORED  : CS segment override prefix is ignored.
  WARN_DS_PREFIX_IGNORED  : DS segment override prefix is ignored.
  WARN_SS_PREFIX_IGNORED  : SS segment override prefix is ignored.
  WARN_ES_PREFIX_IGNORED  : ES segment override prefix is ignored.
  WARN_BND_NO_INIT  : Instruction doesn't init bnd regs.
  WARN_INDEX_REG_NOT_USED_IN_EAC  : Index register is not used in effective address calculation.

Delphinus-Support :

Do you use Delphinus ? You may want to install UnivDisasm from Delphinus.