Komut dosyası dilinden bir Linux sistem çağrısı çağırın


15

Doğrudan bir betik dilinden bir Linux sistem çağrısı (veya en azından libc sarmalayıcısı) çağırmak istiyorum. Hangi betik dilinin umurumda değil - sadece derlenmemesi önemlidir (bunun nedeni temel olarak bağımlılık yolunda bir derleyici istememekle ilgilidir, ancak bu ne burada ne de oradadır). Buna izin veren komut dosyası dilleri (kabuk, Python, Ruby, vb.) Var mı?

Özellikle getrandom sistem çağrısı.


3
getrandom sadece rastgele bayt çeker /dev/urandom. Bunu kesinlikle bir kabuk komut dosyasından yapabilirsiniz.
steve

@steve, tabii ki /devhenüz mevcut değilse. Ama sonra Perl'in hayal edeceğini söylemek zor!
derobert

Kritik olarak, bir dosya olarak / dev / urandom'dan okuma yapmaz entropi havuzu başlatılana kadar engellemek istiyorum.
joshlf

5
/dev/randomBloke olana kadar oku , sonra oku /dev/urandom?
Piskopos

1
"nedeni temelde bağımlılık yolunda bir derleyici istemiyorum ile ilgili, ama bu ne burada ne de orada" -> Ha? Çalışma zamanı bağımlılık yolunu kastediyorsanız, hiçbir durumda olmayacaksınız. C'den derlenen bir ikili dosyayı çalıştırmak için bir C derleyicisine ihtiyacınız yoktur. Hedef mimariniz için bir şeyler derleme yeteneğine bağlı olmak istemiyorsanız, bu yeteneğe sahip olmayacağınızı düşünüyorsanız, Python, Bash veya başka herhangi bir gerçek komut dosyası dilini bu platformda çalıştıramazsınız.
Kevin

Yanıtlar:


33

Perl syscallişlevi ile buna izin verir :

$ perldoc -f syscall
    syscall NUMBER, LIST
            Calls the system call specified as the first element of the list,
            passing the remaining elements as arguments to the system call. If
⋮

Belgeler ayrıca write (2) çağrısına bir örnek verir:

require 'syscall.ph';        # may need to run h2ph
my $s = "hi there\n";
syscall(SYS_write(), fileno(STDOUT), $s, length $s);

Ben ettik diyemeyiz hiç rağmen, bu özelliği kullanılır. Peki, şimdi örnek onaylamak gerçekten işe yarıyor.

Bu, aşağıdakilerle çalışıyor gibi görünüyor getrandom:

$ perl -E 'require "syscall.ph"; $v = " "x8; syscall(SYS_getrandom(), $v, length $v, 0); print $v' | xxd
00000000: 5790 8a6d 714f 8dbe                      W..mqO..

Ve syscall.ph dosyasında getrandom yoksa, numarayı kullanabilirsiniz. Debian testi (amd64) kutumda 318 var. Linux sistem çağrılarının mimariye özgü olduğuna dikkat edin.


2
Perl - B planı çekici!
Thorbjørn Ravn Andersen

28

Python'da , libc ctypesdahil olmak üzere dinamik kitaplıklardaki rastgele işlevlere erişmek için modülü kullanabilirsiniz syscall():

import ctypes

SYS_getrandom = 318 # You need to check the syscall number for your target architecture

libc = ctypes.CDLL(None)
_getrandom_syscall = libc.syscall
_getrandom_syscall.restypes = ctypes.c_int
_getrandom_syscall.argtypes = ctypes.c_int, ctypes.POINTER(ctypes.c_char), ctypes.c_size_t, ctypes.c_uint

def getrandom(size, flags=0):
    buf = (ctypes.c_char * size)()
    result = _getrandom_syscall(SYS_getrandom, buf, size, flags)
    if result < 0:
        raise OSError(ctypes.get_errno(), 'getrandom() failed')
    return bytes(buf)

Libc'niz getrandom()sarmalayıcı işlevini içeriyorsa , bunu da çağırabilirsiniz:

import ctypes

libc = ctypes.CDLL(None)
_getrandom = libc.getrandom
_getrandom.restypes = ctypes.c_int
_getrandom.argtypes = ctypes.POINTER(ctypes.c_char), ctypes.c_size_t, ctypes.c_uint

def getrandom(size, flags=0):
    buf = (ctypes.c_char * size)()
    result = _getrandom(buf, size, flags)
    if result < 0:
        raise OSError(ctypes.get_errno(), 'getrandom() failed')
    return bytes(buf)

Herhangi bir şans getrandomsyscall yerine doğrudan libc işlevini çağırmak için bir örnek eklemek olabilir getrandom? Mümkün mü?
17'de joshlf

@joshlf Elbette mümkün. Cevabımı düzenledim.
cg909

Çalışma SYS_getrandomzamanında değerin doğru değerini dinamik olarak aramanın bir yolu olup olmadığını biliyor musunuz (böylece mevcut platform için doğru olanı elde edersiniz)? Örneğin, /usr/includebaşlık dosyalarını ayrıştırarak mı?
joshlf

Denemedim , ama pycparser ile şansınız olabilir .
cg909

17

Ruby'nin bir syscall(num [, args...]) → integerişlevi var.

Örneğin:

irb(main):010:0> syscall 1, 1, "hello\n", 6
hello
=> 6

İle getrandom():

irb(main):001:0> a = "aaaaaaaa"
=> "aaaaaaaa"
irb(main):002:0> syscall 318,a,8,0
=> 8
irb(main):003:0> a
=> "\x9Cq\xBE\xD6|\x87\u0016\xC6"
irb(main):004:0> 
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.