Sistem çağrı tablosu (çağrılan sys_call_table
) statik bir boyut dizisi olduğu için mümkün değildir . Ve boyutu derleme zamanında kayıtlı sistem sayısı ile belirlenir. Bu, bir başkası için yer olmadığı anlamına gelir.
Tanımlı arch/x86/kernel/syscall_64.c
dosyadaki x86 mimarisi için uygulamayı kontrol edebilirsiniz sys_call_table
. Boyutu tam olarak __NR_syscall_max+1
. __NR_syscall_max
, tüm sistem çağrılarının bulunduğu bir tablo olduğu (son sistem çağrısı sayısı ) arch/x86/kernel/asm-offsets_64.c
olarak tanımlanır .sizeof(syscalls) - 1
syscall
Olası bir çözüm, sys_setaltroot
bellekte daha fazla yer gerektirmeyeceğinden , mevcut bazı (veya mimarinizde bir tane varsa kullanımdan kaldırılmış olanı, örneğin bkz .) Sistem çağrı numarasını yeniden kullanmaktır. Bazı mimarilerde, sistem çağrı tablosunda (x86'nın 64 bit sürümü gibi) delikler de olabilir, böylece bunu da kullanabilirsiniz.
Yeni bir sistem çağrısı geliştiriyorsanız ve denerken yeniden başlatmayı önlemek istiyorsanız bu tekniği kullanabilirsiniz. Yeni sistem çağrınızı tanımlamanız, mevcut girişi syscall tablosunda bulmanız ve daha sonra modülünüzden değiştirmeniz gerekir.
Çekirdek modülünden bunu yapmak önemsiz değildir, çünkü çekirdek sys_call_table
2.6 sürümünden itibaren modüllere dışa aktarmaz (bu sembolün dışa aktarıldığı son çekirdek sürümü idi 2.5.41
).
Bu sorunu çözmenin bir yolu, sys_call_table
sembolü modüllere vermek için çekirdeğinizi değiştirmektir . Bunu yapmak için, aşağıdaki iki satırı eklemelisiniz kernel/kallsyms.c
( bunu üretim makinelerinde yapmayın ):
extern void *sys_call_table;
EXPORT_SYMBOL(sys_call_table);
Diğer bir teknik sistem tablolarını dinamik olarak bulmaktır. Her kelimeyi bir işaretçi ile bilinen sistem çağrısı işleviyle karşılaştırarak çekirdek belleği üzerinde yineleme yaparsınız. Bu bilme sistem aramasının ofsetini bildiğiniz için, tablo başlangıç adresini hesaplayabilirsiniz.