Win x64 : Bug with ExamineAssembly ? i get an invalid

Just starting out? Need help? Post your questions and find answers here.
User avatar
Comtois
Addict
Addict
Posts: 1431
Joined: Tue Aug 19, 2003 11:36 am
Location: Doubs - France

Win x64 : Bug with ExamineAssembly ? i get an invalid

Post by Comtois »

Doc example :

Code: Select all

  DisableDebugger ; do not disassemble any debugger related instructions
  Code_Start:
    ; Place code to be disassembled here
    a = (Random(100) * 5) + 2000
  Code_End:
  
  Text$ = "Disassembled code: " + Chr(13)  
  If ExamineAssembly(?Code_Start, ?Code_End)
    While NextInstruction()
      Text$ + RSet(Hex(InstructionAddress()), SizeOf(Integer)*2, "0")
      Text$ + " " + InstructionString() + Chr(13)
    Wend
  EndIf
  
  MessageRequester("Result", Text$)
I get this
---------------------------
Result
---------------------------
Disassembled code:
000000014000107C push dword 0x64
0000000140001081 pop rcx
0000000140001082 call dword 0x40005d28
0000000140001087 mov r15, rax
000000014000108A invalid

---------------------------
OK
---------------------------
is it normal ?
Please correct my english
http://purebasic.developpez.com/
Helle
Enthusiast
Enthusiast
Posts: 178
Joined: Wed Apr 12, 2006 7:59 pm
Location: Germany
Contact:

Re: Win x64 : Bug with ExamineAssembly ? i get an invalid

Post by Helle »

Udis86 is sh...
My own disassembler gives:
$0000000140001045 68 64 00 00 00 PUSH 00 00 00 00 00 00 00 64
$000000014000104A 59 POP RCX
$000000014000104B E8 6C 10 00 00 CALL 00 00 00 01 40 00 20 BC
$0000000140001050 49 89 C7 MOV R15 , RAX
$0000000140001053 4D 6B FF 05 IMUL R15 , R15 , 05
$0000000140001057 49 81 C7 D0 07 00 00 ADD R15 , 00 00 00 00 00 00 07 D0
$000000014000105E 4C 89 3D 2B 41 00 00 MOV qword ptr [ 00 00 00 01 40 00 51 90 ] , R15

Gruss
Helle
Thorium
Addict
Addict
Posts: 1305
Joined: Sat Aug 15, 2009 6:59 pm

Re: Win x64 : Bug with ExamineAssembly ? i get an invalid

Post by Thorium »

The disassembler lib used in PB is pretty bad. You can't rely on it. There are a lot of instructions, it can not disassemble. It's the same for x86.
xorc1zt
Enthusiast
Enthusiast
Posts: 276
Joined: Sat Jul 09, 2011 7:57 am

Re: Win x64 : Bug with ExamineAssembly ? i get an invalid

Post by xorc1zt »

Helle
Enthusiast
Enthusiast
Posts: 178
Joined: Wed Apr 12, 2006 7:59 pm
Location: Germany
Contact:

Re: Win x64 : Bug with ExamineAssembly ? i get an invalid

Post by Helle »

Ha, I would write this for a few minutes! Take the BeaEngine(64).dll (read the license!) and use this:

Code: Select all

;- Usage of BeaEngine 4.1, 32/64-Bit-Windows
;- "Helle" Klaus Helbing, 20.07.2011, PB4.51, x86/x64

Begin_TestCode:

   ; Place code to be disassembled here
   a = (Random(100) * 5) + 2000 ;Comtois
 
End_TestCode:

