Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1f0ef64b83 | ||
|
|
701e5b6f80 | ||
|
|
fc46ad02e9 | ||
|
|
e7a5dd92c6 | ||
|
|
352456d257 | ||
|
|
d6544ae7cb | ||
|
|
37cd4b415b | ||
|
|
62d0756dbc |
@@ -1,6 +1,13 @@
|
||||
RABCDAsm Changelog
|
||||
==================
|
||||
|
||||
RABCDAsm v1.8 (2011.07.06)
|
||||
--------------------------
|
||||
|
||||
* Fixed handling of orphan methods with multiple references
|
||||
* Treat out-of-bounds namespace/multiname indices as null
|
||||
* Documentation updates
|
||||
|
||||
RABCDAsm v1.7 (2011.06.14)
|
||||
--------------------------
|
||||
|
||||
|
||||
@@ -102,7 +102,7 @@ script-level methods.
|
||||
To assemble the `.asasm` files back, and update the SWF file:
|
||||
|
||||
rabcasm file-0/file-0.main.asasm
|
||||
abcreplace file-0.swf 0 file-0/file-0.main.abc
|
||||
abcreplace file.swf 0 file-0/file-0.main.abc
|
||||
|
||||
The second `abcreplace` argument represents the index of the ABC block in the
|
||||
SWF file, and corresponds to the number in the filename created by `abcexport`.
|
||||
@@ -416,11 +416,15 @@ RABCDAsm users.
|
||||
oSession.SaveResponseBody(path);
|
||||
}
|
||||
|
||||
A more robust version of the above snippet is available as a Fiddler plugin
|
||||
[here][FiddlerAutoCapture].
|
||||
|
||||
Once you have edited a SWF file, you can use Fiddler's [AutoResponder][] to
|
||||
replace the original file with your modified version.
|
||||
|
||||
[Fiddler]: http://www.fiddler2.com/fiddler2/
|
||||
[AutoResponder]: http://www.fiddler2.com/fiddler2/help/AutoResponder.asp
|
||||
[FiddlerAutoCapture]: https://github.com/CyberShadow/FiddlerAutoCapture
|
||||
|
||||
Limitations
|
||||
===========
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
module abcfile;
|
||||
|
||||
import std.string : format; // exception formatting
|
||||
import std.conv;
|
||||
import std.exception;
|
||||
|
||||
/**
|
||||
@@ -222,7 +223,7 @@ class ABCFile
|
||||
uint index; /// instruction index
|
||||
int offset; /// signed offset relative to said instruction
|
||||
}
|
||||
private int absoluteOffset; /// internal temporary value used during reading and writing
|
||||
private ptrdiff_t absoluteOffset; /// internal temporary value used during reading and writing
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1280,18 +1281,18 @@ private final class ABCReader
|
||||
r.instructions = null;
|
||||
|
||||
size_t len = readU30();
|
||||
uint[] instructionAtOffset = new uint[len];
|
||||
auto instructionAtOffset = new uint[len];
|
||||
r.rawBytes = buf[pos..pos+len];
|
||||
|
||||
void translateLabel(ref ABCFile.Label label)
|
||||
{
|
||||
int absoluteOffset = label.absoluteOffset;
|
||||
int instructionOffset = absoluteOffset;
|
||||
auto absoluteOffset = label.absoluteOffset;
|
||||
auto instructionOffset = absoluteOffset;
|
||||
while (true)
|
||||
{
|
||||
if (instructionOffset >= cast(int)len)
|
||||
if (instructionOffset >= len)
|
||||
{
|
||||
label.index = r.instructions.length;
|
||||
label.index = to!uint(r.instructions.length);
|
||||
instructionOffset = len;
|
||||
break;
|
||||
}
|
||||
@@ -1308,23 +1309,23 @@ private final class ABCReader
|
||||
}
|
||||
instructionOffset--;
|
||||
}
|
||||
label.offset = absoluteOffset-instructionOffset;
|
||||
label.offset = to!int(absoluteOffset-instructionOffset);
|
||||
}
|
||||
|
||||
size_t start = pos;
|
||||
size_t end = pos + len;
|
||||
|
||||
uint offset() { return pos - start; }
|
||||
size_t offset() { return pos - start; }
|
||||
|
||||
try
|
||||
{
|
||||
instructionAtOffset[] = uint.max;
|
||||
uint[] instructionOffsets;
|
||||
size_t[] instructionOffsets;
|
||||
while (pos < end)
|
||||
{
|
||||
uint instructionOffset = offset;
|
||||
auto instructionOffset = offset;
|
||||
scope(failure) pos = start + instructionOffset;
|
||||
instructionAtOffset[instructionOffset] = r.instructions.length;
|
||||
instructionAtOffset[instructionOffset] = to!uint(r.instructions.length);
|
||||
ABCFile.Instruction instruction;
|
||||
instruction.opcode = cast(Opcode)readU8();
|
||||
instruction.arguments.length = opcodeInfo[instruction.opcode].argumentTypes.length;
|
||||
@@ -1517,7 +1518,6 @@ private final class ABCWriter
|
||||
writeU8(cast(ubyte)(v>>16));
|
||||
}
|
||||
|
||||
/// Note: may return values larger than 0xFFFFFFFF.
|
||||
void writeU32(ulong v)
|
||||
{
|
||||
if ( v < 128)
|
||||
@@ -1557,8 +1557,9 @@ private final class ABCWriter
|
||||
writeU32(cast(ulong)v);
|
||||
}
|
||||
|
||||
void writeU30(uint v)
|
||||
void writeU30(ulong v)
|
||||
{
|
||||
enforce(v < (1<<30));
|
||||
writeU32(v);
|
||||
}
|
||||
|
||||
@@ -1756,9 +1757,9 @@ private final class ABCWriter
|
||||
writeU30(v.initScopeDepth);
|
||||
writeU30(v.maxScopeDepth);
|
||||
|
||||
uint[] instructionOffsets = new uint[v.instructions.length+1];
|
||||
auto instructionOffsets = new size_t[v.instructions.length+1];
|
||||
|
||||
uint resolveLabel(ref ABCFile.Label label) { return instructionOffsets[label.index]+label.offset; }
|
||||
ptrdiff_t resolveLabel(ref ABCFile.Label label) { return instructionOffsets[label.index]+label.offset; }
|
||||
|
||||
{
|
||||
// we don't know the length before writing all the instructions - swap buffer with a temporary one
|
||||
@@ -1768,12 +1769,12 @@ private final class ABCWriter
|
||||
buf = methodBuf[];
|
||||
pos = 0;
|
||||
|
||||
struct Fixup { ABCFile.Label target; uint pos, base; }
|
||||
struct Fixup { ABCFile.Label target; size_t pos, base; }
|
||||
Fixup[] fixups;
|
||||
|
||||
foreach (ii, ref instruction; v.instructions)
|
||||
{
|
||||
uint instructionOffset = pos;
|
||||
auto instructionOffset = pos;
|
||||
instructionOffsets[ii] = instructionOffset;
|
||||
|
||||
writeU8(instruction.opcode);
|
||||
@@ -1837,7 +1838,7 @@ private final class ABCWriter
|
||||
foreach (ref fixup; fixups)
|
||||
{
|
||||
pos = fixup.pos;
|
||||
writeS24(resolveLabel(fixup.target)-fixup.base);
|
||||
writeS24(to!int(cast(ptrdiff_t)(resolveLabel(fixup.target)-fixup.base)));
|
||||
}
|
||||
|
||||
auto code = buf;
|
||||
|
||||
+10
-10
@@ -622,10 +622,10 @@ private final class ABCtoAS
|
||||
r.arguments[i].stringv = abc.strings[instruction.arguments[i].index];
|
||||
break;
|
||||
case OpcodeArgumentType.Namespace:
|
||||
r.arguments[i].namespacev = namespaces[instruction.arguments[i].index];
|
||||
r.arguments[i].namespacev = namespaces.checkedGet(instruction.arguments[i].index);
|
||||
break;
|
||||
case OpcodeArgumentType.Multiname:
|
||||
r.arguments[i].multinamev = multinames[instruction.arguments[i].index];
|
||||
r.arguments[i].multinamev = multinames.checkedGet(instruction.arguments[i].index);
|
||||
break;
|
||||
case OpcodeArgumentType.Class:
|
||||
r.arguments[i].classv = classes.checkedGet(instruction.arguments[i].index);
|
||||
@@ -655,7 +655,7 @@ private final class ABCtoAS
|
||||
as.majorVersion = abc.majorVersion;
|
||||
|
||||
namespaces.length = abc.namespaces.length;
|
||||
foreach (i, ref namespace; abc.namespaces)
|
||||
foreach (uint i, ref namespace; abc.namespaces)
|
||||
if (i)
|
||||
namespaces[i] = convertNamespace(namespace, i);
|
||||
|
||||
@@ -685,7 +685,7 @@ private final class ABCtoAS
|
||||
instances[i] = convertInstance(instance);
|
||||
|
||||
classes.length = abc.classes.length;
|
||||
foreach (i, ref vclass; abc.classes)
|
||||
foreach (uint i, ref vclass; abc.classes)
|
||||
classes[i] = convertClass(vclass, i);
|
||||
|
||||
as.scripts.length = abc.scripts.length;
|
||||
@@ -798,7 +798,7 @@ private final class AStoABC
|
||||
all.sort;
|
||||
enum { NullOffset = haveNull ? 1 : 0 }
|
||||
values.length = all.length + NullOffset;
|
||||
foreach (i, ref c; all)
|
||||
foreach (uint i, ref c; all)
|
||||
{
|
||||
pool[cast(I)c.value].index = i + NullOffset;
|
||||
values[i + NullOffset] = c.value;
|
||||
@@ -838,7 +838,7 @@ private final class AStoABC
|
||||
auto rp = p in pool;
|
||||
if (rp is null)
|
||||
{
|
||||
pool[p] = Entry(1, p, pool.length);
|
||||
pool[p] = Entry(1, p, to!uint(pool.length));
|
||||
return true;
|
||||
}
|
||||
else
|
||||
@@ -887,7 +887,7 @@ private final class AStoABC
|
||||
topSort:
|
||||
|
||||
// update indices
|
||||
foreach (j, e; all)
|
||||
foreach (uint j, e; all)
|
||||
e.index = j;
|
||||
|
||||
foreach (ref a; pool)
|
||||
@@ -1482,13 +1482,13 @@ private final class AStoABC
|
||||
break;
|
||||
case OpcodeArgumentType.Class:
|
||||
if (instruction.arguments[i].classv is null)
|
||||
r.arguments[i].index = abc.classes.length;
|
||||
r.arguments[i].index = to!uint(abc.classes.length);
|
||||
else
|
||||
r.arguments[i].index = classes.get(instruction.arguments[i].classv);
|
||||
break;
|
||||
case OpcodeArgumentType.Method:
|
||||
if (instruction.arguments[i].methodv is null)
|
||||
r.arguments[i].index = abc.methods.length;
|
||||
r.arguments[i].index = to!uint(abc.methods.length);
|
||||
else
|
||||
r.arguments[i].index = methods.get(instruction.arguments[i].methodv);
|
||||
break;
|
||||
@@ -1562,7 +1562,7 @@ private bool contains(T)(T[] arr, T val)
|
||||
return false;
|
||||
}
|
||||
|
||||
private T checkedGet(T)(T[] array, uint index, T def = null)
|
||||
private T checkedGet(T)(T[] array, uint index, T def = T.init)
|
||||
{
|
||||
return index < array.length ? array[index] : def;
|
||||
}
|
||||
|
||||
+8
-8
@@ -76,7 +76,7 @@ final class Assembler
|
||||
|
||||
string positionStr()
|
||||
{
|
||||
auto lines = splitlines(buf);
|
||||
auto lines = splitLines(buf);
|
||||
foreach (i, line; lines)
|
||||
if (pos <= line.ptr + line.length)
|
||||
return format("%s(%d,%d)", filename, i+1, pos-line.ptr+1);
|
||||
@@ -992,7 +992,7 @@ final class Assembler
|
||||
break;
|
||||
if (peekChar() == ':')
|
||||
{
|
||||
addUnique!("label")(labels, word, instructions.length);
|
||||
addUnique!("label")(labels, word, to!uint(instructions.length));
|
||||
skipChar(); // :
|
||||
continue;
|
||||
}
|
||||
@@ -1008,7 +1008,7 @@ final class Assembler
|
||||
instruction.opcode = *popcode;
|
||||
auto argTypes = opcodeInfo[instruction.opcode].argumentTypes;
|
||||
instruction.arguments.length = argTypes.length;
|
||||
foreach (i, type; argTypes)
|
||||
foreach (uint i, type; argTypes)
|
||||
{
|
||||
final switch (type)
|
||||
{
|
||||
@@ -1044,22 +1044,22 @@ final class Assembler
|
||||
instruction.arguments[i].multinamev = readMultiname();
|
||||
break;
|
||||
case OpcodeArgumentType.Class:
|
||||
localClassFixups ~= LocalFixup(files[0].position, instructions.length, i, readString());
|
||||
localClassFixups ~= LocalFixup(files[0].position, to!uint(instructions.length), i, readString());
|
||||
break;
|
||||
case OpcodeArgumentType.Method:
|
||||
localMethodFixups ~= LocalFixup(files[0].position, instructions.length, i, readString());
|
||||
localMethodFixups ~= LocalFixup(files[0].position, to!uint(instructions.length), i, readString());
|
||||
break;
|
||||
|
||||
case OpcodeArgumentType.JumpTarget:
|
||||
case OpcodeArgumentType.SwitchDefaultTarget:
|
||||
jumpFixups ~= LocalFixup(files[0].position, instructions.length, i, readWord());
|
||||
jumpFixups ~= LocalFixup(files[0].position, to!uint(instructions.length), i, readWord());
|
||||
break;
|
||||
|
||||
case OpcodeArgumentType.SwitchTargets:
|
||||
string[] switchTargetLabels = readList!('[', ']', readWord, false)();
|
||||
instruction.arguments[i].switchTargets.length = switchTargetLabels.length;
|
||||
foreach (li, s; switchTargetLabels)
|
||||
switchFixups ~= LocalFixup(files[0].position, instructions.length, i, s, li);
|
||||
foreach (uint li, s; switchTargetLabels)
|
||||
switchFixups ~= LocalFixup(files[0].position, to!uint(instructions.length), i, s, li);
|
||||
break;
|
||||
}
|
||||
if (i < argTypes.length-1)
|
||||
|
||||
+1
-1
@@ -138,7 +138,7 @@ struct HashDataHandler
|
||||
|
||||
template getRawMixin(string ptr, string len)
|
||||
{
|
||||
enum getRawMixin = "handler.hasher.Add(" ~ ptr ~ ", " ~ len ~ ");";
|
||||
enum getRawMixin = "handler.hasher.Add(" ~ ptr ~ ", to!int(" ~ len ~ "));";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -31,7 +31,7 @@ version(DigitalMars)
|
||||
else
|
||||
const DEFAULT_COMPILER = "gdmd";
|
||||
|
||||
const DEFAULT_FLAGS = "-O -inline";
|
||||
const DEFAULT_FLAGS = "-w -O -inline";
|
||||
|
||||
import std.process;
|
||||
import std.string;
|
||||
|
||||
+13
-10
@@ -20,6 +20,7 @@ module disassembler;
|
||||
|
||||
import std.file;
|
||||
import std.string;
|
||||
import std.array;
|
||||
import std.conv;
|
||||
import std.exception;
|
||||
import std.algorithm;
|
||||
@@ -238,8 +239,10 @@ final class RefBuilder : ASTraitsVisitor
|
||||
}
|
||||
else
|
||||
{
|
||||
enforce(p !in contexts, format("Duplicate object reference: ", contexts[p], " and ", context));
|
||||
contexts[p] = context.dup;
|
||||
if (p in contexts)
|
||||
contexts[p] = [ContextItem("multireferenced")];
|
||||
else
|
||||
contexts[p] = context.dup;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -299,7 +302,7 @@ final class RefBuilder : ASTraitsVisitor
|
||||
{
|
||||
again:
|
||||
string subpath = join(dirSegments[0..l+1], "/");
|
||||
string subpathl = tolower(subpath);
|
||||
string subpathl = toLower(subpath);
|
||||
string* canonicalp = subpathl in filenameMappings;
|
||||
if (canonicalp && *canonicalp != subpath)
|
||||
{
|
||||
@@ -479,7 +482,7 @@ final class RefBuilder : ASTraitsVisitor
|
||||
assert(context.length > 0, "No context");
|
||||
//assert(ns.name is null, "Named private namespace");
|
||||
|
||||
int myPos = context.length;
|
||||
auto myPos = context.length;
|
||||
foreach (i, ref item; context)
|
||||
if (item.type == ContextItem.Type.Multiname && item.multiname.vQName.ns == ns)
|
||||
{
|
||||
@@ -632,7 +635,7 @@ final class Disassembler
|
||||
uint up = 0;
|
||||
while (!full.startsWith(base))
|
||||
base = dirname(base), up++;
|
||||
string rel = repeat("../", up) ~ full[base.length+1..$];
|
||||
string rel = replicate("../", up) ~ full[base.length+1..$];
|
||||
|
||||
StringBuilder sb = new StringBuilder(full);
|
||||
callback(sb);
|
||||
@@ -675,7 +678,7 @@ final class Disassembler
|
||||
sb.newLine();
|
||||
sb.newLine();
|
||||
|
||||
foreach (i, script; as.scripts)
|
||||
foreach (uint i, script; as.scripts)
|
||||
{
|
||||
newInclude(sb, refs.scripts.getFilename(script, "script"), (StringBuilder sb) {
|
||||
dumpScript(sb, script, i);
|
||||
@@ -777,7 +780,7 @@ final class Disassembler
|
||||
static double forceDouble(double d) { static double n; n = d; return n; }
|
||||
if (s != "nan" && s != "inf" && s != "-inf")
|
||||
{
|
||||
for (int i=s.length-1; i>0; i--)
|
||||
foreach_reverse (i; 1..s.length)
|
||||
if (s[i]>='0' && s[i]<='8' && forceDouble(to!double(s[0..i] ~ cast(char)(s[i]+1)))==v)
|
||||
s = s[0..i] ~ cast(char)(s[i]+1);
|
||||
while (s.length>2 && s[$-1]!='.' && forceDouble(to!double(s[0..$-1]))==v)
|
||||
@@ -1285,7 +1288,7 @@ final class Disassembler
|
||||
}
|
||||
|
||||
bool extraNewLine = false;
|
||||
foreach (ii, ref instruction; instructions)
|
||||
foreach (uint ii, ref instruction; instructions)
|
||||
{
|
||||
if (extraNewLine)
|
||||
sb.newLine();
|
||||
@@ -1296,7 +1299,7 @@ final class Disassembler
|
||||
auto argTypes = opcodeInfo[instruction.opcode].argumentTypes;
|
||||
if (argTypes.length)
|
||||
{
|
||||
for (int i=opcodeInfo[instruction.opcode].name.length; i<20; i++)
|
||||
foreach (i; opcodeInfo[instruction.opcode].name.length..20)
|
||||
sb ~= ' ';
|
||||
foreach (i, type; argTypes)
|
||||
{
|
||||
@@ -1369,7 +1372,7 @@ final class Disassembler
|
||||
}
|
||||
sb.newLine();
|
||||
}
|
||||
checkLabel(instructions.length);
|
||||
checkLabel(to!uint(instructions.length));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
-2
@@ -16,6 +16,8 @@
|
||||
|
||||
module murmurhash2a;
|
||||
|
||||
import std.conv;
|
||||
|
||||
struct MurmurHash2A
|
||||
{
|
||||
private static string mmix(string h, string k) { return "{ "~k~" *= m; "~k~" ^= "~k~" >> r; "~k~" *= m; "~h~" *= m; "~h~" ^= "~k~"; }"; }
|
||||
@@ -67,8 +69,8 @@ public:
|
||||
void Add(ref ubyte v) { Add(&v, v.sizeof); }
|
||||
void Add(ref int v) { Add(&v, v.sizeof); }
|
||||
void Add(ref uint v) { Add(&v, v.sizeof); }
|
||||
void Add(string s) { Add(s.ptr, s.length); }
|
||||
void Add(ubyte[] s) { Add(s.ptr, s.length); }
|
||||
void Add(string s) { Add(s.ptr, to!uint(s.length)); }
|
||||
void Add(ubyte[] s) { Add(s.ptr, to!uint(s.length)); }
|
||||
|
||||
private:
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
module swffile;
|
||||
|
||||
import std.zlib;
|
||||
import std.conv;
|
||||
import zlibx;
|
||||
|
||||
/**
|
||||
@@ -243,13 +244,13 @@ private final class SWFWriter
|
||||
{
|
||||
u |= 0x3F;
|
||||
buf ~= toArray(u);
|
||||
uint l = tag.data.length;
|
||||
uint l = to!uint(tag.data.length);
|
||||
buf ~= toArray(l);
|
||||
}
|
||||
buf ~= tag.data;
|
||||
}
|
||||
|
||||
swf.header.fileLength = 8 + buf.length;
|
||||
swf.header.fileLength = to!uint(8 + buf.length);
|
||||
if (swf.header.signature[0] == 'C')
|
||||
buf = cast(ubyte[])compress(buf, 9);
|
||||
buf = toArray(swf.header) ~ buf;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
module zlibx;
|
||||
|
||||
import std.zlib, etc.c.zlib;
|
||||
import std.zlib, etc.c.zlib, std.conv;
|
||||
static import etc.c.zlib;
|
||||
alias std.zlib.Z_SYNC_FLUSH Z_SYNC_FLUSH;
|
||||
|
||||
@@ -15,10 +15,10 @@ ubyte[] exactUncompress(ubyte[] srcbuf, size_t destlen)
|
||||
uint err;
|
||||
|
||||
zs.next_in = srcbuf.ptr;
|
||||
zs.avail_in = srcbuf.length;
|
||||
zs.avail_in = to!uint(srcbuf.length);
|
||||
|
||||
zs.next_out = destbuf.ptr;
|
||||
zs.avail_out = destbuf.length;
|
||||
zs.avail_out = to!uint(destbuf.length);
|
||||
|
||||
err = etc.c.zlib.inflateInit2(&zs, 15);
|
||||
if (err)
|
||||
|
||||
Reference in New Issue
Block a user