Author Topic: disassembler  (Read 4317 times)

0 Members and 1 Guest are viewing this topic.

Offline NOVARSEG

  • Forum Resident
  • Posts: 509
    • View Profile
disassembler
« on: February 19, 2021, 03:55:08 am »
press any key to scroll thru EXE file

Change the file name to what you want.

Very limited right now. Need to add more instructions

Code: QB64: [Select]
  1. OPEN "atestasm.exe" FOR BINARY AS #1
  2. DIM count AS LONG
  3.  
  4. DIM hexString AS STRING
  5.  
  6.  
  7. T = SPACE$(LOF(1))
  8. GET #1, , T
  9. x = 1
  10.  
  11.     IF x > LOF(1) - 10 THEN EXIT DO
  12.  
  13.     x = x + 1
  14.     IF ASC(T, x) = &HC7 THEN
  15.         x = x + 1:
  16.         IF ASC(T, x) = &H00 THEN
  17.             Z = Z + 1
  18.             GOSUB hex4
  19.             PRINT: PRINT "MOV [EAX], "; hexString
  20.         END IF
  21.     END IF
  22.  
  23.  
  24.  
  25.     x = x + 1
  26.     IF ASC(T, x) = &HA1 THEN
  27.         Z = Z + 1
  28.         GOSUB hex4
  29.         PRINT: PRINT "MOV EAX, "; "[ "; hexString; "]"
  30.     END IF
  31.  
  32.  
  33.     IF Z = 10 THEN
  34.         Z = 0
  35.         DO
  36.             i$ = INKEY$
  37.             IF i$ = CHR$(27) THEN END
  38.             IF i$ <> "" THEN EXIT DO
  39.         LOOP
  40.     END IF
  41.  
  42.  
  43.  
  44.  
  45.  
  46.  
  47. hex4:
  48. hexString = ""
  49.     IF xx = 4 THEN xx = 0: EXIT DO
  50.     xx = xx + 1
  51.     A = ASC(T, x + xx)
  52.     R = A MOD 16
  53.     IF R < 10 THEN
  54.         hx = CHR$(R + 48)
  55.     END IF
  56.     IF R >= 10 THEN
  57.         hx = CHR$(R + 55)
  58.     END IF
  59.  
  60.     A = A - R
  61.     A = A / 16
  62.     IF A < 10 THEN
  63.         hx = CHR$(A + 48) + hx
  64.     END IF
  65.     IF A >= 10 THEN
  66.         hx = CHR$(A + 55) + hx
  67.     END IF
  68.  
  69.     hexString = hx + " " + hexString
  70.     hx = ""
  71.  
  72. x = x + 4
  73.  


Offline NOVARSEG

  • Forum Resident
  • Posts: 509
    • View Profile
Re: disassembler
« Reply #1 on: February 21, 2021, 11:42:29 pm »
I'm using some online disassemblers and other sources to make sure code is working. I found that most of the online disassemblers make mistakes example:

83 C0  FF    =   ADD EAX, FFFF

which is wrong for 32 bit assembler

it should be  for 32 bit
83 C0  FFFF   = ADD EAX, FFFF

For 16 bit :
83 C0  FF = ADD AX, FF

********
Also for 32 bit
81 C0  FFFFFFFF   = ADD EAX, FFFFFFFF

for 16 bit
81 C0  FFFF   = ADD AX, FFFF


Another thing, writing a disassembler is not easy!



« Last Edit: February 21, 2021, 11:48:27 pm by NOVARSEG »

Offline NOVARSEG

  • Forum Resident
  • Posts: 509
    • View Profile
Re: disassembler
« Reply #2 on: February 22, 2021, 01:50:08 am »
Ok I've checked about 5 online disassemblers so far and they are all consistently wrong??

83 C0  FF    =   ADD EAX, FFFF

How can that be?

83 C0  EE    =   ADD EAX, FFFFFFEE  ?????

Are these online disassemblers all using the same program ???




Offline NOVARSEG

  • Forum Resident
  • Posts: 509
    • View Profile
Re: disassembler
« Reply #3 on: February 23, 2021, 12:04:49 am »
Online disassemblers don't seem to be working properly.

