eXeLab
eXeL@B ВИДЕОКУРС !

ВИДЕОКУРС ВЗЛОМ
обновлён 2 декабря!


УЗНАТЬ БОЛЬШЕ >>
Домой | Статьи | RAR-cтатьи | FAQ | Форум | Скачать | Видеокурс
Новичку | Ссылки | Программирование | Интервью | Архив | Связь

Русский / Russian English / Английский

Сейчас на форуме: Nihil enim, stronglogic, mkdev (+2 невидимых)
 · Начало · Статистика · Регистрация · Поиск · ПРАВИЛА ФОРУМА · Язык · RSS · SVN ·

 eXeL@B —› Протекторы —› DoSWF - professional flash encrypter
Посл.ответ Сообщение

Ранг: 1.4 (гость)
Статус: Участник

Создано: 26 апреля 2010 15:31 New!
Цитата · Личное сообщение · #1

www.doswf.net/

DoSWF is a professional flash encrypter. The Features as following:

Encrypt swf files for as2 and as3.particularly, DoSWF can encrypt images, buttons and other library files.
Prevent all popular swf-decompiler crack.
Obfuscate actionscript3.0 code.
Do project compositively.
Encrypt swc files.
Lock domains.
Add wartermark on swf. for as2,as3
Remove featrue for module developing.
Cross-Platform OS soft,Adobe AIR virsion for Windows.Mac,Linux.
Multi-language, Support English,Chinese,Japanese.

Китайские камрады утверждают, что их утилита защищает flash-файлы и проекты лучше всех.
www.actionscript.org/forums/showthread.php3?p=942890

На сайте можно потестить он-лайн.


Ранг: 95.2 (постоянный)
Статус: Участник

Создано: 13 июля 2010 15:17 New!
Цитата · Личное сообщение · #2

не врут, та еще гадость.


Ранг: 748.2 (! !)
Статус: Участник
bytecode!

Создано: 14 июля 2010 04:02 · Поправил: 4kusNick New!
Цитата · Личное сообщение · #3

Не такая уж и гадость.
Обфускация у него никакая, а декомпили он нагибает просто юзая классический подход к защите - все данные (графика и код) лежат в укомплектованном виде (в виде строки в данном случае) и есть небольшой код загрузчика, который преобразовывает строку в ByteArray, и затем ее подгружает для исполнения (это и будет целевая swf).

Так что вытащить все можно, просто сдампив загруженную swfку или написав свой маленький лоадер на AIR том же, который их этой строки будет делать swfку.
Код загрузчика нормально декомпилится Eltima'вским Flash Decompiler'ом.

И вообще, прот - говно, т.к. ломает большинство проектов, что на as2, что на as3.


Ранг: 95.2 (постоянный)
Статус: Участник

Создано: 10 августа 2010 09:33 · Поправил: inf1kek New!
Цитата · Личное сообщение · #4

И все таки гадость возьмется кто разобрать обфускцированый код декрипта? не за спасибо конечно.
Если что - достал лицензию самого прота, это может помочь.


Ранг: 748.2 (! !)
Статус: Участник
bytecode!

Создано: 11 августа 2010 13:37 · Поправил: 4kusNick New!
Цитата · Личное сообщение · #5

Лицензия самого прота врядли поможет, она не деобфусцирует код лоадера/декриптера.
Вытащить зашифрованную оригинальную флэшку можно из тэга DefineBinaryData (swftools, Action Script Viewer).
А разобрать лоадер, чтобы написать свой, можно с помощью байткод-декомпилеров, с помощью того же yogda, но это будет не быстро - главное - узнать алгоритм шифрования и проверить не закастомлен ли он, может тут кто и найдется, у кого будет время на все это.

offtop
Забавный топик
www.sothink.com/phpBB2/viewtopic.php?f=10&t=284358
=)


Ранг: 748.2 (! !)
Статус: Участник
bytecode!

Создано: 12 августа 2010 03:44 New!
Цитата · Личное сообщение · #6

