2016-01-10 41 views
0

檢測到我正在使用基於PIN的模擬器來測試一些新的架構修改。我需要用我的模擬器測試帶有兩個操作數(寄存器和內存位置)的「新」指令。在X86代碼中插入一個未定義的指令,以便被英特爾PIN

由於使用GCC機器描述僅添加一條指令非常繁瑣,因此使用NOP或未定義指令似乎很合理。 密碼很容易能夠使用INS_IsNop來檢測NOP指令,但它會干擾NOP自然添加到代碼中,它也沒有操作數或單個內存操作數。

剩下的唯一選擇是使用和未定義的指令。未定義的指令永遠不會干擾代碼的其餘部分,並且可以通過PIN使用INS_IsInvalid來檢測。

問題是我不知道如何使用GCC內聯彙編添加未定義的指令(帶操作數)。我怎麼做?

+0

從你的問題來看,這裏的問題是在gcc中發出一個未定義的指令。從你的評論看來,另一個問題是解碼指令。你有沒有這個問題? – nitzanms

回答

2

所以事實證明,x86有一個明確的「未知指令」(見this)。 GCC可以通過簡單的使用產生這樣:

asm("ud2"); 

至於與操作數定義的指令,我不知道這將意味着。一旦你有一個未定義的操作碼,額外的字節都是未定義的。

但是,也許你可以得到你想要的東西像什麼:

asm(".byte 0x0f, 0x0b"); 
+0

該指令只對GCC沒有定義,對我來說這是對我的新指令的表示。假設我的新指令是ADD ADD OP1,OP2。我將使用PIN提取操作數,然後插入對INS_Delete()的調用,以便指令不會引發異常。 – ProWi

+2

如果目標是生成GCC不理解的asm操作碼,那麼您運氣不好。 GCC不解釋操作碼。把任何東西放在asm中,gcc只會輸出它。如果目標是輸出彙編程序不理解的操作碼,那麼可以使用asm(「xxx 1,2」),彙編程序將拒絕它。如果目標是輸出CPU不理解的操作碼,則可以使用「已知」無效操作碼(ud2)。如何像'asm(「。byte 0x0f,0x0b,0x90,0x90」)''。這應該會生成(看起來像)4字節指令,而不會自然出現。 –

0

嘗試使用一般不適用的指令的前綴。例如

rep add eax, [rsi + rax*4 - 15] 

會組裝得很好。一些指令集擴展以這種方式完成。例如lzcnt編碼爲rep bsf,因此它在舊CPU上執行爲bsf,而不是生成非法指令異常。 (根據x86 ISA的要求,忽略不適用的前綴)

這將讓您利用匯編器對指令操作數進行編碼的能力,正如David Wohlferd在其答案中所指出的那樣,是一個問題,如果您使用ud2