Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement swfimageexport & swfimagereplace #29

Open
Tylerian opened this issue May 30, 2014 · 9 comments
Open

Implement swfimageexport & swfimagereplace #29

Tylerian opened this issue May 30, 2014 · 9 comments

Comments

@Tylerian
Copy link

Hey CyberShadow,
there are many SWFs which have attached images.

Would be cool (and very useful) if you could make a tool to extract those images from the SWFs and replace it (like swfbinexport & swfbinreplace).

@Tylerian
Copy link
Author

I've not tested the code because I havn't a D Compiler here, but it should work.

swfimgexport
/*
 *  Copyright 2010, 2011 Vladimir Panteleev <vladimir@thecybershadow.net>
 *  This file is part of RABCDAsm.
 *
 *  RABCDAsm is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  RABCDAsm 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 General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with RABCDAsm.  If not, see <http://www.gnu.org/licenses/>.
 */

module swfimgexport;

import std.file;
import std.path;
import std.string;
import std.stdio;
import std.exception;
import swffile;

void main(string[] args)
{
    if (args.length == 1)
        throw new Exception("No file specified");
    foreach (arg; args[1..$])
        try
        {
            scope swf = SWFFile.read(cast(ubyte[])read(arg));
            bool found;
            foreach (ref tag; swf.tags)
                if (tag.type == TagType.DefineBitsJPEG2 || tag.type == TagType.DefineBitsJPEG3)
                {
                    found = true;
                    enforce(tag.data.length >= 6);
                    ushort id = *cast(short*)tag.data.ptr;
                    ubyte[] bin = tag.data[6..$];

                    if (bin[0] == 47 && bin[1] == 49 && bin[2] == 46)
                    {
                        std.file.write(format("%s-%d.gif", stripExtension(arg), id), bin);
                    }

                    else if (bin[1] == 80 && bin[2] == 78 && bin[3] == 71)
                    {
                        std.file.write(format("%s-%d.png", stripExtension(arg), id), bin);
                    }

                    else // Must be JPEG file since Flash only accepts 3 file formats!
                    {
                        std.file.write(format("%s-%d.jpg", stripExtension(arg), id), bin);
                    }
                }
            enforce(found, "No DefineBinaryData tags found");
        }
        catch (Exception e)
            writefln("Error while processing %s: %s", arg, e);
}
swfimgreplace
/*
 *  Copyright 2010, 2011, 2012 Vladimir Panteleev <vladimir@thecybershadow.net>
 *  This file is part of RABCDAsm.
 *
 *  RABCDAsm is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  RABCDAsm 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 General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with RABCDAsm.  If not, see <http://www.gnu.org/licenses/>.
 */

module swfimgreplace;

import std.file;
import std.conv;
import swffile;

void main(string[] args)
{
    if (args.length != 4)
        throw new Exception("Bad arguments. Usage: swfimgreplace file.swf id data.(png|gif|jpg)");
    auto swf = SWFFile.read(cast(ubyte[])read(args[1]));
    auto id = to!ushort(args[2]);
    foreach (ref tag; swf.tags)
        if ((tag.type == TagType.DefineBitsJPEG2 || tag.type == TagType.DefineBitsJPEG3) && tag.data.length >= 6 && *cast(short*)tag.data.ptr == id)
        {
            auto bin = cast(ubyte[])read(args[3]);
            tag.data = tag.data[0..6] ~ bin;
            tag.length = cast(uint)tag.data.length;
            write(args[1], swf.write());
            return;
        }
    throw new Exception("DefineBitsJPEG tag with specified ID not found in file");
}

@mildsunrise
Copy link

IMHO that's out of the scope of this project.
RABCDAsm was made to disassemble ActionScript on SWFs.

swfbinexport and swfbinreplace were provided because they often contain whole SWFs you can then disassemble.

Tools for extracting images (like the one you posted), vector paths, sounds, text, controls, etc. should be maintained in a side repository that consumes RABCDAsm as dependency.
That way we keep RABCDAsm's objective clear.

@ghost
Copy link

ghost commented May 30, 2014

For these kinds of tools it would be awesome if RABCDAsm was available as a dub package.

On 30. Mai 2014 11:17:04 MESZ, Xavier Mendez notifications@github.com wrote:

IMHO that's out of the scope of this project.
RABCDAsm was made to disassemble ActionScript on SWFs.

swfbinexport and swfbinreplace were provided because they often
contain whole SWFs you can then disassemble.

Tools for extracting images (like the one you posted), vector paths,
sounds, text, controls, etc. should be maintained in a side repository
that consumes RABCDAsm as dependency.
That way we keep RABCDAsm's objective clear.


Reply to this email directly or view it on GitHub:
#29 (comment)

@mildsunrise
Copy link

@bossfong You're right.

@mildsunrise
Copy link

It's still easy to consume RABCDAsm as dependency using a submodule, like I did on redasm-abc.

@CyberShadow
Copy link
Owner

As more time passes, I moreso regret implementing RABCDAsm as a package of programs, as opposed to a single program with multiple subcommands (like e.g. git, svn etc.). The current setup is wasteful in disk space and build time.

At this point, I'm not comfortable with adding yet another 2 programs to the repertoire, but I'm thinking for RABCDAsm 2.0 to have only one binary (rabcd) with the existing programs implemented as subcommands.

For these kinds of tools it would be awesome if RABCDAsm was available as a dub package.

If anyone would like to contribute a dub.json file, please go ahead, as I don't use Dub.

@mildsunrise
Copy link

@CyberShadow I'm not sure. Git tools are mostly connected together, i.e. a git push without a prior git checkout, git add, git commit doesn't make sense.

However RABCDAsm is a set of tools that are pretty independent of each other, the exception being rabcasm and rabcdasm which do work in pair. The rest of the tools are simple SWF manipulators like the SWFTools package, which also has separate commands (swfextract, swfdump, swfstrings, etc.).

@mildsunrise
Copy link

Instead of subcommands, I'd recommend having just two separate tools.

rabc is the ABC [dis]assembler, with a similar syntax to compression tools like gzip, xz:

# Disassemble ABC for the first time
rabc -d <block.abc> [-o <directory>]
# Then, assemble ABC back
rabc <main.asasm> [-o <block.abc>]

rswf is to manipulate resources in an SWF:

# Extract all resources of a given type (ABC, binary or image)
rswf -x <file.swf> [-a -b -i]
# Extract single resource by offset or ID
rswf -x <file.swf> (-o <offset> | -e <id>) <file>
# Replace single resource by offset or ID
rswf -r <file.swf> (-o <offset> | -e <id>) <file>

@CyberShadow
Copy link
Owner

Another idea is to do what busybox does: hard link a single binary to a bunch of file names, then make it so that the invoked program name indicates the command to run.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants