Sticker Plotter · dokumentace

Statická analýza

Otevřít zdrojový Markdown ↓

Cílená statická analýza protokolu CFL-605RT

Výsledek

Statická analýza uzavřela geometrii, souřadnice, výběr nástroje, profilové hodnoty a epilog omezené první řezací úlohy. Neuzavřela životní cyklus systémového spojení RAW TCP ani bajty před prvním datovým zápisem. První bezpečný POC proto ještě vyžaduje jedinou cílenou síťovou sondu pro každou z těchto dvou mezer.

Analýza nespustila žádnou binárku Windows, neinstalovala ovladač, nekontaktovala plotr a neprovedla USB ani ethernetový záznam. Ghidra 12.1.2 načetla pouze MMKPLT.dll a mpmserv_1.dll do dočasného projektu mimo Git.

Analyzované moduly

Modul SHA-256 Relevantní sekce
payload/Printer_amd64/MMKPLT.dll 611da823f97b5f83afa94c28e8b705c61b7cce44d72ab14478a077e0c1029712 .text VA 0x6a901000, velikost 0x28f3d; .data VA 0x6a92a000; .pdata VA 0x6a931000
payload/PortMonitor_amd64/mpmserv_1.dll 3dde1e24123f4803ae66a6315f87fa9ec447a23dcbb0e2432d2b9b5d9038ad1d .text VA 0x180001000, velikost 0x3f37; .data VA 0x180005000, velikost 0x200
payload/Printer_amd64/CFLJJ.PCD 15e8fe9037d518f09dee5f12e928def5f3deb04da662731e58cb905ccd723d51 textová konfigurace: MODEL=11, CUTTING=1, PENNOMAX=6, PAGEINIT=IN;, COMMAND MGL-IIc=1

Q01 — životní cyklus TCP spojení

Modul a místo: mpmserv_1.dll, SHA-256 3dde1e24123f4803ae66a6315f87fa9ec447a23dcbb0e2432d2b9b5d9038ad1d, export InitializePrintMonitor2 na 0x180001698 v .text a tabulka MONITOR2 na 0x180005140 v .data.

Pozorované bajty a tok: Tabulka začíná bajty b0 00 00 00 00 00 00 00 20 23 00 80 01 00 00 00 14 17 00 80 01 00 00 00 00 00 00 00 00 00 00 00. Hodnota cbSize=0xb0 a pořadí struktury MONITOR2 mapují tyto callbacky:

Posun tabulky Callback Adresa
+0x08 EnumPorts 0x180002320
+0x10 OpenPort 0x180001714
+0x18 OpenPortEx NULL
+0x20 StartDocPort 0x180001794
+0x28 WritePort 0x180001bf8
+0x30 ReadPort 0x180002468
+0x38 EndDocPort 0x180001e04
+0x40 ClosePort 0x180001f94

StartDocPort začíná bajty 48 89 5c 24 10 48 89 6c 24 18 48 89 74 24 20 57 41 54 41 55 41 56 41 57 48 83 ec 60. Rozlišuje vlastní cesty MIMAKI FILE2, MIMAKI1394 a lokální zařízení, jejich cestu otevře přes CreateFileW. WritePort na 0x180001bf8 předává přijatý buffer beze změny do WriteFile. EndDocPort na 0x180001e04 dopíše pouze vlastní 1394 buffer, volá FlushFileBuffers a CloseHandle a žádný protokolový bajt nepřidává. ClosePort tvoří bajty b8 01 00 00 00 c3 a nic dalšího nedělá.

Závěr: Vlastní port-monitorová cesta MPMSERV_1.dll nemá handshake, transformaci proudu ani vlastní síťový transport. OpenPortEx=NULL zároveň nedokládá delegaci do systémového monitoru. Ručně zvolenou konfiguraci S02 obsluhuje systémový Standard TCP/IP Port Monitor, jehož počet spojení, hranici jedné úlohy a okamžik zavření archivované moduly neobsahují.

