Blog. Just Blog

Исследование защиты программы Pixillion Image Converter

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Темная сторона Силы | Автор: ManHunter
Скриншот программы Pixillion Image Converter
Скриншот программы Pixillion Image Converter

Pixillion Image Converter - универсальный конвертер графических файлов в различные форматы. Поддерживается несколько десятков форматов, кроме того, изображения можно ресайзить, поворачивать, накладывать водяной знак, и все это в пакетом режиме. Безусловно, есть много бесплатных программ для подобных операций, но вдруг и эта программа найдет своих поклонников. Естественно, после курса интенсивной антишароварной терапии.

Начинаем с загрузки дистрибутива. Устанавливаем, смотрим. Исполняемый файл ничем не защищен и не упакован, отправляем его на переработку в дизассемблер. Запускаем программу и смотрим, как и что тут можно зарегистрировать.

Окно регистрации программы
Окно регистрации программы

Хех, в самом окне регистрации нам дается подсказка, каким должен быть серийный номер. Отлично, хоть с такой мелочью возиться не придется. Очевидно, что серийник-подсказка ни к чему хорошему не приведет, поэтому попробуем слепить по шаблону какой-нибудь свой, например, "111111-abcdefgh". Пробуем зарегистрировать.

Сообщение о неправильной регистрации
Сообщение о неправильной регистрации

Теперь попробуем найти строку сообщения и условия, при которых она появляется.
  1. .text:0046BAB1                 lea     eax, [esi-1]
  2. ; Сравнить какую-то переменную с фиксированным значением 267D40h
  3. .text:0046BAB4                 cmp     eax, 267D40h
  4. ; Если больше, то перепрыгнуть дальше
  5. .text:0046BAB9                 ja      loc_46BBBA
  6. .text:0046BABF                 cmp     esi, 2818F0h
  7. .text:0046BAC5                 jge     loc_46BBBA
  8. .text:0046BACB                 push    offset a4_06_0  ; "4.06"
  9. .text:0046BAD0                 call    j__atol
  10. .text:0046BAD5                 dec     eax
  11. .text:0046BAD6                 pop     ecx
  12. .text:0046BAD7                 jns     short loc_46BADB
  13. .text:0046BAD9                 xor     eax, eax
  14. .text:0046BADB loc_46BADB:
  15. .text:0046BADB                 push    eax
  16. .text:0046BADC                 mov     esi, edi
  17. .text:0046BADE                 push    offset aTheCodeYouAreA
  18. ; "The code you are attempting to use is n"...
  19. .text:0046BAE3                 lea     edi, [esp+0CD0h+File]
  20. .text:0046BAEA                 call    sub_46A2E9
  21. .text:0046BAEF                 mov     eax, [esp+0CD0h+var_CB0]
Без отладчика тут не обойтись. Запускам программу под отладчиком, ставим точку останова на адрес 0046BAB1 и пробуем повторить процесс регистрации с тем же левым серийником. При срабатывании точки останова мы видим в регистре EAX, который сравнивается с константой, значение 1B207h. Преобразовав его в десятичный вид мы получаем первую половину серийника, то есть 111111. Таким образом, первая часть серийника должна быть десятичным числом больше 267D40h или 2522432. Не вопрос, прибавим пару единичек к стартовому значению и снова пробуем регистрацию с серийником "2522434-abcdefgh".

Сообщение о неправильной регистрации
Сообщение о неправильной регистрации

