পাইপ থেকে নেটিভ বাইনারি কার্যকর করার কোনও উপায় আছে কি?


13
echo 'main(){}' | gcc -xc - -o /dev/stdout | ???

ইউনিক্সের মতো সিস্টেমে আউটপুট বাইনারি চালানোর কোনও উপায় আছে কি?

সম্পাদনা: স্যান্ডবক্সযুক্ত পরিবেশে জি ++ আউটপুট চালানোর জন্য আমার এটির দরকার ছিল যেখানে আমি কোনও ফাইল লিখতে পারি না (দূষিত কিছু নয়, আমি প্রতিশ্রুতি দিই)।


আমি বিশ্বাস করি যে বেসিক সুরক্ষা ব্যবস্থাগুলি অবশ্যই এটি প্রতিরোধ করবে। তবে যদি আপনার ঘনিষ্ঠতাটি সি কোডটি অন-ফ্লাইয়ে চালিত হয় তবে কেবল ব্যবহার করুন csh
rozcietrzewiacz

উত্তর:


10

আমি বিশ্বাস করি না এটি সম্ভব। Exec (2) সিস্টেম কল সবসময় একটি ফাইলের নাম বা পথটি প্রয়োজন (ফাইলের নাম সবসময় একটি হল char*)। posix_spawnফাইলের নামের জন্যও অনুরূপ প্রয়োজনীয়তা রয়েছে।

আপনি যা করতে পারেন তার নিকটতম নামটি হ'ল পাইপটিতে আউটপুটটি পাইপ করা এবং পাইপ থেকে সম্পাদন করার চেষ্টা করুন। এটি কাজ করতে পারে, যদিও শেলটি --x--x--xবিট সেট নেই এমন কোনও ফাইল কার্যকর করতে অস্বীকার করতে পারে । এর সাথে পাইপ তৈরি করুন mkfifo(1)এবং দেখুন যে আপনি এটি কাজ করতে পারেন কিনা।

আরেকটি পদ্ধতির মধ্যে এমন কিছু লেখা থাকবে যা স্ট্যান্ডার্ড ইনপুট পড়ে, একটি অস্থায়ী অঞ্চলে একটি ফাইল লেখায়, এতে --x বিট সেট করে, কাঁটাচামচ করে এবং এক্সিকিউট করে ফাইলটি মুছে দেয়। প্রোগ্রামটি সম্পাদন শেষ না হওয়া পর্যন্ত ইনোড এবং সামগ্রীগুলি থাকবে তবে এটি ফাইল সিস্টেমের মাধ্যমে অ্যাক্সেসযোগ্য হবে না। প্রক্রিয়াটি সমাপ্ত হলে ইনোড প্রকাশিত হবে এবং সঞ্চয়স্থান ফ্রি তালিকায় ফিরে আসবে।

সম্পাদনা: মাদুর পয়েন্ট হিসাবে, প্রথম পদ্ধতির কাজ হবে না কারণ লোডার এক্সিকিউটেবলের মধ্যে ডিমান্ড-পৃষ্ঠা দাবি করার চেষ্টা করবে, যা ফাইলটিতে এলোমেলো ট্র্যাফিক ট্রাফিক তৈরি করবে এবং পাইপটিতে এটি সম্ভব নয়। এটি দ্বিতীয় ধরণের মত পদ্ধতির কিছু ছেড়ে দেয়।


2
পাইপ ট্রিকটি যদি কাজ করে তবে আমি সত্যিই অবাক হব - আপনি পাইপটিতে এলোমেলোভাবে চেষ্টা করতে পারবেন না, এবং এমএমএপ করতে পারবেন না - আমি নিশ্চিত যে রানটাইম লোডার / লিঙ্কারকে বিরক্ত করবে :) আপনার দ্বিতীয় পরামর্শটি ভাল বলে মনে হচ্ছে যদিও অস্থায়ী ফাইল ব্যতীত কিছু নিয়ে আসতে পারে না।
মাদুর

@ ম্যাট - আমি মনে করি আপনি ঠিক বলেছেন। এক্সিকিউটেবলের মধ্যে ডিমান্ড পেজিংয়ের ফলে এলোমেলো অ্যাক্সেস ট্র্যাফিক হবে যা পাইপে কাজ করবে না। হাস্যকরভাবে এটি সম্ভবত এসভিআর ২.০ (শেষ সংস্করণ যা ডিমান্ড পেজিং ব্যবহার করেনি) এ কাজ করেছিল - কেবল আমার বয়স দেখানোর জন্য আমি একবার এসভিআর ২.০ এর সাথে একটি এসএন্ডআর ২.০ দিয়ে ও / এস হিসাবে ব্যবহার করেছিলাম।
কনসার্নড

এ সম্পর্কে আরও কিছু চিন্তা করে, আমি নিশ্চিত যে ইউপিএক্সের মতো এক্স প্যাকারগুলি কেবল পঠনযোগ্য মিডিয়াতে সংক্ষেপণ এবং সম্পাদন করতে পারে । তারা প্যাক করা এক্সিকিউটিবেবলকে ডাইক্রপ্রেস না করে পাইপ থেকে পড়ার জন্য প্যাক করা এক্সিকিউটেবলের কাছে যা কিছু স্টাব লাগায় তা সংশোধন করুন এবং ... কাজ করতে পারে।
মাদুর

