ScriptingListener plug-inInnen kell letölteni. Kicsomagolás után:...Downloads\Win_Scripting_Plug-In\Scripting_Win64\Scripting Utilities\ScriptListener.8liezt az egy filet filet kell ide másolni>C:\Program Files\Adobe\Adobe Photoshop 2020\Plug-insPs újraindít, és a desktopon megjelenik két log file, az egyik Java, a másik VisualBasic.Amit PS-ben csinálsz azt itt logolja.
Utazások (nem csupán) Fotográfiában
2026/09/28
Photoshop scriptelése (+ Scripting listener)
2026/09/10
Roncsoljunk JPEG-et újra
A megadott hossz és a következő valid marker közé beszúrhatunk ugyan byteokat, de ennek a glitch szempontjából nincs értéke, esetleg szteganográfiára használható, de változó, hogyan reagálnak rá a képszerkesztő programok, és ha meg is nyitják, újramentésnél valószínűsíthetően nem fogják tovább vinni a számukra irreleváns, szegmensek közötti adatot, amit feltehetően be sem olvasnak.
1. QT
Értelmezzük, az FF DB a szegmens markere, a 00 84, ami decimálisan 132 byte. Hogy is jön ez ki? Ebbe beleszámít a hosszat leíró két byte (00 84) plusz általában van egy Luminance és egy Chrominance táblánk, egyenként 8*8 byteosak. Tehát:
2 (hossz-byte) + 1 (luminance azonosító) + 64 (tábla mérete) + 1 (chromninance azonosító) + 64 (tábla mérete) = 132
FF DB 00 84 00 - a marker, majd a hossz után a 00 byte határozza meg milyen tábláról van szó, ez a Luminosity tábla, az ötödik byteig tehát nem piszkálható, de az utána következő értékeket már igenis érdemes. Pontosan 64 byte hosszan.
2. Frame Header
lássuk mi van benne:
FF C0 SOF0 —
Érdekesség, hogy amikor a HexEditorral rákerestem az FF C0 markerre, totál mást találtam, egy kisfelbontású, szét-szubsamplingezett képre utaló headert, ami nem lehet más, mint a thumbnail. De mint ilyen, az EXIF része, tehát az EXIF APP1 (FF E1 11 45) 4421 bytejában lapul egy teljes, komplett JPEG, kvantálási táblástól, Headerestől, Huffmannostól és adatstreamestől. Persze a fileban hátrább megtaláltam a teljes kép headerjét is, már nem beágyazva az EXIF adatfolyamába. Na ezért fontos, hogy egy marker után (pl EXIF) azt is megadjuk, hogy a szegmens milyen hosszú (4421 byte), mert így tudjuk, hogy a talált kis JPEG összes markere, szőröstől-bőröstől az EXIF része, tehát nem az igazi kép, csak egy thumbnail.
3. Restart Interval
3.1. Restart Interval marker a bitstreamben.
4. Huffman tábla támadása
Az értékek átírása legtöbbször a kép kinyírását okozza, néha full fehér képet kapunk (túlcsordul), ha a byteokat cserélgetjük random, akkor néha kapunk glitchet is. Nem túl kiszámítható.
- HUFVAL - szimbólum értékek. hossza (12 byte) megegyezik a BITS 16 számának összegével
Bármelyik byte átírható 00-tól 0F-ig (0-15 között decimálisan) és glitchet kapunk, 10-FF (16-255 decimálisan) között sem döglik meg a kép, de hófehér lesz, vagyis túlcsordul. Ha kicsi értékkel írjuk felül, ilyesmi az eredmény, itt most az első 07-et 00-ra cseréltük:
Ez a csökkenő glitch hatás azért van, mert a 07 a legyakoribb fényerő különbségeket kódolja és így haladunk az egyre ritkábbakig 0B-ig. Nem kizárt, hogy a 0B is okoz valamit, csak éppen észre sem vevődik.
Hasonlóan viselkedik, mint az előbbi.
Erre is igaz nagyjából az amit az előbbi táblánál tapasztaltunk.
5. Scan header támadása
Nincs sok támadható byte, a három komponens második bytejait lehet elhazudni, de csak valid Hufmantábla azonosítóra (00, 01, 10, 11), ilyenkor glitch az eredmény, más értékekre meghal a file. Az utolsó 3 byte meg a progresszívre mentett JPEG-ekre vonatkozik, itt semmi hatása nincs, ha átírjuk őket.
6. magának az adatfolyamnak a támadása
Itt teljességgel kitalálhatatlan, hogy melyik byte átírása hova fog ütni. Eleve mi byteokat látunk egy hexeditorban, de a valóságban ez egy bitfolyam, amiben az adathosszúságok bárhány bitesek lehetnek. Jellemzően mégis, ha az adatfolyam elejét támadjuk, akkor a glitch a kép felső részét fogja érinteni, míg ha a végét, akkor az alját. Azt hogy a hiba melyik MCU-t fogja érinteni azt szinte lehetetlen eltalálni de próbálgatással azért lehet közelíteni. A sorhossznyi restart intervalos képeknél a glitch a sor végéig tart, de néha előfordult, hogy a kép végéig az összes MCU-sor megnyikkant. Leginkább 8 pixel magas szürke sávként jelentkezik a hiba, de néha sikerül színes találatot is csinálni. Ami viszont nagyon érdekes, hogyha sorban írjuk át a byteokat és keletkezik egy sor glitch, a következő néhány byte átírásánál nagyon gyakran visszaáll a helyes kép. Kifejezetten gyakori és könnyen előidézhető jelenség. Hiba * hiba = jó kép, mindenesetre furcsa, de biztos a dolog matematikája miatt determinisztikus.
Hosszú és kimerítő utazás volt, két MI-t is fárasztottunk a kérdéseinkkel, nélkülük esélyünk se lett volna a byteok értelmezésében, a végére így is mindketten elkezdtek hallucinálni. De nem sikerült mélységében megérteni a dolgot, inkább rengeteg új perspektívát nyitott ki. Ez csak egyetlen típusú JPEG (plusz egy progresszív a végén bónusznak) körüljárása volt, és az is csak lóugrásokban. De JPEGet menteni sokféleképpen lehet és mind eltérően viselkedhetnek.
És akkor még nem is próbálkoztunk azzal, hogy a támadásokat egymásra halmozzuk. De hátha valaki kedvet kap hozzá és ír egy olyan programot, ami egyesíti a bejegyzés elején meghivatkozott kolléga munkáját az itt felhozott további részletekkel. Mondjuk egy olyat, ami kijelöli a leglátványosabban támadható byteokat és valid támadó értékintervallumot is ajánl ott ahol nem mindegy mit írunk át mire.
2026/08/31
A felejtés, mint glitch
Ezzel a két képpel dolgozunk, PNG formátumban igyekszünk szanaszét glitchelni, az itt és itt ismertetett módon. Esetleg nézd meg ezt a videót is, a kolléga nagyjából hasonlókat művel és őt is a japán művész inspirálta, mint minket. A 15-20 éve eltűnt városképek, amiknek emlékét agyunkban is lassan kikezdi a felejtés, tökéletes alanyok erre a játékra.
A bejegyzés végére nagyjából tudni fogjuk, hogy milyen típusú képeket, és milyen módon érdemes megtámadni ahhoz, hogy értelmezhető glitcheket kapjunk.
![]() |
| Minden filtertípus Averageként kikódolva pont így néz ki. |
2. Az viszont meglepett, hogy a program kezeli az alfa csatornát is, a Nap-korongot vágtuk ki a képből.
![]() |
| A legelső pixelt támadtuk meg, mert a program nem enged menteni támadás nélkül A filtereket viszont meghagytuk, ahogy az eredeti fileban voltak. |
![]() |
| RGBA - összes scanlineja Averagként kibontva, azért ez teljesen mást eredményezett, mint kettővel fennebb. |
3. RGB16-os PNG-vel nem áll szóba a program, tehát csak a 8 bitesek működnek. De hibaüzenettel lekezeli.
4. Az Interlaced képeket is megtagadja a program, ügyesen hibaüzenettel.
Innentől csak RGB8 és large mentésű (vegyes filterezésű és olykor normalizált filterezésű) fileokat támadunk.
5. Pixel támadás mátrixban, vagyis 10*10 pixelenként a teljes kép felületén, filterezést nem bántjuk:
Az eredmény érdekes, mert sejtetni engedi, hogy a photoshop milyen típusú felületeknek, soroknak milyen filtereket választ leginkább, az ég zömmel Sub filterezésű, a felhő töri ezt meg picit, aztán lefelé, ahogy sűrűsödnek a kábelek Paethre vált, a házcserepeknél a fene tudja, Average-re tippelnék, mert nem látszik a 10*10-es mintázatban a fehér pixel (amennyiben None lenne ezt várnánk), aztán lefele a ház fala megint Paeth, az aszfalt Average és a csajok megint Paeth.
![]() |
| Emlékeztetőül ilyen lenne a 10*10-es támadás None-ra normalizált filterű képen. |
A másik képünkön az a nagyon furcsa, hogy az eget nem bántotta, egyetlen pixelt se, erre jelenleg nincs magyarázatunk (még Ps-ben az eredetivel Differenc módban is összenéztük, semmi jele az égben a hibának). Aztán lefele a Paeth, az Average, kicsit megint a Paeth, majd a Sub dominál.
Gondoltuk sorra megnézzük, hogy ugyanezzel a 10*10-es pixeltámadással elhazudjuk az összes filtert is, mondjuk Average-nek, csak egyetlen filtert hagyunk meg ahogy volt, sorra a None, Sub... és hoppá, ha a Sub filterű scanlineokat békén hagyjuk az összes többi Average, akkor az ég érintetlen marad? Vagy van benne némi átlós textúra?
Nézzük csak meg PS-ben Difference módban az eredetivel és egy durva Curve-t ráhúzva!
Ja, vagy így. Hát ott van a glitch, de mivel minden pixelt 255-re tettünk és az ég eleve nagyon világos, ezért alig látszik a hatás, de ott van. Tehát nemcsak az számít, hogy mennyire homogén zóna scanline-jairól van szó (ami alapján filtert választ a program a soroknak) hanem az is, hogy milyen világos vagy sötét tónust milyen byte-értékkel támadunk az egyes pixelpozíciókon.
6. Most azt nézzük meg, hogy a három Custom filterünkkel normalizáltan elkódolt képeink hogyan néznének ki, ha a dekódolásukat az 5 valid filter egyikére hazudnánk. Itt már csak a kevésbé zajos képünket teszteljük, hiszen az már világosan látszik, hogy a filterek támadása egyfajta edge-detection szűrőként hatnak. A részletgazdag (nagyfrekvenciás) képek így a filtertámadás során belefulladnak a zajba, és csak a nagyobb egységes felületek maradnak meg. Mint már várható volt, mindhárom saját elkódolás, None kikódolással egy erős edge detectiont eredményez
Bár a Custom1 és Custom3 bemenet se rossz, de a legjobb eredményt itt is a Custom2 bemenetű Sub és Up-ként interpretált képek adták.
Nyilván az Averagetől várjuk a legtöbbet, és nem is csalódunk, mindhármat mutatjuk:
![]() |
| Custom1 filtered - decoded as Average |
![]() |
| Custom2 filtered - decoded as Average |
![]() |
| Custom3 filtered - decoded as Average |
7. Kipróbáltuk a Custom1 (körkörös prediktorunkat is a kikódolásra). Az egyszerű, vegyes filterű, képeink elég semmilyenek lettek, viszont a Custom 1, Custom 2 és Custom 3 elkódolású képek Custom 1 dekódolással már csöppet érdekesebbek:
Mellesleg az AI szerint ez a teljes projekt, programokkal, szkriptekkel, elemzésekkel, szőröstől-bőröstől pár óra laptophasználat ökológiai lábnyomával ér fel. ennél jóval több számítógéphasználat történt az én kliensoldalamon, legalább 20 óra. Másképpen megközelítve, pár száz palacsintarecept megbeszélése az AI-val ekvivalens öko-lábnyomot eredményez, mint ez a projekt.
![]() |
| Custom2 to Average + byte attack 1-20 |
2026/08/28
PNG autopsy III
És így néznek ki a Custom Filterekkel elkódolt, de valós Filtereknek (azokkal kikódolt) hazudva:
Emlékeztetésnek és összehasonlításnak (az előző bejegyzésből átemelve), a valós filterek egymás között elhazudva így néztek ki:
![]() |
| Kis felbontású és JPG-nek mentett nézet, az eredeti jóval gazdagabb. |
Az eredmény érdekes, de sajnos nem a reményeink szerint való, azt vártuk volna ugyanis, hogy a merőben eltérő encoder filtereink merőben eltérő hatásokat fognak produkálni, rosszabb esetben annyira összeborzolják a képet, hogy az felismerhetetlenné válik. Ezzel szemben a kikódolásra használt filter hatása a domináns, tehát például egy UP függőlegesen vonalas, egy Average átlósan, stb, és egyáltalán nem felismerhetetlen a kép sem.
A további 3 kép, amikor az elkódolás során három saját filtert használtunk, külön érdekes. A bejegyzés elején felsoroltuk ezeket a saját filtereket, a C1 az maga a körkörös, amit a kikódolásra is használunk (C1 - C1). Természetesen nem tudja visszaadni az eredeti képet glitchmentesen, hiszen említettük, hogy a 8 szomszédos pixel értékéből, amiből építkezik, 4 értéke nem ismert. Egyfajta edge-detection hatást vélünk felfedezni itt. A C2-C1 esetében az elkódolás során a második saját filterünket próbáljuk kikódolni az első saját filterünkkel, egyszerűsítve, a C2 az RGB értékeinek eltérését három szomszédjától veszi, a pirosat a baltól, a zöldet a bal felsőtől, a kéket pedig a felsőtől.)
A C3-C1 meg hasonló, de itt a C3 egy inverz Average filter, vagyis jobboldali és alsó szomszédaiból építkezik (gyakorlatilag mindkét szomszédja ismeretlen a kikódolás balról és fentről bejárása miatt), ezért látszik úgy, mintha a zajban az edge-detection fordított irányú lenne az Average-C1-hez képest.
És végezetül így néz ki a normál RGB8 PNG (vegyes scanline filterrel), Custom 1 filterrel kikódolva:
PNG autopsy II.
Régóta dédelgetett, parkoltatott stb. vágyam, hogy megberheljem a PNG-t, de úgy igazán mélyen. S bár az AI azt állítja, hogy a PNG-be nem lehet hexeditorban csak úgy belepiszkítani, nekünk régebb mégis sikerült (gondolom az Irfan megengedőbb a sérült CRC-vel).
Kezdjük ezzel. UCNV japán művész, nagyon érdekes munkái vannak, de most csak a PNG-glitchjeire koncentráljunk. Amiről régebb nem találtunk futtatható programot (Rubyhoz még annyira se értünk mint a Pythonhoz), de most a Claude olyan python-progit ír nekünk, amilyet csak szeretnénk.
A PNG feldolgozási lánca (hol érdemes megtámadi):
- Raw Data (nyers pixelek byte értékei RGB vagy RGBA stb.) — ezt piszkálni valójában BMP glitch, nem PNG-specifikus
- Filtered Data — ide lehet nyúlni - erről fog szólni a bejegyzés
- Compressed Data — ide is lehet nyúlni
- Formatted PNG (checksummal) — ide NEM tanácsos, mert a sérült CRC miatt érvénytelennek látják a képszerkesztő programok, de - ilyet csináltunk már hexeditorban és van progi amivel megnyitható.
<Filter-byte><Pixel1-Red><Pixel1-Green><Pixel1-Blue><Pixel2-Red><Pixel2-Green><Pixel2-Blue> ... <Pixeln-Red><Pixeln-Green> <Pixeln-Blue>
Az 5 filter típus (amiből választ a képmentő program):
- None — nincs filter, minden pixel önálló, saját RGB értéket tartalmaz, egy bitcsere csak lokális zajt okoz
- Sub — az előző (bal oldali) pixel három bytejához viszonyít, és az eltérést tartalmazza → a pixel bytejaiban okozott hiba ezért jobbra "csorog", hiszen a következő pixel bytejai már ebből a sérültből fogja venni az adatot.
- Up — a fölötte lévő sorhoz viszonyít, az eltérést tartalmazza → függőlegesen csoroghat a hiba lefelé
- Average — a Sub és Up átlaga, a balra és fölötte levő szomszédainak átlagára támaszkodik → átlós, lágy, "üstökös-farok" jellegű, kevésbé "glitches", inkább szép színátmenet
- Paeth — a legkomplexebb algoritmus → a leglátványosabb, legkiterjedtebb glitch, miközben a kép formája még felismerhető marad
![]() |
| A megnyitott kép összes sorát az öt hivatalos és több saját filterrel lehet elmenteni |
![]() |
| Kis felbontású és JPG-nek mentett nézet, az eredeti jóval gazdagabb. |
Mint az elején láttuk, két helyen érdemes a PNG-t feszegetni, a filterezett adatnál, illetve a tömörített adatnál. Most már érthető, hogy miért van a PNG-glitcheknek ilyen sajátos megjelenése.
Ha a filterezett adatba piszkálunk, az akkor még eléggé pixelspecifikus, konkrét RGB-értéket ugyan nem (a None filtert leszámítva), de pixel-pozíciót, pixel blokkokat, még precízen tudunk támadni x,y koordináta alapján. A filterezett adatfolyamot képmentés során tömörítik (deflate - zlib) ez lesz a compressed data, amit chunkokba szervez, minden chunknak CRC-t számol, ezután már nem tudunk célzottan és közvetlenül támadni egyes pixeleket, vagy kép-zónákat a deflate algoritmus miatt. Elvileg a Compressed-adat támadás után az új IDAT miatt új CRC-t kell számoltatni, hogy a képnéző programok meg tudják jeleníteni. Mivel az Irfan elég megengedő, és mivel régebb Hex-editorban compressed adatot már hajlítgattunk PNG-ben, ezért ezt a vonalat most nem fejlesztjük tovább. Nem kell hozzá semmi, csak egy Hex-editor és szerencsés találat, hogy ne pont az életfontosságú adatba rondítsunk bele.
Ezeknek a támadásoknak a végrehajtására az AI írt nekünk egy cukor kis Python programot, ami lehetővé teszi pixel/pixelblokkok értékeinek a megváltoztatását. Illetve byte-mintázatok támadását és filterbyteok meghamisítását is. (Ezeket akár kombinálva.)
1. Pixelpozíció támadása
![]() |
| None filternél a 10,100,200 konkrét RGB értéket jelent, nem eltérést. Egyetlen pixelt átszínezett a barna mezőben, szinte nem is látszik.. |
![]() |
| Average esetén átlósan, üstökösen |
![]() |
| Paeth esetén meg a pozíciótól jobbra is, lefele is kumulálódik a hiba. |
2. Byteok-mintázatok támadása
![]() |
| 10 - 150 |
![]() |
| 7-150 |
![]() |
| 5-150 |
![]() |
| 3-150 |
![]() |
| 2-150 |































.png)





