在Linux i386上,int $0x80
系統調用ABI使得在沒有有效用戶空間堆棧的情況下輕鬆執行系統調用。另一方面,vdso/vsyscall接口需要訪問堆棧。其他Linux端口在這方面的表現如何,特別是x86_64?他們有沒有辦法讓系統調用沒有堆棧?是否有可用的系統調用每個拱門的方法?在沒有堆棧的情況下在Linux上進行系統調用
3
A
回答
4
一般:不知道。即使在i386上,如果有第6個參數,它也必須在堆棧上傳遞(例如mmap
)。
對於x86_64的具體爲:把系統調用編號在%rax
(小心:系統調用號碼被分配完全不同,以32位的),直至在%rdi
6個參數,%rsi
,%rdx
,%r10
,%r8
和%r9
(其幾乎與通常的ABI參數傳入寄存器相同,但不完全相同 - 請注意使用%r10
而不是%rcx
),並使用syscall
指令。結果返回%rax
,%rcx
和%r11
被破壞。
x86_64 ABI信息可在http://www.x86-64.org/documentation/abi.pdf找到; Linux ABI記錄在附錄中。 (如果環顧其他地方x86_64的ABI的信息,要知道,64位Windows使用它自己的不同的ABI)。
我不相信有用戶堆棧幀爲syscall
工作的任何要求正常。在被信號中斷的情況下,處理程序顯然需要一個理智的堆棧;但下面的實驗,使用備用信號棧和故意象垃圾一樣清除%rsp
的syscall
左右,正常工作對我來說:
$ cat syscall_sig.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <time.h>
#include <unistd.h>
#define __NR_nanosleep 35
static sig_atomic_t alrm = 0;
void handler(int sig)
{
if (sig == SIGALRM)
alrm = 1;
}
int main(void)
{
stack_t ss;
struct sigaction sa;
struct timespec req, rem;
long ret;
ss.ss_flags = 0;
ss.ss_size = SIGSTKSZ;
ss.ss_sp = malloc(ss.ss_size);
sigaltstack(&ss, NULL);
memset(&sa, 0, sizeof(sa));
sa.sa_handler = handler;
sa.sa_flags = SA_ONSTACK;
sigaction(SIGALRM, &sa, NULL);
alarm(1);
req.tv_sec = 5;
req.tv_nsec = 0;
asm("xorq $0x12345678, %%rsp ; syscall ; xorq $0x12345678, %%rsp"
: "=a" (ret)
: "0" (__NR_nanosleep), "D" (&req), "S" (&rem)
: "rcx", "r11", "memory");
printf("syscall return code %ld, alarm flag %d\n", ret, alrm);
return 0;
}
$ gcc -Wall -o syscall_sig syscall_sig.c
$ ./syscall_sig
syscall return code -4, alarm flag 1
$
相關問題
- 1. 在沒有kldload的情況下向FreeBSD添加系統調用
- 2. Linux - 有沒有辦法在不派生新進程的情況下調用系統調用(bash腳本)?
- 3. STM32f429ZI在沒有調試器的情況下記錄調用堆棧
- 4. 在沒有安裝python的情況下在Linux上運行python
- 5. 在沒有apt-get的情況下在Linux(Ubuntu)上運行OpenCV
- 6. 在沒有堆棧的情況下創建NPE
- 7. 在沒有System.Collections的情況下創建堆棧類
- 8. Lua:如何在沒有堆棧跟蹤的情況下調用錯誤
- 9. 在系統中沒有其他負載的情況下阻塞系統調用(linux內核)
- 10. 在沒有調試器的情況下進行調試
- 11. 如何在沒有jQuery的情況下進行AJAX調用?
- 12. 如何在沒有獲得NPE的情況下在堆棧上彈出節點
- 13. C++在沒有初始化的情況下在堆棧上分配
- 14. 在沒有X-Window系統的情況下使用OpenGL
- 15. 在沒有統計的情況下獲取沒有行的表
- 16. 如何在沒有pdb文件的情況下進行調試?
- 17. 如何在沒有Visual Studio的情況下進行調試?
- 18. 在沒有GUI的情況下在Linux上簽名BlackBerry Code
- 19. Matlab,在沒有simulink的情況下研究非線性系統
- 20. 在不使用系統的情況下從perl調用java類
- 21. 在沒有調試器的情況下運行時獲取閃存應用程序的堆棧跟蹤
- 22. 如何在系統verilog中運行時顯示調用堆棧?
- 23. 只有在關係存在的情況下才進行加載
- 24. 獲取堆棧指針x86_64 linux系統調用
- 25. 如何在沒有與Haskell中的類型系統進行對抗的情況下對monad進行抽象?
- 26. 如何在沒有SipCallOptionHandler.java的情況下在Android 5.1.1中進行SIP調用?
- 27. 在沒有UAC的情況下在系統上執行具有管理員權限的應用程序
- 28. 在Linux系統上增加堆大小
- 29. 在沒有下載的情況下在ftp上運行jarfile
- 30. 如何在沒有kexec的情況下執行linux內核?
這是我在做什麼(間接通過別人因爲我沒有直接訪問到x86_64系統進行移植)。其實現在我有一個堆棧,但我知道後面我將不得不面對一個我不會的情況,但我已經遇到了麻煩。你所描述的方法是有效的,除非系統調用被一個信號中斷,但如果它被中斷並且試圖恢復,它會在`syscall`指令上發生段錯誤...'syscall`是否需要一個特定的棧幀來設置它,中斷/恢復? – 2011-02-11 04:08:50