Page 1 of 1

Win x64 : Bug with ExamineAssembly ? i get an invalid

Posted: Sun Jul 17, 2011 9:38 am
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 ?

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

Posted: Sun Jul 17, 2011 11:29 am
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

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

Posted: Wed Jul 20, 2011 9:49 am
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.

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

Posted: Wed Jul 20, 2011 4:30 pm
by xorc1zt

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

Posted: Wed Jul 20, 2011 4:50 pm
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

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

Posted: Wed Jul 20, 2011 7:08 pm
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$)

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

Posted: Wed Jul 20, 2011 11:39 pm
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.

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

Posted: Thu Jul 21, 2011 10:40 am
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]"

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

Posted: Wed Feb 24, 2021 3:12 pm
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   
---------------------------

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

Posted: Thu Feb 25, 2021 2:55 am
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

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

Posted: Thu Feb 25, 2021 3:22 am
by BarryG
It's weird because it says "Invalid" for "Sleep_(255)", but disassembles "Sleep_(254)" and "Sleep_(256)" without any problems.