2016-08-28 61 views
0

我想寫一些彙編代碼,可以找出它是否運行在x86或x64二進制文件(我想做這樣一個奇怪的事情的原因是,我將注入此代碼在任何給定的二進制文件,並且代碼運行時,它將決定應該執行哪種類型的系統調用並運行該代碼的一部分。沒有惡意,只是一個「hello world」,然後作爲練習傳遞給實際入口點)。如何在運行時確定ASM代碼是在x86還是x64 CPU中運行?

無論如何,一個「溶液」我想的結果如下:

  • 讀取堆棧指針到通用寄存器X
  • 推0
  • 讀取堆棧指針到GP寄存器Y
  • 從X
  • 減法Y(結果存儲到X)
  • 彈出到Y(以固定堆棧)
  • X已經寄存器的大小,相應的行爲

這是最接近我能得到:

0: 54      push rsp 
1: 54      push rsp 
2: 5b      pop rbx 
3: 58      pop rax 
4: 48 29 d8    sub rax,rbx <--- 
7: 83 f8 08    cmp eax,0x8 
a: 74 ??     je  64_bit_code_addr 

這會產生相同的字節用於x86,除了爲0x48地址爲0x4。我怎樣才能以獨立於架構的方式編寫該指令?或者我有什麼其他解決方案可以實現這一效果?

(請不要呈現出的現成的解決方案,比如等。「你可以通過檢查EI_CLASS一個ELF文件的偏移確定類可執行的」)

+0

實現你檢查堆棧增量的最簡單方法是'mov eax,esp' /'push rbp' /'sub eax,esp' /'cmp eax,4' /'je mode_32bit'。如果RSP的低32包裝,這仍然有效。您可以通過'lea eax,[rsp-4]'開始保存CMP,然後在SUB之後測試ZF。作爲獎勵,現在你的功能已經在堆棧上保存了一個寄存器以釋放它以備使用。但也請參閱這個重複使用與哈羅德答案相同的想法。 –

回答

2

它可以更簡單,使用32位代碼,REX.W是DEC:

48 90 

其中在64位的代碼是:

rex.w nop ; still a nop 

和32位代碼:

dec eax 
nop 

把它放在它之前,當然就是xor eax, eax

+0

哇,真是太棒了!因此,如下所示: 31 c0 48 90 85 c0 74 XY ... 將在x64以下跳轉0xXY字節。精彩的提示,謝謝! – kubuzetto

+1

甚至更​​短:'xor' /'rex jz'。看到我的鏈接副本。 –

+0

我當然沒有想到這是如此之短:)有趣的是,似乎我最初的嘗試也會起作用。 – kubuzetto

相關問題