Scout Password追加ツール
SWF に Scout のパスワードを追加するやつ。
/**
* Copyright bkzen ( http://wonderfl.net/user/bkzen )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/lYcS
*/
package
{
import com.bit101.components.HBox;
import com.bit101.components.InputText;
import com.bit101.components.Label;
import com.bit101.components.PushButton;
import com.bit101.components.VBox;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.FocusEvent;
import flash.events.MouseEvent;
import flash.net.FileFilter;
import flash.net.FileReference;
/**
* SWF に Scout のパスワードを追加するやつ。 パスワード強制上書きモードつき(こっそり)
* @author jc at bk-zen.com
*/
[SWF (backgroundColor = "0xFFFFFF", frameRate = "30", width = "465", height = "465")]
public class Test158 extends Sprite
{
private var loadBtn:PushButton;
private var telemBtn:PushButton;
private var passInput:InputText;
private var loadFile: FileReference;
private var saveFile: FileReference;
private var fileLoaded: Boolean;
private var resultLabel:Label;
private var reader:SWFReader;
private var saveBtn:PushButton;
private var vbox:VBox;
public function Test158()
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e: Event = null): void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
vbox = new VBox(this, 10, 10);
new Label(vbox, 0, 0, "Telemetry Tool version 2");
loadBtn = new PushButton(vbox, 0, 0, "load", onClickLoad);
passInput = new InputText(vbox, 0, 0, "password", onInputText);
telemBtn = new PushButton(vbox, 0, 0, "Telemetry", onClickTelemetry);
resultLabel = new Label(vbox, 0, 0, "result");
saveBtn = new PushButton(vbox, 0, 0, "save", onClickSave);
saveBtn.enabled = telemBtn.enabled = false;
loadFile = new FileReference();
saveFile = new FileReference();
loadFile.addEventListener(Event.SELECT, onSelectFile);
loadFile.addEventListener(Event.COMPLETE, onCompLoad);
passInput.textField.addEventListener(FocusEvent.FOCUS_IN, onFocusIn);
//passInput.textField.addEventListener(FocusEvent.FOCUS_OUT, onFocusOut);
}
private function onClickLoad(e: MouseEvent): void
{
loadFile.browse([new FileFilter("swf file", "*.swf", "*.swf")]);
}
private function onSelectFile(e:Event):void
{
fileLoaded = false;
saveBtn.enabled = false;
loadFile.load();
}
private function onCompLoad(e: Event): void
{
fileLoaded = true;
var pass: String = passInput.text;
//telemBtn.enabled = (fileLoaded && pass && pass != "password");
//telemBtn.enabled = fileLoaded;
telemBtn.enabled = fileLoaded && pass != "password";
}
private function onFocusIn(e:FocusEvent):void
{
passInput.textField.removeEventListener(FocusEvent.FOCUS_IN, onFocusIn);
if (passInput.text == "password")
passInput.text = "";
telemBtn.enabled = fileLoaded;
}
/*
private function onFocusOut(e:FocusEvent):void
{
if (passInput.text == "")
passInput.text = "password";
}
*/
private function onInputText(e: Event):void
{
//telemBtn.enabled = (fileLoaded && pass && pass != "password");
telemBtn.enabled = fileLoaded;
}
private function onClickTelemetry(e: MouseEvent): void
{
try
{
reader = new SWFReader(loadFile.data);
reader.init(passInput.text);
if (reader.replaced)
{
resultLabel.text = "###### password was changed #######";
}
else
{
resultLabel.text = "telemetry";
}
saveBtn.enabled = true;
}
catch (err: Error)
{
resultLabel.text = err.message;
trace(err.getStackTrace());
}
}
private function onClickSave(e: MouseEvent): void
{
saveFile.save(reader.output, loadFile.name);
}
}
}
import com.adobe.crypto.SHA256;
import flash.utils.ByteArray;
import flash.utils.Endian;
class SWFReader
{
private var _bytes: ByteArray;
private var _output: ByteArray;
private var _replaced: Boolean;
function SWFReader(bytes: ByteArray)
{
_bytes = bytes;
_bytes.endian = Endian.LITTLE_ENDIAN;
}
public function init(password: String): void
{
readHeader();
readTag(password);
}
private function readHeader(): void
{
var signature: String = _bytes.readUTFBytes(3);
var version: int = _bytes.readByte();
var fileSize: int = _bytes.readUnsignedInt();
if (version < 0x09)
{
_bytes.clear();
_bytes = null;
throw new Error("swf version error");
}
switch (signature)
{
case "FWS":
break;
case "CWS":
var p: uint = _bytes.position;
_bytes = decomp(_bytes);
_bytes.endian = Endian.LITTLE_ENDIAN;
_bytes.position = p;
break;
case "ZWS":
_bytes.clear();
_bytes = null;
throw new Error("not supports LZMA");
break;
default:
_bytes.clear();
_bytes = null;
throw new Error("Bad SWF");
break;
}
if (_bytes == null)
return;
//
var b: ByteArray = new ByteArray()
_output = new ByteArray();
_output.endian = Endian.LITTLE_ENDIAN;
_output.writeUTFBytes("FWS");
_output.writeByte(version);
_output.writeUnsignedInt(0); // dummy;
var r: int = _bytes.readByte();
var nbits: int = ((r >> 3) << 2) - 3;
_bytes.position --;
_bytes.readBytes(b, 0, (nbits >> 3) + 1);
b.position = 0;
_output.writeBytes(b);//rect
_output.writeUnsignedInt(_bytes.readUnsignedInt()); // frameRate and numFrame
_output.writeByte(0);
_bytes.position++;
}
private function readTag(password: String): void
{
if (_output == null)
return;
var b: ByteArray = new ByteArray(), isWait: Boolean, tmp: uint, is63: Boolean;
while (true)
{
var pos: uint = _bytes.position;
var header: uint = _bytes.readUnsignedShort();
var tagCode: uint = header >> 6;
var tagLength: uint = header & 0x3F;
is63 = false;
if (tagLength == 0x3F)
is63 = true, tagLength = _bytes.readInt();
//
_bytes.position = pos;
b.length = 0, b.writeByte(header & 0xFF), b.writeByte((header >> 0x08) & 0xFF); // writeUnsignedShort
_bytes.readBytes(b, 0, tagLength + 2 + (is63 ? 4 : 0));
if (isWait)
{
var writeBefore: Boolean = tagCode == 77;
if (writeBefore)
{
_output.writeBytes(b);
}
addTelemetryTag(password);
if (!writeBefore)
{
_output.writeBytes(b);
}
isWait = false;
}
else if (tagCode == 93)
{
_replaced = true;
}
else if (tagCode == 92)
{
_bytes.clear(), _bytes = null;
_output.clear(), _output = null;
throw new Error("Bad SWF : Signed SWFs are not supported");
break;
}
else if (tagCode == 69)
{
_output.writeBytes(b);
isWait = true;
}
else if (tagCode == 0)
{
_output.writeShort(0);
break;
}
else
{
_output.writeBytes(b);
}
}
_output.position = 4;
_output.writeUnsignedInt(_output.length);
_output = comp(_output);
}
private function addTelemetryTag(password: String): void
{
SHA256.hashToBase64(password);
var code: int = 93, length: int, tmp: uint;
if (password == "")
length = 2;
else
length = SHA256.digest.length + 2;
if (length >= 63)
{
tmp = (code << 6) | 0x3F;
_output.writeByte(tmp & 0xFF);
_output.writeByte((tmp >> 8) & 0xFF);
_output.writeUnsignedInt(length);
}
else
{
tmp = (code << 6) | length;
_output.writeByte(tmp & 0xFF);
_output.writeByte((tmp >> 8) & 0xFF);
}
_output.writeShort(0);
if (password != "")
_output.writeBytes(SHA256.digest);
}
private static function comp(data: ByteArray): ByteArray
{
var h: ByteArray = new ByteArray();
var d: ByteArray = new ByteArray();
var c: ByteArray = new ByteArray();
h.writeBytes(data, 3, 5);
d.writeBytes(data, 8);
d.compress();
c.writeUTFBytes("CWS");
c.writeBytes(h);
c.writeBytes(d);
return c;
}
private static function decomp(data: ByteArray): ByteArray
{
var h: ByteArray = new ByteArray();
var d: ByteArray = new ByteArray();
var c: ByteArray = new ByteArray();
h.writeBytes(data, 3, 5);
c.writeBytes(data, 8);
c.uncompress();
d.writeUTFBytes("FWS");
d.writeBytes(h);
d.writeBytes(c);
return d;
}
public function get output(): ByteArray { return _output; }
public function get replaced(): Boolean { return _replaced; }
}