@ ম্যাট প্যাকারদের ইতিমধ্যে একটি চিত্র লোড হয়েছে তারা কোনও নতুন প্রক্রিয়া শুরু করে না। অনুরূপ করার জন্য আমার ইনপুট ডেটাগুলিতে স্বেচ্ছাসেবী ঝাঁপ দেওয়ার জন্য একটি প্রক্রিয়া থাকা দরকার (যা একটি সুরক্ষার দুর্বলতা হিসাবে বিবেচিত হবে)।
অ্যালেক্স বি

@ অ্যালেক্স বি: আপনি বিশেষভাবে জিজ্ঞাসা করছেন কীভাবে ইনপুট ডেটাগুলিতে একটি স্বেচ্ছাসেবী ঝাঁপ দেওয়া যায়। আপনি ঠিক এমনটি করার পরামর্শ দিলে আপনি কেন অভিযোগ করবেন? আপনি যা করতে চেষ্টা করছেন তা রোধ করার জন্য স্যান্ডবক্সের উদ্দেশ্যটি কি বিশেষভাবে?
ডেভিড শোয়ার্জ

7

মেমফেড সিস্কেল ব্যবহার করে একটি সমাধান: https://github.com/abbat/elfexec

এটি মেমোরিতে একটি নামকৃত ফাইল বর্ণনাকারী তৈরি করে যা এতে ব্যবহার করা যেতে পারে exec। একটি সিউডো কোড:

#include <linux/memfd.h>
...
int memfd = syscall(SYS_memfd_create, "someName", 0);
...
write(memfd,... elf-content...);
...
fexecve(memfd, argv, environ);

1
আপনি ব্যবহার করতে না চাইলে আপনার memfd.hশিরোনামের প্রয়োজন হবে না MFD_CLOEXEC(যা #! /bin/shলিনাক্সের বাগগুলির কারণে স্ক্রিপ্টগুলি ভেঙে দেয় fexecve())। এটি খুব জটিল নয়, আপনি আপনার উত্তরে একটি ২০-লাইনের কার্যকারী নমুনা অন্তর্ভুক্ত করতে পারেন (উদাঃ এই গিট গিস্ট - যদিও এটি আপনার জন্য ড্রপ-ইন প্রতিস্থাপন নয় elfexec, কারণ এটি আপনাকে নির্দিষ্ট করারও অনুমতি দেবে argv[0]এবং একটি বাইনারি চালাবে কেবল একটি পাইপ থেকে (ইউইউসি আদেশ ;-))
ম্যাসভি

সুতরাং আমি কীভাবে এটি প্রত্যাশিতভাবে কাজ করব তা পাই না। gcc .oফাইলগুলি / tmp এ লিখবে এবং না পারলে মরে যাবে।
জোশুয়া

4

আপনি টি সি সি চেষ্টা করতে পারেন , যা কোনও ধাপে কোনও প্রোগ্রামের সংকলন এবং সম্পাদন করবে, কোনও মধ্যবর্তী ফাইল না লিখে step এটি জিসিসি নয়, যা আপনার পক্ষে সমস্যা হতে পারে, তবে এটি দর্শনীয়ভাবে দ্রুত, সুতরাং এটি আপনার উদ্দেশ্যগুলির জন্য জিসিসি-র চেয়ে আরও ভাল বাজিও লাগতে পারে।


2

এটি স্বয়ংক্রিয়ভাবে আপনার কোডের সংকলন চালাবে, তবে এটি করার জন্য ফাইল সিস্টেমে একটি ফাইল (অস্থায়ীভাবে) তৈরি করে।

echo 'main(){}' | gcc -xc -o /tmp/a.out && chmod u+x /tmp/a.out && /tmp/a.out && rm -f /tmp/a.out

(আমি বর্তমানে এটি পরীক্ষা করছি, তবে আমি নিশ্চিত যে এটি, বা এর কাছাকাছি কিছু আপনার পক্ষে কাজ করবে)

সম্পাদনা: যদি আপনার পাইপিংয়ের লক্ষ্যটি গতির জন্য সমীকরণের বাইরে শারীরিক ডিস্কগুলি কেটে ফেলা হয় তবে মধ্যবর্তী ফাইলটি ধরে রাখতে একটি র‌্যাম ডিস্ক তৈরি করার বিষয়টি বিবেচনা করুন।


এটি অবশ্যই কাজ করবে, তবে এটি প্রশ্নের মূল পয়েন্টটি মিস করে - একটি বাইনারি কোড চালায় যা কখনও ডিস্কে লেখা হয় না।
রোজিট্রিজেভিয়াকজ

@ জর্জিট্রিজেভিয়াকজ আমার আশাটি কার্যকর হয়েছিল যদি লক্ষ্যটি প্রয়োজনীয় শারীরিক ফাইল নিয়ে কাজ না করে সহজেই ফ্লাইটিতে কোড স্লিপিট চালানো হত।
dtyler

হ্যাঁ আমি বুঝেছি. তবে তার জন্য, একটি সহজভাবে ব্যবহার করতে পারে csh
rozcietrzewiacz

0

শুধু @TheQUUX প্রস্তাব, আমি এটা আমার স্ব পরীক্ষিত না কিন্তু আপনি চেষ্টা করে দেখতে চাইতে পারেন cling- "ইন্টারেক্টিভ সি ++ ইন্টারপ্রেটার, LLVM এবং ঝনঝন লাইব্রেরি উপরে নির্মিত।"।

এখানে আরও তথ্য সন্ধান করুন: https://cdn.rawgit.com/root-project/cling/master/www/index.html

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.