Sveiki visiem
MÄs, Viktors Antipovs un Iļja AleÅ”ins, Å”odien runÄsim par savu pieredzi darbÄ ar USB ierÄ«cÄm, izmantojot Python PyUSB, un nedaudz par reverso inženieriju.
AizvÄsture
2019. gadÄ Krievijas FederÄcijas valdÄ«bas dekrÄts Nr. 224 āPar noteikumu apstiprinÄÅ”anu tabakas izstrÄdÄjumu marÄ·ÄÅ”anai ar identifikÄcijas lÄ«dzekļiem un valsts informÄcijas sistÄmas ievieÅ”anas pazÄ«mÄm to preÄu aprites uzraudzÄ«bai, kurÄm obligÄti jÄmarÄ·Ä ar identifikÄcijas lÄ«dzekļiem attiecÄ«bÄ uz tabakas izstrÄdÄjumiemā stÄjÄs spÄkÄ.
DokumentÄ paskaidrots, ka no 1. gada 2019. jÅ«lija ražotÄjiem ir jÄmarÄ·Ä katrs tabakas iepakojums. Un tieÅ”ajiem izplatÄ«tÄjiem Å”ie produkti ir jÄsaÅem, noformÄjot universÄlo nodoÅ”anas dokumentu (UDD). SavukÄrt veikaliem ar kases aparÄta starpniecÄ«bu jÄreÄ£istrÄ marÄ·ÄtÄs produkcijas tirdzniecÄ«ba.
TÄpat no 1.gada 2020.jÅ«lija ir aizliegta nemarÄ·Äto tabakas izstrÄdÄjumu aprite. Tas nozÄ«mÄ, ka visas cigareÅ”u paciÅas ir jÄmarÄ·Ä ar Ä«paÅ”u Datamatrix svÄ«trkodu. TurklÄt - svarÄ«gs punkts - izrÄdÄ«jÄs, ka Datamatrix nebÅ«s parasta, bet gan apgriezta. Tas ir, nevis melns kods uz balta, bet otrÄdi.
MÄs pÄrbaudÄ«jÄm savus skenerus, un izrÄdÄ«jÄs, ka lielÄkÄ daļa no tiem ir jÄatjauno / jÄapmÄca, pretÄjÄ gadÄ«jumÄ tie vienkÄrÅ”i nevar normÄli strÄdÄt ar Å”o svÄ«trkodu. Å Äds notikumu pavÄrsiens mums garantÄja pamatÄ«gas galvassÄpes, jo mÅ«su uzÅÄmumam ir daudz veikalu, kas izkaisÄ«ti plaÅ”Ä teritorijÄ. VairÄki desmiti tÅ«kstoÅ”u kases aparÄtu ā un ļoti maz laika.
Kas bija jÄdara? Ir divi varianti. PirmkÄrt: uz vietas esoÅ”ie inženieri manuÄli atsvaidzina un pielÄgo skenerus. OtrkÄrt: mÄs strÄdÄjam attÄlinÄti un, vÄlams, vienÄ iterÄcijÄ aptveram vairÄkus skenerus vienlaikus.
Pirmais variants, acÄ«mredzot, mums nebija piemÄrots: mums bÅ«tu jÄtÄrÄ nauda, āāapmeklÄjot inženierus, un Å”ajÄ gadÄ«jumÄ bÅ«tu grÅ«ti kontrolÄt un koordinÄt procesu. Bet pats galvenais, lai cilvÄki strÄdÄtu, proti, mÄs potenciÄli dabÅ«tu daudz kļūdu un, visticamÄk, neiekļūtu termiÅÄ.
Otrais variants ir labs visiem, ja ne vienai lietai. Dažiem pÄrdevÄjiem nebija attÄlÄs mirgoÅ”anas rÄ«ku, kas mums bija nepiecieÅ”ami visÄm nepiecieÅ”amajÄm operÄtÄjsistÄmÄm. Un tÄ kÄ termiÅi tuvojÄs beigÄm, man bija jÄdomÄ ar savu galvu.
TÄlÄk mÄs jums pastÄstÄ«sim, kÄ mÄs izstrÄdÄjÄm rÄ«kus rokas skeneriem operÄtÄjsistÄmai Debian 9.x (visi mÅ«su kases aparÄti ir Debian).
Atrisiniet mÄ«klu: kÄ mirgot skenerim
Viktors Antipovs ziÅo.
PÄrdevÄja nodroÅ”inÄtÄ oficiÄlÄ utilÄ«ta darbojas operÄtÄjsistÄmÄ Windows un tikai ar IE. LietderÄ«ba var mirgot un konfigurÄt skeneri.
TÄ kÄ mÅ«su mÄrÄ·a sistÄma ir Debian, mÄs instalÄjÄm usb-redirector serveri Debian un usb-redirector klientu operÄtÄjsistÄmÄ Windows. Izmantojot usb-redirector utilÄ«tas, mÄs pÄrsÅ«tÄ«jÄm skeneri no Linux iekÄrtas uz Windows iekÄrtu.
Windows pÄrdevÄja utilÄ«ta redzÄja skeneri un pat to normÄli pazibinÄja. TÄdÄjÄdi mÄs izdarÄ«jÄm pirmo secinÄjumu: nekas nav atkarÄ«gs no OS, tas ir mirgojoÅ”Ä protokola jautÄjums.
LABI. MÄs palaidÄm mirgoÅ”anu operÄtÄjsistÄmÄ Windows un noÅÄmÄm izgÄztuves operÄtÄjsistÄmÄ Linux.
MÄs iebÄzÄm izgÄztuvi WireShark un... kļuva skumji (es izlaidÄ«Å”u dažas izgÄztuves detaļas, tÄs neinteresÄ).
Ko izgÄztuve mums parÄdÄ«ja:
Adreses 0000-0030, spriežot pÄc Wireshark, ir USB pakalpojuma informÄcija.
MÅ«s interesÄja daļa 0040-0070.
No viena pÄrraides kadra nekas nebija skaidrs, izÅemot MOCFT rakstzÄ«mes. Å Ä«s rakstzÄ«mes izrÄdÄ«jÄs rakstzÄ«mes no programmaparatÅ«ras faila, kÄ arÄ« atlikuÅ”Äs rakstzÄ«mes lÄ«dz kadra beigÄm (programmaparatÅ«ras fails ir iezÄ«mÄts):
Ko nozÄ«mÄja simboli fd 3e 02 01 fe, man personÄ«gi, tÄpat kÄ Iļjam, nebija ne jausmas.
Es paskatÄ«jos uz Å”Ädu rÄmi (Å”eit ir noÅemta pakalpojuma informÄcija, programmaparatÅ«ras fails ir izcelts):
Kas kļuva skaidrs? Ka pirmie divi baiti ir sava veida konstante. Visi nÄkamie bloki to apstiprinÄja, bet pirms pÄrraides bloka beigÄm:
Å is kadrs bija arÄ« satriecoÅ”s, jo konstante bija mainÄ«jusies (izcelta) un, dÄ«vainÄ kÄrtÄ, bija daļa no faila. Faila pÄrsÅ«tÄ«to baitu lielums liecinÄja, ka tika pÄrsÅ«tÄ«ti 1024 baiti. Es atkal nezinÄju, ko nozÄ«mÄ atlikuÅ”ie baiti.
PirmkÄrt, kÄ vecs BBS segvÄrds, es pÄrskatÄ«ju standarta pÄrraides protokolus. Neviens protokols nepÄrsÅ«tÄ«ja 1024 baitus. Es sÄku pÄtÄ«t aparatÅ«ru un saskÄros ar 1K Xmodem protokolu. Tas ļÄva pÄrsÅ«tÄ«t 1024, taÄu ar piesardzÄ«bu: sÄkumÄ tikai 128, un tikai tad, ja nebija kļūdu, protokols palielinÄja pÄrsÅ«tÄ«to baitu skaitu. Man uzreiz bija 1024 baitu pÄrsÅ«tÄ«Å”ana. Es nolÄmu izpÄtÄ«t pÄrraides protokolus un Ä«paÅ”i X-modemu.
Modemam bija divas variÄcijas.
PirmkÄrt, XMODEM pakotnes formÄts ar CRC8 atbalstu (oriÄ£inÄlais XMODEM):
OtrkÄrt, XMODEM pakeÅ”u formÄts ar CRC16 atbalstu (XmodemCRC):
Tas izskatÄs lÄ«dzÄ«gi, izÅemot SOH, iepakojuma numuru un CRC un iepakojuma garumu.
Es paskatÄ«jos uz otrÄ pÄrraides bloka sÄkumu (un atkal redzÄju programmaparatÅ«ras failu, bet jau ar 1024 baitiem atkÄpi):
Es redzÄju pazÄ«stamo galveni fd 3e 02, bet nÄkamie divi baiti jau bija mainÄ«juÅ”ies: tas bija 01 fe un kļuva par 02 fd. Tad es pamanÄ«ju, ka otrais bloks tagad ir numurÄts ar 02 un tÄdÄjÄdi sapratu: manÄ priekÅ”Ä bija pÄrraides bloka numerÄcija. Pirmais 1024 pÄrnesums ir 01, otrais ir 02, treÅ”ais ir 03 un tÄ tÄlÄk (bet, protams, seÅ”stÅ«rÄ«). Bet ko nozÄ«mÄ pÄreja no fe uz fd? Acis redzÄja samazinÄjumu par 1, smadzenes atgÄdinÄja, ka programmÄtÄji skaita no 0, nevis 1. Bet kÄpÄc tad pirmais bloks ir 1, nevis 0? Es joprojÄm neesmu atradis atbildi uz Å”o jautÄjumu. Bet es sapratu, kÄ tiek skaitÄ«ts otrais bloks. Otrais bloks ir nekas cits kÄ FF ā (mÄ«nus) pirmÄ bloka numurs. TÄdÄjÄdi otrais bloks tika apzÄ«mÄts kÄ = 02 (FF-02) = 02 FD. TurpmÄkÄ izgÄztuves lasÄ«Å”ana apstiprinÄja manu minÄjumu.
Tad sÄka parÄdÄ«ties Å”Äds pÄrraides attÄls:
PÄrraides sÄkums
fd 3e 02 ā SÄkt
01 FE ā pÄrraides skaitÄ«tÄjs
PÄrsÅ«tÄ«Å”ana (34 bloki, pÄrsÅ«tÄ«ti 1024 baiti)
fd 3e 1024 baiti datu (sadalīti 30 baitu blokos).
PÄrraides beigas
fd 25
AtlikuÅ”ie dati jÄsaskaÅo ar 1024 baitiem.
KÄ izskatÄs bloka transmisijas gala rÄmis:
fd 25 ā signÄla uz beigu bloka pÄrraide. NÄkamais 2f 52 ā pÄrÄjais fails lÄ«dz 1024 baitiem. 2f 52, spriežot pÄc protokola, ir 16 bitu CRC kontrolsumma.
Veco laiku labÄ es izveidoju programmu C valodÄ, kas no faila izvilka 1024 baitus un aprÄÄ·inÄja 16 bitu CRC. Programmas palaiÅ”ana parÄdÄ«ja, ka Ŕī nav 16 bitu CRC. Atkal stupors - apmÄram trÄ«s dienas. Visu Å”o laiku mÄÄ£inÄju saprast, kas tas varÄtu bÅ«t, ja ne kontrolsumma. StudÄjot angļu valodas vietnes, atklÄju, ka X-modems izmanto savu kontrolsummas aprÄÄ·inu - CRC-CCITT (XModem). Es neatradu nevienu Ŕī aprÄÄ·ina C ievieÅ”anu, bet es atradu vietni, kas aprÄÄ·inÄja Å”o kontrolsummu tieÅ”saistÄ. PÄrsÅ«tot uz tÄ«mekļa lapu 1024 baitus no mana faila, vietne man parÄdÄ«ja kontrolsummu, kas pilnÄ«bÄ atbilda faila kontrolsummai.
UrrÄ! PÄdÄjÄ mÄ«kla tika atrisinÄta, tagad man vajadzÄja izveidot savu programmaparatÅ«ru. TÄlÄk es nodevu savas zinÄÅ”anas (un tÄs palika tikai manÄ galvÄ) Iļjam, kurÅ” ir pazÄ«stams ar jaudÄ«go rÄ«ku komplektu Python.
Programmas izveide
Iļja AleÅ”ins ziÅo.
SaÅÄmis atbilstoÅ”os norÄdÄ«jumus, es biju ļoti ālaimÄ«gsā.
Kur sÄkt? TieÅ”i tÄ, no sÄkuma. ļ No USB porta noÅemÅ”anas.
Palaidiet USB-pcap
Atlasiet portu, kuram ierÄ«ce ir pievienota, un failu, kurÄ saglabÄsim izgÄztuvi.
MÄs savienojam skeneri ar iekÄrtu, kurÄ ir instalÄta sÄkotnÄjÄ EZConfigScanning programmatÅ«ra operÄtÄjsistÄmai Windows.
TajÄ mÄs atrodam vienumu komandu nosÅ«tÄ«Å”anai uz ierÄ«ci. Bet kÄ ar komandÄm? Kur tÄs var dabÅ«t?
Programmai startÄjot, iekÄrta tiek aptaujÄta automÄtiski (to redzÄsim nedaudz vÄlÄk). Un tur bija mÄcÄ«bu svÄ«trkodi no oficiÄlajiem ekipÄjuma dokumentiem. DEFALT. Å Ä« ir mÅ«su komanda.
NepiecieÅ”amie dati ir saÅemti. Atveriet dump.pcap, izmantojot wireshark.
BloÄ·Ät, startÄjot EZConfigScanning. Vietas, kurÄm jÄpievÄrÅ” uzmanÄ«ba, ir atzÄ«mÄtas ar sarkanu krÄsu.
Pirmo reizi to visu redzot, es zaudÄju sirdi. Nav skaidrs, kur rakt tÄlÄk.
Neliela prÄta vÄtra un-un-un... Aha! IzgÄztuvÄ ÄrÄ - Vai inUn in Å”is ÄrÄ.
PameklÄju googlÄ, kas ir URB_INTERRUPT. UzzinÄju, ka Ŕī ir datu pÄrsÅ«tÄ«Å”anas metode. Un ir 4 Å”Ädas metodes: kontrole, pÄrtraukums, izohrons, lielapjoma. Par tiem var lasÄ«t atseviŔķi.
Un galapunktu adreses USB ierÄ«ces saskarnÄ var iegÅ«t, izmantojot komandu ālsusb āvā, vai izmantojot pyusb.
Tagad mums ir jÄatrod visas ierÄ«ces ar Å”o VID. Varat meklÄt Ä«paÅ”i pÄc VID:PID.
Tas izskatÄs Å”Ädi:
TÄtad, mums ir nepiecieÅ”amÄ informÄcija: P_INFO komandas. vai DEFALT, adreses, kur rakstÄ«t komandas endpoint=03 un kur iegÅ«t atbildi endpoint=86. Atliek tikai konvertÄt komandas uz hex.
TÄ kÄ ierÄ«ci jau esam atraduÅ”i, atvienosim to no kodola...
...un rakstiet galapunktam ar adresi 0x03,
... un pÄc tam nolasiet galapunkta atbildi ar adresi 0x86.
StrukturÄta atbilde:
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
MÄs redzam Å”os datus dump.pcap.
Lieliski! KonvertÄjiet sistÄmas svÄ«trkodus uz hex. Tas arÄ« viss, apmÄcÄ«bas funkcionalitÄte ir gatava.
KÄ ar programmaparatÅ«ru? Å Ä·iet, ka viss ir tÄpat, bet ir kÄda nianse.
PÄc pilnÄ«gas mirgoÅ”anas procesa izgÄztuves mÄs aptuveni sapratÄm, ar ko mums ir darÄ«Å”ana. Å eit ir raksts par XMODEM, kas bija ļoti noderÄ«gs, lai saprastu, kÄ notiek Ŕī saziÅa, lai gan vispÄrÄ«gi:
AplÅ«kojot izgÄztuvi, jÅ«s varat redzÄt, ka kadra izmÄrs ir 1024, bet URB datu izmÄrs ir 64.
TÄtad ā 1024/64 ā blokÄ iegÅ«stam 16 rindiÅas, pa 1 rakstzÄ«mei nolasÄm programmaparatÅ«ras failu un veidojam bloku. 1 rindiÅas papildinÄÅ”ana blokÄ ar speciÄlajÄm rakstzÄ«mÄm fd3e02 + bloka numurs.
NÄkamÄs 14 rindas tiek papildinÄtas ar fd25 +, izmantojot XMODEM.calc_crc() aprÄÄ·inÄm visa bloka kontrolsummu (pagÄja daudz laika, lai saprastu, ka āFF ā 1ā ir CSUM) un tiek papildinÄta pÄdÄjÄ, 16. rinda. ar fd3e.
Å Ä·iet, ka viss, izlasiet programmaparatÅ«ras failu, nospiediet blokus, atvienojiet skeneri no kodola un nosÅ«tiet to uz ierÄ«ci. Bet tas nav tik vienkÄrÅ”i. Skeneris ir jÄpÄrslÄdz uz programmaparatÅ«ras režīmu,
Š¾ŃŠæŃŠ°Š²ŠøŠ² ŠµŠ¼Ń NEWAPP = ā\xfd\x0a\x16\x4e\x2c\x4e\x45\x57\x41\x50\x50\x0dā.
No kurienes Ŕī komanda?? No izgÄztuves.
Bet mÄs nevaram nosÅ«tÄ«t visu bloku skenerim 64 ierobežojuma dÄļ:
Nu, skeneris NEWAPP mirgoÅ”anas režīmÄ nepieÅem hex. TÄpÄc jums bÅ«s jÄtulko katra rinda 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]
Un pÄc tam nosÅ«tiet Å”os datus uz skeneri.
MÄs saÅemam atbildi:
[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]
PÄrbaudot rakstu par XMODEM, kļūs skaidrs: dati ir pieÅemti.
Kad visi bloki ir pÄrsÅ«tÄ«ti, mÄs pabeidzam pÄrsÅ«tÄ«Å”anu END_TRANSFER = 'xfdx01x04'.
TÄ kÄ Å”ie bloki nesniedz nekÄdu informÄciju parastajiem cilvÄkiem, mÄs pÄc noklusÄjuma instalÄsim programmaparatÅ«ru slÄptÄ režīmÄ. Un katram gadÄ«jumam mÄs organizÄsim progresa joslu, izmantojot tqdm.
PatiesÄ«bÄ tad runa ir par sÄ«kumiem. Atliek tikai ietÄ«t risinÄjumu skriptos masveida replikÄcijai skaidri noteiktÄ laikÄ, lai nepalÄninÄtu darba procesu pie kasÄm, un pievienot reÄ£istrÄÅ”anu.
Kopsavilkums
PatÄrÄjot daudz laika un pūļu un matus uz galvas, mÄs varÄjÄm izstrÄdÄt nepiecieÅ”amos risinÄjumus, kÄ arÄ« ievÄrot termiÅu. TajÄ paÅ”Ä laikÄ skeneri tagad tiek atjauninÄti un atkÄrtoti apmÄcÄ«ti centralizÄti, mÄs skaidri kontrolÄjam visu procesu. UzÅÄmums ietaupÄ«ja laiku un naudu, un mÄs guvÄm nenovÄrtÄjamu pieredzi Å”Äda veida reversÄs inženierijas iekÄrtÄs.
Avots: www.habr.com