XIncludeFile "BeaEnginePB.pbi"              ;the header
;- show the disassembled code between Begin_TestCode and End_TestCode
CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
  DLLOK = OpenLibrary(0, "BeaEngine.dll")   ;or with path
  Architecture = $0 
  Prototype.i ProtoDisasm0()
  Revision.ProtoDisasm0 = GetFunction(0, "_BeaEngineRevision@0")
  Version.ProtoDisasm0 = GetFunction(0, "_BeaEngineVersion@0")
  Prototype.i ProtoDisasm1(Var1.i)
  LenInstr.ProtoDisasm1 = GetFunction(0, "_Disasm@4")  
 CompilerElse                               ;#PB_Compiler_Processor = #PB_Processor_x64
  DLLOK = OpenLibrary(0, "BeaEngine64.dll") ;or with path
  Architecture = $40
  Prototype.i ProtoDisasm0()
  Revision.ProtoDisasm0 = GetFunction(0, "BeaEngineRevision")
  Version.ProtoDisasm0 = GetFunction(0, "BeaEngineVersion")
  Prototype.i ProtoDisasm1(Var1.i)
  LenInstr.ProtoDisasm1 = GetFunction(0, "Disasm")  
CompilerEndIf

If DLLOK
  MyDisasm._Disasm\EIP = ?Begin_TestCode
  MyDisasm._Disasm\Archi = Architecture 
  While MyDisasm._Disasm\EIP < ?End_TestCode
    OP$=""
    Len = LenInstr(@MyDisasm._Disasm\EIP)   
    If Len = #OUT_OF_BLOCK Or Len = #UNKNOWN_OPCODE   ;or Select/Case 
      Break
    EndIf
    For j = 0 To Len - 1
      OP$ + RSet(Hex(PeekB(MyDisasm._Disasm\EIP + j) & $FF), 2, "0") + " "    
    Next    
    ASM$ + Hex(MyDisasm._Disasm\EIP) + "   " + OP$ + Space(80 - 1.67 * Len(OP$)) + PeekS(@MyDisasm._Disasm\CompleteInstr, 64, #PB_Ascii) + #CRLF$    ;Space for optic
    MyDisasm._Disasm\EIP + Len
  Wend
  BE$ = " , BeaEngine Version " + PeekS(Version()) + " , Revision " + PeekS(Revision())    
  CloseLibrary(0) 
  ;SetClipboardText(ASM$)               ;only for copy the output-string
  OpenWindow(0, 0, 0, 700, 600, "Using BeaEngine with PureBasic" + BE$, #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  StringGadget(0, 10, 10, 680, 580, ASM$, #PB_String_ReadOnly | #ES_MULTILINE | #ESB_DISABLE_LEFT | #ESB_DISABLE_RIGHT | #WS_VSCROLL)   
  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
  CloseWindow(0)
 Else 
  MessageRequester("Error!", "Please test the DLL or the path!")
EndIf
This is the BeaEnginePB.pbi:

Code: Select all

; *****************************************
;
;   Header for BeaEngine 4.1 (PureBasic 4.51, x86/x64)
;  "Helle" Klaus Helbing, 20.07.2011
;   Save this as BeaEnginePB.pbi
;
; *****************************************

Structure REX_Struct
  W_.b
  R_.b
  X_.b
  B_.b
  state.b
EndStructure 

Structure PREFIXINFO
  Number.l
  NbUndefined.l
  LockPrefix.b
  OperandSize.b
  AddressSize.b
  RepnePrefix.b
  RepPrefix.b
  FSPrefix.b
  SSPrefix.b
  GSPrefix.b
  ESPrefix.b
  CSPrefix.b
  DSPrefix.b
  BranchTaken.b
  BranchNotTaken.b
  REX.REX_Struct
EndStructure

Structure EFLStruct
  OF_.b                      ;(bit 11)
  SF_.b                      ;(bit 7)
  ZF_.b                      ;(bit 6)
  AF_.b                      ;(bit 4)
  PF_.b                      ;(bit 2)
  CF_.b                      ;(bit 0)
  TF_.b                      ;(bit 8)
  IF_.b                      ;(bit 9)
  DF_.b                      ;(bit 10)
  NT_.b                      ;(bit 14)
  RF_.b                      ;(bit 16)
  AL_.b                      ;alignment
EndStructure

Structure MEMORYTYPE
  BaseRegister.l
  IndexRegister.l
  Scale.l
  Displacement.q
EndStructure

Structure INSTRTYPE
  Category.l
  Opcode.l
  Mnemonic.b[16]
  BranchType.l
  Flags.EFLStruct
  AddrValue.q
  Immediat.q
  ImplicitModifiedRegs.l
EndStructure

Structure ARGTYPE
  ArgMnemonic.b[32]
  ArgType.l
  ArgSize.l
  AccessMode.l
  Memory.MEMORYTYPE
  SegmentReg.l
EndStructure

Structure _Disasm
  EIP.i
  VirtualAddr.q
  SecurityBlock.l
  CompleteInstr.b[64]
  Archi.l
  Options.q
  Instruction.INSTRTYPE
  Argument1.ARGTYPE
  Argument2.ARGTYPE
  Argument3.ARGTYPE
  Prefix.PREFIXINFO
  Reserved.l[40]  
EndStructure

#ESReg = 1
#DSReg = 2
#FSReg = 3
#GSReg = 4
#CSReg = 5
#SSReg = 6

; ********** Prefixes
#InvalidPrefix      = 4
#InUsePrefix        = 1
#SuperfluousPrefix  = 2
#NotUsedPrefix      = 0
#MandatoryPrefix    = 8

; ********** EFLAGS states
#TE_ = 1                     ;test
#MO_ = 2                     ;modify
#RE_ = 4                     ;reset
#SE_ = 8                     ;set
#UN_ = 16                    ;undefined
#PR_ = 32                    ;restore prior value

; __________________________________________________________________________________________________________
;
;                                       INSTRUCTION_TYPE
; __________________________________________________________________________________________________________

#GENERAL_PURPOSE_INSTRUCTION = $00010000
#FPU_INSTRUCTION             = $00020000
#MMX_INSTRUCTION             = $00040000
#SSE_INSTRUCTION             = $00080000
#SSE2_INSTRUCTION            = $00100000
#SSE3_INSTRUCTION            = $00200000
#SSSE3_INSTRUCTION           = $00400000
#SSE41_INSTRUCTION           = $00800000
#SSE42_INSTRUCTION           = $01000000
#SYSTEM_INSTRUCTION          = $02000000
#VM_INSTRUCTION              = $04000000
#UNDOCUMENTED_INSTRUCTION    = $08000000
#AMD_INSTRUCTION             = $10000000

#ILLEGAL_TYPE                = $20000000
#SUPERFLUOUS_PREFIX          = $40000000
#INCOMPATIBLE_TYPE           = $80000000
    

#DATA_TRANSFER               = 1
#ARITHMETIC_INSTRUCTION      = 2
#LOGICAL_INSTRUCTION         = 3
#SHIFT_ROTATE                = 4
#BIT_BYTE                    = 5
#CONTROL_TRANSFER            = 6
#STRING_INSTRUCTION          = 7
#InOutINSTRUCTION            = 8
#ENTER_LEAVE_INSTRUCTION     = 9
#FLAG_CONTROL_INSTRUCTION    = 10
#SEGMENT_REGISTER            = 11
#MISCELLANEOUS_INSTRUCTION   = 12

#COMPARISON_INSTRUCTION      = 13
#LOGARITHMIC_INSTRUCTION     = 14
#TRIGONOMETRIC_INSTRUCTION   = 15
#UNSUPPORTED_INSTRUCTION     = 16
    
#LOAD_CONSTANTS              = 17
#FPUCONTROL                  = 18
#STATE_MANAGEMENT            = 19

#CONVERSION_INSTRUCTION      = 20

#SHUFFLE_UNPACK              = 21
#PACKED_SINGLE_PRECISION     = 22
#SIMD128bits                 = 23
#SIMD64bits                  = 24
#CACHEABILITY_CONTROL        = 25
   
#FP_INTEGER_CONVERSION       = 26 
#SPECIALIZED_128bits         = 27
#SIMD_FP_PACKED              = 28
#SIMD_FP_HORIZONTAL          = 29 
#AGENT_SYNCHRONISATION       = 30

#PACKED_ALIGN_RIGHT          = 31  
#PACKED_SIGN                 = 32

; ****************************************** SSE4
    
#PACKED_BLENDING_INSTRUCTION = 33
#PACKED_TEST                 = 34
    
; CONVERSION_INSTRUCTION -> Packed Integer Format Conversions et Dword Packing With Unsigned Saturation
; COMPARISON -> Packed Comparison SIMD Integer Instruction
; ARITHMETIC_INSTRUCTION -> Dword Multiply Instruction
; DATA_TRANSFER -> POPCNT

#PACKED_MINMAX               = 35
#HORIZONTAL_SEARCH           = 36
#PACKED_EQUALITY             = 37
#STREAMING_LOAD              = 38
#INSERTION_EXTRACTION        = 39
#DOT_PRODUCT                 = 40
#SAD_INSTRUCTION             = 41
#ACCELERATOR_INSTRUCTION     = 42
#ROUND_INSTRUCTION           = 43

; __________________________________________________________________________________________________________
;
;                                       BranchTYPE
; __________________________________________________________________________________________________________

#Jo_                         = 1
#Jno_                        = -1
#Jc_                         = 2
#Jnc_                        = -2
#Je_                         = 3
#Jne_                        = -3
#Ja_                         = 4
#Jna_                        = -4
#Js_                         = 5
#Jns_                        = -5
#Jp_                         = 6
#Jnp_                        = -6
#Jl_                         = 7
#Jnl_                        = -7
#Jg_                         = 8
#Jng_                        = -8
#Jb_                         = 9
#Jnb_                        = -9
#Jecxz_                      = 10
#JmpType                     = 11
#CallType                    = 12
#RetType                     = 13

; __________________________________________________________________________________________________________
;
;                                       ARGUMENTS_TYPE
; __________________________________________________________________________________________________________

#NO_ARGUMENT                 = $10000000
#REGISTER_TYPE               = $20000000
#MEMORY_TYPE                 = $40000000
#CONSTANT_TYPE               = $80000000

#MMX_REG                     = $00010000
#GENERAL_REG                 = $00020000
#FPU_REG                     = $00040000
#SSE_REG                     = $00080000
#CR_REG                      = $00100000
#DR_REG                      = $00200000
#SPECIAL_REG                 = $00400000
#MEMORY_MANAGEMENT_REG       = $00800000       ; GDTR (REG0), LDTR (REG1), IDTR (REG2), TR (REG3)
#SEGMENT_REG                 = $01000000       ; ES (REG0), CS (REG1), SS (REG2), DS (REG3), FS (REG4), GS (REG5)

#RELATIVE_                   = $04000000
#ABSOLUTE_                   = $08000000

#Read                        = 1
#WRITE                       = 2
; ************ Regs
#REG0                        = 1
#REG1                        = 2
#REG2                        = 4
#REG3                        = 8
#REG4                        = $10
#REG5                        = $20
#REG6                        = $40
#REG7                        = $80
#REG8                        = $100
#REG9                        = $200
#REG10                       = $400
#REG11                       = $800
#REG12                       = $1000
#REG13                       = $2000
#REG14                       = $4000
#REG15                       = $8000

; ************ SPECIAL_REG
#UNKNOWN_OPCODE              = -1
#OUT_OF_BLOCK                = 0
#NoTabulation                = 0
#Tabulation                  = 1
#MasmSyntax                  = 0
#GoAsmSyntax                 = $100
#NasmSyntax                  = $200
#PrefixedNumeral             = $10000
#SuffixedNumeral             = 0
#ShowSegmentRegs             = $01000000
Helle
User avatar
Psychophanta
Always Here
Always Here
Posts: 5153
Joined: Wed Jun 11, 2003 9:33 pm
Location: Anare
Contact:

Re: Win x64 : Bug with ExamineAssembly ? i get an invalid

Post by Psychophanta »

Thorium wrote:The disassembler lib used in PB is pretty bad. You can't rely on it. There are a lot of instructions, it can not disassemble. It's the same for x86.
As long as i know, there is a bijection, i.e. for each asm mnemonic instruction is only an opcode, and for each opcode is only the correponding asm mnemonic, so Can not understand why is bad a dissasembler.

BTW, this does not return any asm at win i386, which is a bug:

Code: Select all

  DisableDebugger ; do not disassemble any debugger related instructions
  f1.f=45
  f2.f=4
  Code_Start:
  a.f=Mod(f1,f2)
  Code_End:
  Debug a
  Text$ = "Disassembled code: " + Chr(13)  
  If ExamineAssembly(?Code_Start, ?Code_End)
    While NextInstruction()
      Text$ + RSet(Hex(InstructionAddress()), SizeOf(Integer)*2, "0")
      Text$ + " " + InstructionString() + Chr(13)
    Wend
  EndIf
  
  MessageRequester("Result", Text$)
http://www.zeitgeistmovie.com

while (world==business) world+=mafia;
Thorium
Addict
Addict
Posts: 1305
Joined: Sat Aug 15, 2009 6:59 pm

Re: Win x64 : Bug with ExamineAssembly ? i get an invalid

Post by Thorium »

Psychophanta wrote:
Thorium wrote:The disassembler lib used in PB is pretty bad. You can't rely on it. There are a lot of instructions, it can not disassemble. It's the same for x86.
As long as i know, there is a bijection, i.e. for each asm mnemonic instruction is only an opcode, and for each opcode is only the correponding asm mnemonic, so Can not understand why is bad a dissasembler.
As i wrote, it's bad because it actualy does not know all opcodes and can not disassemble all the code you can throw at it.
User avatar
Psychophanta
Always Here
Always Here
Posts: 5153
Joined: Wed Jun 11, 2003 9:33 pm
Location: Anare
Contact:

Re: Win x64 : Bug with ExamineAssembly ? i get an invalid

Post by Psychophanta »

Thorium wrote:
Psychophanta wrote:
Thorium wrote:The disassembler lib used in PB is pretty bad. You can't rely on it. There are a lot of instructions, it can not disassemble. It's the same for x86.
As long as i know, there is a bijection, i.e. for each asm mnemonic instruction is only an opcode, and for each opcode is only the correponding asm mnemonic, so Can not understand why is bad a dissasembler.
As i wrote, it's bad because it actualy does not know all opcodes and can not disassemble all the code you can throw at it.
Yes, i know i know, but i just don't understand why there is not a dissasembler which doesn't know ALL opcodes correctly, because it is just a pure bijection map:
"uP opcode, [data]" -> "asm mnemonic, [data]"
http://www.zeitgeistmovie.com

while (world==business) world+=mafia;
BarryG
Addict
Addict
Posts: 4178
Joined: Thu Apr 18, 2019 8:17 am

Re: Win x64 : Bug with ExamineAssembly ? i get an invalid

Post by BarryG »

This also fails to disassemble:

Code: Select all

DisableDebugger ; Do not disassemble any debugger related instructions.

Code_Start:
; Place code to be disassembled here.
Sleep_(255)
Code_End:

If ExamineAssembly(?Code_Start,?Code_End)
  While NextInstruction()
    text$+RSet(Hex(InstructionAddress()),SizeOf(Integer)*2,"0")
    text$+" "+InstructionString()+#LF$
  Wend
EndIf

MessageRequester("Result",text$,#PB_MessageRequester_Info)
It shows this messagebox:

Code: Select all

---------------------------
Result
---------------------------
0040107B invalid 
---------------------------
OK   
---------------------------
User avatar
Keya
Addict
Addict
Posts: 1890
Joined: Thu Jun 04, 2015 7:10 am

Re: Win x64 : Bug with ExamineAssembly ? i get an invalid

Post by Keya »

I agree with Helle, the Udis86 disassembler that PB uses is very outdated, and becoming more useless every year.
Beaengine is okish, but the best disassembler I'm aware of is the opensource Capstone, which is implemented in pure C so it's easily integrated with PB
https://www.capstone-engine.org
Last edited by Keya on Thu Feb 25, 2021 3:29 am, edited 1 time in total.
BarryG
Addict
Addict
Posts: 4178
Joined: Thu Apr 18, 2019 8:17 am

Re: Win x64 : Bug with ExamineAssembly ? i get an invalid

Post by BarryG »

It's weird because it says "Invalid" for "Sleep_(255)", but disassembles "Sleep_(254)" and "Sleep_(256)" without any problems.
Post Reply