I'm Mahdi - Isfahan - Mehr mah - Linux, programming, OS, tech, game, Music, book and ... lover
برنامه نویسی: دزدیدن اطلاعات فلش USB با پایتون 3 ,2021 (+ آموزش pyinstaller)
این مقاله صرفا به منظور آموزش و اطلاع رسانی نوشته شده و مسئولیت استفاده از آن به عهده ی خود شخص است.
مقدمه ی کوتاه:
برای کپی کردن اطلاعات یک USB متصل به کامپیوتر روش های زیادی وجود داره. از ساده ترین روش ها پرت کردن حواس صاحب USB و کپی کردن دستی فایل ها و فولدر هاست ولی خب اگه به روش های هکرگونه و خودکار علاقه دارید دو تا رَوِش وجود داره:
اول) استفاده از نرم افزار های آماده برای این کار: مثل "FileStealer F2h" [لینک دانلود (+)]
اگه حال و حوصله و ذوق یادگیری برنامه نویسی ندارید دیگه این مقاله رو ادامه ندید و از لینک بالا برنامه رو دانلود و استفاده کنید.
دوم) برنامه نویسی برای ساختن برنامه ای که بتونه اینکار رو انجام بده.
خب اگه روش دوم رو انتخاب کردید حالا میرسیم به بحث اینکه کدوم زبان برنامه نویسی رو انتخاب کنیم برای آموزش ؛ پس بین پایتون و سی شارپ باید انتخاب میکردم. چون انتخاب نسبتا سختی بود گفتم که چه بهتره هر دو رو بنویسم ولی فقط پایتون رو آموزش بدم چون راحت تره.
ولی شما میتونید سورس کد هر دو رو توی گیت هاب ببینید (لینک های پایین)
خب اگه بازم حوصله ی آموزش پایتون و الگوریتم و خوندن اضافی جات ندارید و مستقیم خود کد رو میخواهید ، این لینک ها رو قرار میدم:
سورس کد پایتون: [لینک دانلود (+)]
سورس کد سی شارپ: [لینک دانلود (+)]
فایل اجرایی (exe) پایتون برای ویندوز: [لینک دانلود (+)]
فایل اجرایی (exe و dll) سی شارپ برای ویندوز: [لینک دانلود (+)]
آموزش سه بخش میشه:
اول) طراحی الگوریتم برنامه و فهمیدن روش کار کردن برنامه و پایتون
دوم) نوشتن برنامه با پایتون
سوم) خروجی گرفتن از برنامه
البته در نظر داشته باشید که این آموزش فقط برای ایده دادن و نشون دادنش به پایتونی ها و برنامه نویس ها و حتی تازه کار هاست و روش های خیلی بهتری و قوی تری برای اینکار هم وجود داره.
الگوریتم:
خب یه برنامه میخوایم که بتونه اول از همه USB های متصل به کامپیوتر رو پیدا کنه ، اگه چیزی پیدا نکرد بگه که چیزی نبود. اگه پیدا کرد ، به ترتیب بره توی هر کدوم و فایل ها و فولدرهای اون رو کپی کنه و توی یه مسیر مشخص بریزه و یه progressbar هم نشون بده ، آخر از همه هم پیغام بده که تموم شد.
آموزش مبتدی پایتون:
قبل هر چیز اگه اصلا تجربه ی برنامه نویسی و یا برنامه نویسی پایتون ندارید ، اول مقاله زیر رو یه بار مطالعه کنید و یاد بگیرید چون توی اون مقاله خیلی خیلی توضیحات سطحی و اضافی دادم که دیگه اینجا اونا رو تکرار نمیکنم و چیز های تازه تری رو میگم:
- یک) __init__: یکی از متدهای سازنده یا constructor زبان پایتون هست. این تابع هر بار دقیقا بعد از نسبت دادن یک کلاس به شی ، اجرا میشه.
- دو) abstractmethod@: اگه با بعضی زبان های برنامه نویسی مثل جاوا و سی شارپ و ... آشنایی داشته باشید ، میدونید که وقتی یه متد به صورت abstract تعریف میشه ، توی کلاس های فرزند حتما باید تعریف بشه.
پس وقتی abstractmethod@ قبل یه تابع نوشته بشه ، اون تابع به صورت abstract میشه.
- سه) staticmethod@: باز هم اگه آشنایی با زبان های دیگه داشته باشید ، میدونید که وقتی یه متد با static تعریف بشه میتونه بدون اینکه وابستگی به اون کلاس داشته باشه (بدون ساختن شی از کلاس) فراخوانی بشه.
این تابع نیازی به نوشتن self ندارد.
- چهار) ()super: کاربرد های متفاوتی ممکنه داشته باشه. اینجا برای فراخوانی متد __init__ کلاس والد استفاده میشه.
آموزش کتابخانه های پایتون:
کتابخانه abc:
اینجا از دو کلاس ABC و abstracmethod استفاده میکنیم ، دلیل و روش استفاده رو بالا توضیح دادم.
کتابخانه platform:
از کلاس system برای فهمیدن سیستم عامل حال حاضر ، استفاده میکنیم. روش استفاده : با فراخوانی ، یه رشته بر میگردونه.
کتابخانه time:
کاربرد های خیلی گسترده ای میتونه داشته باشه. اینجا از کلاس sleep برای تاخیر انداختن در بسته شدن برنامه استفاده میکنیم ، روش استفاده:
sleep(number_in_seconds)
کتابخانه os:
این کتابخانه بیشتر برای تعامل با سیستم عامل هست (فرقی بین نوع سیستم عامل نیست) ، از این کتابخانه کلاس های زیر استفاده میکنیم:
chdir(Location): برای عوض کردن دایرکتوری/فولدر که برنامه در آن فعالیت میکنه
listdir(Location): برای لیست کردن همه ی فولدر ها و فایل های داخل یه دایرکتوری/فولدر
mkdir(Folder_name): برای ساختن یه پوشه با اسم داخل پرانتز در فولدری که در آن برنامه فعالیت داره
path: کاربرد های زیادی برای فایل ها و فولدر های توی یه مسیر داره
sep: علامت جدا کردن (اسلش یا بک اسلش) فایل ها و فولدر ها از هم که برای هر سیستم عامل متفاوت است
مثالها:
فهمیدن فایل بودن یه آیتم: (path.isfile(file_name
فهمیدن فولدر بودن یه آیتم: (path.isdir(folder_name
کتابخانه shutil:
برای استفاده از فایل ها و فولدر ها هست ، ما از کلاس های copytree و copyfile برای کپی کردن فولدر ها و فایل ها استفاده میکنیم:
copyfile(source, destination) و copytree(source, destination)
کتابخانه progressbar:
همونطور که از اسمش پیداست ، برای استفاده از نوار پیشرونده در برنامه است که ما از کلاس های زیر استفاده میکنیم:
- اول) (widget : ProgressBar(widget, maxval مشخصاتی هست که میخوایم بهش بدیم و maxval هم حداکثر مقداری هست که میتونه پیشروی کنه و برای آپدیت کردن مقدار اون ، اول یه متغییر bar تعریف میکنیم و (ProgressBar(widget, maxval رو بهش مقدار میدیم و با (bar.update(number اون رو آپدیت میکنیم. بقیه ی کلاس ها رو هم خودتون امتحان کنید ، جالبن ?
خب بریم سراغ برنامه نویسی و از اول شروع کنیم به نوشتن برنامه مون.
قبل از اون ، اگه کتابخانه ای رو نصب ندارید با دستور زیر اون رو نصب کنید.
pip install library_name
برای لینوکس pip3 استفاده کنید.
به جای library_name ، اسم کتابخانه ی مورد نظر رو بنویسید.
تذکر : برای سادگی کار و به هم نریختن فونت و چیزای دیگه توی سایت ویرگول از عکس کد ها استفاده کردم و اگه دوست دارید خود کد ها رو داشته باشید ، از مقدمه لینک ها رو پیدا کنید.
شروع:
- اول از همه کتابخانه های برنامه مشترک برای ویندوز و لینوکس رو وارد میکنیم.
- بعد از اون سه تا کلاس جدید میسازیم ، یکی والد و اون دو تا فرزند تا مجبور نباشیم هر بار برای نوشتن کد های سیستم عامل های مختلف ، یه سری کد ها رو تکرار کنیم. در آخر هم یه شرط میگذاریم. این شرط به معنی اینکه ، اگه برنامه به صورت مستقیم باز شد این کارها رو انجام بده و زیرشرط ها هم برای فراخوانی کلاس های هر کدوم از سیستم عامل ها هستند.
- برای کلاس Main یه تابع سازنده تعریف میکنیم و دو تا ورودی ، یکی به عنوان محل ساختن پوشه برای کپی کردن فایل ها و یکی هم محل کپی کردن فایل ها در نظر میگیریم.
- این دو تا متغییر گرفته شده رو با self تعریف میکنیم تا جاهای دیگه ای هم از کلاس یا زیر کلاس ها هم قابل استفاده باشه.
- یک متغییر برای نگه داشتن تعداد USB های استفاده شده هم تعریف میکنیم و مقدار پیش فرض را صفر میدیم.
- یک لیست هم تعریف میکنیم تا محل USB ها رو در اون نگه داریم.
- بعد با یه شرط مطمئن میشیم که فولدر USB Files در محل خودش وجود داره یا نه ، اگه وجود داشت که هیچی ، اگه نداشت یکی برامون بسازه و بره داخلش.
من home رو \\:C و dest رو C:\\USB Files در نظر گرفتم. از اینجا به بعد به dest ، فولدر مقصد میگیم.
- یه دستور پرینت هم با یه سری متن بهش میدیم که مثلا برنامه ی ما آنتی ویروس هست ، و اگه کسی دید که ما برنامه مون رو باز کردیم بتونیم بهش بگیم که داره دنبال ویروس میگرده (البته این روش خوبی برای اینکار نیست ولی برای افراد خیلی غیرتکنولوژی مثل شوهر عمه ها میشه استفاده کرد ، البته شاید)
- وقتی چند تا USB به کامپیوتر وصل باشه ، چطوری قراره که فایل ها و فولدر هاشون رو کپی کنیم و با هم قاطی نشن ؟ خب یه راهش میتونه این باشه که به USB ها شماره بدیم یا از اسم خودشون استفاده کنیم (از اسم خودشون استفاده کردن رو توی پایتون نتونستم کد مربوط بهش رو پیدا کنم ولی توی سی شارپ نوشتم ، میتونید ببینید)
- پس اول یه تابع تعریف میکنیم تا توی فولدر مقصد بگرده و همه ی اعدادی که اسم پوشه ها هستند رو پیدا کنه ، مقایسه کنه و بیشترین شون رو پیدا کنه و بزاره توی self.usbNum که همون اول تعریف کرده بودیم ، تا اگه خواستیم بازم پوشه بسازیم ، بدونیم چه عددی رو باید استفاده کنیم.
- قسمت دوم رو هم توضیح دادم قبلا. این تابع رو هم با pass مینویسیم که کاری به محتویات داخلش نداشته باشه تا بعدا در زیرکلاس ها تعریفش کنیم.
- این تابع رو هم برای این تعریف میکنیم تا اگه تعداد USB های پیدا شده ، صفر بود (اصلا چیزی پیدا نشد) ، یه پیغام رو چند ثانیه نشون بده و بعدش از برنامه خارج بشه. میتونیم این تابع رو از نوع استتیک تعریف کنیم و یه ورودی هم به عنوان لیست USB ها بگیره. شاید بگید که خب چرا از self.usb_drive_list استفاده نمیکنیم و یه ورودی میگیریم ؟ خب چون قرار نیست این متغییر توی خود تابع Main مقدار بگیره و خب قاعدتا نباید مقداری هم داشته باشه وقتی مستقیما از خود کلاس Main استفاده میکنیم (متوجه نشدید ، یه بار استتیک رو پاک کنید و سعی کنید با روش خودتون انجامش بدید)
- خب حالا دو تا تابع تعریف میکنیم ، اولی برای اینکه یکی یکی داخل USB ها بره و دومی برای اینکه فایل و فولدر های داخل اون USB ای که درش هست رو به فولدر مقصد (+ شماره USB) کپی کنه.
توضیح تابع دوم در عکس زیر ...
- اول از همه یه متغییر به اسم pwd تعریف میکنیم که بهش لیست فایل ها و فولدر های داخل پوشه ای که الان برنامه در اون داره فعالیت میکنه (".") رو میدیم و با استفاده از pwd میتونیم فایل ها و فولدر ها رو از هم مشخص کنیم ، برای اینکار دو تا لیست تعریف میکنیم.
اگه متوجه نشدید که دو تا لیست چطوری مقدار دهی شدن ، توی گوگل سرچ کنید:
python list comprehensions
- خطوط بعدش رو قبلا توضیح دادم ، ولی برای محکم کاری ، widget ویژگی های progressbar شما رو تعیین میکنه ، که خیلی راحت میتونید جاهاشون رو عوض کنید یا حذف شون کنید ببینید که چه اتفاقی میفته. متغییر bar هم خود progressbar رو برامون نگه میداره. متغییر x یه نگه دارنده ی مقدار bar هست که میتونید حتی اسم های دیگه ای هم بهش بدید
- پس اول از همه به bar دستور شروع میدیم یعنی: ()bar.start
- بعد دو تا حلقه ی for تعریف میکنیم ، که اولی برای کپی کردن فولدر های توی USB هست با استفاده از copytree هست و با هر بار کپی شدن یک فولدر ، یک واحد هم به bar اضافه میکنه و هم به x.
- هر دو Try و except هم برای هندل کردن ارور هایی هست که موقع اجرای این کد ممکنه پیش بیاد. به صورت که اول سعی میکنه کد توی try رو اجرا کنه ، اگه نشد کد توی except رو اجرا میکنه.
البته این مدل نوشتن except استاندارد نیست ولی برای آموزش بد نیست.
- حلقه ی دوم for هم مثل قبلی عمل میکنه ولی اینبار برای کپی کردن فایل ها با استفاده از copyfile
- مدل نوشتنی که توی پرانتز copytree و copyfile استفاده شده به این صورته:
اول از همه منبع (همون که قراره کپی بشه) .
بعد از اون : فولدر مقصد + شماره USB + جداکننده + اسم فولدر/فایل
مثال در ویندوز : ("Copyfile(“I:\\new.txt”, “C:\\USB Files” + “1” + “\\” + “new.txt
مقادیر رشته با علامت + به هم دیگه میچسبند
- در آخر هم bar رو با ()bar.finish تموم میکنیم.
و تابع آخر در کلاس Main که وقتی برنامه تموم میشه یه پیام رو نشون میده و منتظر میمونه تا با زدن اینتر از برنامه خارج بشه.
خب حالا نوبت اینه که کلاس های فرزند رو تعریف کنیم ، از ویندوز شروع میکنیم.
قسمت MainWindow:
- اول از همه متد سازنده رو تعریف میکنیم و از ()super استفاده میکنیم تا کد های داخل __init__ کلاس Main در این کلاس هم قابل استفاده بشن. اگه یادتون باشه دو تا ورودی هم بهش میدادیم که توی Main استفاده میشد.
بعد از اینکار باید بریم سراغ اینکه یکی یکی توابع رو صدا بزنیم تا کارشون رو برای ما انجام بدن.
- اول از همه ()self.USB_Number که تعداد های از قبل استفاده شده در فولدر مقصد رو پیدا کنه
- بعد یه لیست به اسم self.usb_drive_list میسازیم و مقدارش رو ، مقدار برگردونده شده از تابع USB_Drive_List قرار میدیم ، شاید بپرسید که ما هنوز کاملش نکردیم (با pass ازش رد شدیم) پس چطوری استفاده کنیم ، خب مشکلی نیست بعدا این تابع رو تعریف میکنیم.
این لیست همه ی USB های متصل به کامپیوتر هست.
اگه توجه کرده باشید که یه لیست به اسم self.usb_drive_list و یه تابع به اسم self.USB_Drive_List داریم و هر دو اسمشون دقیقا شبیه هم دیگست پس چرا قاطی پاتی نمیشن ؟ خب پایتون زبان حساس به بزرگ و کوچکی حروف هست و مشکلی براش پیش نمیاد با این حالت نام گذاری ، پس نگران نباشید.
- خب لیست ایجاد شده رو به تابع self.USB_Found_Or_Not میدیم تا ببینیم آیا خالی هست یا نه و باید بعدش چیکار کنه.
- بعد از گذر از این مرحله میریم سراغ دو تا تابع self.Copy و self.Copy_Try که قبلا توضیح دادم چیکار میکنن و در آخر هم که self.Final باید اجرا بشه.
خب حالا دیگه نوبت اینه که USB_Drive_List رو تعریف کنیم
اگه بازم متوجه نشدید که چرا همونجا توی Main کاملش نکردیم ، بعد از کامل شدن برنامه این تابع رو در کلاس MainWindow و MainLinuxمقایسه کنید تا متوجه بشید چقدر با هم فرق دارن و اصلا ربطی به همدیگه ندارن .
- اول از همه کتابخانه های مورد نیازش رو وارد میکنیم و یه لیست خالی به اسم drive_list تعریف میکنیم تا USB ها رو در اون بریزیم.
بقیه ی کد ها رو اصلا قرار نیست کامل متوجه بشید که چی هستن و چطوری کار میکنن ، من هم توضیح نمیدم (من هم این تیکه کد رو از اینترنت گرفتم و بهش مسلط نیستم ) ولی بدونید که روش پیدا کردن USB ها اینه.
- در آخرش هم که همون لیست drive_list رو برمیگردونیم (قبلا گفتیم کجا استفاده میشه ، قسمت MianWindow رو دوباره بخونید)
قسمت MainLinux:
خب این کلاس یه تفاوت هایی با MainWindow داره که توضیح میدم.
- اول از همه کتابخانه های مرتبط با لینوکس رو وارد میکنیم.
- بعد از اون باید username فردی که روی سیستم هست رو پیدا کنیم چون بدون اون USB ها و دایرکتوری home و media رو نمیتونیم پیدا کنیم.
برای مثال:
یوزرنیم من master هست پس
متغییر home باید به این شکل باشه: Home = “/home/master/”
و dest به این شکل: Dest = “/home/master/USB Files/”
بعد از این کد های داخل __init__ کاملا با کد های داخل کلاس MainWindow یکسانه و دیگه توضیح نمیدم.
- اینبار پیدا کردن USB ها کار سختی نیست و فقط باید این مسیر رو ببینیم: /media/username/
- پس اول از همه با chdir به اون پوشه میریم. همه ی پوشه های داخلش رو توی لیست drive_list میریزیم و در آخر هم لیست رو برمیگردونیم.
برای خروجی گرفتن از برنامه ، از pyinstaller استفاده میکنیم ، برای نصب در Terminal و CMD یا PowerShell:
pip install pyinstaller
برای لینوکس باید یه 3 به pip اضافه کنید.
بعد به فولدری که فایل برنامه را در آن ذخیره کرده بودیم میریم و دستور:
pyinstaller .\FileStealerUSB2PC.py --name FileStealerUSB2PC.Win 64 --onefile --icon=.\usb.ico
بعد توی همون پوشه ، پوشه ای به اسم dist ساخته شده و برنامه ی شما آماده ی استفاده است
دقت کنید: اگه سیستم شما 64 بیتی هست ، نسخه ای که با pyinstaller ساخته میشه هم 64 بیتی هست و نمیتونید اون رو روی سیستم های 32 بیتی اجرا کنید ولی برعکسش ممکنه .
به جای اینکار ، میتونید یه سیستم عامل مجازی 32 بیتی نصب کنید و روی اون pyinstaller رو اجرا کنید که دیگه براتون مشکل نباشه.
خب امیدوارم خوشتون اومده باشه. اگه سوالی داشتین یا نظری در مورد اینکه جایی از مقاله ناقص هست یا اشتباهه حتما کامنت کنید. اگه دوست داشتین و به دردتون خورد حتما لایک کنید.
مقاله های من:
پر بازدید ترین:
بقیه مقاله ها:
Telegram: @bestmahdi2
Instagram:
https://www.instagram.com/bestmahdi2/
مطلبی دیگر از این انتشارات
کمی دیوانهبازی با f-string های python
مطلبی دیگر از این انتشارات
بهترین دوره های تحلیل تکنیکال
مطلبی دیگر از این انتشارات
ساخت یک آپلودر ساده برا دسترسی راحت از هاست