題:
GAS / x86將裸gs寄存器反彙編為指令,這是一個錯誤嗎?
perror
2013-08-23 20:01:18 UTC
view on stackexchange narkive permalink

我遇到了一個奇怪的x86-32指令(操作碼 0x65 ),由 objdump 解碼為 gs (不是%gs 代碼>,但 gs )。我在對二進製文件( objdump -D )進行完全線性掃描時發現了它,因此解碼肯定不正確。但是, objdump 仍未將其解碼為(錯誤)指令,因此這意味著可以遇到它,我想知道它的含義。

這是此指令的示例:

  080484fc <_IO_stdin_used>:80484fc:01 00 add%eax,(%eax)80484fe:02 00 add(%eax), %al 8048500:12月48日%eax 8048501:65 gs < =======================這裡!!! 8048502:6c insb(%dx),%es:(%edi)8048503:6c insb(%dx),%es:(%edi)8048504:6f outsl%ds:(%esi),(%dx)8048505: 20 57 6f和%dl,0x6f(%edi)8048508:72 6c jb 8048576 <_IO_stdin_used + 0x7a> 804850a:64 21 0a和%ecx,%fs:(%edx)804850d:00 44 6f 64添加%al,0x64( edi,%ebp,2)8048511:67 65 20 54 68和%dl,%gs:0x68(%si)8048516:69 .byte 0x69 8048517:73 21 jae 804853a <_IO_stdin_used + 0x3e>  

請注意,由於%gs 寄存器會掩蓋所有其他可能的結果,因此在Web上搜索該指令非常困難。

那麼,這是真正的“指令”嗎?還是由 gas 產生的故障?

嗯,這似乎是來自GNU binutils的錯誤……操作碼0x65實際上對應於與%gs:(mem_ref)相對應的前綴。但是,在這裡,`libopcodes`解析器似乎錯誤地解釋了它,而* forget *則將後面的解釋解釋為內存引用...(我可能是錯的,但是當我對所有這些都了解更多時,我會盡力回答) 。
根據Intel的手冊,`ins *`指令* ignore *段會覆蓋前綴,並始終使用%es。
因此,這意味著這是因為您在操作碼0x65後面加上了一個ins指令,表明解碼器是錯誤的……我知道,這很有趣。謝謝。
有點晚了,但是:解碼器將它弄錯了,因為您正在反彙編以零結尾的*文本字符串*。當輸入錯誤的輸入時,您不能對“好”或“壞”的拆卸做出決定。 (有趣:這個字符串非常有名,以至於我在對前三個字符進行解碼後才得到它。)
一 回答:
Igor Skochinsky
2013-08-23 20:36:07 UTC
view on stackexchange narkive permalink

嚴格來說,這不是指令。這是段覆蓋前綴(前綴被視為指令的一部分)。

默認情況下,大多數內存訪問使用 DS 段選擇器,但涉及 ESP code的訪問器除外>或 EBP 寄存器(默認為 SS )和一些“字符串”指令( movs scas 等) 。段覆蓋前綴允許您使用另一個段選擇器訪問數據。例如。在DOS時代, CS 替代通常用於訪問存儲在代碼段中的數據(例如跳轉表):

  seg001:00EA shl bx,1; SWITCHseg001:00EC jmp cs:off_13158 [bx];切換跳轉... seg001:0588 off_13158 dw偏移loc_12DD7;數據XREF:_main + E6rseg001:0588 dw偏移量loc_12DE5;開關語句的跳轉表eg001:0588 dw偏移loc_12DE5seg001:0588 dw偏移loc_12DE5  

80386增加了兩個額外的段寄存器( GS FS )和相應的前綴。

由於 GS 前綴實際上不會影響上述代碼中的以下指令( insb ),因此GAS選擇了

在以下某些說明中,您將看到它如何影響反彙編:

  64 21 0a ->和%ecx, %fs:(%edx)^^ ^^^ 67 65 20 54 68 ->和%dl,%gs:0x68(%si)^^ ^^^  

BTW,67是另一個前綴,這次是地址大小覆蓋。這就是指令使用16位 SI 寄存器而不使用完整的 ESI 的原因。

這非常簡潔明了(一如既往,Igor!)。但是,您會認為這是“ gas”的有害行為(錯誤)嗎?
好吧,我不知道。您可以雙向爭論。並不是說GAS可以針對廢話/混淆代碼進行強化,但您應該很高興它至少沒有崩潰:)
附言有時將前綴放在單獨的偽指令中確實有意義,例如[此代碼段](http://pastie.org/pastes/8263242/text)來自某些舊的libc。
如果我能很好地理解您的示例,則該符號會在指令的前綴之後**放置?這確實意味著,取決於我們是從塊前來還是通過符號跳轉到塊,其語義並不完全相同(一個是原子的,另一個不是原子的)。我絕對討厭x86,這讓我頭疼! :-)


該問答將自動從英語翻譯而來。原始內容可在stackexchange上找到,我們感謝它分發的cc by-sa 3.0許可。
Loading...