وظیفه ای برای یک توسعه دهنده، یا اینکه چگونه اسکنرهای دستی را بدون فروشنده فلش کردیم

سلام بر همه

ما، ویکتور آنتی‌پوف و ایلیا آلشین، امروز در مورد تجربه کار با دستگاه‌های USB از طریق Python PyUSB و کمی در مورد مهندسی معکوس صحبت خواهیم کرد.

وظیفه ای برای یک توسعه دهنده، یا اینکه چگونه اسکنرهای دستی را بدون فروشنده فلش کردیم

ماقبل تاریخ

در سال 2019، فرمان شماره 224 دولت فدراسیون روسیه "در مورد تصویب قوانین برچسب گذاری محصولات تنباکو با ابزار شناسایی و ویژگی های اجرای یک سیستم اطلاعات دولتی برای نظارت بر گردش کالاهای مشمول برچسب گذاری اجباری با وسایل شناسایی در رابطه با محصولات تنباکو» لازم الاجرا شد.
در این سند توضیح داده شده است که از اول جولای 1، تولیدکنندگان موظفند هر بسته تنباکو را برچسب گذاری کنند. و توزیع کنندگان مستقیم باید این محصولات را با اجرای سند انتقال جهانی (UDD) دریافت کنند. فروشگاه ها نیز به نوبه خود نیاز به ثبت فروش محصولات دارای برچسب از طریق صندوق دارند.

همچنین از اول جولای 1، گردش محصولات دخانی بدون برچسب ممنوع است. این بدان معنی است که تمام پاکت های سیگار باید با یک بارکد ویژه Datamatrix علامت گذاری شوند. علاوه بر این - یک نکته مهم - معلوم شد که Datamatrix معمولی نیست، بلکه معکوس خواهد بود. یعنی نه کد سیاه روی سفید، بلکه برعکس.

ما اسکنرهای خود را آزمایش کردیم، و معلوم شد که بیشتر آنها نیاز به reflash / آموزش مجدد دارند، در غیر این صورت آنها به سادگی قادر به کار عادی با این بارکد نیستند. این چرخش وقایع برای ما یک سردرد شدید را تضمین کرد، زیرا شرکت ما فروشگاه های زیادی دارد که در یک قلمرو وسیع پراکنده شده اند. چند ده هزار صندوق - و زمان بسیار کمی.

چه باید کرد؟ دو گزینه وجود دارد. اول: مهندسان در محل به صورت دستی اسکنرها را بازخوانی و تنظیم می کنند. دوم: ما از راه دور کار می کنیم و ترجیحاً بسیاری از اسکنرها را به طور همزمان در یک تکرار پوشش می دهیم.

بدیهی است که گزینه اول برای ما مناسب نبود: ما باید برای بازدید از مهندسان پول خرج کنیم و در این مورد کنترل و هماهنگی روند دشوار خواهد بود. اما مهمترین چیز این است که مردم کار کنند، یعنی به طور بالقوه خطاهای زیادی دریافت می کنیم و به احتمال زیاد ضرب الاجل را رعایت نمی کنیم.

گزینه دوم برای همه خوب است، اگر نه برای یک چیز. برخی از فروشندگان ابزارهای چشمک زن از راه دور مورد نیاز ما برای همه سیستم عامل های مورد نیاز را نداشتند. و از آنجایی که مهلت‌ها تمام می‌شد، باید با سر خودم فکر می‌کردم.

در مرحله بعد، به شما خواهیم گفت که چگونه ابزارهایی را برای اسکنرهای دستی برای سیستم عامل Debian 9.x توسعه دادیم (همه صندوق‌های نقدی ما در دبیان هستند).

حل معما: چگونه یک اسکنر را فلش کنیم

ویکتور آنتیپوف گزارش می دهد.

ابزار رسمی ارائه شده توسط فروشنده تحت ویندوز و فقط با IE کار می کند. ابزار می تواند فلش کند و اسکنر را پیکربندی کند.

از آنجایی که سیستم هدف ما دبیان است، یک سرور usb-redirector در دبیان و یک سرویس گیرنده usb-redirector در ویندوز نصب کردیم. با استفاده از ابزارهای usb-redirector، ما اسکنر را از یک ماشین لینوکس به یک ماشین ویندوز ارسال کردیم.

