2013-01-19 1048 views
10

在執行該指令之前,fs包含0x0。什麼是「mov rax,QWORD PTR fs:0x28」彙編指令呢?

另外我想知道我可以從GDB的這個內存區讀取什麼命令呢?

+5

http://stackoverflow.com/questions/10325713/why-does-this-memory-address-have-a-random-value – Abhineet

+0

請參閱http://stackoverflow.com/questions/10325713/why-does-這個內存地址有一個隨機值的第一部分 –

+0

感謝,從我看到它類似的指令,它看起來像它只是從[FS + 0x28]讀取rax。由於fs是0x0,這應該轉化爲簡單的0x28,但是當我嘗試從GDB中的0x28讀取時,我不允許這樣做,但程序本身可以執行此指令。因此,這可能不是對這個指令的正確理解嗎? – ioctlvoid

回答

8

現代操作系統(如Linux和Windows)中的fsgs寄存器指向線程特定的和其他OS定義的結構。修改段寄存器是一個受保護的指令,所以只有操作系統可以爲你設置它們。

這個問題應該有助於解釋到底是什麼點:amd64 fs/gs registers in linux

fs寄存器的實際值不是地址。它是一個選擇器 - GDT中的偏移量,它描述了該段可以/不能用於的內容。您無法看到隱藏的fs基址和限制寄存器的值是什麼 - 它們是內部CPU寄存器,只有通過向fs寫入新的「選擇器」(在此處基準/限制寄存器從GDT更新)纔會更新。

+0

但是,如何從GDB內部自己讀取這些內存? – ioctlvoid

+0

在具有FSGSBASE功能的CPU上,64位代碼可以使用['rdfsbase'](https://hjlebbink.github.io/x86doc/html/RDFSBASE_RDGSBASE.html)和'wrfsbase'。他們沒有特權。 (我不確定那個擴展是多大的。) –

+0

另外,修改一個段寄存器本身並沒有特權;您需要內核的幫助,因爲沒有FSGSBASE,內核需要更新LDT中該段描述的基地址,這當然是用戶空間無法訪問的。如果有第二段描述有你想要的基地址,我*想*你可以在用戶空間中使用'mov fs,eax',並在多個FS基地之間來回切換,而不用調用內核。 –