एक स्क्रिप्टिंग भाषा से लिनक्स syscall को कॉल करें


15

मैं एक स्क्रिप्टिंग भाषा से सीधे लिनक्स syscall (या कम से कम libc आवरण) को कॉल करना चाहता हूं। मुझे परवाह नहीं है कि भाषा की स्क्रिप्टिंग क्या है - यह सिर्फ इतना महत्वपूर्ण है कि इसे संकलित नहीं किया जाना चाहिए (मूल रूप से इसका कारण निर्भरता पथ में एक कंपाइलर नहीं चाहते हैं, लेकिन यह न तो यहां है और न ही है)। क्या कोई स्क्रिप्टिंग भाषाएं (शेल, पायथन, रूबी, आदि) हैं जो इसे अनुमति देती हैं?

विशेष रूप से, यह गेट्रैंडम syscall है।


3
getrandom बस यादृच्छिक बाइट्स में से खींचती है /dev/urandom। आप निश्चित रूप से एक शेल स्क्रिप्ट से कर सकते हैं।
स्टीव

@ वास्तव में बचाओ, जब तक कि पाठ्यक्रम /devउपलब्ध नहीं है। लेकिन तब पर्ल की कल्पना करना मुश्किल होगा!
derobert

गंभीर रूप से, मैं चाहता हूं कि जब तक एन्ट्रापी पूल को इनिशियलाइज़ नहीं किया जाता है, तब तक इसे ब्लॉक करना है, जो कि फाइल के रूप में / dev / urandom से पढ़ता है।
जोशेल

5
/dev/randomजब तक यह अनब्लॉक न हो जाए, तब तक पढ़ें /dev/urandom?
बिशप

1
"कारण मूल रूप से निर्भरता पथ में एक कंपाइलर नहीं चाहते हैं, लेकिन यह न तो यहाँ है और न ही" -> हुह? यदि आपका मतलब रनटाइम डिपेंडेंसी पथ है, तो आप किसी भी स्थिति में नहीं होंगे। सी से संकलित बाइनरी को चलाने के लिए आपको सी कंपाइलर की आवश्यकता नहीं है। यदि आपका मतलब है कि आप अपने लक्ष्य वास्तुकला के लिए चीजों को संकलित करने की क्षमता पर निर्भर नहीं होना चाहते हैं, क्योंकि आपको लगता है कि आपके पास वह क्षमता नहीं होगी, तो यह संभावना नहीं है कि आप पायथन, बैश या किसी अन्य वास्तविक स्क्रिप्टिंग भाषा को उस मंच पर चला पाएंगे।
केविन

जवाबों:


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
⋮

प्रलेखन भी बुलावा लिखने का एक उदाहरण देता है (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 है। ध्यान दें कि लिनक्स syscall नंबर वास्तुकला-विशिष्ट हैं।


2
पर्ल - योजना बी हथौड़ा!
Thorbjørn रेवन एंडरसन

28

पायथन में आप 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? क्या यह संभव है?
जोशेल

@ जोशफुल यह संभव है। मैंने अपना उत्तर संपादित किया।
cg909

क्या आप जानते हैं कि क्या SYS_getrandomरनटाइम पर मूल्य के सही मान को गतिशील रूप से देखने का कोई तरीका है (इसलिए आप इसे वर्तमान प्लेटफ़ॉर्म के लिए सही पाते हैं)? जैसे, /usr/includeहेडर फाइल को पार्स करके ?
जोशेल

मैंने यह कोशिश नहीं की, लेकिन आप 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> 
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.