####################################################################### Proofs of GPL violations in MagicISO by Luigi Auriemma e-mail: aluigi@autistici.org web: aluigi.org ####################################################################### 1) Introduction 2) Proof 1 3) Proof 2 ####################################################################### --------------- 1) Introduction --------------- For who doesn't know it, MagicISO (http://www.magiciso.com) is a chinese trialware CD burner tool which is becoming enough known in the last years (from 2006) for having used its proprietary image format (UIF) for distribuiting CD/DVDs of copyrighted material through the BitTorrent protocol, with the conseguence that who wants to use such contents (good or bad this is not the point of this text) is forced to buy this program. MagicISO 5.5.0.272, released at the end of July 2008, has added support for the DAA format, another closed proprietary format created and used in the program PowerISO and (ab)used on BitTorrent for the same reasons explained before... selling their products. As already stated, this format is proprietary and in all Internet only my open source GPLed daa2iso tool supports it, and in fact the code used in MagicISO is just the one of my GPL software which leads to the violation of my license and naturally there are no references about me, my code or my license in that program or in its documentation... The following are the proofs of the two "most evident" pieces of code that were taken from daa2iso 0.1.5a (the source code of that specific version is available at http://aluigi.org/misc/daa2iso_015a.c), so anyone can see and understand them without having big skills in programming or reversing. Remember to verify the MagicISO's instructions at runtime when the program is running because the executable is compressed/encrypted. ####################################################################### ---------- 2) Proof 1 ---------- The following is the piece of code I used to calculate some parameters of the latest version of the DAA file format. The solution I adopted in daa2iso was a personal "work-around", which means that the real method used by PowerISO is more complex and differs from mine and some of my checks DON'T exist in PowerISO at all. The method used by MagicISO is 100% the same "wrong one" used by my GPLed software. daa2iso lines 247->252 ---------------------- daa.data_offset &= 0xffffff; daa.chunksize = (daa.chunksize & 0xfff) << 14; bittype = daa.hdata[5]; for(bitsize = 0, len = daa.chunksize; len != bittype; bitsize++, len >>= 1); bitsize -= bittype & (~7); // useless??? if(bitsize < 1) bitsize = 1; MagicISO -------- :0045176C 816118FFFFFF00 and dword ptr [ecx+18], 00FFFFFF :00451773 8B4590 mov eax, dword ptr [ebp-70] :00451776 8B4D90 mov ecx, dword ptr [ebp-70] :00451779 8B5024 mov edx, dword ptr [eax+24] :0045177C 81E2FF0F0000 and edx, 00000FFF :00451782 C1E20E shl edx, 0E :00451785 895124 mov dword ptr [ecx+24], edx :00451788 33D2 xor edx, edx :0045178A 8B4590 mov eax, dword ptr [ebp-70] :0045178D 33C9 xor ecx, ecx :0045178F 8A503D mov dl, byte ptr [eax+3D] :00451792 89957CFFFFFF mov dword ptr [ebp+FFFFFF7C], edx :00451798 894D80 mov dword ptr [ebp-80], ecx :0045179B 8B4590 mov eax, dword ptr [ebp-70] :0045179E 8B5024 mov edx, dword ptr [eax+24] :004517A1 899570FFFFFF mov dword ptr [ebp+FFFFFF70], edx :004517A7 8B8D70FFFFFF mov ecx, dword ptr [ebp+FFFFFF70] :004517AD 3B8D7CFFFFFF cmp ecx, dword ptr [ebp+FFFFFF7C] :004517B3 7417 je 004517CC * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:004517CA(C) | :004517B5 FF4580 inc [ebp-80] :004517B8 D1BD70FFFFFF sar dword ptr [ebp+FFFFFF70], 1 :004517BE 8B8570FFFFFF mov eax, dword ptr [ebp+FFFFFF70] :004517C4 3B857CFFFFFF cmp eax, dword ptr [ebp+FFFFFF7C] :004517CA 75E9 jne 004517B5 * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:004517B3(C) | :004517CC 8B957CFFFFFF mov edx, dword ptr [ebp+FFFFFF7C] :004517D2 83E2F8 and edx, FFFFFFF8 :004517D5 295580 sub dword ptr [ebp-80], edx :004517D8 837D8001 cmp dword ptr [ebp-80], 00000001 :004517DC 7D07 jge 004517E5 :004517DE C7458001000000 mov [ebp-80], 00000001 ####################################################################### ---------- 3) Proof 2 ---------- The following is my implementation of the obfuscation function used by PowerISO after handling the chunks compressed with the LZMA algorithm. As for the previous proof also in this case I used a personal method which differs from the original pre-compiled code of PowerISO (like the inizialization of the variables and so on) while it's exactly the same in MagicISO. FYI 006FE1D8 and 006FE1E0 point to the "shit" and "shiz" buffers. UPDATE 23 Aug 2008: FYI, this function which originally I though was used for obfuscating the output in reality is the x86_Convert function of the LZMA SDK (thanx to Joe Lowe for the info). But this changes nothing because MagicISO copied the implementation created by me from scratch and not that one of LZMA. daa2iso lines 424->480 ---------------------- // what's the purpose of this function? only deobfuscating... blah void poweriso_is_shit(u8 *chunk, int chunksize) { u32 num, bp, e10, e20, e28; int i; u8 shit[8] = { 0, 1, 2, 2, 3, 3, 3, 3 }, shiz[8] = { 1, 1, 1, 0, 1, 0, 0, 0 }, tmp; bp = 0; e10 = -1; e20 = 5; // add esi,5 e28 = 0; for(i = 0; (i + 5) <= chunksize; i++) { if((chunk[i] & 0xfe) != 0xe8) continue; if((i - e10) <= 3) { bp = (bp << ((i - e10 - 1) & 0xff)) & 7; } else { bp = 0; } if(bp) { tmp = chunk[i - shit[bp] + 4]; if(!shiz[bp] || !tmp || (tmp == 0xff)) { bp = ((bp & 3) << 1) | 1; e10 = i; continue; } } e10 = i; if((chunk[i + 4] != 0) && (chunk[i + 4] != 0xff)) { bp = ((bp & 3) << 1) | 1; continue; } num = (chunk[i + 4] << 24) | (chunk[i + 3] << 16) | (chunk[i + 2] << 8) | chunk[i + 1]; for(;;) { if(!e28) { num -= i + e20; } else { num += i + e20; } if(!bp) break; tmp = num >> (24 - (shit[bp] << 3)); if((tmp != 0) && (tmp != 0xff)) break; num ^= ((1 << (32 - (shit[bp] << 3))) - 1); } chunk[++i] = num; chunk[++i] = num >> 8; chunk[++i] = num >> 16; chunk[++i] = ~(((num >> 24) & 1) - 1); } } MagicISO -------- :00451D68 55 push ebp :00451D69 8BEC mov ebp, esp :00451D6B 83C4DC add esp, FFFFFFDC :00451D6E 8B05D8E16F00 mov eax, dword ptr [006FE1D8] :00451D74 8B15E0E16F00 mov edx, dword ptr [006FE1E0] :00451D7A 33C9 xor ecx, ecx :00451D7C 53 push ebx :00451D7D 56 push esi :00451D7E 8945E4 mov dword ptr [ebp-1C], eax :00451D81 8B05DCE16F00 mov eax, dword ptr [006FE1DC] :00451D87 8945E8 mov dword ptr [ebp-18], eax :00451D8A 8955DC mov dword ptr [ebp-24], edx :00451D8D 8B15E4E16F00 mov edx, dword ptr [006FE1E4] :00451D93 33C0 xor eax, eax :00451D95 8955E0 mov dword ptr [ebp-20], edx :00451D98 894DFC mov dword ptr [ebp-04], ecx :00451D9B C745F8FFFFFFFF mov [ebp-08], FFFFFFFF :00451DA2 C745F405000000 mov [ebp-0C], 00000005 :00451DA9 8945F0 mov dword ptr [ebp-10], eax :00451DAC 33D2 xor edx, edx :00451DAE 8955EC mov dword ptr [ebp-14], edx :00451DB1 8B4D08 mov ecx, dword ptr [ebp+08] :00451DB4 8BC1 mov eax, ecx :00451DB6 E95B010000 jmp 00451F16 * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:00451F1F(C) | :00451DBB 33D2 xor edx, edx :00451DBD 8A10 mov dl, byte ptr [eax] :00451DBF 81E2FE000000 and edx, 000000FE :00451DC5 81FAE8000000 cmp edx, 000000E8 :00451DCB 0F8541010000 jne 00451F12 :00451DD1 8B55EC mov edx, dword ptr [ebp-14] :00451DD4 2B55F8 sub edx, dword ptr [ebp-08] :00451DD7 83FA03 cmp edx, 00000003 :00451DDA 7716 ja 00451DF2 :00451DDC 8BCA mov ecx, edx :00451DDE 49 dec ecx :00451DDF 81E1FF000000 and ecx, 000000FF :00451DE5 8B55FC mov edx, dword ptr [ebp-04] :00451DE8 D3E2 shl edx, cl :00451DEA 83E207 and edx, 00000007 :00451DED 8955FC mov dword ptr [ebp-04], edx :00451DF0 EB05 jmp 00451DF7 * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:00451DDA(C) | :00451DF2 33C9 xor ecx, ecx :00451DF4 894DFC mov dword ptr [ebp-04], ecx * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:00451DF0(U) | :00451DF7 837DFC00 cmp dword ptr [ebp-04], 00000000 :00451DFB 7441 je 00451E3E :00451DFD 8B55FC mov edx, dword ptr [ebp-04] :00451E00 33C9 xor ecx, ecx :00451E02 8A4C15E4 mov cl, byte ptr [ebp+edx-1C] :00451E06 8B55EC mov edx, dword ptr [ebp-14] :00451E09 2BD1 sub edx, ecx :00451E0B 8B4D08 mov ecx, dword ptr [ebp+08] :00451E0E 8A4C1104 mov cl, byte ptr [ecx+edx+04] :00451E12 8B55FC mov edx, dword ptr [ebp-04] :00451E15 807C15DC00 cmp byte ptr [ebp+edx-24], 00 :00451E1A 7409 je 00451E25 :00451E1C 84C9 test cl, cl :00451E1E 7405 je 00451E25 :00451E20 80F9FF cmp cl, FF :00451E23 7519 jne 00451E3E * Referenced by a (U)nconditional or (C)onditional Jump at Addresses: |:00451E1A(C), :00451E1E(C) | :00451E25 8B55FC mov edx, dword ptr [ebp-04] :00451E28 83E203 and edx, 00000003 :00451E2B 03D2 add edx, edx :00451E2D 83CA01 or edx, 00000001 :00451E30 8955FC mov dword ptr [ebp-04], edx :00451E33 8B4DEC mov ecx, dword ptr [ebp-14] :00451E36 894DF8 mov dword ptr [ebp-08], ecx :00451E39 E9D4000000 jmp 00451F12 * Referenced by a (U)nconditional or (C)onditional Jump at Addresses: |:00451DFB(C), :00451E23(C) | :00451E3E 8B55EC mov edx, dword ptr [ebp-14] :00451E41 8955F8 mov dword ptr [ebp-08], edx :00451E44 8A5004 mov dl, byte ptr [eax+04] :00451E47 84D2 test dl, dl :00451E49 7418 je 00451E63 :00451E4B 80FAFF cmp dl, FF :00451E4E 7413 je 00451E63 :00451E50 8B4DFC mov ecx, dword ptr [ebp-04] :00451E53 83E103 and ecx, 00000003 :00451E56 03C9 add ecx, ecx :00451E58 83C901 or ecx, 00000001 :00451E5B 894DFC mov dword ptr [ebp-04], ecx :00451E5E E9AF000000 jmp 00451F12 * Referenced by a (U)nconditional or (C)onditional Jump at Addresses: |:00451E49(C), :00451E4E(C) | :00451E63 81E2FF000000 and edx, 000000FF :00451E69 C1E218 shl edx, 18 :00451E6C 33C9 xor ecx, ecx :00451E6E 8A4803 mov cl, byte ptr [eax+03] :00451E71 C1E110 shl ecx, 10 :00451E74 0BD1 or edx, ecx :00451E76 33C9 xor ecx, ecx :00451E78 8A4802 mov cl, byte ptr [eax+02] :00451E7B C1E108 shl ecx, 08 :00451E7E 0BD1 or edx, ecx :00451E80 33C9 xor ecx, ecx :00451E82 8A4801 mov cl, byte ptr [eax+01] :00451E85 0BD1 or edx, ecx :00451E87 8B4DFC mov ecx, dword ptr [ebp-04] :00451E8A 8D5C0DE4 lea ebx, dword ptr [ebp+ecx-1C] * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:00451EE5(U) | :00451E8E 837DF000 cmp dword ptr [ebp-10], 00000000 :00451E92 750A jne 00451E9E :00451E94 8B4DEC mov ecx, dword ptr [ebp-14] :00451E97 034DF4 add ecx, dword ptr [ebp-0C] :00451E9A 2BD1 sub edx, ecx :00451E9C EB08 jmp 00451EA6 * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:00451E92(C) | :00451E9E 8B4DEC mov ecx, dword ptr [ebp-14] :00451EA1 034DF4 add ecx, dword ptr [ebp-0C] :00451EA4 03D1 add edx, ecx * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:00451E9C(U) | :00451EA6 837DFC00 cmp dword ptr [ebp-04], 00000000 :00451EAA 743B je 00451EE7 :00451EAC 33C9 xor ecx, ecx :00451EAE 8A0B mov cl, byte ptr [ebx] :00451EB0 C1E103 shl ecx, 03 :00451EB3 51 push ecx :00451EB4 B918000000 mov ecx, 00000018 :00451EB9 5E pop esi :00451EBA 2BCE sub ecx, esi :00451EBC 8BF2 mov esi, edx :00451EBE D3EE shr esi, cl :00451EC0 8BCE mov ecx, esi :00451EC2 84C9 test cl, cl :00451EC4 7405 je 00451ECB :00451EC6 80F9FF cmp cl, FF :00451EC9 751C jne 00451EE7 * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:00451EC4(C) | :00451ECB 33C9 xor ecx, ecx :00451ECD 8A0B mov cl, byte ptr [ebx] :00451ECF C1E103 shl ecx, 03 :00451ED2 51 push ecx :00451ED3 B920000000 mov ecx, 00000020 :00451ED8 5E pop esi :00451ED9 2BCE sub ecx, esi :00451EDB BE01000000 mov esi, 00000001 :00451EE0 D3E6 shl esi, cl :00451EE2 4E dec esi :00451EE3 33D6 xor edx, esi :00451EE5 EBA7 jmp 00451E8E * Referenced by a (U)nconditional or (C)onditional Jump at Addresses: |:00451EAA(C), :00451EC9(C) | :00451EE7 FF45EC inc [ebp-14] :00451EEA 40 inc eax :00451EEB 8BCA mov ecx, edx :00451EED C1E908 shr ecx, 08 :00451EF0 8810 mov byte ptr [eax], dl :00451EF2 40 inc eax :00451EF3 FF45EC inc [ebp-14] :00451EF6 8808 mov byte ptr [eax], cl :00451EF8 40 inc eax :00451EF9 FF45EC inc [ebp-14] :00451EFC 8BCA mov ecx, edx :00451EFE C1E910 shr ecx, 10 :00451F01 8808 mov byte ptr [eax], cl :00451F03 40 inc eax :00451F04 C1EA18 shr edx, 18 :00451F07 FF45EC inc [ebp-14] :00451F0A 80E201 and dl, 01 :00451F0D 4A dec edx :00451F0E F6D2 not dl :00451F10 8810 mov byte ptr [eax], dl * Referenced by a (U)nconditional or (C)onditional Jump at Addresses: |:00451DCB(C), :00451E39(U), :00451E5E(U) | :00451F12 FF45EC inc [ebp-14] :00451F15 40 inc eax * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:00451DB6(U) | :00451F16 8B55EC mov edx, dword ptr [ebp-14] :00451F19 83C205 add edx, 00000005 :00451F1C 3B550C cmp edx, dword ptr [ebp+0C] :00451F1F 0F8E96FEFFFF jle 00451DBB :00451F25 5E pop esi :00451F26 5B pop ebx :00451F27 8BE5 mov esp, ebp :00451F29 5D pop ebp :00451F2A C3 ret #######################################################################