۲۹-تير-۱۳۹۳, ۱۸:۲۰:۴۸
گاهی اوفات پیش میاد که یه برنامه یه فایلی رو باز کرده؛ و ما احتیاج داری اون فایل رو ببنیدم
راه ساده اینه که کل برنامه رو ببنیدیم (kill کنیم)؛
ولی هنگامی که نمیخواییم به پروسه دست بزنیم؛ راه حل چیه؟
راه حل اینه که به پروسه مورد نظرمون اتچ بشیم و سپس با استفاده از شماره فایل هندل اقدام به بستن اون کنیم؛
با یه مثال توضیح میدم
اسکریپت زیر (به زبان پرل) رو با نام p.pl ذخیره میکنیم
و با دستور زیر اجراش میکنیم
این اسکریپت اول به فایلی رو بنام file برای نوشتن باز میکنه؛ و میمونه کاربر یه اینتر بزنه؛ پ بعدش کلمهی TEST رو توی فایل مینویسه!
هدف اینه که وقتی بنرامه منتظر ورودی کاربر هست (که اینتر بزنه) ما این فایل هندل رو ببندیم؛
برای اینکار از دستور lsof استفاده میکنیم؛ این برنامه لبست تمام فایلهایی که باز هستن رو لیست میکنه؛ با استفاده از پارامتر c میتونیم تعیین کنیم فقط باز شده توسط یه پروسهی خاص رو نشون بده..
پس دستور زیر رو میزنیم:
خروجی ای شبیه زیر به ما نشون میده:
در خط یکی مونده به آخر ؛ یعنی این خط:
میبینیم اسم فایلمون رو نوشته! (برنامه رو در مسیر /tmp/ii اجرا کرده بودم و نام فایلی هم که قرار بود باز بشه file بود)
و همچنین در قسمت fd نوشته شده 3w ؛
3w یعنی نام شماه هندل فایل ۳ هست و برای نوشتن (w) باز شده!
علاوه بر اینها به شماره پروسه هم نیاز داریم که در خط بالا معلومه؛ نوشته شده 5705
توسط gdb به این پروسه وصل میشیم؛ و از این فایل هندل رو میبندیم! انگار که خود برنامه اینکارو کرده!
بعد از اینکه اعلان خط فرمان gdb ظاهر شد:
فرمان بستن فایل هندل ۳ رو میدیم:
با استفاده از
فرمان بسته شدن رو دادیم؛ و نتیجه این اجرا صفر بود که یعنی فرمان با موفقیت اجرا شده
و بعد دستور quit رو میزنیم و y رو انتخاب میکنیم؛ با اینکار دیگه به برنامه اتچ نیستیم
دوباره دستور بالارو اجرا میکنیم
میتونیم مشاهده کنیم که هیچ اثری از شماره فایل 3 و فایل file نیست!!!
میریم سراغ برنامهی پرل که منتظر ورودی ما هست؛ اینتر میزنیم و برنامه به پایان میرسه
محتویات فایل file رو با دستور زیر میبینیم:
همونطور که انتظار داشتیم چیزی نشوته نشده!!!
دوباره برنامه رو اجرا میکنیم:
و اینتر میزنیم؛ و محتویات فایل file میبینیم؛ اینبار عبارت TEST داخل فایل نوشته شده ...
باید دو نکته رو توجه داشت:
۱ - وقتی به برنامهای اتچ میشیم؛ برنماه از روال عادی خارج میشه و به حالت خوابیده میره تا وقتی دستور ادامهی کار رو به برنامه بدیم
۲ - همه چیز در لینوکس فایل هست! یعنی شما میتونید با این روس سوکت ها رو هم ببنید! چون از دیدی لینوکس سوکت هم فایله! میتونید به فایرفاکس اتچ بشید و سوکتهای مورد نظر رو ببنید ...
منبع: خودم
راه ساده اینه که کل برنامه رو ببنیدیم (kill کنیم)؛
ولی هنگامی که نمیخواییم به پروسه دست بزنیم؛ راه حل چیه؟
راه حل اینه که به پروسه مورد نظرمون اتچ بشیم و سپس با استفاده از شماره فایل هندل اقدام به بستن اون کنیم؛
با یه مثال توضیح میدم
اسکریپت زیر (به زبان پرل) رو با نام p.pl ذخیره میکنیم
کد php:
#!/usr/bin/perl
open (KK,">file");
<STDIN>;
print KK "TEST\n";
close(KK);
و با دستور زیر اجراش میکنیم
کد php:
perl p.pl
این اسکریپت اول به فایلی رو بنام file برای نوشتن باز میکنه؛ و میمونه کاربر یه اینتر بزنه؛ پ بعدش کلمهی TEST رو توی فایل مینویسه!
هدف اینه که وقتی بنرامه منتظر ورودی کاربر هست (که اینتر بزنه) ما این فایل هندل رو ببندیم؛
برای اینکار از دستور lsof استفاده میکنیم؛ این برنامه لبست تمام فایلهایی که باز هستن رو لیست میکنه؛ با استفاده از پارامتر c میتونیم تعیین کنیم فقط باز شده توسط یه پروسهی خاص رو نشون بده..
پس دستور زیر رو میزنیم:
کد php:
lsof -c perl
خروجی ای شبیه زیر به ما نشون میده:
کد php:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
perl 5705 ali cwd DIR 8,1 4096 1970504 /tmp/ii
perl 5705 ali rtd DIR 8,1 4096 2 /
perl 5705 ali txt REG 8,1 1462760 2224069 /usr/bin/perl
perl 5705 ali mem REG 8,1 4447600 2231771 /usr/lib/locale/locale-archive
perl 5705 ali mem REG 8,1 34316 530920 /lib/i386-linux-gnu/libcrypt-2.15.so
perl 5705 ali mem REG 8,1 1730024 530919 /lib/i386-linux-gnu/libc-2.15.so
perl 5705 ali mem REG 8,1 124663 530928 /lib/i386-linux-gnu/libpthread-2.15.so
perl 5705 ali mem REG 8,1 173576 530930 /lib/i386-linux-gnu/libm-2.15.so
perl 5705 ali mem REG 8,1 13940 530934 /lib/i386-linux-gnu/libdl-2.15.so
perl 5705 ali mem REG 8,1 134344 530931 /lib/i386-linux-gnu/ld-2.15.so
perl 5705 ali 0u CHR 136,0 0t0 3 /dev/pts/0
perl 5705 ali 1u CHR 136,0 0t0 3 /dev/pts/0
perl 5705 ali 2u CHR 136,0 0t0 3 /dev/pts/0
perl 5705 ali 3w REG 8,1 0 1965991 /tmp/ii/file
perl 5705 ali 8r REG 0,3 0 1682256 /proc/5191/auxv
در خط یکی مونده به آخر ؛ یعنی این خط:
کد php:
perl 5705 ali 3w REG 8,1 0 1965991 /tmp/ii/file
میبینیم اسم فایلمون رو نوشته! (برنامه رو در مسیر /tmp/ii اجرا کرده بودم و نام فایلی هم که قرار بود باز بشه file بود)
کد php:
/tmp/ii/file
و همچنین در قسمت fd نوشته شده 3w ؛
3w یعنی نام شماه هندل فایل ۳ هست و برای نوشتن (w) باز شده!
علاوه بر اینها به شماره پروسه هم نیاز داریم که در خط بالا معلومه؛ نوشته شده 5705
توسط gdb به این پروسه وصل میشیم؛ و از این فایل هندل رو میبندیم! انگار که خود برنامه اینکارو کرده!
کد php:
sudo gdb -p 5705
بعد از اینکه اعلان خط فرمان gdb ظاهر شد:
کد php:
(gdb)
فرمان بستن فایل هندل ۳ رو میدیم:
کد php:
(gdb) call close(3)
$1 = 0
با استفاده از
کد php:
call close(3)
فرمان بسته شدن رو دادیم؛ و نتیجه این اجرا صفر بود که یعنی فرمان با موفقیت اجرا شده
و بعد دستور quit رو میزنیم و y رو انتخاب میکنیم؛ با اینکار دیگه به برنامه اتچ نیستیم
دوباره دستور بالارو اجرا میکنیم
کد php:
lsof -c perl
میتونیم مشاهده کنیم که هیچ اثری از شماره فایل 3 و فایل file نیست!!!
میریم سراغ برنامهی پرل که منتظر ورودی ما هست؛ اینتر میزنیم و برنامه به پایان میرسه
محتویات فایل file رو با دستور زیر میبینیم:
کد php:
cat file
همونطور که انتظار داشتیم چیزی نشوته نشده!!!
دوباره برنامه رو اجرا میکنیم:
کد php:
perl p.pl
باید دو نکته رو توجه داشت:
۱ - وقتی به برنامهای اتچ میشیم؛ برنماه از روال عادی خارج میشه و به حالت خوابیده میره تا وقتی دستور ادامهی کار رو به برنامه بدیم
۲ - همه چیز در لینوکس فایل هست! یعنی شما میتونید با این روس سوکت ها رو هم ببنید! چون از دیدی لینوکس سوکت هم فایله! میتونید به فایرفاکس اتچ بشید و سوکتهای مورد نظر رو ببنید ...
منبع: خودم