На этот раз поведение программы изменилось, выводится сообщение о неправильном серийном номере в виде подсказки у поля ввода. Значит первая половина серийника принята и проверка обламывается на второй половине. Смотрим в листинге дизассемблера, куда бы был выполнен переход в случае первой успешной проверки.
  1. ; Сюда мы попадаем после успешной первой поверки
  2. .text:0046BBBA                 lea     eax, [esp+0CC8h+var_CB8]
  3. .text:0046BBBE                 push    eax
  4. .text:0046BBBF                 push    esi
  5. .text:0046BBC0                 lea     edi, [esp+0CD0h+Data]
  6. .text:0046BBC7                 mov     [esp+0CD0h+var_CB8], ebx
  7. ; вызвать функцию следующей проверки
  8. .text:0046BBCB                 call    sub_46CFD3
  9. .text:0046BBD0                 cmp     [esp+0CC8h+var_CB8], ebx
  10. .text:0046BBD4                 mov     edi, [esp+0CC8h+var_CB0]
  11. ; Сохранить ее результат из регистра AL в ячейку памяти
  12. .text:0046BBD8                 mov     [esp+0CC8h+var_CB1], al
  13. .text:0046BBDC                 jnz     short loc_46BBED
  14. .text:0046BBDE                 push    esi
  15. .text:0046BBDF                 push    edi
  16. .text:0046BBDE                 push    esi
  17. .text:0046BBDF                 push    edi
  18. ; Онлайн-проверка, но если программу не выпускать в интернет, то все нормально
  19. .text:0046BBE0                 call    sub_46BF70
  20. .text:0046BBE5                 test    al, al
  21. .text:0046BBE7                 jz      loc_46BCA5
  22. .text:0046BBED loc_46BBED:
  23. ; Сравнить сохраненное значение регистра с нулем
  24. .text:0046BBED                 cmp     [esp+0CC8h+var_CB1], bl
  25. ; Если ноль, то серийниый номер неправильный
  26. .text:0046BBF1                 jz      loc_46BC7E
  27. ; Сохранить введенный серийник и поблагодарить за регистрацию
  28. .text:0046BBF7                 push    esi             ; Args
  29. .text:0046BBF8                 push    offset aId      ; "ID"
  30. .text:0046BBFD                 mov     esi, offset aRegistration
  31. ; "Registration"
  32. .text:0046BC02                 push    esi             ; int
  33. .text:0046BC03                 mov     dword_538CAC, ebx
  34. .text:0046BC09                 call    sub_401E41
  35. .text:0046BC0E                 lea     eax, [esp+0CC8h+Data]
  36. .text:0046BC15                 push    eax             ; lpData
  37. .text:0046BC16                 push    offset aKey     ; "Key"
Посмотрим функцию проверки, отвечающую за вторую половину серийника. Сперва в дизассемблере, где мы видим несколько операций сравнений.
  1. .text:0046CFD3                 push    ebp
  2. .text:0046CFD4                 mov     ebp, esp
  3. .text:0046CFD6                 mov     eax, [ebp+arg_0]
  4. .text:0046CFD9                 sub     esp, 208h
  5. .text:0046CFDF                 push    ebx
  6. .text:0046CFE0                 push    esi
  7. .text:0046CFE1                 push    64h
  8. .text:0046CFE3                 pop     ecx
  9. .text:0046CFE4                 xor     edx, edx
  10. .text:0046CFE6                 div     ecx
  11. .text:0046CFE8                 mov     ebx, [ebp+arg_4]
  12. .text:0046CFEB                 lea     esi, [ebp+var_208]
  13. .text:0046CFF1                 push    eax
  14. ; Из первой половины серийника вычислить контрольную строку
  15. .text:0046CFF2                 call    sub_46CE57
  16. ; Первый символ строки и первый символ второй половины серийника
  17. .text:0046CFF7                 mov     ax, [ebp+var_208]
  18. .text:0046CFFE                 cmp     ax, [edi]
  19. .text:0046D001                 jnz     short loc_46D063
  20. ; Второй символ строки и второй символ второй половины серийника
  21. .text:0046D003                 mov     ax, [ebp+var_206]
  22. .text:0046D00A                 cmp     ax, [edi+2]
  23. .text:0046D00E                 jnz     short loc_46D063
  24. ; Третий символ строки и третий символ второй половины серийника
  25. .text:0046D010                 mov     ax, [ebp+var_204]
  26. .text:0046D017                 cmp     ax, [edi+4]
  27. .text:0046D01B                 jnz     short loc_46D063
  28. ; Четвертый символ строки и четвертый символ второй половины серийника
  29. .text:0046D01D                 mov     ax, [ebp+var_202]
  30. .text:0046D024                 cmp     ax, [edi+6]
  31. .text:0046D028                 jnz     short loc_46D063
  32. ; Пятый символ второй половины серийника должен быть "c"
  33. .text:0046D02A                 cmp     word ptr [edi+8], 63h
  34. .text:0046D02F                 jnz     short loc_46D063
  35. ; Шестой символ второй половины серийника должен быть "l"
  36. .text:0046D031                 cmp     word ptr [edi+0Ah], 6Ch
  37. .text:0046D036                 jnz     short loc_46D063
  38. .text:0046D038                 mov     eax, edi
  39. .text:0046D03A                 mov     dword ptr [ebx], 1
  40. .text:0046D040                 lea     edx, [eax+2]
  41. ; Проверить количество символов во второй половине серийника
  42. .text:0046D043 loc_46D043:
  43. .text:0046D043                 mov     cx, [eax]
  44. .text:0046D046                 inc     eax
  45. .text:0046D047                 inc     eax
  46. .text:0046D048                 test    cx, cx
  47. .text:0046D04B                 jnz     short loc_46D043
  48. .text:0046D04D                 sub     eax, edx
  49. .text:0046D04F                 sar     eax, 1
  50. ; Количество символов должно быть равно 8
  51. .text:0046D051                 cmp     eax, 8
  52. .text:0046D054                 jnz     short loc_46D0C1
  53. ; Сравнить первую половину серийника со значением 100000000
  54. .text:0046D056                 cmp     [ebp+arg_0], 5F5E100h
  55. .text:0046D05D                 jbe     short loc_46D063
  56. .text:0046D05F loc_46D05F:
  57. ; Если больше 100000000 и проверки второй половины пройдены, то серийник
  58. ; считается правильным, установить AL=1 и выйти из функции проверки
  59. .text:0046D05F                 mov     al, 1
  60. .text:0046D061                 jmp     short loc_46D0C9