ابزاری از یک فروشنده ویندوز اسکنر را دید و حتی آن را به طور معمول فلش کرد. بنابراین، ما اولین نتیجه را گرفتیم: هیچ چیز به سیستم عامل بستگی ندارد، این موضوع مربوط به پروتکل فلش است.

خوب. ما فلش را روی دستگاه ویندوز اجرا کردیم و dump را در دستگاه لینوکس حذف کردیم.

ما زباله را در WireShark گذاشتیم و ... غمگین شدیم (من برخی از جزئیات زباله را حذف می کنم، آنها هیچ علاقه ای ندارند).

آنچه زباله دان به ما نشان داد:

وظیفه ای برای یک توسعه دهنده، یا اینکه چگونه اسکنرهای دستی را بدون فروشنده فلش کردیم

وظیفه ای برای یک توسعه دهنده، یا اینکه چگونه اسکنرهای دستی را بدون فروشنده فلش کردیم

آدرس‌های 0000-0030، با قضاوت بر اساس Wireshark، اطلاعات سرویس USB هستند.

ما به قسمت 0040-0070 علاقه مند بودیم.

هیچ چیز از یک فریم انتقال مشخص نبود به جز کاراکترهای MOCFT. معلوم شد که این کاراکترها کاراکترهایی از فایل سیستم عامل و همچنین کاراکترهای باقی مانده تا انتهای قاب هستند (فایل سیستم عامل برجسته شده است):

وظیفه ای برای یک توسعه دهنده، یا اینکه چگونه اسکنرهای دستی را بدون فروشنده فلش کردیم

نمادهای fd 3e 02 01 fe به چه معنی بودند، من شخصاً مانند ایلیا هیچ ایده ای نداشتم.

من به فریم زیر نگاه کردم (اطلاعات سرویس در اینجا حذف شده است، فایل سیستم عامل برجسته شده است):

وظیفه ای برای یک توسعه دهنده، یا اینکه چگونه اسکنرهای دستی را بدون فروشنده فلش کردیم

چه چیزی مشخص شد؟ که دو بایت اول نوعی ثابت هستند. همه بلوک های بعدی این را تایید کردند، اما قبل از پایان بلوک انتقال:

وظیفه ای برای یک توسعه دهنده، یا اینکه چگونه اسکنرهای دستی را بدون فروشنده فلش کردیم

این فریم نیز گیج‌کننده بود، زیرا ثابت تغییر کرده بود (هایلایت شده) و به طرز عجیبی، بخشی از فایل وجود داشت. اندازه بایت های انتقال یافته فایل نشان می دهد که 1024 بایت منتقل شده است. من دوباره نمی دانستم بایت های باقی مانده چه معنایی دارند.

اول از همه، به عنوان یک نام مستعار قدیمی BBS، پروتکل های انتقال استاندارد را بررسی کردم. هیچ پروتکلی 1024 بایت ارسال نکرده است. من شروع به مطالعه سخت افزار کردم و با پروتکل 1K Xmodem مواجه شدم. این اجازه ارسال 1024 را می داد، اما با یک هشدار: در ابتدا فقط 128، و فقط در صورت عدم وجود خطا، پروتکل تعداد بایت های ارسال شده را افزایش داد. من بلافاصله انتقال 1024 بایت داشتم. تصمیم گرفتم پروتکل های انتقال و به طور خاص مودم X را مطالعه کنم.

دو نوع مودم وجود داشت.

ابتدا قالب بسته XMODEM با پشتیبانی از CRC8 (XMODEM اصلی):

وظیفه ای برای یک توسعه دهنده، یا اینکه چگونه اسکنرهای دستی را بدون فروشنده فلش کردیم

دوم، قالب بسته XMODEM با پشتیبانی از CRC16 (XmodemCRC):

وظیفه ای برای یک توسعه دهنده، یا اینکه چگونه اسکنرهای دستی را بدون فروشنده فلش کردیم

به نظر مشابه است، به جز SOH، شماره بسته و CRC و طول بسته.

من به ابتدای بلوک انتقال دوم نگاه کردم (و دوباره فایل سیستم عامل را دیدم، اما قبلاً با 1024 بایت فرورفته شده بود):

وظیفه ای برای یک توسعه دهنده، یا اینکه چگونه اسکنرهای دستی را بدون فروشنده فلش کردیم

