: Gördüğünüz gibi, parametreler HTML tablosundan olanlara uyuyor,
off_t lseek(int fd, off_t offset, int whence);
Linux'taki standart programlama dili C'dir. Bu nedenle, sistem çağrılarının en iyi açıklamaları, bunları çağrılacak C işlevleri olarak gösterecektir. Bir C işlevi olarak açıklamaları ve montajda gerçek sistem çağrısına nasıl haritalanacağı bilgisi verildiğinde, kolayca istediğiniz herhangi bir sistem çağrısını kullanabilirsiniz. Onlar C programcısı görünecektir gibi tüm sistem çağrıları için
Öncelikle, bir başvuru gerekiyor. En iyi bildiğim, Linux man-pages project, özellikle system calls bölümüdür.
sizin söz konusu biridir, çünkü o, bir örnek olarak
write
sistem çağrısını ele alalım. Gördüğünüz gibi, ilk parametre, genellikle
open
sistem çağrısı tarafından döndürülen bir dosya tanıtıcısı olan bir işaretli tamsayıdır. Bu dosya tanıtıcıları, genellikle ilk üç dosya tanıtıcısı için olduğu gibi (0 = stdin, 1 = stdout, 2 = stderr), ana işleminizden miras alınmış olabilir. İkinci parametre, bir arabelleğin işaretçisidir ve üçüncü parametre, arabellek boyutudur (işaretsiz bir tam sayı olarak). Son olarak, işlev yazılan bayt sayısı veya bir hata için negatif bir sayı olan bir işaretli tamsayı döndürür.
Şimdi, nasıl gerçek sistem çağrısına bu haritaya? 32-bit x86'da bir sistem çağrısı yapmanın birçok yolu vardır (büyük olasılıkla kullandığınız, kayıt isimlerine bağlı olarak); 64-bit x86'da tamamen farklı olmasına dikkat edin (32-bit modda bir araya getirdiğinizden ve 32-bit bir yürütülebilir dosyayı bağladığınızdan emin olun; aksi halde, hataların nasıl ters gidebileceğine dair bir örnek için bkz. this question). 32-bit x86'daki en eski, en basit ve en yavaşı, int $0x80
yöntemidir.
int $0x80
yöntemi için, sen %eax
sistem çağrı numarasını koymak ve parametreler %ebx
, %ecx
, %edx
, %esi
, %edi
ve %ebp
, bu sırayla. Ardından, int $0x80
numaralı telefonu arayın ve sistem çağrısından dönüş değeri %eax
üzerindeyken. Bu dönüş değerinin, referansın söylediklerinden farklı olduğunu unutmayın; referans C kütüphanesinin nasıl geri getireceğini gösterir, ancak sistem çağrısı -errno
hata ile döner (örneğin -EINVAL
). C kitaplığı bu durumu errno
'a taşır ve bu durumda -1
döndürür. Daha fazla ayrıntı için bkz. syscalls(2) ve intro(2).
Yani, write
örnekte, (%eax
yılında write
sistem çağrı numarası, %ebx
ilk parametre (dosya tanıtıcı numarası), %ecx
ikinci parametre (dize işaretçisi) ve üçüncü parametre koyardı dizgenin uzunluğu) %edx
. Sistem çağrısı %eax
'da yazılan bayt sayısı veya reddedilen hata numarası olarak geri dönecektir (dönüş değeri -1 ve -4095 arasındaysa, bu bir negatif hata numarasıdır).
Son olarak, sistem çağrı numaralarını nasıl buluyorsunuz? Bunlar /usr/include/linux/unistd.h
adresinde bulunabilir. Benim sistemimde, bu sadece /usr/include/asm/unistd_32.h
içerir /usr/include/asm/unistd.h
içerir, bu yüzden sayılar vardır (write
için, __NR_write
4
olduğunu görebilirsiniz). Aynı durum, /usr/include/linux/errno.h
(sistemimde, ilk harfleri /usr/include/asm-generic/errno-base.h
'da ve geri kalanını /usr/include/asm-generic/errno.h
numaralı telefonda bulduktan sonra dahil olmak üzere) gelen hata sayıları için de geçerlidir. Diğer sabitleri veya yapıları kullanan sistem çağrıları için, belgeleri, ilgili tanımları bulmak için hangi başlıklara bakmanız gerektiğini söyler. Dediğim gibi
Şimdi, int $0x80
en eski ve en yavaş yöntemdir. Daha yeni işlemciler, daha hızlı olan özel sistem çağrı yönergelerine sahiptir. Bunları kullanmak için, çekirdek, sanal bir dinamik paylaşımlı nesneyi (vDSO
; paylaşılan bir kitaplığa benzer, ancak yalnızca bellekte), donanımınız için mevcut en iyi yöntemi kullanarak sistem çağrısı yapmak üzere çağıran bir işlevle kullanılabilir hale getirir. Ayrıca, sistem çağrısı yapmak zorunda kalmadan, şimdiki zamanı elde etmek için özel işlevler ve birkaç şey daha sunar. Elbette, dinamik bir bağlayıcı kullanmıyorsanız kullanmak biraz daha zordur.
Başka bir eski yöntem de vsyscall
, vDSO
'a benzer, ancak sabit bir adreste tek bir sayfa kullanır. Bu yöntem kullanımdan kaldırılır, en son çekirdeği kullanıyorsanız, daha yeni çekirdekler üzerinde önyükleme sırasında devre dışı bırakılabilir ve gelecekte kaldırılabiliyorsa, sistem günlüğüne uyarılarla sonuçlanır. Bunu kullanma.
Tabii ki, her birini Google'da veya uygulama için kaynak kodlu aramada arama yapsanız bile, nasıl kullanıldığına dair doğrudan örnekler bulabilirsiniz. Mesajımın amacı, arama ve analiz etmeyi güzel bir hile sayfasıyla atlamak. Teşekkürler. –