스크립팅 언어에서 Linux syscall 호출


15

스크립트 언어에서 직접 Linux syscall (또는 최소한 libc 래퍼)을 호출하고 싶습니다. 나는 어떤 스크립팅 언어를 신경 쓰지 않는다-컴파일되지 않는 것이 중요하다 (이유는 기본적으로 의존성 경로에서 컴파일러를 원하지 않는 것과 관련이 있지만, 여기도 거기도 없다). 이것을 가능하게하는 스크립팅 언어 (쉘, 파이썬, 루비 등)가 있습니까?

특히, getrandom syscall입니다.


3
getrandom은에서 임의의 바이트를 가져옵니다 /dev/urandom. 쉘 스크립트에서 확실히 할 수 있습니다.
steve

물론 @steve를 /dev사용할 수 없다면 @steve도 마찬가지 입니다. 그러나 펄을 상상하기 어렵다!
derobert

비판적으로, 나는 엔트로피 풀이 초기화 될 때까지 이것을 차단하고 싶습니다. 파일은 / dev / urandom에서 읽지 않습니다.
joshlf

5
에서 읽기 /dev/random가 차단을 해제 할 때까지, 그때부터 읽어 /dev/urandom?
주교

1
"이유는 기본적으로 의존성 경로에서 컴파일러를 원하지 않는 것과 관련이 있지만, 여기도 거기도 없다"-> 허? 런타임 종속성 경로 를 의미한다면 어떤 경우에도 아닙니다. C에서 컴파일 된 이진 파일을 실행하기 위해 C 컴파일러가 필요하지 않습니다. 타겟 아키텍처를 위해 컴파일 할 수있는 기능에 의존하고 싶지 않다면, 해당 기능이 없다고 생각하기 때문입니다. Python, Bash 또는 다른 실제 스크립팅 언어를 해당 플랫폼에서 실행할 수 없을 것입니다.
Kevin

답변:


33

펄은 이것을 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);

내가 한 말을 할 수 없습니다 적이 있지만,이 기능을 사용했다. 글쎄, 지금 바로 그 예를 확인하기 위해 실제로 작동합니다.

이것은 다음과 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이 없으면 대신 숫자를 사용할 수 있습니다. 내 데비안 테스트 (amd64) 상자에 318입니다. Linux syscall 번호는 아키텍처별로 다릅니다.


2
펄-계획 B 망치!
Thorbjørn Ravn Andersen

28

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)

getrandomsyscall 대신 libc 함수를 직접 호출하는 예제를 추가 할 수 getrandom있습니까? 가능합니까?
joshlf

@joshlf 물론 가능합니다. 내 답변을 편집했습니다.
cg909

SYS_getrandom런타임에 올바른 값을 동적으로 찾는 방법이 있는지 알고 있습니까? (현재 플랫폼에 맞게 설정하십시오) 예를 들어, /usr/include헤더 파일 을 구문 분석하여 ?
joshlf

나는 그것을 시도하지 않았지만 pycparser 와 함께 운이 좋을 수도 있습니다 .
cg909

17

루비에는 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> 
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.