من هدر آشنا fd 3e 02 را دیدم، اما دو بایت بعدی قبلاً تغییر کرده بود: 01 fe بود و 02 fd شد. سپس متوجه شدم که بلوک دوم اکنون شماره 02 است و به این ترتیب فهمیدم: جلوی من شماره گذاری بلوک انتقال بود. دنده 1024 اول 01، دومی 02، سومی 03 و غیره (البته به صورت هگز). اما تغییر از fe به fd به چه معناست؟ چشم ها کاهش 1 را مشاهده کردند، مغز یادآور شد که برنامه نویسان از 0 می شمارند نه 1. اما پس چرا بلوک اول 1 است و 0 نیست؟ من هنوز جواب این سوال را پیدا نکردم. اما فهمیدم که بلوک دوم چگونه حساب می شود. بلوک دوم چیزی بیش از FF نیست - (منهای) تعداد بلوک اول. بنابراین، بلوک دوم به عنوان = 02 (FF-02) = 02 FD تعیین شد. خواندن بعدی روگرفت حدس من را تأیید کرد.

سپس تصویر زیر از انتقال شروع به نمایان شدن کرد:

شروع انتقال
fd 3e 02 - شروع
01 FE – شمارنده انتقال
انتقال (34 بلوک، 1024 بایت منتقل شده)
fd 3e 1024 بایت داده (تقسیم شده به بلوک های 30 بایتی).
پایان انتقال
fd 25

داده های باقیمانده باید به 1024 بایت تراز شوند.

قاب انتهایی انتقال بلوک چگونه است:

وظیفه ای برای یک توسعه دهنده، یا اینکه چگونه اسکنرهای دستی را بدون فروشنده فلش کردیم

fd 25 - انتقال سیگنال به بلوک پایانی. 2f 52 بعدی – بقیه فایل تا 1024 بایت حجم دارد. 2f 52، با قضاوت بر اساس پروتکل، یک CRC 16 بیتی است.

به خاطر قدیم، برنامه ای به زبان C ساختم که 1024 بایت را از یک فایل بیرون می آورد و یک CRC 16 بیتی را محاسبه می کرد. راه اندازی برنامه نشان داد که این یک CRC 16 بیتی نیست. دوباره بی حوصلگی - برای حدود سه روز. تمام این مدت سعی می کردم بفهمم که چه چیزی می تواند باشد، اگر نه یک چک سام. در حین مطالعه سایت های انگلیسی زبان، متوجه شدم که X-modem از محاسبات کنترلی خود استفاده می کند - CRC-CCITT (XModem). من هیچ پیاده سازی C از این محاسبه را پیدا نکردم، اما سایتی را پیدا کردم که این چک جمع را به صورت آنلاین محاسبه می کرد. پس از انتقال 1024 بایت از فایل من به صفحه وب، سایت یک چک‌سوم را به من نشان داد که کاملاً با چک‌سوم فایل مطابقت داشت.

هورا! آخرین معما حل شد، حالا باید فریمور خودم را بسازم. سپس، دانش خود را (و فقط در ذهنم ماند) به ایلیا، که با ابزار قدرتمند پایتون آشناست، منتقل کردم.

ایجاد یک برنامه

ایلیا آلشین گزارش می دهد.

با دریافت دستورالعمل های مناسب، بسیار "خوشحال" بودم.

از کجا شروع کنیم؟ درست است، از ابتدا.  از برداشتن dump از درگاه USB.

USB-pcap را اجرا کنید https://desowin.org/usbpcap/tour.html

پورتی که دستگاه به آن متصل است و فایلی که در آن dump را ذخیره خواهیم کرد را انتخاب کنید.

وظیفه ای برای یک توسعه دهنده، یا اینکه چگونه اسکنرهای دستی را بدون فروشنده فلش کردیم

ما اسکنر را به دستگاهی متصل می کنیم که در آن نرم افزار بومی EZConfigScanning برای ویندوز نصب شده است.

وظیفه ای برای یک توسعه دهنده، یا اینکه چگونه اسکنرهای دستی را بدون فروشنده فلش کردیم

در آن موردی را برای ارسال دستورات به دستگاه پیدا می کنیم. اما تیم ها چطور؟ از کجا می توانم آنها را تهیه کنم؟
هنگامی که برنامه شروع می شود، تجهیزات به طور خودکار مورد بررسی قرار می گیرند (این را کمی بعد خواهیم دید). و بارکدهای آموزشی از اسناد رسمی تجهیزات وجود داشت. DEFALT. این تیم ماست.

وظیفه ای برای یک توسعه دهنده، یا اینکه چگونه اسکنرهای دستی را بدون فروشنده فلش کردیم

