Author Topic: Bits 32 and Bits 16  (Read 21017 times)

Offline Mezo40

  • Jr. Member
  • *
  • Posts: 8
Bits 32 and Bits 16
« on: August 15, 2011, 11:55:36 PM »
Hi everyone,  :)
I am new to NASM forums.  :)

I have a question and i hope from anyone to answer me :)


How to know if the NASM used Bits 32 or Bits 16 in compiling a binary or PE file ?
i mean if i converted a binary file to hex , which part from it will tell me if NASM used bits 32 or Bits 16 in compiling that binary file?
 and which part from the PE file will tell me if NASM used bits 16 or bits 32 in compiling it?
-----------------------------------
Thanks in advance. :)

Offline MJaoune

  • Jr. Member
  • *
  • Posts: 94
Re: Bits 32 and Bits 16
« Reply #1 on: August 16, 2011, 12:28:30 AM »
Listing files are great to use (-l), also, are you saying that you want to use a hex-editor?
I believe you can use a GUI Disassembler (Easier for you), and you can see how Registers were used or segments were seperated.

Frank Kotler is great in answering such questions, but he might answer you as soon as he gets online, he is a great guy I tell you :)

Best,
Mahmoud

Offline Bryant Keller

  • Forum Moderator
  • Full Member
  • *****
  • Posts: 360
  • Country: us
    • About Bryant Keller
Re: Bits 32 and Bits 16
« Reply #2 on: August 16, 2011, 03:24:19 AM »
If you just want to know what bit-mode you're running in during compilation, you can use the __BITS__ equate to check this.

Code: [Select]
%if __BITS__ == 16
 ; This code in 16-bit code.
%elif __BITS__ == 32
 ; This code is 32-bit code
%elfi __BITS__ == 64
 ; This code is 64-bit code
%endif

The internal BITS macro sets this value.

http://www.nasm.us/doc/nasmdoc4.html#section-4.11.5

About Bryant Keller
bkeller@about.me

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Bits 32 and Bits 16
« Reply #3 on: August 16, 2011, 04:09:00 AM »
Thanks, Mahmoud!

Mezo40 - Welcome! If your "mystery file" is an .exe format for either dos or Windows, it will begin with "MZ" (4D 5A) signature as the first two bytes. If it is for Windows, this will be followed by a "PE" (50 45) signature at an offset specified by a dword at offset 3Ch. It's at offset 70h in the .exe I'm looking at, but it can vary, I think. In this case, you'll probably recognize text in the "dos stub", "this program requires win32", or so. If it doesn't have this "PE", it's probably "bits 16", if it does, probably "bits 32". If it doesn't have "MZ", and appears to start off with code, it could be a .com format - probably "bits 16".

Or it could be something else... an executable for Linux/BSD would begin with 7F 'E' 'L' 'F' - probably "bits 32"...

It is possible for Nasm to switch bitness in mid-file - code that switches from real mode to protected mode, for example. It can be tricky (though it should be possible) to find where the switch (and back?) was done. You don't mention "bits 64" as a possibility - that would add further complication!

If you can identify an instruction that loads an immediate, you can get a clue from the size of the immediate - two bytes for "bits 16", four bytes for "bits 32"... though a 66h prefix before the opcode would reverse that. An eight byte immediate would indicate "bits 64", I guess...

Instead of hex, I sometimes use ndisasm to disassemble the file - trying "-b16", "-b32", or "-b64" to see which "makes sense". Ndisasm will try to disassemble everything in sight, whether it's code or not, so it won't all "make sense" in the best of cases...

You don't say if you're "new" or just "new to the forum". It can take some experience to figure this stuff out! Might as well start getting it, if you need to. :)

If you can't figure it out, tell us more about what you're seeing. (We don't do "reverse engineering" here, though!)

Best,
Frank


Offline Mezo40

  • Jr. Member
  • *
  • Posts: 8
Re: Bits 32 and Bits 16
« Reply #4 on: August 16, 2011, 12:17:42 PM »
Hi,
At first thank you very much for your answers :)

You don't say if you're "new" or just "new to the forum". It can take some experience to figure this stuff out! Might as well start getting it, if you need to. :)

I am new to forum and actually i didn't use NASM for a long time. :)

If you can't figure it out, tell us more about what you're seeing. (We don't do "reverse engineering" here, though!)

I don't need that for reverse engineering :)


now i have this program as a small example about what i want :) :
the first example is for a small loop that uses "bits 16" :
Code: [Select]
bits 32
jmp main

main:

.loop:
jmp .loop

and here its hex:
Code: [Select]
0xE9 0x00 0x00 0x00 0x00 EB FB
and this code is also the same code but using "bits 16" :
Code: [Select]
bits 16
jmp main

main:

.loop:
jmp .loop

and here is its hex:
Code: [Select]
0xE9 0x00 0x00 EB FB
now i didn't figure out a regular change to use it in the checking to know if it used bits 16 or 32
I only found that is the number of 0x00 before the other commands changed , in 32 is <0x00 0x00 0x00 0x00> and in 16 is <0x00 0x00> , is it a regular change? :)
--------------------------------------------
Thanks in advance.