Jistota: vysoká pro vlastní callbacky MPMSERV_1.dll; nízká pro životní cyklus ručně zvoleného systémového RAW TCP portu. Q01 zůstává otevřená.

Q02 — handshake a první síťový bajt

Modul a místo: mpmserv_1.dll, SHA-256 3dde1e24123f4803ae66a6315f87fa9ec447a23dcbb0e2432d2b9b5d9038ad1d, ReadPort na 0x180002468 v .text; MMKPLT.dll, SHA-256 611da823f97b5f83afa94c28e8b705c61b7cce44d72ab14478a077e0c1029712; CFLJJ.PCD, SHA-256 15e8fe9037d518f09dee5f12e928def5f3deb04da662731e58cb905ccd723d51, s PAGEINIT=IN;.

Pozorované bajty a tok: Celý vlastní ReadPort tvoří 41 83 21 00 b8 01 00 00 00 c3. Funkce zapíše do *pcbRead nulu a vrátí TRUE. StartDocPort vlastní cesty nečte před prvním zápisem a WritePort data nemění. Modelová konfigurace vkládá do spoolovacího proudu IN;.

Závěr: Vlastní cesta MPMSERV_1.dll před daty nečte a nepřidává handshake. Tento závěr nelze přenést na ručně zvolený systémový Standard TCP/IP Port Monitor. Statická analýza proto nepotvrzuje, zda je prvním síťovým bajtem I z IN;, ani zda systémová cesta před prvním zápisem očekává odpověď.

Jistota: vysoká pro vlastní cestu MPMSERV_1.dll; nízká pro první bajt systémové RAW TCP cesty. Q02 zůstává otevřená.

Q03 — epilog omezené první úlohy

Modul a místo: MMKPLT.dll, SHA-256 611da823f97b5f83afa94c28e8b705c61b7cce44d72ab14478a077e0c1029712, tabulka DRVFN na 0x6a92fe50 v .data, DrvEnableDriver na 0x6a902b88, DrvSendPage na 0x6a909a9c, DrvEndDoc na 0x6a909a38 a zapisovací funkce 0x6a905294 a 0x6a90533c v .text.

Pozorované bajty a tok: DrvEnableDriver vrací verzi 0x20000, 25 položek a ukazatel na tabulku. Položky iFunc=0x20, 0x21, 0x22 a 0x23 ukazují postupně na 0x6a909a9c, 0x6a9092ec, 0x6a909a38 a 0x6a907ab8. Ve veřejné struktuře winddi.h odpovídají funkcím DrvSendPage, DrvStartPage, DrvEndDoc a DrvStartDoc.

DrvSendPage začíná bajty 48 8b c4 48 89 58 10 48 89 68 18 48 89 70 20 57 48 83 ec 40. Pro MODEL=11, COMMAND MGL-IIc a vypnuté rozšířené přesuny stránky vede obyčejná větev na řetězec PUSP0; na 0x6a901908, délku 6 a následné volání 0x6a90533c(..., 9). Větev modelu 11 přeskočí kandidát ;JE; na 0x6a90193c. DrvEndDoc běžné větvi žádné další bajty nepřidá.

Závěr: Omezená první úloha končí přesně bajty PUSP0;, tedy zdvihem nástroje a volbou SP0, a následným flush spoolovacího bufferu. Závěr platí pouze pro MODEL=11, jeden běžný list a bez rozšířeného posunu nebo podávání stránky.

Jistota: vysoká. Q03 je pro takto omezený POC uzavřená.

Q04 — pohyb bez řezu a s řezem

Modul a místo: MMKPLT.dll, SHA-256 611da823f97b5f83afa94c28e8b705c61b7cce44d72ab14478a077e0c1029712, dispečery 0x6a913324, 0x6a913488 a 0x6a913544, modelová funkce 0x6a911f38 a řetězce na 0x6a901c44 až 0x6a901c54 v .text.