داده های لازم دریافت شده است. dump.pcap را از طریق wireshark باز کنید.

هنگام شروع EZConfigScanning مسدود کنید. مکان هایی که باید به آنها توجه کنید با رنگ قرمز مشخص شده اند.

وظیفه ای برای یک توسعه دهنده، یا اینکه چگونه اسکنرهای دستی را بدون فروشنده فلش کردیم

وظیفه ای برای یک توسعه دهنده، یا اینکه چگونه اسکنرهای دستی را بدون فروشنده فلش کردیم

با دیدن همه اینها برای اولین بار، دلم از دست رفت. معلوم نیست بعد کجا باید حفاری کرد.

کمی طوفان فکری و-و-و... آها! در زباله دان خارج - آیا inو in این خارج.

من در گوگل سرچ کردم URB_INTERRUPT چیست. من متوجه شدم که این یک روش انتقال داده است. و 4 روش وجود دارد: کنترل، وقفه، هم زمان، فله. شما می توانید در مورد آنها به طور جداگانه مطالعه کنید.

و آدرس های نقطه پایانی در رابط دستگاه USB را می توان از طریق دستور "lsusb –v" یا با استفاده از pyusb به دست آورد.

اکنون باید همه دستگاه های دارای این VID را پیدا کنیم. شما می توانید به طور خاص با VID:PID جستجو کنید.

وظیفه ای برای یک توسعه دهنده، یا اینکه چگونه اسکنرهای دستی را بدون فروشنده فلش کردیم

این به نظر می رسد:

وظیفه ای برای یک توسعه دهنده، یا اینکه چگونه اسکنرهای دستی را بدون فروشنده فلش کردیم

وظیفه ای برای یک توسعه دهنده، یا اینکه چگونه اسکنرهای دستی را بدون فروشنده فلش کردیم

بنابراین، ما اطلاعات لازم را داریم: دستورات P_INFO. یا DEFALT، محل نوشتن دستورات endpoint=03 و محل دریافت پاسخ endpoint=86 را نشان می دهد. تنها چیزی که باقی می ماند تبدیل دستورات به هگز است.

وظیفه ای برای یک توسعه دهنده، یا اینکه چگونه اسکنرهای دستی را بدون فروشنده فلش کردیم

وظیفه ای برای یک توسعه دهنده، یا اینکه چگونه اسکنرهای دستی را بدون فروشنده فلش کردیم

از آنجایی که قبلاً دستگاه را پیدا کرده ایم، بیایید آن را از هسته جدا کنیم...

وظیفه ای برای یک توسعه دهنده، یا اینکه چگونه اسکنرهای دستی را بدون فروشنده فلش کردیم

... و در نقطه پایانی با آدرس 0x03 بنویسید،

وظیفه ای برای یک توسعه دهنده، یا اینکه چگونه اسکنرهای دستی را بدون فروشنده فلش کردیم

... و سپس پاسخ را از نقطه پایانی با آدرس 0x86 بخوانید.

وظیفه ای برای یک توسعه دهنده، یا اینکه چگونه اسکنرهای دستی را بدون فروشنده فلش کردیم

پاسخ ساختاریافته:

P_INFOfmt: 1
mode: app
app-present: 1
boot-present: 1
hw-sn: 18072B44CA
hw-rev: 0x20
cbl: 4
app-sw-rev: CP000116BBA
boot-sw-rev: CP000014BAD
flash: 3
app-m_name: Voyager 1450g
boot-m_name: Voyager 1450g
app-p_name: 1450g
boot-p_name: 1450g
boot-time: 16:56:02
boot-date: Oct 16 2014
app-time: 08:49:30
app-date: Mar 25 2019
app-compat: 289
boot-compat: 288
csum: 0x6986

ما این داده ها را در dump.pcap می بینیم.

وظیفه ای برای یک توسعه دهنده، یا اینکه چگونه اسکنرهای دستی را بدون فروشنده فلش کردیم

وظیفه ای برای یک توسعه دهنده، یا اینکه چگونه اسکنرهای دستی را بدون فروشنده فلش کردیم

وظیفه ای برای یک توسعه دهنده، یا اینکه چگونه اسکنرهای دستی را بدون فروشنده فلش کردیم

عالی! بارکد سیستم را به هگز تبدیل کنید. تمام است، عملکرد آموزشی آماده است.

