Nhiệm vụ dành cho nhà phát triển hoặc cách chúng tôi cài đặt máy quét cầm tay mà không cần nhà cung cấp

Xin chào tất cả mọi người.

Chúng tôi, Viktor Antipov và Ilya Aleshin, hôm nay sẽ nói về trải nghiệm của chúng tôi khi làm việc với các thiết bị USB thông qua Python PyUSB và một chút về kỹ thuật đảo ngược.

Nhiệm vụ dành cho nhà phát triển hoặc cách chúng tôi cài đặt máy quét cầm tay mà không cần nhà cung cấp

thời tiền sử

Năm 2019, Nghị định của Chính phủ Liên bang Nga số 224 “Về việc phê duyệt Quy tắc ghi nhãn sản phẩm thuốc lá bằng phương tiện nhận dạng và tính năng triển khai hệ thống thông tin nhà nước để giám sát việc lưu thông hàng hóa phải dán nhãn bắt buộc bằng phương tiện nhận dạng liên quan đến các sản phẩm thuốc lá” đã có hiệu lực.
Văn bản giải thích rằng từ ngày 1/2019/XNUMX, các nhà sản xuất phải dán nhãn cho từng bao thuốc lá. Và các nhà phân phối trực tiếp phải nhận những sản phẩm này bằng việc thực hiện chứng từ chuyển giao chung (UDD). Ngược lại, các cửa hàng cần phải đăng ký bán sản phẩm có dán nhãn thông qua máy tính tiền.

Ngoài ra, từ ngày 1 tháng 2020 năm XNUMX, việc lưu hành các sản phẩm thuốc lá không nhãn mác cũng bị cấm. Điều này có nghĩa là tất cả các gói thuốc lá phải được đánh dấu bằng mã vạch Datamatrix đặc biệt. Hơn nữa - một điểm quan trọng - hóa ra Datamatrix sẽ không bình thường mà nghịch đảo. Tức là không phải mã đen nền trắng mà ngược lại.

Chúng tôi đã kiểm tra máy quét của mình và hóa ra hầu hết chúng cần được flash lại/đào tạo lại, nếu không chúng đơn giản là không thể hoạt động bình thường với mã vạch này. Diễn biến này khiến chúng tôi phải đau đầu dữ dội vì công ty chúng tôi có rất nhiều cửa hàng nằm rải rác trên một lãnh thổ rộng lớn. Vài chục ngàn máy tính tiền – và rất ít thời gian.

Điều gì đã được thực hiện? Có hai lựa chọn. Đầu tiên: các kỹ sư tại chỗ sẽ khởi động lại và điều chỉnh máy quét theo cách thủ công. Thứ hai: chúng tôi làm việc từ xa và tốt nhất là bao quát nhiều máy quét cùng một lúc trong một lần lặp.

Rõ ràng, lựa chọn đầu tiên không phù hợp với chúng tôi: chúng tôi sẽ phải chi tiền cho các kỹ sư đến thăm và trong trường hợp này sẽ khó kiểm soát và điều phối quy trình. Nhưng điều quan trọng nhất là mọi người sẽ làm việc, tức là chúng ta có thể mắc rất nhiều sai sót và rất có thể là không hoàn thành đúng thời hạn.

Lựa chọn thứ hai tốt cho tất cả mọi người, nếu không phải vì một điều. Một số nhà cung cấp không có công cụ flash từ xa mà chúng tôi cần cho tất cả các hệ điều hành được yêu cầu. Và vì thời hạn sắp hết nên tôi phải tự suy nghĩ bằng chính cái đầu của mình.

Tiếp theo, chúng tôi sẽ cho bạn biết cách chúng tôi phát triển các công cụ dành cho máy quét cầm tay cho hệ điều hành Debian 9.x (tất cả máy tính tiền của chúng tôi đều chạy trên Debian).

Giải câu đố: làm thế nào để flash máy quét

Báo cáo của Victor Antipov.

Tiện ích chính thức do nhà cung cấp cung cấp hoạt động trong Windows và chỉ với IE. Tiện ích này có thể flash và cấu hình máy quét.

Vì hệ thống mục tiêu của chúng tôi là Debian nên chúng tôi đã cài đặt máy chủ chuyển hướng usb trên Debian và máy khách chuyển hướng usb trên Windows. Bằng cách sử dụng tiện ích chuyển hướng usb, chúng tôi đã chuyển tiếp máy quét từ máy Linux sang máy Windows.