Quote
http://shell-storm.org/online/Online-Assembler-and-Disassembler/?opcodes=83c081%0D%0A%0D%0A%0D%0A%0D%0A&arch=x86-16&endianness=big&dis_with_addr=True&dis_with_raw=True&dis_with_ins=True#disassembly

83 C0 80  =    add ax, -0x80

83 C0 81   =   add ax, -0x7f

Quote
https://defuse.ca/online-x86-assembler.htm#disassembly2

83 c0 79      =          add    eax,0x79

83 c0 80      =         add    eax,0xffffff80

Quote
https://onlinedisassembler.com/odaweb/

83c079 =  add  eax, 0x79

83c080   =  add eax,0xffffff80


« Last Edit: February 23, 2021, 12:14:12 am by NOVARSEG »

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: disassembler
« Reply #4 on: February 23, 2021, 12:53:08 am »
Seems like it’s just impossible to disassemble an EXE anymore. 
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline NOVARSEG

  • Forum Resident
  • Posts: 509
    • View Profile
Re: disassembler
« Reply #5 on: February 23, 2021, 01:06:45 am »
It's doable

From some good sources, they recommend starting with the MOV instructions and then go from there.

From my experience with 16 bit assembler, start with simple instructions, The more complex ones are based on the simple instructions.

« Last Edit: February 23, 2021, 01:11:24 am by NOVARSEG »

Offline luke

  • Administrator
  • Seasoned Forum Regular
  • Posts: 324
    • View Profile
Re: disassembler
« Reply #6 on: February 23, 2021, 08:25:56 am »
Is it perhaps, just maybe, possible that all the disassemblers are correct and you're mistaken?

Opcode 83 is "add imm8 to r/m16/m32 with sign extension", which means the imm8 is treated as a signed value that is sign-extended to the size of the destination.

0x80 sign-extended to a 32 bit number can be written as either -0x7f or 0xffffff80 by the properties of twos complement, so either output is correct.

If you're going to write something that works with x86 instructions you really can't escape sitting down with the Intel Developer Manuals.
« Last Edit: February 23, 2021, 08:27:47 am by luke »

Offline SpriggsySpriggs

  • Forum Resident
  • Posts: 1145
  • Larger than life
    • View Profile
    • GitHub
Re: disassembler
« Reply #7 on: February 23, 2021, 08:32:56 am »
This sounds quite complex
Shuwatch!

Offline NOVARSEG

  • Forum Resident
  • Posts: 509
    • View Profile
Re: disassembler
« Reply #8 on: February 23, 2021, 06:31:41 pm »
@luke

Thanks, did not know that 83 was opcode with a signed immediate value

That 2s compliment stuff is what confused me.

Quote
https://defuse.ca/online-x86-assembler.htm#disassembly2

Ok so let's use an immediate value that has a  positive  signed value  = 7FFF FFFF

The disassembler in the above link is in 32 bit mode so it should accept 4 bytes for the immediate value field.

Here is what the result is:

Quote
Disassembly:
0:  83 c0 ff                add    eax,0xffffffff
3:  ff                      (bad)
4:  ff                      (bad)
5:  7f                      .byte 0x7f

The disassembler is rejecting 3 bytes. Is this how the immediate value should be decoded?

whereas it get it right with

Quote
Disassembly:
0:  81 c0 ff ff ff 7f       add    eax,0x7fffffff

When we use a negative signed value 8000 0000 look what happens

Quote
Disassembly:
0:  83 c0 00                add    eax,0x0
3:  00 00                   add    BYTE PTR [eax],al
5:  80                      .byte 0x80

the assembler inserts an instruction in the immediate value field

but gets it right with

Quote
Disassembly:
0:  81 c0 00 00 00 80       add    eax,0x80000000
« Last Edit: February 23, 2021, 07:28:57 pm by NOVARSEG »

Offline luke

  • Administrator
  • Seasoned Forum Regular
  • Posts: 324
    • View Profile
Re: disassembler
« Reply #9 on: February 23, 2021, 07:37:08 pm »
You are wrong to assume that 0x83 takes an immediate value of varying width on difference architectures.