Такие участки кода в статике анализировать не очень удобно, лучше всего посмотреть процесс сравнений под отладчиком. Ставим точку останова на начало функции и повторяем процесс регистрации. Все обнаруженное я отобразил в комментариях к коду, продублирую словами. На основании первой половины серийника генерируется строка из 6 символов. Первые четыре из них должны равняться первым четырем символам второй части серийника, пятый и шестой символы второй части являются постоянными и должны равняться строчке "cl" ("corporate license"?), последние два символа в проверке не используются, но должны быть, чтобы общая длина второй половины серийника была строго 8 символов. А самое интересное, что в случае выполнения этих условий снова проверяется первая часть серийника, и, если она больше 100000000, то серийный номер признается корректным. Дальше по коду есть еще одна проверка, похожая на эту, только контрольная строка другая. Похоже на проверку "single license". Но нам вполне достаточно найденных условий. В свете новой линии партии тестовый серийник превращается в "100000001-abcdclmh". Повторяем регистрацию. Остановившись на генерации контрольной строки, выясняем, что заветные четыре контрольных символа в этом случае должны быть "zuhh". И вот момент истины, искомый серийный номер получается "100000001-zuhhclmh". Закрываем отладчик, запускаем программу в обычном режиме и регистрируем ее свеженаколдованным серийным номером:

Программа успешно зарегистрирована
Программа успешно зарегистрирована

Программа успешно зарегистрирована
Программа успешно зарегистрирована

В принципе, на этом можно было и остановиться, валидный серийный номер есть, программа работает без ограничений. Но в качестве приятного бонуса разберем алгоритм генерации контрольной строки. Начнем с того, что выясним, какое именно значение передается для генерации.
  1. ; Первая часть серийника
  2. .text:0046CFD6                 mov     eax, [ebp+arg_0]
  3. .text:0046CFD9                 sub     esp, 208h
  4. .text:0046CFDF                 push    ebx
  5. .text:0046CFE0                 push    esi
  6. ; Делитель = 100
  7. .text:0046CFE1                 push    64h
  8. .text:0046CFE3                 pop     ecx
  9. .text:0046CFE4                 xor     edx, edx
  10. .text:0046CFE8                 mov     ebx, [ebp+arg_4]
  11. .text:0046CFEB                 lea     esi, [ebp+var_208]
  12. .text:0046CFF1                 push    eax
  13. .text:0046CFF2                 call    sub_46CE57
  14. ; Разделить первую часть серийника
  15. .text:0046CFE6                 div     ecx
  16. .text:0046CFE8                 mov     ebx, [ebp+arg_4]
  17. .text:0046CFEB                 lea     esi, [ebp+var_208]
  18. ; Передать результат деления в генератор
  19. .text:0046CFF1                 push    eax
  20. .text:0046CFF2                 call    sub_46CE57
