Natív komponens - wolfi95/szgbizt2020-asdfgh GitHub Wiki

A C++ CAFF parser

A parser feladata

A natív nyelven megvalósított parser felada egy bemeneti CAFF fájlból való előkép generálása. A parsernek nem feladata a teljes CAFF fájl integritásának vizsgálata, viszont az előkép generáláshoz szükséges ellenőrzéseket el kell vegéznie.

Az webes környezetben is megjeleníthető előkép generáláshoz egy CIFF blokkra van szükség a CAFF fájlon belül. A parser minden CAFF fájl esetén megkeresi az első CIFF blokkot és ezt használja. Amennyiben nincs CIFF blokk, úgy nem készül előkép. A böngészők azonban nem képesek a CIFF fájlok megjelenítésére, így a blokkot valamilyen böngészők által is támogatott képformátumra kell transzformálni. Mivel a CIFF alapvetően tömörítetlen bitmap formában tárolja a képeket, a választásunk a bitmap (BMP) képformátumra esett.

A parser működése

A parser paraméterként megkapja a feldolgozandó CAFF fájl nevét, ellenőrzi a nevet, majd elkezdi a parsolást. A parsolás a CAFF fájl blokkjainak olvasását jelenti mindaddig, amíg el nem érjük az első CIFF blokkot. A CIFF headerből kinyerjük a CIFF fájl méretét és dimenzióját. Ezek alapján a parser létrehoz egy BMP fájlt és inicializálja annak File és Info header-jeit a CIFF fájl adatai alapján. Ezután a CIFF fájl adat részét pixelről pixelre átkonvertálja a BMP formátumnak megfelelő formába, végül lezárja a fájlokat. Minden feldolgozás megjelenik a logban, valamint az esetleges hibák is rögzítésre kerülnek. Az eredeti elképzelés a BMP fájl visszatérési értékként való visszaadása volt, amely esetben a kész előképet nem kell fájlba írni majd beolvasni, ám a c# és c++ közötti char* -> byte[] transzformáció során olyan problémába ütköztünk, amelyet egyelőre nem sikerült megoldanunk.

A parser futtatása

A parser jelenleg buildelés után exe-ként futattható vagy dll-ként hívható. A parser két paramétert vár:

  1. A forrás CAFF fájl neve
  2. A kimeneti BMP fájl neve

Példa: caff_parser.exe ../../caff_files/1.caff preview.bmp

A parser tesztelése

Statikus analízis

Az általános hibák, biztonsági hiányosságok és gyengeségek tesztelésére a CppCheck statikus analízis ezközt használtuk. A parser tesztelése során az ezköz nem talált ilyen hibát.

Fuzzing

A natív komponens fuzzolásához AFL-t használtunk. A fuzzolás hatékonyságát nagy mértékben rontotta a példa bemenet (1.caff) mérete és az I/O műveletek lassúsága. Alapértelmezett módban az AFL rendkívül lassú volt, így a használhatóbb működés érdekéban a -d flaggal is futtattuk, ami már hasznosnak bizonyult.

Az alapértelmezett mód futtatása nem talált crash-t vagy hang-et. afl-alap

afl-alap-plot

A piszkos mód sem talált crash-t, azonban azonosított 2 hang-et, melyek 'true posotive'-nak bizonyultak. Az egyik hibát a CAFF alapblokkok 'length' header értékének ellenőrzésének elmulasztása okozta, így specifikus, invalid esetekben végtelen ciklusba került a parser. A másik hang oka pedig a kiolvasott CIFF blokk dimenzióinak ellenőrzésének hiánya volt. A hibákat a megfelelő generált inputok futtatásával azonosítottuk. A forráskódot javításra került. afl-dirty

afl-dirty-plot

Memóriakezelés tesztelése

A parser működéséből kifolyólag az implementáció során végül nem volt szükségünk memóriakezelésre, hiszen a bementi CIFF fájlt pixelről pixelre fájlba írtuk. Ennek megfelelően a memóriakezeléssel kapcsolatos hibák ellenőrzésére nem volt szükség. Amennyiben a jövőben implemenjuk a BMP fájl byte[]-ként való visszadását, úgy szükségünk lesz ilyen jellegű dinamikus tesztek futtatására is.