https://www.felixcloutier.com/x86/add Note that 0x83 always takes an imm8 argument - a single byte immediate value. It does not make sense to provide a larger number, the opcode simply doesn't work that way.

Offline NOVARSEG

  • Forum Resident
  • Posts: 509
    • View Profile
Re: disassembler
« Reply #10 on: February 23, 2021, 07:46:37 pm »
Ok imm8.   

I tried even with the disassembler in 64 bit mode and it is still imm8

opcode 83  is NOT effected by a 66h prefix byte yep

What confused me was the imm8 spec

« Last Edit: February 23, 2021, 08:10:12 pm by NOVARSEG »

Offline NOVARSEG

  • Forum Resident
  • Posts: 509
    • View Profile
Re: disassembler
« Reply #11 on: February 24, 2021, 09:58:52 pm »
..............
« Last Edit: February 25, 2021, 10:46:22 am by NOVARSEG »

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: disassembler
« Reply #12 on: February 25, 2021, 12:02:55 am »
Do you understand how negative values are stored in memory, or represented as hex values?

Run this little program, which prints out the hex values for -1 to -20, as signed bytes, integers, and longs:

Code: QB64: [Select]
  1. FOR i = 1 TO 20
  2.     v%% = -i: v% = -i: v& = -i
  3.     PRINT i,
  4.     PRINT HEX$(v%%), 'byte
  5.     PRINT HEX$(v%), 'integer
  6.     PRINT HEX$(v&) 'long

Your output should look like the following:
Code: [Select]
1       FF        FFFF      FFFFFFFF
 2       FE        FFFE      FFFFFFFE
 3       FD        FFFD      FFFFFFFD
 4       FC        FFFC      FFFFFFFC
 5       FB        FFFB      FFFFFFFB
 6       FA        FFFA      FFFFFFFA
 7       F9        FFF9      FFFFFFF9
 8       F8        FFF8      FFFFFFF8
 9       F7        FFF7      FFFFFFF7
 10      F6        FFF6      FFFFFFF6
 11      F5        FFF5      FFFFFFF5
 12      F4        FFF4      FFFFFFF4
 13      F3        FFF3      FFFFFFF3
 14      F2        FFF2      FFFFFFF2
 15      F1        FFF1      FFFFFFF1
 16      F0        FFF0      FFFFFFF0
 17      EF        FFEF      FFFFFFEF
 18      EE        FFEE      FFFFFFEE
 19      ED        FFED      FFFFFFED
 20      EC        FFEC      FFFFFFEC

Now, as you can see, the value of -1 starts as a full complement of F values.  For a byte, it's FF.  For an integer, it's FFFF.  For a long, it's FFFFFFFF.   As your negative value increases, you simply count down from there.  FE or FFFE, or FFFFFFFE.

Not only do you need to know your variable value, but you also have to know the variable type, to know what the value is.

So pushing 81 into a single byte gives you the correct value of -0x7F, for that byte. 

Now, for the x86 disassembler, you need to remember that your full x86 register is in 32-bit bytes -- EAX.

EAX is the full 32-bit value
AX is the lower 16-bits
AL is the lower 8 bits
AH is the bits 8 through 15 (zero-based)

So 81 as a byte is going to be the same as EAX FFFFFF81.

You pushed 81 into the lowest 8 bits of your 32-bit register, but the disassembler is reporting the value of the whole 32-bit EAX register for you.



And that's the great and mysterious issue you're seeing with your disassembly that has you running around in circles wondering what's going on.  It's just basically different ways of representing the same value...

81 as a signed byte = FF81 as a signed integer = FFFFFF81 as a signed long.

That's all there is to it!
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline NOVARSEG

  • Forum Resident
  • Posts: 509
    • View Profile
Re: disassembler
« Reply #13 on: February 25, 2021, 12:29:34 am »
@SMcNeill


............
« Last Edit: February 25, 2021, 12:34:05 am by NOVARSEG »

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: disassembler
« Reply #14 on: February 25, 2021, 02:20:28 am »
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!