Теперь разберем по шагам генератор контрольной строки. Для удобства я буду называть результат деления первой части серийника контрольным числом. Еще я немного поменял несколько участков кода, чтобы было наглядно и более логично. На функционал это не влияет.
  1. ; Инициализация строки начальным значением "abcdef"
  2. .text:0046CE60                 mov     eax, offset aAbcdef ; "abcdef"
  3. .text:0046CE65                 call    sub_401039
  4. ...
  5. ...
  6. ; Заполнить первый массив указателями на шестисимвольные строки
  7. .text:0046CE74                 mov     [ebp+var_44], offset aMnbvaq ; "mnbvaq"
  8. .text:0046CE7B                 mov     [ebp+var_40], offset aCxzlbr ; "cxzlbr"
  9. .text:0046CE82                 mov     [ebp+var_3C], offset aKjhgct ; "kjhgct"
  10. .text:0046CE89                 mov     [ebp+var_38], offset aFdsady ; "fdsady"
  11. .text:0046CE90                 mov     [ebp+var_34], offset aPoiueu ; "poiueu"
  12. .text:0046CE97                 mov     [ebp+var_30], offset aYtrefo ; "ytrefo"
  13. .text:0046CE9E                 mov     [ebp+var_2C], offset aWqalgx ; "wqalgx"
  14. .text:0046CEA5                 mov     [ebp+var_28], offset aKsjdhv ; "ksjdhv"
  15. .text:0046CEAC                 mov     [ebp+var_24], offset aHfgbif ; "hfgbif"
  16. ; Заполнить второй массив указателями на шестисимвольные строки
  17. .text:0046CEB3                 mov     ebx, offset aQazwja ; "qazwja"
  18. .text:0046CEB8                 mov     edi, offset aTgbymh ; "tgbymh"
  19. .text:0046CEBD                 mov     ecx, esi
  20. .text:0046CEBF                 mov     [ebp+var_20], ebx
  21. .text:0046CEC2                 mov     [ebp+var_1C], offset aSxedkf ; "sxedkf"
  22. .text:0046CEC9                 mov     [ebp+var_18], offset aCrfvlg ; "crfvlg"
  23. .text:0046CED0                 mov     [ebp+var_14], edi
  24. .text:0046CED3                 mov     [ebp+var_10], offset aHnujni ; "hnujni"
  25. .text:0046CEDA                 mov     [ebp+var_C], offset aMiklop ; "miklop"
  26. .text:0046CEE1                 mov     [ebp+var_8], offset aPlokpc ; "plokpc"
Контрольная строка инициализируется начальным значением "abcdef", заполняется два массива указателями на строки. Дальше выполняется несколько похожих операций.
  1. ; Поделить контрольное число на 9
  2. .text:0046CE6A                 mov     eax, [ebp+arg_0]
  3. .text:0046CE6D                 push    9
  4. .text:0046CE6F                 pop     ecx
  5. .text:0046CE70                 xor     edx, edx
  6. .text:0046CE72                 div     ecx
  7. ...
  8. ...
  9. ; Сохранить результат деления. В регистре EDX остаток от деления
  10. .text:0046CEE8                 mov     [ebp+var_4], eax
  11. ; Указатель на элемент первого массива строк
  12. .text:0046CEEB                 mov     eax, [ebp+edx*4+var_44]
  13. ; Функция преобразования
  14. .text:0046CEEF                 call    sub_46CDB1
Небольшое отступление на функцию преобразования. Ее оригинальный текст вы можете посмотреть сами, тут я его приводить не буду. Если ее свернуть в псевдокод при помощи плагина Hex-Rays, а потом еще привести в человеческий вид, то все преобразование сведется к следующим действиям:

; cstr - контрольная строка
; mstr - строка из массива, выбранная по номеру (указателю)
cstr[0] = (cstr[0] + mstr[0] - 194) % 26 + 97
cstr[1] = (cstr[1] + mstr[1] - 194) % 26 + 97
cstr[2] = (cstr[2] + mstr[2] - 194) % 26 + 97
cstr[3] = (cstr[3] + mstr[3] - 194) % 26 + 97
cstr[4] = (cstr[4] + mstr[4] - 194) % 26 + 97
cstr[5] = (cstr[5] + mstr[5] - 194) % 26 + 97

Едем дальше. На втором шаге контрольная строка преобразуется с элементом из второго массива строк.
  1. ; Результат предыдущего деления контрольного числа
  2. .text:0046CEF4                 mov     eax, [ebp+var_4]
  3. ; Делитель
  4. .text:0046CEF7                 push    7
  5. .text:0046CEF9                 pop     ecx
  6. .text:0046CEFA                 xor     edx, edx
  7. .text:0046CEFC                 div     ecx
  8. .text:0046CEFE                 mov     ecx, esi
  9. ; Указатель на строку второго массива
  10. .text:0046CF00                 mov     eax, [ebp+edx*4+var_20]
  11. .text:0046CF04                 call    sub_46CDB1