فریمور چطور؟ به نظر می رسد همه چیز یکسان است، اما یک تفاوت ظریف وجود دارد.

پس از بررسی کامل فرآیند چشمک زدن، تقریباً متوجه شدیم که با چه چیزی سر و کار داریم. در اینجا مقاله ای در مورد XMODEM وجود دارد که برای درک چگونگی این ارتباط بسیار مفید بود، البته به صورت کلی: http://microsin.net/adminstuff/others/xmodem-protocol-overview.html خواندن را توصیه می کنم.

با نگاه کردن به dump، می توانید ببینید که اندازه فریم 1024 است و اندازه URB-data 64 است.

وظیفه ای برای یک توسعه دهنده، یا اینکه چگونه اسکنرهای دستی را بدون فروشنده فلش کردیم

بنابراین - 1024/64 – 16 خط در یک بلوک می گیریم، فایل سیستم عامل را هر بار 1 کاراکتر می خوانیم و یک بلوک تشکیل می دهیم. تکمیل 1 خط در یک بلوک با کاراکترهای خاص fd3e02 + شماره بلوک.
14 خط بعدی با fd25 + تکمیل می‌شوند، با استفاده از XMODEM.calc_crc() جمع چک کل بلوک را محاسبه می‌کنیم (زمان زیادی طول کشید تا بفهمیم "FF – 1" CSUM است) و آخرین خط شانزدهم تکمیل می‌شود. با fd16e.

به نظر می رسد همین است، فایل سیستم عامل را بخوانید، بلوک ها را بزنید، اسکنر را از هسته جدا کنید و آن را به دستگاه ارسال کنید. اما به این سادگی نیست. اسکنر باید به حالت سیستم عامل تغییر کند،
отправив ему NEWAPP = ‘\xfd\x0a\x16\x4e\x2c\x4e\x45\x57\x41\x50\x50\x0d’.
این تیم اهل کجاست؟؟ از زباله دان.

وظیفه ای برای یک توسعه دهنده، یا اینکه چگونه اسکنرهای دستی را بدون فروشنده فلش کردیم

اما به دلیل محدودیت 64 نمی توانیم یک بلوک کامل را به اسکنر ارسال کنیم:

وظیفه ای برای یک توسعه دهنده، یا اینکه چگونه اسکنرهای دستی را بدون فروشنده فلش کردیم

خوب، اسکنر در حالت چشمک زن NEWAPP هگز را نمی پذیرد. بنابراین، شما باید هر خط bytes_array را ترجمه کنید

[253, 10, 22, 78, 44, 78, 69, 87, 65, 80, 80, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

و سپس این داده ها را به اسکنر ارسال کنید.

جواب میگیریم:

[2, 1, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

اگر مقاله XMODEM را بررسی کنید، مشخص می شود: داده ها پذیرفته شده اند.

وظیفه ای برای یک توسعه دهنده، یا اینکه چگونه اسکنرهای دستی را بدون فروشنده فلش کردیم

بعد از اینکه همه بلوک ها منتقل شدند، انتقال را تکمیل می کنیم END_TRANSFER = 'xfdx01x04'.

خوب، از آنجایی که این بلوک ها هیچ اطلاعاتی را برای افراد عادی حمل نمی کنند، به طور پیش فرض فریمور را در حالت مخفی نصب می کنیم. و در هر صورت، نوار پیشرفت را از طریق tqdm سازماندهی خواهیم کرد.

وظیفه ای برای یک توسعه دهنده، یا اینکه چگونه اسکنرهای دستی را بدون فروشنده فلش کردیم

در واقع، پس موضوع چیزهای کوچکی است. تنها چیزی که باقی می ماند این است که راه حل را در اسکریپت هایی برای تکرار انبوه در زمان مشخصی بپیچید تا روند کار در صندوق ها کند نشود و ورود به سیستم اضافه شود.

مجموع

با صرف زمان و تلاش زیاد و مو بر روی سرمان، توانستیم راه حل های مورد نیاز خود را توسعه دهیم و همچنین ضرب الاجل را رعایت کنیم. در همان زمان، اسکنرها اکنون مجدداً فلش می شوند و به طور مرکزی آموزش می بینند، ما به وضوح کل فرآیند را کنترل می کنیم. این شرکت در زمان و هزینه صرفه جویی کرد و ما تجربه بسیار ارزشمندی در تجهیزات مهندسی معکوس از این نوع به دست آوردیم.

منبع: www.habr.com

اضافه کردن نظر