作者descent (「雄辯是銀,沉默是金」)
看板C_and_CPP
標題Re: [問題] 請問為什麼Win和Linux執行檔不能互通?
時間Wed Jul 3 14:17:58 2013
這不是蠢問題, 這是個不容易回答的問題。
我在很久以前學習組合語言時 (雖然很久之前就學, 不過還是沒學好),
也有這個疑問?
不能執行的條件有很多, 只要不符合其中之一, 就不能執行了。
那來討論怎麼樣才可以在 linux 執行 windows compile 的執行檔。
c 太複雜, 以組合語言為例:
nop
只有一個 nop 的組合語言在 windows 用 vc compile 得到
pe 執行檔, 要怎麼在 linux 下執行它?
linux 下編譯出來的是 elf 執行檔, loader 會 parse elf 執行檔,
載入 programming header 所指的 segment。
所以不要奢望 linux loader, 自己寫一個 loader,
parse 這個 pe 檔案, 把 nop 的機械碼位址找出來,
nop 會翻成 0x90, 將這部份載入到記憶體, 再用 funcion pointer
的方式執行那位址即可。
當然, 如果要回到 linux shell 下, 那得在花點功夫。
簡化版不討論這個 (其實是我不會 XD)。
以這個例子來說, 搞定 pe 檔格式即可。
再來複雜一點的:
一樣是組合語言 nop, 後面加上呼叫 printf。
pseudo code
ex:
nop
push "test printf"
call printf
這要怎麼辦?
在 windows vc compile 的 printf 以 win_printf 表示。
在 linux 下要怎麼處理?
printf 會產生類似 e8 win_printf_addr 的機械碼。
當 parse pe 這段機械碼後並載入到記憶體後,
需要將 e8 win_printf_addr 改成 e8 linux_printf_addr
這樣這個 pe 檔就可以在 linux 下執行。
這邊是簡化表示, e8 後面的值其實不是這樣。
而 printf 的參數也要搞定才行。
當然也要載入 linux_printf 並知道他的位址才行。
以上我沒做過, 純粹嘴炮分享, 說來簡單, 其實很繁雜。
在更複雜的情形呢?這就交給 wine 來處理吧。
每個不能執行的關卡都要打破, 這真的不容易。
※ 引述《pluseus (回憶真美麗)》之銘言:
: 問題(Question):
: 抱歉問一個蠢問題
: 請問為什麼在Windows OS下compile過後的執行檔(.exe)
: 拿到「同一台」機器下的Linux OS,為什麼不能執行?
: 而要在Linux下source code重新compile才能使用
: 我會有這個問題
: 是因為我的理解是,source code經過compile過後
: 就變成for某種cpu的機器碼了(例如x86機器碼)
: 而Windows OS和Linux OS,因為是同一台機器,假如也都是使用相同的x86機器碼
: 但是為什麼執行檔在不同OS不能互通呢?
: 謝謝! ^^
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 59.125.239.51
※ 編輯: descent 來自: 59.125.239.51 (07/03 14:19)
→ erspicu:你覺得1+1為何等於2 是怎樣的問題 某些人問這個問題 07/03 14:20
→ erspicu:是一個層次 某些人問這個問題是一個層次 天差地遠 07/03 14:20
→ erspicu:另外除了格式問題外 其實系統OS API也都不同 07/03 14:21
※ 編輯: descent 來自: 59.125.239.51 (07/03 14:48)
→ MOONRAKER:1+1為何等於2非常直觀 我看過所謂高層次的解答都在胡搞 07/03 16:36
→ MOONRAKER:而已 拿很多axiom來湊成別的axiom 證明遊戲而已 07/03 16:37
→ MOONRAKER:用這個例子類比binary不能互通,不就是說都在狡辯。 07/03 16:38
推 damody:ABI啦 PE啦 看有沒有有錢人去改一個 通windows 的 linux 07/03 23:16
推 Bencrie:樓上你說的不就跑在 kernel space 的 wine XD 07/04 00:16
推 damody:是還蠻像的 = = 不過還是有差距。 07/04 01:10
推 fakeqq:更麻煩的是所有 global, func, code seg 的 VA 全部重建 07/04 01:21