Linuxのsyscall(または少なくともlibcラッパー)をスクリプト言語から直接呼び出したいのですが。どのスクリプト言語でもかまいません。コンパイルしないことが重要です(その理由は基本的に、依存関係のパスにコンパイラを必要としないことに関係していますが、ここにもありません)。これを可能にするスクリプト言語(Shell、Python、Rubyなど)はありますか?
特に、それは getrandom syscallです。
Perlはsyscall
関数でこれを許可します:
$ 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
⋮
ドキュメントには、write(2)の呼び出し例も記載されています。
require 'syscall.ph'; # may need to run h2ph
my $s = "hi there\n";
syscall(SYS_write(), fileno(STDOUT), $s, length $s);
ただし、この機能を使用したことはありませんever。さて、前に今例を確認すると、実際に機能します。
これは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..
Syscall.phにgetrandomがない場合は、代わりに数値を使用できます。私のDebianテスト(AMD64)ボックスでは318です。 Linuxのsyscall番号はアーキテクチャー固有であることに注意してください。
Pythonでは、 ctypes
モジュールを使用して、動的ライブラリの任意の関数にアクセスできます syscall()
libcから:
_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にgetrandom()
ラッパー関数が含まれている場合は、それも呼び出すことができます。
_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)
_
Rubyにはsyscall(num [, args...]) → integer
関数があります。
例えば:
_irb(main):010:0> syscall 1, 1, "hello\n", 6
hello
=> 6
_
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>
_