Как выяснилось, для шифрования там юзается простой xor, но до конца алго не дает восстановить обфускация, т.к. там не тупой ксор по всей длине, метод расшифровки такой:
Code:
  1. private function getCompressedByteArray(arg1:flash.utils.ByteArray):flash.utils.ByteArr ay
  2.         {
  3.             var loc3:*=0;
  4.             arg1.position = 0;
  5.             this.ʟߒ = arg1.readByte() - 3;
  6.             this.nSomeByteForXOR = arg1.readByte();
  7.             this.ʟߒ = arg1.readUnsignedInt();
  8.             this.ʟߒ = arg1.readUnsignedInt();
  9.             var loc1:*=new flash.utils.ByteArray();
  10.             loc1.writeBytes(arg1, arg1.length - this.ʟߒ, this.ʟߒ);
  11.             var loc2:*=0;
  12.             for (;;)
  13.             {
  14.                 loc3 = 0;
  15.                 while (loc3 < this.&#671;&#2002;)
  16.                 {
  17.                     loc1[loc2] = loc1[loc2] ^ this.nSomeByteForXOR;
  18.                     ++loc2;
  19.                     if (loc2 >= this.&#671;&#2002;)
  20.                     {
  21.                         break;
  22.                     }
  23.                     loc3 = loc3 + 2;
  24.                 }
  25.                 loc2 = loc2 + this.&#671;&#2002;;
  26.                 if (!(loc2 >= this.&#671;&#2002;))
  27.                 {
  28.                     continue;
  29.                 }
  30.                 break;
  31.             }
  32.             return loc1;
  33.         }


Ранг: 748.2 (! !)
Статус: Участник
bytecode!

Создано: 12 августа 2010 03:45 New!
Цитата · Личное сообщение · #7

В байткоде выглядит так:

Code:
  1. function * (flash.utils:ByteArray):flash.utils:ByteArray PARAM_NAMES 
  2.  {
  3.  
  4.     // Max stack           : 4
  5.     // Local count         : 5
  6.     // Scope depth         : 10
  7.     // Max Scope depth     : 11
  8.     // Exception Count     : 0
  9.     // Trait Count         : 0
  10.     // Code Length         : 278 bytes.
  11.  
  12.  
  13.        1  debugfile        F:\dropbox\My Dropbox\projects\2009\doswf\DoSWF_air\laan\swf\doswf\release;;EncryptB ase.as
  14.        4  debugline        139
  15.  // 
  16.        8  jump    LOC_1:
  17.        12  newobject       360711
  18. LOC_1:
  19. LOC_2:
  20.        13  label  
  21.        14  getlocal0       
  22.        15  pushscope       
  23.        17  pushbyte        0
  24.        18  convert_u       
  25.        20  setlocal        4
  26.        26  debug  1,doneBytes,0,139
  27.        32  debug  1,newSWFBytes,1,146
  28.        38  debug  1,i,2,148
  29.        41  debugline       140
  30.  // 
  31.        42  getlocal1       
  32.        44  pushbyte        0
  33.        46  setproperty     position
  34.        49  debugline       141
  35.  // 
  36.        50  getlocal0       
  37.        51  getlocal1       
  38.        54  callproperty    readByte,0
  39.        56  pushbyte        3
  40.        57  subtract        
  41.        59  initproperty    EY??:EY?
  42.        62  debugline       142
  43.  // 
  44.        63  getlocal0       
  45.        64  getlocal1       
  46.        67  callproperty    readByte,0
  47.        69  initproperty    EY??:EY?
  48.        72  debugline       143
  49.  // 
  50.        73  getlocal0       
  51.        77  jump   LOC_3:
  52.        79  inclocal_i      0
  53. LOC_3:
  54. LOC_4:
  55.        80  label  
  56.        81  getlocal1       
  57.        84  callproperty    readUnsignedInt,0
  58.        86  initproperty    EY??:EY?
  59.        89  debugline       144
  60.  // 
  61.        90  getlocal0       
  62.        91  getlocal1       
  63.        94  callproperty    readUnsignedInt,0
  64.        96  initproperty    EY??:EY?
  65.        99  debugline       146
  66.  // 
  67.        101  findpropstrict flash.utils:ByteArray
  68.        104  constructprop  flash.utils:ByteArray,0
  69.        106  coerce         flash.utils:ByteArray
  70.        107  setlocal2      
  71.        110  debugline      147
  72.  // 
  73.        111  getlocal2      
  74.        112  getlocal1      
  75.        113  getlocal1      
  76.        115  getproperty    length
  77.        116  getlocal0      
  78.        118  getproperty    EY??:EY?
  79.        119  subtract       
  80.        120  getlocal0      
  81.        122  getproperty    EY??:EY?
  82.        126  jump  LOC_5:
  83.        130  newarray       387986
  84. LOC_5:
  85. LOC_6:
  86.        131  label 
  87.        134  callpropvoid   writeBytes,3
  88.        137  debugline      148
  89.  // 
  90.        139  pushbyte       0
  91.        140  convert_u      
  92.        141  setlocal3      
  93.        145  jump  LOC_7:
  94. LOC_8:
  95.        146  label 
  96.        152  debug 1,j,3,150
  97.        155  debugline      150
  98.  // 
  99.        157  pushbyte       0
  100.        158  convert_u      
  101.        160  setlocal       4
  102.        164  jump  LOC_9:
  103. LOC_10:
  104.        165  label 
  105.        168  debugline      151
  106.  // 
  107.        169  getlocal2      
  108.        170  getlocal3      
  109.        171  getlocal2      
  110.        172  getlocal3      
  111.        174  getproperty    multinameL
  112.        175  getlocal0      
  113.        177  getproperty    EY??:EY?
  114.        178  bitxor         
  115.        180  setproperty    multinameL
  116.        183  debugline      152
  117.  // 
  118.        184  getlocal3      
  119.        185  increment      
  120.        186  convert_u      
  121.        187  setlocal3      
  122.        191  jump  LOC_11:
  123.        192  returnvalue    
  124. LOC_11:
  125. LOC_12:
  126.        193  label 
  127.        196  debugline      154
  128.  // 
  129.        197  getlocal3      
  130.        198  getlocal0      
  131.        200  getproperty    EY??:EY?
  132.        204  ifnge LOC_13:
  133.        207  debugline      155
  134.  // 
  135.        211  jump  LOC_14:
  136. LOC_13:
  137.        214  debugline      150
  138.  // 
  139.        216  getlocal       4
  140.        218  pushbyte       2
  141.        219  add   
  142.        220  convert_u      
  143.        222  setlocal       4
  144. LOC_9:
  145.        224  getlocal       4
  146.        225  getlocal0      
  147.        227  getproperty    EY??:EY?
  148.        231  iflt  LOC_10:
  149. LOC_14:
  150.        234  debugline      158
  151.  // 
  152.        235  getlocal3      
  153.        236  getlocal0      
  154.        238  getproperty    EY??:EY?
  155.        239  add   
  156.        240  convert_u      
  157.        241  setlocal3      
  158.        244  debugline      159
  159.  // 
  160.        245  getlocal3      
  161.        246  getlocal0      
  162.        248  getproperty    EY??:EY?
  163.        252  ifnge LOC_7:
  164.        255  debugline      160
  165.  // 
  166.        259  jump  LOC_15:
  167. LOC_7:
  168.        262  debugline      149
  169.  // 
  170.        266  jump  LOC_8:
  171. LOC_15:
  172.        269  debugline      164
  173.  // 
  174.        273  jump  LOC_16:
  175.        274  returnvalue    
  176. LOC_16:
  177. LOC_17:
  178.        275  label 
  179.        276  getlocal2      
  180.        277  returnvalue    
  181.  }


Ранг: 748.2 (! !)
Статус: Участник
bytecode!

Создано: 12 августа 2010 04:24 · Поправил: 4kusNick New!
Цитата · Личное сообщение · #8

Из того, что понял:
1. Сначала читаем первый байт.
2. Объявляем переменную = первому байту минус 3,
3. Затем еще одну = первому байту - она у нас будет ключем для xor.
4. Затем читаем дважды длину в две разные переменные.

5. Потом, в новый ByteArray. который у нас будет в итоге на выходе, перекидываем из дешифруемого все байты, кроме нескольких первых, то, есть со смещения = длина искомого минус длина, полученная в 4 шаге, это получается все, что идет после некоего заголовка, в моем случае это 21 байт, аккурат вот это:

Code:
  1. Offset      0  1  2  3  4  5  6  7   8  9  A  B  C  D  E  F
  2.  
  3. 00000000   13 CB 00 00 00 00 00 00  1F FE 00 09 64 6F 73 77    E       ?  dosw
  4. 00000010   66 2E 63 6F 6D                                     f.com


1F FE - это та самая длина (8190), адлина всего дампа, который анпакается - 8211.
А вот дальше - все зависит от переменных, которые проинициализировались во 2 и 4 шагах - они у меня все одинаково называются и хз какая где учавствует =(

В итоге алго таков:
Code:
  1. private function getCompressedByteArray(arg1:flash.utils.ByteArray):flash.utils.ByteArr ay
  2.         {
  3.             var loc3:*=0;
  4.             arg1.position = 0;
  5.             this.nVar1 = arg1.readByte() - 3;
  6.             this.nSomeByteForXOR = arg1.readByte();
  7.             this.nVar2 = arg1.readUnsignedInt();
  8.             this.nVar3 = arg1.readUnsignedInt();
  9.             var baDecrypted:*=new flash.utils.ByteArray();
  10.             baDecrypted.writeBytes(arg1, arg1.length - this.nVar2, this.nVar2);
  11.             var loc2:*=0;
  12.             for (;;)
  13.             {
  14.                 loc3 = 0;
  15.                 while (loc3 < this.nVar) 
  16.                 {
  17.                     baDecrypted[loc2] = baDecrypted[loc2] ^ this.nSomeByteForXOR;
  18.                     ++loc2;
  19.                     if (loc2 >= this.nVar) 
  20.                     {
  21.                         break;
  22.                     }
  23.                     loc3 = loc3 + 2;
  24.                 }
  25.                 loc2 = loc2 + this.nVar;
  26.                 if (!(loc2 >= this.nVar)) 
  27.                 {
  28.                     continue;
  29.                 }
  30.                 break;
  31.             }
  32.             return baDecrypted;
  33.         }


Там, где this.nVar - это либо this.nVar1, либо this.nVar2, либо this.nVar3 ...

Если кто разглядит различия на своих примерах - говорите - можно будет "анвраппер" написать.

Для порядка, прикрепил архив со своей swf, накрытой почти со всеми настройками, дампом и кодом загрузчика (оргинальный и после изучения).

{ Атач доступен только для участников форума } - test.7z


Ранг: 748.2 (! !)
Статус: Участник
bytecode!

Создано: 12 августа 2010 13:22 · Поправил: 4kusNick New!
Цитата · Личное сообщение · #9

Готово.
Написал анпакер.

Точнее, расшифровщик.
Ему надо скармливать bin, выдранный из тэга DefineBinaryData.


Ранг: 748.2 (! !)
Статус: Участник
bytecode!

Создано: 12 августа 2010 14:31 · Поправил: 4kusNick New!
Цитата · Личное сообщение · #10

Жаль, что расшифрованная флэшка содердит в себе много бяки (привязки к перемнным, ватермарк в нереганной версии и т.д.), и чтобы она заработала без всяких загрузчиков, ее тоже надо допиливать.

Зато можно в декомпиляторе уже спокойно ее посмотреть, и код и ресурсы (ну, код можно спокойно смотреть, только если он не обфусцирован был при накрывании флэшки).

ADDED
Приаттачил декриптор.
При запуске натравляете его на дамп тэга DefineBinaryData, затем сохраняете полученный файл в виде swf, после этого можете его ковырять в декомпиляторе.

Может не сработать, я на всех опциях не тестил, если что - пишите.
Далее следует изучить что DoSWF добавлят в покрываемую SWFку и научиться это дело килять, но для этого нужен регнутый DoSWF (чтобы ватермарк не мешался и прочая лабуда) и куча времени =)

{ Атач доступен только для участников форума } - decrypt.swf


Ранг: 95.2 (постоянный)
Статус: Участник

Создано: 12 августа 2010 15:27 New!
Цитата · Личное сообщение · #11

респект


Ранг: 748.2 (! !)
Статус: Участник
bytecode!

Создано: 12 августа 2010 17:48 New!
Цитата · Личное сообщение · #12

В общем, восстановил оригинальную swfку в своем случае:
1. Удалил обфусцированный класс с кодом, который прицепляет лого и вешает на него клик (я мог бы этого и не делать - но лишний мусор неприятен).
2. В конструкторе убрал код создания этого класса с параметрами, один из которых - длиннющая строка, похоже на само изображение в каком-то b64. Код был такого вида:

Code:
  1.  super();
  2. new _название_обфусцированного_класса_(this, "_image_&#10001;LT&#10001;iVBORw0.........ORK5CYII=&#10001;http://www.doswf.com/buy&#10002;");
  3. return;


3. Реплэйснул у рута _doswf_stage на stage и _doswf_loaderInfo на loaderInfo (иначе пришлось бы загружать флэшку через лоадер в котором надо было написать что-то вроде:
Code:
  1. Object.prototype._doswf_stage = stage;
  2. Object.prototype.setPropertyIsEnumerable("_doswf_stage", false);
  3. Object.prototype._doswf_loaderInfo = loaderInfo;
  4. Object.prototype.setPropertyIsEnumerable("_doswf_loaderInfo", false);
  5.  
  6. var lcLoaderContext:LoaderContext = new LoaderContext(false, ApplicationDomain.currentDomain);
  7. if (lcLoaderContext.hasOwnProperty("allowLoadBytesCodeExecution")) 
  8. {
  9.     Object(lcLoaderContext).allowLoadBytesCodeExecution = true;
  10. }
  11. var ldr:Loader = new Loader();
  12. ldr.load(new URLRequest('target.swf'), lcLoaderContext);
  13. addChild(ldr);
  14.  


4. Кильнул из главного класса метод, в котором вешается таймер для открытия странички DoSWF.
5. Установил характеристики сцены (fps, размеры, цвет фона) такие же, как в запротекченной swf.

Получился работоспособный файл, почти такого же размера, как и оригинал.


Проверил декриптор на одной as2 swfке - после декрипта не пришлось ничего править - вышла рабочая swfка.
Также обнаружил странную багу при декрипте большой as3 флэшки - неверно детектится длина одна - надо проверять\править, т.к. возможно это проявляется на всех больших дампах.

И еще - при накрывании с привязкой - не замел, где она чекается, может просто проглядел, а может в нерегнутой версии это не работает.

Вообще, больше у меня не найдется времени на это, я готов передать сорцы тому, кто захочет дофиксить баги и\или написать более полноценный анвраппер - чтобы он сам вытаскивал дамп из тэга DefineBinaryData, сам этот дамп декриптил и чистил результат от DoSWF'овского шлака.


Ранг: 95.2 (постоянный)
Статус: Участник

Создано: 12 августа 2010 18:41 · Поправил: inf1kek New!
Цитата · Личное сообщение · #13

Могу ошибатся, но с большими флешками длина может определятся не верно, потому-что она занимает три байта (и более), а не два как у тебя в примере.


Ранг: 748.2 (! !)
Статус: Участник
bytecode!

Создано: 12 августа 2010 20:42 New!
Цитата · Личное сообщение · #14

Не, эта длина считывается верно, речь идет о другой части кода, тут я его не приводил.
 eXeL@B —› Протекторы —› DoSWF - professional flash encrypter

Оригинальный DVD-ROM: eXeL@B DVD !

Вы находитесь на форуме сайта EXELAB.RU
Проект ReactOS