3

I'm reverse engineering a binary and I'm confused, because my theoretical knowledge is currently clashing with what's actually happening.

I thought that this instruction writes the value 0xdeadbeef into edx:

mov edx, DWORD PTR ds:0xdeadbeef

And I thought that this instruction dereferences that address 0xdeadbeef and writes whatever DWORD value is stored at that address into edx:

mov edx, DWORD PTR ds:[0xdeadbeef]

However, in reality, running this instruction:

mov edx, DWORD PTR ds:0x804bdf4

Results in the value of edx being:

edx = 0xb73fc115

0xb73fc115 is the value that's stored at the address 0x804bdf4:

x 0x804bdf4
0x804bdf4 <gContents>: 0xb73fc115

So that means that the address was dereferenced, even though the assembly didn't contain any square brackets. I thought thatsquare brackets signified a dereferencing operation. What have I misunderstood?

I'm using GDB


Update: I just tested it on radare2, and it shows the instruction in the format that I would expect

mov edx, dword [obj.gContents]

I also tested it with objdump, and the result was the same as with GDB. I assume it's some sort of syntax I don't currently understand?

1
  • dword ptr: = sq bkts. [. ] ptr means pointer it dereferences what is in the address 0xdeadbeef and moves it to register. it will mov reg , const for direct write not mov (extend) reg, size ptr addr
    – blabb
    Dec 23, 2021 at 15:18

2 Answers 2

3

The default assembler syntax used by IDA (MASM based) does not use square brackets when the dereference is unambiguous. In your case the second operand is obviously a memory address from which the value is read, and DWORD PTR is another hint that a dereference is taking place. If you prefer to always see square brackets, you can switch to the TASM assembler in Options > General..., Analysis.

IDA Options

2
  • But what about this one: mov eax,DWORD PTR [rax]. Why are the brackets not omitted in that example as well? Assuming DWORD PTR tells you a dereference is taking place, it should be unambiguous as well?
    – Nopslide__
    Jan 3 at 13:50
  • Or is it the ds: part that makes it unambiguous?
    – Nopslide__
    Jan 3 at 14:13
1

if the operand has square brackets it is dereference
if the operator is preceded by Size PTR segment: then it is dereference
if the size of source operand is not the same as destination then the moves will need a specific extension
either Zero Extend or Sign Extend

in some cases (IDA mostly) will display

.text:00404EB1                 movzx   eax, ds:byte_40523D[eax] 

which is equivalent to

0F B6 80 3D 52 40 00    movzx eax, byte ptr [eax + 0x40523d]

in this case eax will hold a switch case and the constant is a jumptable

for direct writes the operation it will be

mov reg , const 

like

mov edx,0xdeadbeef with no other decorations added

you may go to this site for assembling and disassembling tests of the following snippet

mov edx, dword ptr ds:[0xdeadbeef]
movzx edx, word ptr ds:[0xdeadbeef]
movzx edx, byte ptr ds:[0xdeadbeef]
movsx edx, word ptr ds:[0xdeadbeef]
movsx edx, byte ptr ds:[0xdeadbeef]

nop
nop

mov edx, dword ptr ds:0xdeadbeef
movzx edx, word ptr ds:0xdeadbeef
movzx edx, byte ptr ds:0xdeadbeef
movsx edx, word ptr ds:0xdeadbeef
movsx edx, byte ptr ds:0xdeadbeef

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.