Pozorované bajty a tok: Dispečer začátku kontury 0x6a913324 začíná 48 83 ec 38 48 8b 81 70 0a 00 00 83 b9 18 09 00 00 01. Dispečer řezného bodu 0x6a913488 začíná 48 83 ec 38 48 8b 81 70 0a 00 00 41 b9 01 00 00 00. Oba pro modelovou hodnotu 0x0b pokračují přes větev <0x15 do 0x6a911f38.

Funkce 0x6a911f38 používá řetězce PU na 0x6a901c44, PD na 0x6a901c4c, PA na 0x6a901c50 a PR na 0x6a901c54. Start nebo přesun bez řezu emituje PU, absolutní režim PA a dvojici podepsaných desítkových souřadnic. Řezný bod emituje PD, PA a stejnou dvojici. Relativní větev emituje PD, PR a rozdíly souřadnic. Bajty 45 50 na 0x6a901c48 jsou EP, nikoli PD.

Závěr: Minimální absolutní geometrie používá PU + PAx,y pro pohyb bez řezu a PD + PAx,y pro pohyb s řezem. Souřadnice jsou podepsaná desítková celá čísla oddělená čárkou. Ovladač mezi těmito mnemoniky nevkládá středník.

Jistota: vysoká. Q04 je uzavřená.

Q05 — jednotky, počátek a osy

Modul a místo: MMKPLT.dll, SHA-256 611da823f97b5f83afa94c28e8b705c61b7cce44d72ab14478a077e0c1029712, 0x6a911f38 v .text; veřejný zdroj S01 pro GDP UNIT a plochu 610 × 510 mm; S02 pro počátek vlevo dole.

Pozorované bajty a tok: Při context+0xdb8 == 0 funkce ukládá x_cmd=x_gdi a y_cmd=page_height-y_gdi. Varianty rotace 1 až 3 osy prohazují nebo invertují. Funkce 0x6a9051e0 serializuje výsledné hodnoty jako podepsaná desítková celá čísla. Ovladač dostává už kvantované souřadnice GDI; neprovádí převod z milimetrů.

S01 povoluje pouze jednotky 0,025 mm a 0,010 mm. S01 uvádí efektivní plochu 610 × 510 mm. S02 vyžaduje počátek vlevo dole.

Závěr: První POC musí zakázat rotaci, vyžadovat počátek vlevo dole a mít explicitní profil gdp_unit_mm s hodnotou 0.025 nebo 0.010. Přímý encoder z milimetrů použije x_cmd=x_mm/gdp_unit_mm a y_cmd=y_mm/gdp_unit_mm v soustavě vlevo dole. Host musí před serializací použít a zdokumentovat vlastní pravidlo kvantování; ovladač jeho volbu nedokládá.

Z fyzické plochy a jednotky vycházejí tyto odvozené meze: při 0,025 mm x=0…24400, y=0…20400; při 0,010 mm x=0…61000, y=0…51000. Nejde o publikované protokolové maximum.

Jistota: vysoká pro orientaci a povolené jednotky; střední pro odvozené číselné meze. Q05 je uzavřená.

Q06 — SP a fyzický nástroj

Modul a místo: MMKPLT.dll, SHA-256 611da823f97b5f83afa94c28e8b705c61b7cce44d72ab14478a077e0c1029712, profilová funkce 0x6a9143b4, řetězec SP na 0x6a901d50 v .text; S01, PEN ASSIGN.

Pozorovaný tok: Pro model 0x0b funkce 0x6a9143b4 načte z 28bajtového profilového záznamu logické číslo v druhém 32bitovém poli a emituje SP následované desítkovým číslem. PCD omezuje počet logických per na šest.