Offline MJaoune

  • Jr. Member
  • *
  • Posts: 94
Re: Bits 32 and Bits 16
« Reply #5 on: August 16, 2011, 12:49:11 PM »
Frank, Welcome! :)

and here its hex:
Code: [Select]
0xE9 0x00 0x00 0x00 0x00 EB FB
and here is its hex:
Code: [Select]
0xE9 0x00 0x00 EB FB

As anyone would notice that 32 = 16 x 2 or 8 x 4, that is why you have only 2 "0x00"s in the 16 bit program (8 x 2), and you have got 4 "0x00"s in a 32 bit program (8x4 or 16x2)

Since every 0x00 is treated as 8 bits in memory, I think ???

Best,
Mahmoud

Offline Mezo40

  • Jr. Member
  • *
  • Posts: 8
Re: Bits 32 and Bits 16
« Reply #6 on: August 16, 2011, 01:24:20 PM »
hm , then its a regular change , thank you Mahmoud :)

Offline Mezo40

  • Jr. Member
  • *
  • Posts: 8
Re: Bits 32 and Bits 16
« Reply #7 on: August 16, 2011, 01:44:16 PM »
I made another try , i found that it isn't a regular change :(

Offline Mezo40

  • Jr. Member
  • *
  • Posts: 8
Re: Bits 32 and Bits 16
« Reply #8 on: August 16, 2011, 02:14:01 PM »
OK , i found another way to get it :D,
after the "jmp main" in the last example, if the bits 32 used , you will find
0x00 0x00 0x00 0x00 , but if the bits 16 used you will find after "jmp main" 0x00 0x00
Thank you very much for your replies :D

Offline MJaoune

  • Jr. Member
  • *
  • Posts: 94
Re: Bits 32 and Bits 16
« Reply #9 on: August 16, 2011, 05:11:58 PM »
OK , i found another way to get it :D,
after the "jmp main" in the last example, if the bits 32 used , you will find
0x00 0x00 0x00 0x00 , but if the bits 16 used you will find after "jmp main" 0x00 0x00
Thank you very much for your replies :D

Yup, maybe some assemblers automatically add the "bits32" or "bits16" before every label.

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Bits 32 and Bits 16
« Reply #10 on: August 16, 2011, 07:42:06 PM »
"jmp" is kind of a tricky one to judge, since it comes in two forms - "jmp short" and "jmp near". "near", rather unintuitively, being the larger. "jmp short" has only a one byte operand - a "signed byte" - which will jump forward or backward by +/-127 bytes. "Old Nasm" defaulted to "near" if you just say "jmp". Newer versions will automatically use "jmp short" if it will fit. This is evidently what you've got - notice that "jmp main" (the label has not yet been "seen") uses "jmp near main", but "jmp .loop" (the label has been "seen") uses "jmp short .loop". If you use the "-O" switch on the command line - I used to use "-O999" - Nasm would use multiple passes and would see that "jmp main" could be "jmp short main". At some point, "-Ox" could be used (some very large number of passes). Newest versions (from 2.07 or 2.08, I think) default to using "-Ox", and you'd have to use "-O0" to get it to not optimize. You can't tell from "jmp short" whether you've got 16-bit or 32-bit code - they both use a one-byte operand. If you specify "jmp near", you'll get the two-byte (16 bit) or four byte (32 bit) operand. So it matters which version of Nasm you're using.

What I had in mind for observing the size of an immediate was like:

Code: [Select]
mov ax, 1
mov eax, 1

With "bits 16" (the default for "-f bin" or "-f obj") you'll see 0xB8 0x01 0x00 0x66 0xB8 0x01 0x00 0x00 0x00. With "bits 32", you'll see 0x66 0xB8 0x01 0x00 0xB8 0x01 0x00 0x00 0x00. Notice that the opcode 0xB8 is the same - in 16-bit code, we use ax and two bytes to store the 1, the 0x66 "size override prefix" tells us to use eax and four bytes to store the 1. In 32-bit code, we use eax and four bytes - the 0x66 prefix tells us to use ax and two bytes to store the 1. There's no "short form" to "mov", so any version of Nasm would do the same.

You're obviously willing to "experiment", and seem to have figured out what you need to know, so you can ignore my babbling and "try it". Probably easier, and "the CPU's opinion is the only one that counts"! :)

Best,
Frank


Offline MJaoune

  • Jr. Member
  • *
  • Posts: 94
Re: Bits 32 and Bits 16
« Reply #11 on: August 16, 2011, 10:04:24 PM »
you'll see 0xB8 0x01 0x00 0x66 0xB8 0x01 0x00 0x00 0x00. With "bits 32", you'll see 0x66 0xB8 0x01 0x00 0xB8 0x01 0x00 0x00 0x00.

That is why I hate HEX and I always use Binary :)

Offline Mezo40

  • Jr. Member
  • *
  • Posts: 8
Re: Bits 32 and Bits 16
« Reply #12 on: August 17, 2011, 02:14:01 AM »
Thank you Frank , Mahmoud and Bryant. :D
You helped me very much :D