Một tiện ích từ nhà cung cấp Windows đã nhìn thấy máy quét và thậm chí còn flash nó bình thường. Vì vậy, chúng tôi đã đưa ra kết luận đầu tiên: không có gì phụ thuộc vào hệ điều hành, đó là vấn đề của giao thức nhấp nháy.

ĐƯỢC RỒI. Chúng tôi đã chạy quá trình flash trên máy Windows và xóa kết xuất trên máy Linux.

Chúng tôi đã nhét kết xuất vào WireShark và... rất buồn (Tôi sẽ bỏ qua một số chi tiết về kết xuất, chúng không được quan tâm chút nào).

Những gì bãi rác đã cho chúng ta thấy:

Nhiệm vụ dành cho nhà phát triển hoặc cách chúng tôi cài đặt máy quét cầm tay mà không cần nhà cung cấp

Nhiệm vụ dành cho nhà phát triển hoặc cách chúng tôi cài đặt máy quét cầm tay mà không cần nhà cung cấp

Địa chỉ 0000-0030, theo đánh giá của Wireshark, là thông tin dịch vụ USB.

Chúng tôi quan tâm đến phần 0040-0070.

Không có gì rõ ràng từ một khung truyền ngoại trừ các ký tự MOCFT. Các ký tự này hóa ra là các ký tự từ tệp chương trình cơ sở, cũng như các ký tự còn lại cho đến cuối khung (tệp chương trình cơ sở được tô sáng):

Nhiệm vụ dành cho nhà phát triển hoặc cách chúng tôi cài đặt máy quét cầm tay mà không cần nhà cung cấp

Các ký hiệu fd 3e 02 01 fe có nghĩa là gì, cá nhân tôi cũng như Ilya, không biết.

Tôi đã xem khung sau (thông tin dịch vụ đã bị xóa ở đây, tệp chương trình cơ sở đã được đánh dấu):

Nhiệm vụ dành cho nhà phát triển hoặc cách chúng tôi cài đặt máy quét cầm tay mà không cần nhà cung cấp

Điều gì đã trở nên rõ ràng? Rằng hai byte đầu tiên là một loại hằng số. Tất cả các khối tiếp theo đều xác nhận điều này, nhưng trước khi kết thúc khối truyền:

Nhiệm vụ dành cho nhà phát triển hoặc cách chúng tôi cài đặt máy quét cầm tay mà không cần nhà cung cấp

Khung hình này cũng gây kinh ngạc vì hằng số đã thay đổi (được đánh dấu) và kỳ lạ thay, có một phần của tệp. Kích thước byte được truyền của tệp cho thấy 1024 byte đã được truyền. Tôi lại không biết những byte còn lại có ý nghĩa gì.

Trước hết, với tư cách là biệt danh BBS cũ, tôi đã xem lại các giao thức truyền dẫn tiêu chuẩn. Không có giao thức nào được truyền 1024 byte. Tôi bắt đầu nghiên cứu phần cứng và tìm hiểu giao thức 1K Xmodem. Nó cho phép truyền 1024, nhưng có một cảnh báo: lúc đầu chỉ có 128 và chỉ khi không có lỗi, giao thức mới tăng số byte được truyền. Tôi ngay lập tức chuyển 1024 byte. Tôi quyết định nghiên cứu các giao thức truyền dẫn và đặc biệt là modem X.

Có hai biến thể của modem.

Đầu tiên, định dạng gói XMODEM có hỗ trợ CRC8 (XMODEM gốc):

Nhiệm vụ dành cho nhà phát triển hoặc cách chúng tôi cài đặt máy quét cầm tay mà không cần nhà cung cấp

Thứ hai, định dạng gói XMODEM có hỗ trợ CRC16 (XmodemCRC):

Nhiệm vụ dành cho nhà phát triển hoặc cách chúng tôi cài đặt máy quét cầm tay mà không cần nhà cung cấp

Nó trông tương tự, ngoại trừ SOH, số gói, CRC và chiều dài gói.

Tôi đã xem phần đầu của khối truyền thứ hai (và một lần nữa thấy tệp chương trình cơ sở, nhưng đã thụt vào 1024 byte):

Nhiệm vụ dành cho nhà phát triển hoặc cách chúng tôi cài đặt máy quét cầm tay mà không cần nhà cung cấp

