The MASM Forum Archive 2004 to 2012

Project Support Forums => GoAsm Assembler and Tools => Topic started by: donkey on May 09, 2011, 03:16:21 AM

Title: Using segment overrides in X64
Post by: donkey on May 09, 2011, 03:16:21 AM
Hi Jeremy,

I've been trying to get the TIB in X64 but the segment override either doesn't work or the area in memory can no longer be read in user mode. I'm not sure which, here's what I have been trying:

gs mov rax,[0x28]

In C I would use the intrinsic __readgsqword which is defined as (from mingw-w64):

/* for __x86_64 only */
unsigned __int64 __readgsqword(unsigned long Offset)
{
   void *ret;
   __asm__ volatile ("movq    %%gs:%1,%0"
     : "=r" (ret) ,"=m" ((*(volatile long *) (unsigned __int64) Offset)));
   return (unsigned __int64) ret;
}


The assembled GoAsm code is (from WinDbg):

00000000`00401000 65488b0528000000 mov     rax,qword ptr gs:[image00000000_00400000+0x1030 (00000000`00401030)] gs:00000000`00401030=48000000ecb9d231

The GS segment register contains 0x2b

The error returned is EXCEPTION_ACCESS_VIOLATION

Any help or suggestions would be appreciated.
Title: Re: Using segment overrides in X64
Post by: donkey on May 09, 2011, 06:05:08 AM
Mmmm.

Coding it by hand I tried this:

ReadGSQword(%Byte) macro
DB 0x65,0x48,0x8b,0x04,0x25,%Byte,0x00,0x00,0x00
endm

WriteGSQword(%Byte) macro
DB 0x65,0x48,0x89,0x04,0x25,%Byte,0x00,0x00,0x00
endm

ReadGSQword(0x28)


Which shows as the following in WinDbg

00000000`00401005 65488b042528000000 mov   rax,qword ptr gs:[28h]

No exception was thrown when executed, still have to test it though.
Title: Re: Using segment overrides in X64
Post by: dedndave on May 09, 2011, 11:56:31 AM
what i have read is that the TIB section is a win32 thing (also, win95)
maybe that means it isn't a win64 thing - i dunno   :P
i find no mention of 64-bit in the articles i have read - but, then, they are kinda old
Title: Re: Using segment overrides in X64
Post by: donkey on May 09, 2011, 12:49:58 PM
Hi Dave,

Its used in Win64 as well, defined in winnt.h.
Title: Re: Using segment overrides in X64
Post by: dedndave on May 09, 2011, 12:58:25 PM
only makes sense that they would use it   :bg
Title: Re: Using segment overrides in X64
Post by: donkey on May 09, 2011, 01:43:21 PM
Quote from: dedndave on May 09, 2011, 12:58:25 PM
only makes sense that they would use it   :bg

Yup, it would have been too radical a change without it, the hand written code tests OK so I'll go with that for now.
Title: Re: Using segment overrides in X64
Post by: donkey on May 22, 2011, 09:46:56 PM
The final version of the macros is a bit more complicated as it allows for different registers than RAX.

RGSQREGRAX = 0x48,0x8b,0x04
RGSQREGRBX = 0x48,0x8b,0x1C
RGSQREGRCX = 0x48,0x8b,0x0C
RGSQREGRDX = 0x48,0x8b,0x14
RGSQREGRDI = 0x48,0x8b,0x3C
RGSQREGRSI = 0x48,0x8b,0x34
RGSQREGRSP = 0x48,0x8b,0x24
RGSQREGRBP = 0x48,0x8b,0x2C
RGSQREGR8 = 0x4C,0x8b,0x04
RGSQREGR9 = 0x4C,0x8b,0x0C
RGSQREGR10 = 0x4C,0x8b,0x14
RGSQREGR11 = 0x4C,0x8b,0x1C
RGSQREGR12 = 0x4C,0x8b,0x24
RGSQREGR13 = 0x4C,0x8b,0x2C
RGSQREGR14 = 0x4C,0x8b,0x34
RGSQREGR15 = 0x4C,0x8b,0x3C

readgsqword(%1,%2) macro
#IFDEF RGSQREG%1
DB 0x65,RGSQREG%1,0x25,%2,0x00,0x00,0x00
#ELSE
GoAsm_echo "readgsqword uses capitalized 64 bit register names only"
GoAsm_exit
#ENDIF
endm

WGSQREGRAX = 0x48,0x89,0x04
WGSQREGRBX = 0x48,0x89,0x1C
WGSQREGRCX = 0x48,0x89,0x0C
WGSQREGRDX = 0x48,0x89,0x14
WGSQREGRDI = 0x48,0x89,0x3C
WGSQREGRSI = 0x48,0x89,0x34
WGSQREGRSP = 0x48,0x89,0x24
WGSQREGRBP = 0x48,0x89,0x2C
WGSQREGR8 = 0x4C,0x89,0x04
WGSQREGR9 = 0x4C,0x89,0x0C
WGSQREGR10 = 0x4C,0x89,0x14
WGSQREGR11 = 0x4C,0x89,0x1C
WGSQREGR12 = 0x4C,0x89,0x24
WGSQREGR13 = 0x4C,0x89,0x2C
WGSQREGR14 = 0x4C,0x89,0x34
WGSQREGR15 = 0x4C,0x89,0x3C

writegsqword(%1,%2) macro
#IFDEF WGSQREG%2
DB 0x65,WGSQREG%2,0x25,%1,0x00,0x00,0x00
#ELSE
GoAsm_echo "writegsqword uses capitalized 64 bit register names only"
GoAsm_exit
#ENDIF
endm


Syntax:

readgsqword(RAX,0x28)
writegsqword(0x28,RDI)


These macros will be added to macros.h in the next update.