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?
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?
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 bycs
.
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).
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!
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
fs
and gs
selectors often have non-zero base.
– Igor Skochinsky
Aug 06 '18 at 09:56
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 ???????? ???????? ???????? ????????
mov ds, ax
should work fords
and other segment registers.cs
can only be manipulated with far jmp/far call/far ret/iret – sudhackar Aug 06 '18 at 08:15