5

I am reversing a 32-bits ELF executable.

I see something like:

mov al, byte ptr ds:xxxxx

xxxxx is an absolute address. What is the meaning of ds here?

5
  • Yes but the address is absolute so i do not understand why there is this notion of segment there
    – Bob5421
    Aug 5, 2018 at 16:17
  • Segment registers have a different use in protected mode (32 bit). Most segments have a base address of 0 but control protection.
    – NirIzr
    Aug 5, 2018 at 20:47
  • So you mean if i change ds to another segment, it won’t change address but only restriction ? How can i change ds value ?
    – Bob5421
    Aug 6, 2018 at 6:49
  • @Bob5421 mov ds, ax should work for ds and other segment registers. cs can only be manipulated with far jmp/far call/far ret/iret
    – sudhackar
    Aug 6, 2018 at 8:15
  • Duplicate on Stack Overflow: 2 1
    – user202729
    Aug 6, 2018 at 9:35

3 Answers 3

1

this answer is just to address the query in comment

And for example fs[0] on win32 points on TIb structure. Is there another way to get this address ? (I mean where is it in the 4Gb address Space of process?)

in user mode the thread environment block is pointed by fs:[0]

you can view it in the virtual address space using any of the following commands under windbg

0:000> ? fs
Evaluate expression: 59 = 0000003b
0:000> dd fs:[0] l 8
003b:00000000  0012f5b0 00130000 0012d000 00000000
003b:00000010  00001e00 00000000 7ffdf000 00000000
0:000> dd 3b:00000000 l8
003b:00000000  0012f5b0 00130000 0012d000 00000000
003b:00000010  00001e00 00000000 7ffdf000 00000000
0:000> dd @$thread l8
7ffdf000  0012f5b0 00130000 0012d000 00000000
7ffdf010  00001e00 00000000 7ffdf000 00000000
0:000> dd @$teb l8
7ffdf000  0012f5b0 00130000 0012d000 00000000
7ffdf010  00001e00 00000000 7ffdf000 00000000
0:000> ? @$teb
Evaluate expression: 2147348480 = 7ffdf000
0:000> ? @$thread
Evaluate expression: 2147348480 = 7ffdf000

confirming using ds selector

0:000> ? ds
Evaluate expression: 35 = 00000023
0:000> dd ds:[7ffdf000] l8
0023:7ffdf000  0012f5b0 00130000 0012d000 00000000
0023:7ffdf010  00001e00 00000000 7ffdf000 00000000

in x86 cs es ds and ss all will point to same virtual address but fs and gs wont as seen below

0:000> ? ds
Evaluate expression: 35 = 00000023
0:000> dd ds:[7ffdf000] l8
0023:7ffdf000  0012f5b0 00130000 0012d000 00000000
0023:7ffdf010  00001e00 00000000 7ffdf000 00000000
0:000> ? cs
Evaluate expression: 27 = 0000001b
0:000> dd cs:[7ffdf000] l8
001b:7ffdf000  0012f5b0 00130000 0012d000 00000000
001b:7ffdf010  00001e00 00000000 7ffdf000 00000000
0:000> dd es:[7ffdf000] l8
0023:7ffdf000  0012f5b0 00130000 0012d000 00000000
0023:7ffdf010  00001e00 00000000 7ffdf000 00000000
0:000> dd ss:[7ffdf000] l8
0023:7ffdf000  0012f5b0 00130000 0012d000 00000000
0023:7ffdf010  00001e00 00000000 7ffdf000 00000000
0:000> dd fs:[7ffdf000] l8
003b:7ffdf000  ???????? ???????? ???????? ????????
003b:7ffdf010  ???????? ???????? ???????? ????????
0:000> dd gs:[7ffdf000] l8
0000:f000  ???????? ???????? ???????? ????????
0000:f010  ???????? ???????? ???????? ????????
4

Just to clarify the answer of memo (which lacks of a good example).

When speaking about the segment registers (cs, ds, es, ss), the semantic of the syntax cs:0xdeadbeef must be interpreted as the concatenation of the prefix stored in cs and the value appended to it. But, if we step back to see the big picture, it can be seen as:

The address 0xdeadbeef in the memory segment pointed by cs.

In fact, since Intel 8086, the memory model of these CPU is segment based, meaning that each segment register store a prefix for the memory address that will allow to reach one block of memory for a specific usage.

As you can see on the picture below (courtesy to Wikipedia page about Intel x86 memory segmentation), the main memory is sliced into several memory segments and accessed through calls to several segment registers (not on the picture, but you can guess that these registers are initialized with the LDT).

Intel 8086 memory model based on segment registers

In your case:

mov al, byte ptr ds:xxxxx

Does probably means that you are moving a variable from the data segment to your al register.

But, this kind of code is not needed in normal mode as the ds registers is often set to zero (and have no effect when used like that). On the contrary, in protected mode, the ds segment register will be needed to point onto the right memory segment. And, that is probably a line which comes from an assembly code which is executed in protected mode (except if it has been obfuscated, then they break the rules all the time and we cannot tell anymore what was the intent without knowing what is the value of ds).

I hope this was a bit more clear this way!

2

In protected mode DS is a selector, not a segment. It defines physical address, permissions and other properties. Normally, an instruction such as the one in your example, uses DS by default, but this can be overridden (by instruction prefixes) to use a different one (ES, FS, GS, SS etc.)

Have a look at the programming manual from Intel: https://www.intel.com/content/www/us/en/architecture-and-technology/64-ia-32-architectures-software-developer-vol-1-manual.html

3
  • I do not understand something: On a 32 bits x86 system, the process has an adress space of 4GB starting 000000 to FFFFFFFF. If i write mov al, byte ptr 12341234 for example, i do not understand this notion of selector...
    – Bob5421
    Aug 6, 2018 at 8:41
  • @Bob5421 even though most OSes use flat memory layout, the selectors are still supported by the processor. And, for example, the fs and gs selectors often have non-zero base.
    – Igor Skochinsky
    Aug 6, 2018 at 9:56
  • And for example fs[0] on win32 points on TIb structure. Is there another way to get this address ? (I mean where is it in the 4Gb address Space of process?)
    – Bob5421
    Aug 6, 2018 at 16:43

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.