Тут номер элемента получается из остатка деления результата первого деления контрольного числа на 7.
  1. ; Контрольное число делится на 63
  2. .text:0046CF09                 mov     eax, [ebp+arg_0]
  3. .text:0046CF0C                 push    3Fh
  4. .text:0046CF0E                 xor     edx, edx
  5. .text:0046CF10                 pop     ecx
  6. .text:0046CF11                 div     ecx
  7. ; Результат деления делится еще на 9
  8. .text:0046CF13                 push    9
  9. .text:0046CF15                 pop     ecx
  10. .text:0046CF16                 xor     edx, edx
  11. ; Результат этого деления - новое контрольное число
  12. .text:0046CF18                 mov     [ebp+arg_0], eax
  13. ; Делим новое контрольное число на 9
  14. .text:0046CF1B                 div     ecx
  15. .text:0046CF1D                 mov     ecx, esi
  16. ; Сохранить результат деления
  17. .text:0046CF1F                 mov     [ebp+var_4], eax
  18. ; Указатель на строку из первого массива
  19. .text:0046CF22                 mov     eax, [ebp+edx*4+var_44]
  20. ; Функция преобразования
  21. .text:0046CF26                 call    sub_46CDB1
На этом шаге контрольное число меняется. Сперва оно делится на 63, затем на 9. Новое контрольное число делится еще раз на 9, остаток - номер элемента из первого массива строк, результат деления сохраняется на будущее.
  1. ; Сохраненный результат деления
  2. .text:0046CF2B                 mov     eax, [ebp+var_4]
  3. .text:0046CF2E                 push    7
  4. .text:0046CF30                 pop     ecx
  5. .text:0046CF31                 xor     edx, edx
  6. ; Поделить на 7
  7. .text:0046CF33                 div     ecx
  8. .text:0046CF35                 mov     ecx, esi
  9. ; Остаток - номер элемента второго массива
  10. .text:0046CF37                 mov     eax, [ebp+edx*4+var_20]
  11. ; Функция преобразования
  12. .text:0046CF3B                 call    sub_46CDB1
Сохраненный результат деления делится на 7, остаток является номером строки из второго массива.
  1. ; Контрольное число
  2. .text:0046CF40                 mov     eax, [ebp+arg_0]
  3. .text:0046CF43                 push    3Fh
  4. .text:0046CF45                 xor     edx, edx
  5. .text:0046CF47                 pop     ecx
  6. .text:0046CF48                 div     ecx
  7. .text:0046CF4A                 push    9
  8. .text:0046CF4C                 pop     ecx
  9. .text:0046CF4D                 xor     edx, edx
  10. .text:0046CF4F                 mov     [ebp+arg_0], eax
  11. .text:0046CF52                 div     ecx
  12. .text:0046CF54                 mov     ecx, esi
  13. .text:0046CF56                 mov     [ebp+var_4], eax
  14. .text:0046CF59                 mov     eax, [ebp+edx*4+var_44]
  15. .text:0046CF5D                 call    sub_46CDB1
Точно так же еще раз меняется контрольное число. Оно снова делится на 63 и на 9. Результат деления вновь делится на 9, остаток - указатель на элемент первого массива, результат сохраняется. Все точно так же, как на предыдущем шаге.
  1. .text:0046CF62                 mov     eax, [ebp+var_4]
  2. .text:0046CF65                 push    7
  3. .text:0046CF67                 xor     edx, edx
  4. .text:0046CF69                 pop     ecx
  5. .text:0046CF6A                 div     ecx
  6. .text:0046CF6C                 mov     eax, [ebp+edx*4+var_20]
  7. .text:0046CF70                 mov     ecx, esi
  8. .text:0046CF72                 call    sub_46CDB1