Tôi thấy tiêu đề quen thuộc fd 3e 02, nhưng hai byte tiếp theo đã thay đổi: đó là 01 fe và trở thành 02 fd. Sau đó tôi nhận thấy khối thứ hai bây giờ được đánh số 02 và như vậy tôi hiểu: trước mặt tôi là số của khối truyền tải. Bánh răng 1024 đầu tiên là 01, bánh răng thứ hai là 02, bánh răng thứ ba là 03, v.v. (tất nhiên là ở dạng hex). Nhưng sự thay đổi từ fe sang fd có ý nghĩa gì? Mắt thấy giảm đi 1, não nhắc nhở lập trình viên đếm từ 0 chứ không phải 1. Nhưng tại sao khối đầu tiên lại là 1 mà không phải 0? Tôi vẫn chưa tìm được câu trả lời cho câu hỏi này. Nhưng tôi đã hiểu khối thứ hai được tính như thế nào. Khối thứ hai không gì khác hơn là FF – (trừ) số của khối đầu tiên. Do đó, khối thứ hai được chỉ định là = 02 (FF-02) = 02 FD. Việc đọc kết xuất sau đó đã xác nhận suy đoán của tôi.

Sau đó, hình ảnh truyền tải sau đây bắt đầu xuất hiện:

Bắt đầu truyền
fd 3e 02 – Bắt đầu
01 FE – bộ đếm truyền
Chuyển (34 khối, chuyển 1024 byte)
fd 3e 1024 byte dữ liệu (được chia thành các khối 30 byte).
Kết thúc truyền tải
fd 25

Dữ liệu còn lại được căn chỉnh thành 1024 byte.

Khung kết thúc truyền khối trông như thế nào:

Nhiệm vụ dành cho nhà phát triển hoặc cách chúng tôi cài đặt máy quét cầm tay mà không cần nhà cung cấp

fd 25 – tín hiệu kết thúc truyền khối. 2f 52 tiếp theo – phần còn lại của tệp có kích thước tối đa 1024 byte. 2f 52, được đánh giá theo giao thức, là tổng kiểm tra CRC 16 bit.

Vì lợi ích của ngày xưa, tôi đã tạo một chương trình bằng C để lấy 1024 byte từ một tệp và tính CRC 16 bit. Khởi chạy chương trình cho thấy đây không phải là CRC 16 bit. Lại sững sờ - trong khoảng ba ngày. Suốt thời gian qua tôi đã cố gắng hiểu nó có thể là gì nếu không phải là tổng kiểm tra. Khi nghiên cứu các trang web tiếng Anh, tôi phát hiện ra rằng X-modem sử dụng tính toán tổng kiểm tra của riêng nó - CRC-CCITT (XModem). Tôi không tìm thấy bất kỳ triển khai C nào của phép tính này, nhưng tôi đã tìm thấy một trang web tính tổng kiểm tra này trực tuyến. Sau khi chuyển 1024 byte tệp của tôi sang trang web, trang web hiển thị cho tôi tổng kiểm tra hoàn toàn khớp với tổng kiểm tra từ tệp.

Hoan hô! Câu đố cuối cùng đã được giải, bây giờ tôi cần phải tạo phần sụn của riêng mình. Tiếp theo, tôi truyền lại kiến ​​thức của mình (và nó chỉ còn đọng lại trong đầu tôi) cho Ilya, người đã quen thuộc với bộ công cụ mạnh mẽ Python.

Tạo một chương trình

Ilya Aleshin báo cáo.

Nhận được những hướng dẫn thích hợp, tôi rất “vui mừng”.

Nơi để bắt đầu? Đúng vậy, ngay từ đầu.  Từ việc lấy kết xuất từ ​​cổng USB.

Khởi chạy USB-pcap https://desowin.org/usbpcap/tour.html

Chọn cổng mà thiết bị được kết nối và tệp nơi chúng tôi sẽ lưu kết xuất.

Nhiệm vụ dành cho nhà phát triển hoặc cách chúng tôi cài đặt máy quét cầm tay mà không cần nhà cung cấp

Chúng tôi kết nối máy quét với máy đã cài đặt phần mềm EZConfigScanning gốc dành cho Windows.

Nhiệm vụ dành cho nhà phát triển hoặc cách chúng tôi cài đặt máy quét cầm tay mà không cần nhà cung cấp