S01 definuje uživatelsky měnitelné PEN ASSIGN 1 až 6. Tovární mapa je: 1 = B/REC.CUTTER1, 2 = B/ROLLER1, 3 = B/θCUTTER, 4 = B/ROLLER2, 5 = A/SWIVEL, 6 = A/PEN.

Závěr: SPn vybírá logický slot n v rozsahu 1 až 6, nikoli neměnný fyzický nástroj. Profil POC musí uvést pen_slot a obsluha musí před ostrým řezem potvrdit aktuální panelové přiřazení. Tovární mapa je vodítko pro kontrolu, ne implementační výchozí hodnota.

Jistota: vysoká. Q06 je uzavřená explicitním slotem a kontrolou panelu.

Q07 — rychlost, tlak a offset

Modul a místo: MMKPLT.dll, SHA-256 611da823f97b5f83afa94c28e8b705c61b7cce44d72ab14478a077e0c1029712, 0x6a9143b4 a formátovač 0x6a914264 v .text; řetězce VS, ZF, FS, ZO a AS na 0x6a901d54 až 0x6a901d64.

Pozorované bajty a tok: Pro model 11 čte 0x6a9143b4 z 28bajtového záznamu:

  • bajt na posunu 0x0c; pokud není nula, emituje VS a celé desítkové číslo;
  • 16bitovou hodnotu na posunu 0x0e; pokud není nula, emituje FS nebo ZF a celé desítkové číslo podle příkazového režimu PCD;
  • float na posunu 0x14; při kladné hodnotě emituje ZO a výsledek formátovače 0x6a914264.

Formátovač 0x6a914264 začíná bajty 48 8b c4 48 89 58 08 48 89 68 18 66 89 50 10 56 57 41 54 48 83 ec 30. Volá _fcvt(value, 2, …) a vždy tvoří dvě desetinná místa. Modelová větev 11 zde neemituje AS ani ZA. Nulová rychlost, tlak nebo offset příkaz zcela vynechá; neemituje hodnotu nula.

S01 uvádí fyzickou rychlost 0,2 až 30 cm/s a offset 0,00 až 2,50 mm v kroku 0,05 mm. Tlak závisí na nástroji: například swivel 30 až 1000 g, tangenciální nůž a roller 500 až 1500 g. Ovladač serializuje rychlost jako celé číslo, takže omezený POC smí použít pouze celočíselnou rychlost 1 až 30 cm/s. Kódování desetinné rychlosti zůstává neověřené a první POC je nepotřebuje.

Závěr: Profil používá SPn, volitelně VSv, FSf nebo ZFf a ZOo.oo. Příkazy se řetězí bez vloženého středníku, například SP1VS10FS100ZO0.30. Chybějící hodnota ponechá prioritu panelu. Profil nesmí mít obecný výchozí tlak; musí validovat rozsah vybraného nástroje. ZA zůstane pro první POC panelovým nastavením.

Jistota: vysoká pro bajtovou serializaci a vynechání nul; vysoká pro veřejné fyzické rozsahy; nízká pro desetinnou rychlost, kterou omezený POC zakazuje. Q07 je uzavřená pro tento POC.

Otázky třídy D

Q08 (více průchodů a pořadí), Q09 (odpovědi a stavové čtení) a Q10 (hostitelské spuštění registračních značek) neblokují první samostatný jednosměrný řez. Tato etapa je pouze klasifikuje a dál je nerozebírá. U Q09 je doloženo jen to, že vlastní ReadPort modulu mpmserv_1.dll vrací nula bajtů; chování systémové RAW TCP cesty zůstává neověřené.

Hloubkové doplnění po odložení capture

Protože síťový capture je odložen o několik dní, byla statická analýza dotažena na maximum. Následující byte-chainy uzavírají dřívější mezery obsahu proudu.

FS vs. ZF řídí PCD klíč CUTTING, ne COMMAND (E38 → potvrzeno)