Это мы уже видели. Делим сохраненный результат на 7, из остатка получаем номер элемента второго массива.
  1. .text:0046CF77                 mov     eax, [ebp+arg_0]
  2. .text:0046CF7A                 push    3Fh
  3. .text:0046CF7C                 xor     edx, edx
  4. .text:0046CF7E                 pop     ecx
  5. .text:0046CF7F                 div     ecx
  6. .text:0046CF81                 push    9
  7. .text:0046CF83                 pop     ecx
  8. .text:0046CF84                 xor     edx, edx
  9. .text:0046CF86                 div     ecx
  10. .text:0046CF88                 mov     ecx, esi
  11. .text:0046CF8A                 mov     [ebp+arg_0], eax
  12. .text:0046CF8D                 mov     eax, [ebp+edx*4+var_44]
  13. .text:0046CF91                 call    sub_46CDB1
  14. .text:0046CF96                 mov     eax, [ebp+arg_0]
  15. .text:0046CF99                 push    7
  16. .text:0046CF9B                 pop     ecx
  17. .text:0046CF9C                 xor     edx, edx
  18. .text:0046CF9E                 div     ecx
  19. .text:0046CFA0                 mov     ecx, esi
  20. .text:0046CFA2                 mov     eax, [ebp+edx*4+var_20]
  21. .text:0046CFA6                 call    sub_46CDB1
Тут даже комментировать не буду, снова повторяются два шага.
  1. ; Если забыли, то регистры указывают на эти строки
  2. .text:0046CEB3                 mov     ebx, offset aQazwja ; "qazwja"
  3. .text:0046CEB8                 mov     edi, offset aTgbymh ; "tgbymh"
  4. ...
  5. ...
  6. ...
  7. .text:0046CFAB                 mov     eax, offset aKjhgct ; "kjhgct"
  8. .text:0046CFB0                 call    sub_46CDB1
  9. ; Смотри выше
  10. .text:0046CFB5                 mov     eax, edi
  11. .text:0046CFB7                 call    sub_46CDB1
  12. .text:0046CFBC                 mov     eax, offset aMnbvaq ; "mnbvaq"
  13. .text:0046CFC1                 call    sub_46CDB1
  14. ; Смотри выше
  15. .text:0046CFC6                 mov     eax, ebx
  16. .text:0046CFC8                 call    sub_46CDB1
И последний этап - четыре преобразования с фиксированными строками. Две вызываются по адресу, адреса двух других берутся из регистров, куда они были записаны при заполнении массивов. Это уже происки компилятора, оптимизация, понимаешь. После всех преобразований на выходе получается готовая контрольная строка. Писанины много, на самом деле алгоритм совсем не сложный.

Вот и все, теперь можно писать генератор ключей аж на корпоративную лицензию. Остальные продукты разработчика кейгенятся аналогичным образом, защита там похожая.

Поделиться ссылкой ВКонтакте
Просмотров: 3056 | Комментариев: 2

Внимание! Статья опубликована больше года назад, информация могла устареть!

Комментарии

Отзывы посетителей сайта о статье
ManHunter (19.09.2017 в 06:34):
Конечно можно, и не одним способом.
xussr (19.09.2017 в 06:22):
Можно и пропачить
CPU Disasm
Address   Hex dump          Command                                  Comments
00CCC458  |.  5B            POP EBX
00CCC459  |.  C9            LEAVE
00CCC45A  |.  C3            RETN
00CCC45B  |>  8D4D FC       LEA ECX,[LOCAL.1]
00CCC45E  |.  51            PUSH ECX                                 ; /Arg2 => OFFSET LOCAL.1
00CCC45F  |.  50            PUSH EAX                                 ; |Arg1
00CCC460  |.  8DBD F0FDFFFF LEA EDI,[LOCAL.132]                      ; |
00CCC466  |.  8975 FC       MOV DWORD PTR SS:[LOCAL.1],ESI           ; |
00CCC469  |.  E8 650B0000   CALL 00CCCFD3                            ; \pixillion.00CCCFD3
00CCC46E  |.  84C0          TEST AL,AL
00CCC470  |.^ 74 D2         JZ SHORT 00CCC444
00CCC472  |.  2135 AC8CD900 AND DWORD PTR DS:[0D98CAC],ESI
00CCC478  |.  B0 01         MOV AL,1
00CCC47A  \.^ EB DA         JMP SHORT 00CCC456
00CCC47C  /$  53            PUSH EBX
00CCC47D  |.  56            PUSH ESI

Добавить комментарий

Заполните форму для добавления комментария
Имя*:
Текст комментария (не более 2000 символов)*:

*Все поля обязательны для заполнения.
Комментарии, содержащие рекламу, ненормативную лексику, оскорбления и т.п., а также флуд и сообщения не по теме, будут удаляться. Нарушителям может быть заблокирован доступ к сайту.
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2024
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.08 сек. / MySQL: 2 (0.0097 сек.) / Память: 4.5 Mb
Наверх