Trong đó chúng ta tìm thấy mục gửi lệnh tới thiết bị. Nhưng còn các đội thì sao? Tôi có thể lấy chúng ở đâu?
Khi chương trình bắt đầu, thiết bị sẽ tự động được thăm dò (chúng ta sẽ thấy điều này sau). Và đã có mã vạch đào tạo từ các tài liệu thiết bị chính thức. MẶC ĐỊNH. Đây là đội của chúng tôi.

Nhiệm vụ dành cho nhà phát triển hoặc cách chúng tôi cài đặt máy quét cầm tay mà không cần nhà cung cấp

Các dữ liệu cần thiết đã được nhận. Mở dump.pcap qua wireshark.

Chặn khi khởi động EZConfigScanning. Những nơi bạn cần chú ý được đánh dấu màu đỏ.

Nhiệm vụ dành cho nhà phát triển hoặc cách chúng tôi cài đặt máy quét cầm tay mà không cần nhà cung cấp

Nhiệm vụ dành cho nhà phát triển hoặc cách chúng tôi cài đặt máy quét cầm tay mà không cần nhà cung cấp

Lần đầu tiên nhìn thấy tất cả những điều này, tôi đã mất hồn. Không rõ nơi để đào tiếp theo.

Một chút động não và-và-và... Aha! Trong bãi rác ra - là inin này ra.

Tôi đã tìm trên Google URB_INTERRUPT là gì. Tôi phát hiện ra rằng đây là một phương pháp truyền dữ liệu. Và có 4 phương pháp như vậy: điều khiển, ngắt, đẳng thời, số lượng lớn. Bạn có thể đọc về chúng một cách riêng biệt.

Và các địa chỉ điểm cuối trong giao diện thiết bị USB có thể được lấy thông qua lệnh “lsusb –v” hoặc sử dụng pyusb.

Bây giờ chúng ta cần tìm tất cả các thiết bị có VID này. Bạn có thể tìm kiếm cụ thể theo VID:PID.

Nhiệm vụ dành cho nhà phát triển hoặc cách chúng tôi cài đặt máy quét cầm tay mà không cần nhà cung cấp

Dường như thế này:

Nhiệm vụ dành cho nhà phát triển hoặc cách chúng tôi cài đặt máy quét cầm tay mà không cần nhà cung cấp

Nhiệm vụ dành cho nhà phát triển hoặc cách chúng tôi cài đặt máy quét cầm tay mà không cần nhà cung cấp

Như vậy, chúng ta đã có những thông tin cần thiết: lệnh P_INFO. hoặc DEFALT, địa chỉ nơi viết lệnh endpoint=03 và nơi nhận phản hồi endpoint=86. Tất cả những gì còn lại là chuyển đổi các lệnh thành hex.

Nhiệm vụ dành cho nhà phát triển hoặc cách chúng tôi cài đặt máy quét cầm tay mà không cần nhà cung cấp

Nhiệm vụ dành cho nhà phát triển hoặc cách chúng tôi cài đặt máy quét cầm tay mà không cần nhà cung cấp

Vì chúng ta đã tìm thấy thiết bị nên hãy ngắt kết nối nó khỏi kernel...

Nhiệm vụ dành cho nhà phát triển hoặc cách chúng tôi cài đặt máy quét cầm tay mà không cần nhà cung cấp

...và ghi vào điểm cuối có địa chỉ 0x03,

Nhiệm vụ dành cho nhà phát triển hoặc cách chúng tôi cài đặt máy quét cầm tay mà không cần nhà cung cấp

... rồi đọc phản hồi từ điểm cuối có địa chỉ 0x86.

Nhiệm vụ dành cho nhà phát triển hoặc cách chúng tôi cài đặt máy quét cầm tay mà không cần nhà cung cấp

Câu trả lời có cấu trúc:

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

Chúng tôi thấy dữ liệu này trong dump.pcap.

Nhiệm vụ dành cho nhà phát triển hoặc cách chúng tôi cài đặt máy quét cầm tay mà không cần nhà cung cấp

Nhiệm vụ dành cho nhà phát triển hoặc cách chúng tôi cài đặt máy quét cầm tay mà không cần nhà cung cấp

Nhiệm vụ dành cho nhà phát triển hoặc cách chúng tôi cài đặt máy quét cầm tay mà không cần nhà cung cấp

Tuyệt vời! Chuyển đổi mã vạch hệ thống sang hex. Vậy là xong, chức năng đào tạo đã sẵn sàng.