Příznak [pdev+0xa70]+0x104 je plněn parserem PCD. Keyword tabulka na 0x6a92a6b0 váže CUTTING na handler 0x6a926e80, který dělá add rcx,0x104 a tail-calluje generický atoi setter 0x6a9264b8. Default recordu je nula (0x6a925f82: mov [rbx+0x104], r13d s r13d=0). Handler COMMAND (0x6a926e98) cílí jiné pole +0x118. V CFLJJ.PCD je CUTTING=1 → +0x104=1. Emisní větev 0x6a914617: přednabije ZF (0x6a901d58), cmp [rax+0x104],0, jne → +0x104=1≠0 ponechá ZF; FS (0x6a901d5c) by padlo jen při CUTTING=0. Tentýž +0x104 gatuje i druhou emisní kopii 0x6a914b9b a barevnou/řezovou větev 0x6a91468f.

Souřadnice se nezaokrouhlují (E39 → potvrzeno)

Geometrie 0x6a911f38 počítá jen celočíselně (sub edi,r8d; sub esi,edx) a předává serializeru 0x6a9051e0, který volá msvcrt!_ltoa s bází 10 (IAT 0x6a901488). Jediné MulDiv (0x6a91ac8a) je na dráze rozlišení/DPI, ne per-vertex. Driver tedy dostává už kvantované celé číslo; pravidlo zaokrouhlení mm→jednotka je plně na hostovi.

Zápisová cesta je jednosměrná (E29 → potvrzeno)

MMKPLT importuje WritePrinter/WriteFile, ne ReadPrinter; ReadFile je jen se souborovým mapováním konfigurace. V kódu nejsou status-opkódy (OH/OS/OA/OI/!). Vlastní ReadPort MPMSERV_1.dll vrací nula bajtů. Status jde jen out-of-band (SNMP / Event Mail).

Softwarové stropy rychlosti a tlaku (E20/E22 → potvrzeno)

MMKPLT při serializaci neclampuje (jen !=0 a delta-suprese). Stropy vynucuje MMK_UI přes UDM_SETRANGE: model 11 rychlost 0–50 (0x6a912fe1: mov eax,0x32) vs. ostatní 0–40 (0x6a912fb9: 0x28); tlak 0–5000 (0x6a912ff5: mov r15d,0x1388). Dřívější „10000 g" byla chyba; skutečný strop je 5000.

Delegace legacy monitoru vyloučena (E36 → potvrzeno)

Parse importů mpmserv_1.dll: 58 funkcí z šesti systémových DLL, žádný Winsock, žádný LoadLibrary/GetProcAddress. Všech 194 nepřímých volání míří do vlastní IAT 0x180001000–0x1800011e0. DeviceIoControl cílí lokální \\?\1394#mimaki&printer_status, ne TCP/AFD. OpenPortEx=NULL tedy není skrytá delegace — RAW cesta na 11110 běží výhradně přes systémový tcpmon.dll, který v podkladech není.

Registrační značky (E32)

MMKPLT neemituje žádný mnemonik čtení značek; detekci provádí senzor stroje, host jen nastaví režim přes UI dialog 608 ([RegMark] 0/1).

Hranice závěru

  • PUSP0; platí pro omezenou běžnou větev MODEL=11; rozšířené posuny a podávání stránky jsou zakázané.
  • Převod milimetrů na celé jednotky je odpovědnost budoucího hosta. Ovladač nepředepisuje jeho zaokrouhlení.
  • Tovární PEN ASSIGN se může na panelu změnit.
  • Absence čtení v MPMSERV_1.dll není důkazem chování systémového Standard TCP/IP Port Monitoru.
  • Aktuální DeviceIO 5.12.3 používá oddělené app-vrstvové cesty CDeviceEtherData a CDeviceIDCut. Jejich porty a rámce nejsou důkazem legacy RAW TCP/11110.
  • Podobnost názvu MGL s HP-GL nebyla použita jako důkaz žádného příkazu.