From e05df39b3d07e1572eea73e895a170d86549b5ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=C5=99=C3=ADk?= Date: Sun, 21 Jan 2024 10:31:51 +0100 Subject: [PATCH] Added #2185 16bit MochiCrypt packer support Changed #2185 MochiCrypt no longer offered for auto decrypt, user needs to choose variant from "Use unpacker" menu --- CHANGELOG.md | 5 + .../flash/packers/MochiCryptPacker16Bit.java | 135 ++++++++++++++++++ ...Packer.java => MochiCryptPacker32Bit.java} | 10 +- .../flash/tags/DefineBinaryDataTag.java | 12 +- 4 files changed, 153 insertions(+), 9 deletions(-) create mode 100644 libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/packers/MochiCryptPacker16Bit.java rename libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/packers/{MochiCryptPacker.java => MochiCryptPacker32Bit.java} (94%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ea4cbfee..686755f0e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ All notable changes to this project will be documented in this file. - Folder preview for sounds - [#2176] Ignoring letter spacing on text search (only applies to global search, not to search inside text) - [#2179] Collapse all option for tree items +- [#2185] 16bit MochiCrypt packer support ### Fixed - Debugger - getting children of top level variables @@ -24,6 +25,9 @@ All notable changes to this project will be documented in this file. - [#2177] Leftover process when invalid SWF opened - now main window is shown - Opening files with "Open with FFDec" on windows did not use same instance +### Changed +- [#2185] MochiCrypt no longer offered for auto decrypt, user needs to choose variant from "Use unpacker" menu + ## [20.1.0] - 2023-12-30 ### Added - Configurable tab size (formatting must be set to use tabs) - default matches indent size of 3 @@ -3371,6 +3375,7 @@ Major version of SWF to XML export changed to 2. [alpha 7]: https://github.com/jindrapetrik/jpexs-decompiler/releases/tag/alpha7 [#2176]: https://www.free-decompiler.com/flash/issues/2176 [#2179]: https://www.free-decompiler.com/flash/issues/2179 +[#2185]: https://www.free-decompiler.com/flash/issues/2185 [#2149]: https://www.free-decompiler.com/flash/issues/2149 [#2172]: https://www.free-decompiler.com/flash/issues/2172 [#2174]: https://www.free-decompiler.com/flash/issues/2174 diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/packers/MochiCryptPacker16Bit.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/packers/MochiCryptPacker16Bit.java new file mode 100644 index 000000000..5f3fd28f7 --- /dev/null +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/packers/MochiCryptPacker16Bit.java @@ -0,0 +1,135 @@ +/* + * Copyright (C) 2010-2023 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.packers; + +import com.jpexs.decompiler.flash.tags.DefineBinaryDataTag; +import com.jpexs.helpers.Helper; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.zip.DeflaterOutputStream; +import java.util.zip.InflaterInputStream; + +/** + * + * @author JPEXS + */ +public class MochiCryptPacker16Bit implements Packer { + + @Override + public Boolean suitableForBinaryData(DefineBinaryDataTag dataTag) { + /*if (dataTag.getClassNames().contains("mochicrypt.Payload")) { + return true; + }*/ + return null; + } + + @Override + public boolean decrypt(InputStream is, OutputStream os) throws IOException { + byte[] payload = Helper.readStream(is); + if (!handleXor(payload)) { + return false; + } + try { + Helper.copyStreamEx(new InflaterInputStream(new ByteArrayInputStream(payload)), os); + } catch (IOException ex) { + return false; + } + + return true; + } + + private boolean handleXor(byte[] payload) { + if (payload.length < 16) { + return false; + } + int[] S = new int[256]; + int i = 0; + int j; + int k; + int n; + int u; + int v; + + n = payload.length - 16; + while (i < 256) { + S[i] = i; + i++; + } + j = 0; + i = 0; + while (i < 256) { + j = (j + S[i] + (payload[n + (i & 15)] & 0xff)) & 255; + u = S[i]; + S[i] = S[j]; + S[j] = u; + i++; + } + + if (n > 0x20000) { + n = 0x20000; + } + j = 0; + i = 0; + k = 0; + while (k < n) { + i = (i + 1) & 255; + u = S[i]; + j = (j + u) & 255; + v = S[j]; + S[i] = v; + S[j] = u; + payload[k] = (byte) ((payload[k] & 0xff) ^ S[u + v & 255]); + k++; + } + return true; + } + + @Override + public boolean encrypt(InputStream is, OutputStream os) throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + DeflaterOutputStream def = new DeflaterOutputStream(baos); + Helper.copyStreamEx(is, def); + def.finish(); + byte[] payload = baos.toByteArray(); + + if (!handleXor(payload)) { + return false; + } + + os.write(payload); + + return true; + } + + @Override + public String getName() { + return "MochiCrypt 16bit"; + } + + @Override + public Boolean suitableForData(byte[] data) { + return null; + } + + @Override + public String getIdentifier() { + return "mochicrypt16"; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/packers/MochiCryptPacker.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/packers/MochiCryptPacker32Bit.java similarity index 94% rename from libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/packers/MochiCryptPacker.java rename to libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/packers/MochiCryptPacker32Bit.java index 641438720..f73d2daa7 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/packers/MochiCryptPacker.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/packers/MochiCryptPacker32Bit.java @@ -30,13 +30,13 @@ import java.util.zip.InflaterInputStream; * * @author JPEXS */ -public class MochiCryptPacker implements Packer { +public class MochiCryptPacker32Bit implements Packer { @Override public Boolean suitableForBinaryData(DefineBinaryDataTag dataTag) { - if (dataTag.getClassNames().contains("mochicrypt.Payload")) { + /*if (dataTag.getClassNames().contains("mochicrypt.Payload")) { return true; - } + }*/ return null; } @@ -120,7 +120,7 @@ public class MochiCryptPacker implements Packer { @Override public String getName() { - return "MochiCrypt"; + return "MochiCrypt 32bit"; } @Override @@ -130,6 +130,6 @@ public class MochiCryptPacker implements Packer { @Override public String getIdentifier() { - return "mochicrypt"; + return "mochicrypt32"; } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineBinaryDataTag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineBinaryDataTag.java index 46476944f..552ef2ac7 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineBinaryDataTag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineBinaryDataTag.java @@ -23,7 +23,8 @@ import com.jpexs.decompiler.flash.configuration.Configuration; import com.jpexs.decompiler.flash.configuration.CustomConfigurationKeys; import com.jpexs.decompiler.flash.configuration.SwfSpecificCustomConfiguration; import com.jpexs.decompiler.flash.packers.HarmanAirPacker; -import com.jpexs.decompiler.flash.packers.MochiCryptPacker; +import com.jpexs.decompiler.flash.packers.MochiCryptPacker16Bit; +import com.jpexs.decompiler.flash.packers.MochiCryptPacker32Bit; import com.jpexs.decompiler.flash.packers.Packer; import com.jpexs.decompiler.flash.tags.base.BinaryDataInterface; import com.jpexs.decompiler.flash.tags.base.CharacterTag; @@ -71,7 +72,8 @@ public class DefineBinaryDataTag extends CharacterTag implements BinaryDataInter private PackedBinaryData sub; private static final Packer[] PACKERS = { - new MochiCryptPacker(), + new MochiCryptPacker16Bit(), + new MochiCryptPacker32Bit(), new HarmanAirPacker() }; @@ -133,8 +135,10 @@ public class DefineBinaryDataTag extends CharacterTag implements BinaryDataInter BinaryDataInterface binaryData = this; if (usedPacker != null) { unpack(usedPacker); - is = new ByteArrayInputStream(sub.getDataBytes().getRangeData()); - binaryData = sub; + if (sub != null) { + is = new ByteArrayInputStream(sub.getDataBytes().getRangeData()); + binaryData = sub; + } } SWF bswf = new SWF(is, null, "(SWF Data)", Configuration.parallelSpeedUp.get(), charset);