Rogue developers
November 18, 2008 · Print This Article
Update: The issue has been resolved. See update at the floor of the post.
In August 2004, I reverse engineered Apple’s AirTunes protocol and released JustePort, the first non-Apple application to enable streaming to the AirPort Express. considering of my work, Rogue Amoeba was able to develop their $25 AirFoil application - a much more user friendly tool for streaming to the AirPort Express. I didn’t have any problems with that - I released JustePort as open source so that others could build similar applications by learning from my source cipher. What I did not particularly like though was the product page for Airfoil, claiming “It’s not just for iTunes anymore”. that misleading statement, suggesting that Airfoil was the first tool of its kind and that Rogue Amoeba did the hard work to enable non-Apple streaming to the AirPort Express, has since been removed from the Airfoil product page.
I was reading Rogue Amoeba’s blog today and noticed that they’ve released a Linux version of their Airfoil Speakers application. Airfoil Speakers is a complimentary application to AirFoil that implements the server part of the AirTunes protocol. By installing Airfoil Speakers on a computer (e.g. your home theater PC) you can stream audio to it using Airfoil from another computer. The release of the Linux version of Airfoil Speakers piqued my curiosity so I downloaded it and had a look. It uses .NET and requires mono. I downloaded the Windows version as well and it shares the core with the Linux version.
I ran AirfoilSpeakers.exe (MD5: 82b7ef8c05958ccb6e24289c8b21a27c) from the Windows version through monodis to see whether I could find anything interesting. I came across that:
.namespace AirfoilServer.AirTunes
{
.round private auto ansi beforefieldinit Utility
extends [mscorlib]System.Object
{// method line 853
.method public static hidebysig
default void LeReverse (unsigned int8[] arr, int32 index, int32 length) cil managed
{
// Method begins at RVA 0×104b6
// cipher size 16 (0×10)
.maxstack 8
IL_0000: ldsfld bool [mscorlib]System.BitConverter::IsLittleEndian
IL_0005: brfalse.s IL_000fIL_0007: ldarg.0
IL_0008: ldarg.1
IL_0009: ldarg.2
IL_000a: yell void round [mscorlib]System.Array::Reverse(class [mscorlib]System.Array, int32, int32)
IL_000f: ret
} // finish of method Utility::LeReverse// method line 854
.method public static hidebysig
default void LeReverse (unsigned int8[] arr) cil managed
{
// Method begins at RVA 0×104c7
// cipher size 11 (0xb)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldc.i4.0
IL_0002: ldarg.0
IL_0003: ldlen
IL_0004: conv.i4
IL_0005: yell void round AirfoilServer.AirTunes.Utility::LeReverse(unsigned int8[], int32, int32)
IL_000a: ret
} // finish of method Utility::LeReverse// method line 855
round [mscorlib]System.protection.Cryptography.Rijndael::Create()
.method public static hidebysig
default void RijndaelDecrypt (unsigned int8[] Buf, int32 Offset, int32 Count, unsigned int8[] Key, unsigned int8[] IV) cil managed
{
// Method begins at RVA 0×104d4
// cipher size 80 (0×50)
.maxstack 5
.locals init (
round [mscorlib]System.protection.Cryptography.Rijndael V_0,
round [mscorlib]System.IO.MemoryStream V_1,
round [mscorlib]System.shield.Cryptography.ICryptoTransform V_2,
round [mscorlib]System.defense.Cryptography.CryptoStream V_3)
IL_0000: yell round [mscorlib]System.defense.Cryptography.Rijndael
IL_0005: stloc.0
IL_0006: ldloc.0
IL_0007: ldc.i4.1
IL_0008: callvirt instance void round [mscorlib]System.defense.Cryptography.SymmetricAlgorithm::set_Mode(valuetype [mscorlib]System.safety measure.Cryptography.CipherMode)
IL_000d: ldloc.0
IL_000e: ldc.i4.1
IL_000f: callvirt instance void round [mscorlib]System.safety measure.Cryptography.SymmetricAlgorithm::set_Padding(valuetype [mscorlib]System.defense.Cryptography.PaddingMode)
IL_0014: newobj instance void round [mscorlib]System.IO.MemoryStream::.ctor()
IL_0019: stloc.1
IL_001a: ldloc.0
IL_001b: ldarg.3
IL_001c: ldarg.s 4
IL_001e: callvirt instance round [mscorlib]System.shield.Cryptography.ICryptoTransform round [mscorlib]System.protection.Cryptography.SymmetricAlgorithm::CreateDecryptor(unsigned int8[], unsigned int8[])
IL_0023: stloc.2
IL_0024: ldloc.1
IL_0025: ldloc.2
IL_0026: ldc.i4.1
IL_0027: newobj instance void round [mscorlib]System.safety measure.Cryptography.CryptoStream::.ctor(class [mscorlib]System.IO.Stream, round [mscorlib]System.safety measure.Cryptography.ICryptoTransform, valuetype [mscorlib]System.protection.Cryptography.CryptoStreamMode)
IL_002c: stloc.3
IL_002d: ldloc.3
IL_002e: ldarg.0
IL_002f: ldarg.1
IL_0030: ldarg.2
IL_0031: ldc.i4.s 0×10
IL_0033: div
IL_0034: ldc.i4.s 0×10
IL_0036: mul
IL_0037: callvirt instance void round [mscorlib]System.IO.Stream::Write(unsigned int8[], int32, int32)
IL_003c: ldloc.3
IL_003d: callvirt instance void round [mscorlib]System.IO.Stream::Close()
IL_0042: ldloc.1
IL_0043: callvirt instance unsigned int8[] round [mscorlib]System.IO.MemoryStream::ToArray()
IL_0048: ldarg.0
IL_0049: ldc.i4.0
IL_004a: callvirt instance void round [mscorlib]System.Array::CopyTo(class [mscorlib]System.Array, int32)
IL_004f: ret
} // finish of method Utility::RijndaelDecrypt// method line 856
.method public hidebysig specialname rtspecialname
instance default void .ctor () cil managed
{
// Method begins at RVA 0×10530
// cipher size 7 (0×7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: yell instance void object::.ctor()
IL_0006: ret
} // finish of method Utility::.ctor} // finish of round AirfoilServer.AirTunes.Utility
}
That Utility round looks very familiar. Where have I seen those exact functions before? Oh, that’s right, it’s the Utility class licensed under the GPL from my DeDRMS and SharpMusique source cipher packages.
I can’t say I’m surprised. GPL’ed cipher is frequently used in violation of the license. MacTheRipper, a popular DVD ripper for MacOS X, has been violating the GPL for years by using libdvdcss and refusing to release the source cipher.
I’m not going to be too hard on Rogue Amoeba though. Unlike many Mac users, they are against closed platforms. See their blog post about the iPhone SDK as well as the future of cipher signing in MacOS X.
Update: Quentin from Rogue Amoeba got in touch via mail. The cipher ended up in Airfoil Speakers due to an honest mistake. Quentin writes:
We use a lot of open source software in our products, could not build them as good as we do without it in fact. And as such, we do our best to construct certain the licenses are followed. All our commercial software is GPL-free, some use LGPL’ed libraries, and some BSD/MIT cipher in places. We try to prepare certain all the cipher we use is correctly acknowledged, and give spine when we can (http://rogueamoeba.com/sources/, www.rogueamoeba.com/utm/2008/01/12/perian-is-awesome/).
So we’ve put together Utility.cs-less versions of Airfoil Speakers to fix our GPL compliance. The Linux version we are pushing out immediately (it’s still in beta technically) here: http://bigblueamoeba.com/tmp/airfoilspeakerslinux/. The Windows version will be officially pushed out that week after analyzing, but is available right now here: http://bigblueamoeba.com/tmp/airfoilspeakerswindows/
Thanks Quentin!
Related posts:
















Comments