From 5bf48d14bb4535948eb01727a942127f8c0d2db2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=C5=99=C3=ADk?= Date: Wed, 18 Nov 2015 06:43:36 +0100 Subject: [PATCH] Password tags improvements Telemetry improvements --- .../src/com/jpexs/decompiler/flash/SWF.java | 58 +++++++++++++++++++ .../flash/tags/EnableDebugger2Tag.java | 3 +- .../flash/tags/EnableDebuggerTag.java | 3 +- .../flash/tags/EnableTelemetryTag.java | 42 ++++++++++++-- .../decompiler/flash/tags/ProtectTag.java | 3 +- .../flash/types/annotations/HashType.java | 26 +++++++++ .../flash/types/annotations/Password.java | 2 + 7 files changed, 128 insertions(+), 9 deletions(-) create mode 100644 libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/annotations/HashType.java diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java index 41e2a9f48..2797cdd27 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java @@ -82,6 +82,7 @@ import com.jpexs.decompiler.flash.tags.DefineSpriteTag; import com.jpexs.decompiler.flash.tags.DoInitActionTag; import com.jpexs.decompiler.flash.tags.EnableDebugger2Tag; import com.jpexs.decompiler.flash.tags.EnableDebuggerTag; +import com.jpexs.decompiler.flash.tags.EnableTelemetryTag; import com.jpexs.decompiler.flash.tags.EndTag; import com.jpexs.decompiler.flash.tags.ExportAssetsTag; import com.jpexs.decompiler.flash.tags.FileAttributesTag; @@ -536,6 +537,16 @@ public final class SWF implements SWFContainerItem, Timelined { return (fileAttributes != null && fileAttributes.actionScript3) || (fileAttributes == null && !getAbcList().isEmpty()); } + public MetadataTag getMetadata() { + for (Tag t : tags) { + if (t instanceof MetadataTag) { + return (MetadataTag) t; + } + } + + return null; + } + public FileAttributesTag getFileAttributes() { for (Tag t : tags) { if (t instanceof FileAttributesTag) { @@ -546,6 +557,15 @@ public final class SWF implements SWFContainerItem, Timelined { return null; } + public EnableTelemetryTag getEnableTelemetry() { + for (Tag t : tags) { + if (t instanceof EnableTelemetryTag) { + return (EnableTelemetryTag) t; + } + } + return null; + } + public int getNextCharacterId() { int max = 0; for (int characterId : getCharacters().keySet()) { @@ -3094,8 +3114,23 @@ public final class SWF implements SWFContainerItem, Timelined { * and debugfile instructions to AS3 code * * @param injectCode Modify AS3 code with debugfile / debugline ? + * @param decompileDir Directory to virtual decompile (will affect + * debugfile) */ public void enableDebugging(boolean injectCode, File decompileDir) { + enableDebugging(injectCode, decompileDir, false); + } + + /** + * Enables debugging. Adds tags to enable debugging and injects debugline + * and debugfile instructions to AS3 code. Optionally enables Telemetry + * + * @param injectCode Modify AS3 code with debugfile / debugline ? + * @param decompileDir Directory to virtual decompile (will affect + * debugfile) + * @param telemetry Enable telemetry info? + */ + public void enableDebugging(boolean injectCode, File decompileDir, boolean telemetry) { if (injectCode) { List packs = getAS3Packs(); @@ -3135,4 +3170,27 @@ public final class SWF implements SWFContainerItem, Timelined { tags.add(pos, new ProtectTag(this)); } } + + public boolean enableTelemetry(String password) { + + EnableTelemetryTag et = getEnableTelemetry(); + + if (et == null) { + FileAttributesTag fat = getFileAttributes(); + if (fat == null) { + return false; + } + int insertTo = tags.indexOf(fat) + 1; + MetadataTag mt = getMetadata(); + if (mt != null) { + insertTo = tags.indexOf(mt) + 1; + } + + et = new EnableTelemetryTag(this); + tags.add(insertTo, et); + } + et.setPassword(password); + //TODO: SWFs with tag 92 (signed) are unsupported + return true; + } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/EnableDebugger2Tag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/EnableDebugger2Tag.java index 721337fca..628cfa158 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/EnableDebugger2Tag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/EnableDebugger2Tag.java @@ -21,6 +21,7 @@ import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.tags.base.PasswordTag; import com.jpexs.decompiler.flash.types.BasicType; +import com.jpexs.decompiler.flash.types.annotations.HashType; import com.jpexs.decompiler.flash.types.annotations.Password; import com.jpexs.decompiler.flash.types.annotations.Reserved; import com.jpexs.decompiler.flash.types.annotations.SWFType; @@ -48,7 +49,7 @@ public class EnableDebugger2Tag extends Tag implements PasswordTag { /** * MD5 hash of password */ - @Password + @Password(type = HashType.MD5CRYPT) public String passwordHash; /** diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/EnableDebuggerTag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/EnableDebuggerTag.java index 6c45bf1d1..2371fc902 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/EnableDebuggerTag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/EnableDebuggerTag.java @@ -21,6 +21,7 @@ import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.tags.base.PasswordTag; import com.jpexs.decompiler.flash.types.BasicType; +import com.jpexs.decompiler.flash.types.annotations.HashType; import com.jpexs.decompiler.flash.types.annotations.Password; import com.jpexs.decompiler.flash.types.annotations.Reserved; import com.jpexs.decompiler.flash.types.annotations.SWFType; @@ -48,7 +49,7 @@ public class EnableDebuggerTag extends Tag implements PasswordTag { /** * MD5 hash of password */ - @Password + @Password(type = HashType.MD5CRYPT) public String passwordHash; /** diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/EnableTelemetryTag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/EnableTelemetryTag.java index 8a33c57d1..f29541992 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/EnableTelemetryTag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/EnableTelemetryTag.java @@ -19,13 +19,20 @@ package com.jpexs.decompiler.flash.tags; import com.jpexs.decompiler.flash.SWF; import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; +import com.jpexs.decompiler.flash.tags.base.PasswordTag; import com.jpexs.decompiler.flash.types.BasicType; +import com.jpexs.decompiler.flash.types.annotations.HashType; import com.jpexs.decompiler.flash.types.annotations.Optional; +import com.jpexs.decompiler.flash.types.annotations.Password; import com.jpexs.decompiler.flash.types.annotations.Reserved; import com.jpexs.decompiler.flash.types.annotations.SWFType; import com.jpexs.decompiler.flash.types.annotations.SWFVersion; import com.jpexs.helpers.ByteArrayRange; +import com.jpexs.helpers.Helper; import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; import java.util.logging.Level; import java.util.logging.Logger; @@ -35,7 +42,7 @@ import java.util.logging.Logger; * @author JPEXS */ @SWFVersion(from = 17) -public class EnableTelemetryTag extends Tag { +public class EnableTelemetryTag extends Tag implements PasswordTag { public static final int ID = 93; @@ -46,8 +53,8 @@ public class EnableTelemetryTag extends Tag { public int reserved; @Optional - @SWFType(value = BasicType.UI8, count = 32) - public byte[] passwordHash; + @Password(type = HashType.SHA256) + public String passwordHash; /** * Constructor @@ -56,7 +63,7 @@ public class EnableTelemetryTag extends Tag { */ public EnableTelemetryTag(SWF swf) { super(swf, ID, NAME, null); - passwordHash = new byte[32]; + passwordHash = sha256(""); } /** @@ -79,7 +86,7 @@ public class EnableTelemetryTag extends Tag { Logger.getLogger(EnableTelemetryTag.class.getName()).log(Level.WARNING, "PasswordHash should be 32 bytes"); } - passwordHash = sis.readBytesEx(32, "passwordHash"); + passwordHash = Helper.byteArrayToHex(sis.readBytesEx(32, "passwordHash")); } } @@ -93,7 +100,30 @@ public class EnableTelemetryTag extends Tag { public void getData(SWFOutputStream sos) throws IOException { sos.writeUB(16, reserved); if (passwordHash != null) { - sos.write(passwordHash); + sos.write(Helper.hexToByteArray(passwordHash)); } } + + private String sha256(String password) { + MessageDigest md; + + try { + md = MessageDigest.getInstance("SHA-256"); + md.update(password.getBytes("UTF-8")); + return Helper.byteArrayToHex(md.digest()); + } catch (NoSuchAlgorithmException | UnsupportedEncodingException ex) { + + } + return null; + } + + @Override + public void setPassword(String password) { + this.passwordHash = sha256(password); + } + + @Override + public boolean hasPassword(String password) { + return sha256(password).equals(this.passwordHash); + } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/ProtectTag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/ProtectTag.java index 8c9930b65..9530ec7e1 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/ProtectTag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/ProtectTag.java @@ -21,6 +21,7 @@ import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.tags.base.PasswordTag; import com.jpexs.decompiler.flash.types.BasicType; +import com.jpexs.decompiler.flash.types.annotations.HashType; import com.jpexs.decompiler.flash.types.annotations.Password; import com.jpexs.decompiler.flash.types.annotations.Reserved; import com.jpexs.decompiler.flash.types.annotations.SWFType; @@ -48,7 +49,7 @@ public class ProtectTag extends Tag implements PasswordTag { /** * MD5 hash of password */ - @Password + @Password(type = HashType.MD5CRYPT) public String passwordHash; /** diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/annotations/HashType.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/annotations/HashType.java new file mode 100644 index 000000000..3b5bf5241 --- /dev/null +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/annotations/HashType.java @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2010-2015 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.types.annotations; + +/** + * + * @author JPEXS + */ +public enum HashType { + + MD5CRYPT, SHA256 +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/annotations/Password.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/annotations/Password.java index 2a95bf119..6e9ede47e 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/annotations/Password.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/annotations/Password.java @@ -30,4 +30,6 @@ import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface Password { + + HashType type(); }