Còn phần sụn thì sao? Mọi thứ dường như giống nhau, nhưng có một sắc thái.

Sau khi hoàn thành quá trình nhấp nháy, chúng tôi gần như hiểu được những gì chúng tôi đang giải quyết. Đây là một bài viết về XMODEM, rất hữu ích trong việc hiểu cách thức giao tiếp này xảy ra, mặc dù nói chung là: http://microsin.net/adminstuff/others/xmodem-protocol-overview.html Tôi khuyên bạn nên đọc.

Nhìn vào kết xuất, bạn có thể thấy kích thước khung là 1024 và kích thước dữ liệu URB là 64.

Nhiệm vụ dành cho nhà phát triển hoặc cách chúng tôi cài đặt máy quét cầm tay mà không cần nhà cung cấp

Vì thế – 1024/64 – chúng tôi nhận được 16 dòng trong một khối, đọc tệp chương trình cơ sở mỗi lần 1 ký tự và tạo thành một khối. Bổ sung 1 dòng trong một khối bằng các ký tự đặc biệt fd3e02 + số khối.
14 dòng tiếp theo được bổ sung fd25+, sử dụng XMODEM.calc_crc() ta tính tổng kiểm tra của toàn khối (mất rất nhiều thời gian mới hiểu “FF – 1” là CSUM) và dòng cuối cùng, dòng thứ 16 được bổ sung với fd3e.

Có vẻ như vậy đó, đọc tệp chương trình cơ sở, nhấn các khối, ngắt kết nối máy quét khỏi kernel và gửi nó đến thiết bị. Nhưng nó không đơn giản như vậy. Máy quét cần được chuyển sang chế độ phần sụn,
отправив ему NEWAPP = ‘\xfd\x0a\x16\x4e\x2c\x4e\x45\x57\x41\x50\x50\x0d’.
Đội này đến từ đâu?? Từ bãi rác.

Nhiệm vụ dành cho nhà phát triển hoặc cách chúng tôi cài đặt máy quét cầm tay mà không cần nhà cung cấp

Nhưng chúng tôi không thể gửi toàn bộ khối tới máy quét do giới hạn 64:

Nhiệm vụ dành cho nhà phát triển hoặc cách chúng tôi cài đặt máy quét cầm tay mà không cần nhà cung cấp

Chà, máy quét ở chế độ nhấp nháy NEWAPP không chấp nhận hex. Vì vậy, bạn sẽ phải dịch từng dòng 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]

Và sau đó gửi dữ liệu này đến máy quét.

Chúng tôi nhận được câu trả lời:

[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]

Nếu bạn kiểm tra bài viết về XMODEM, bạn sẽ thấy rõ: dữ liệu đã được chấp nhận.

Nhiệm vụ dành cho nhà phát triển hoặc cách chúng tôi cài đặt máy quét cầm tay mà không cần nhà cung cấp

Sau khi tất cả các khối đã được chuyển, chúng tôi hoàn tất quá trình chuyển END_TRANSFER = 'xfdx01x04'.

Chà, vì các khối này không mang bất kỳ thông tin nào cho người bình thường nên chúng tôi sẽ cài đặt chương trình cơ sở ở chế độ ẩn theo mặc định. Và để đề phòng, chúng tôi sẽ tổ chức một thanh tiến trình thông qua tqdm.

Nhiệm vụ dành cho nhà phát triển hoặc cách chúng tôi cài đặt máy quét cầm tay mà không cần nhà cung cấp

Thực ra thì đó chỉ là vấn đề nhỏ nhặt. Tất cả những gì còn lại là gói giải pháp vào các tập lệnh để nhân rộng hàng loạt vào một thời điểm được xác định rõ ràng, để không làm chậm quá trình làm việc tại quầy thanh toán và thêm tính năng ghi nhật ký.

Tổng

Đã dành rất nhiều thời gian, công sức và mái tóc trên đầu, chúng tôi đã có thể phát triển các giải pháp mình cần và cũng đáp ứng được thời hạn. Đồng thời, các máy quét hiện đã được tân trang lại và đào tạo lại một cách tập trung, chúng tôi kiểm soát rõ ràng toàn bộ quá trình. Công ty đã tiết kiệm được thời gian và tiền bạc, đồng thời chúng tôi đã thu được kinh nghiệm vô giá về thiết bị kỹ thuật đảo ngược loại này.

Nguồn: www.habr.com

Thêm một lời nhận xét