Введение в крэкинг с нуля, используя OllyDbg - Глава 30

Дата публикации 9 июл 2008

Введение в крэкинг с нуля, используя OllyDbg - Глава 30 — Архив WASM.RU



Файлы к статье

Ок, после того, как попрактиковались, и если вы ещё живы, продолжаем с PCODE.

У нас есть ещё кое-какие опкоды, собранные из туториалов JBDUC’а.

  • 6c -> ILdRf Поместить адрес в стек
  • 1b -> LitStr5 Поместить строку в стек
  • fb -> Lead0 Сравнить две строки (хе-хе, для чего это могло служить )
  • 30 -> EqStr Сравнить две строки(хе-хе, для чего это могло служить )
  • 2f -> FFree1Str Освободить используемую память
  • 1a -> FFree1Ad Освободить используемую память
  • 0f -> VCallAd Выполнить опкод в виртуальной машине
  • 1c -> BranchF Сделать переход, если предшествующее сравнение дало ложь ( аналог jne/jnz в ассемблере )
  • 1d -> BranchT Сделать переход, если предшествующее сравнение дало истину ( аналог je/jz в ассемблере )
  • 1e -> Безусловный переход ( хе-хе, угадайте, для чего её можно использовать )
  • fc -> Lead1 Прерывает выполнение программы (хе-хе, прекрасно...)
  • c8 -> End Прерывает выполнение программы (хе-хе, прекрасно...)
  • f3 -> LitI2 Сохраняет заданное число типа Integer в стек
  • f4 -> LitI2_Byte Конвертирует Byte-значение в Integer и помещает его в стек
  • 70 -> FStI2 Сохраняет последний Integer, помещённый в стек, в заданную глобальную переменную
  • 6b -> FLdI2 Загружает в стек Integer из заданной локальной переменной
  • a9 -> AddI2 Складывает два последних Integer'а, помещённых в стек, на вершину которого помещает результат
  • ad -> SubI2 Использует для вычитания два последних Integer’а, помещённых в стек, и кладёт в последний результат
  • b1 -> MulI2 Умножает два последних Integer’а, помещённых в стек, и кладёт в последний результат. Думаю, что если переполнение игнорируется.

Ок, есть ещё опкоды, которые мы сейчас рассматривать не будем. К статье прилагает файл под названием “P-CODE OPCODES”, который, предположительно, распространялся Микрософтом. Он может немного помочь, так как в нём перечислены опкоды и что они делают (но не все, хе-хе), так что если встретим незнакомый опкод, то можем посмотреть, есть ли там описание.

Как я и обещал вам, сначала рассмотрим крэкми «clave 2», которое осталось у нас в качестве домашнего упражнения с прошлого раза. Посмотрим, можем ли мы получить листинг с помощью EXDEC’а.

Вот он, и видим, что начинается с 401cc0. Не будем слепо верить EXDEC’у, так как бывали случаи, когда он обманывал. Посмотрим, сможем ли мы найти первый опкод вручную, как мы это делали в предыдущей части.

Смотрим, находится ли переход на API-функцию MethCallEngine за EP.

Вот он. Становимся на него, делаем FOLLOW, чтобы перейти к API-функции и также устанавливаем там BP.

Готово, теперь делаем RUN, чтобы остановиться на одном из установленных BP.

Окно появляется до того, как сработает останов, дело в том, что окно появляется до того, как начинается P-CODE, хотя нужно пояснить, что такое бывает не всегда, может сначала сработать останов, а потом появиться окно, но в данном случае оно сделало это первым. Вводим имя и неправильный серийный номер.

После нажатия на «REGISTRAR» срабатывает останов на JMP. Идём в первую секцию (помните, что не надо использовать пропатченный OllyDbg для OEP’ов) и устанавливаем “BPM ON ACCESS” на секцию кода.

Теперь жмём RUN, пока не встретится знакомая инструкция, где читается опкод.

Вот тут, помним, что ESI всегда должен указывать на опкод (который сам перемещается в AL).

Как видим, EXDEC не ошибся, и первый опкод – это 04 и начинается с 401cc0.

Код (Text):
  1.  
  2. Proc: 401e90
  3. 401CC0: 04 FLdRfVar                local_008C

Помним, что 04 – это просто PUSH, в данном случае его аргументом является EBP-8C, как это видно из пояснения рядом с опкодом

Код (Text):
  1.  
  2. 04    567B 0B8E 2 1 2      Push arg

Из этого нам становится понятно, что каждая цифра, в нашем случае 0B8E, является RVA опкода, 2 – это количество байтов, которые в общей сложности занимают параметры, 1 нам говорит, что аргумент только один, и последнее значение (2) указывает нам размер, занимаемый каждым аргументом в отдельности.

Хорошо, вот PUSH EBP-8C, продолжаем изучать исходник, пока без трассировки шаг за шагом. Смотрим.

Код (Text):
  1.  
  2. 401D4C: 0d VCallHresult            get__ipropTEXTEDIT
  3.  
  4. 401DFB: 0d VCallHresult            get__ipropTEXTEDIT

Видим, что используется два вызова для считывания введённого в окне регистрации, вероятно, что в первый раз читает имя, а во второй – неправильный серийник, использованный нами. Устанавливаем BPM ON ACCESS на первом вызове, то есть на 401d4C.

Allí esta el opcode y le coloco el BPM y doy RUN.

Вот опкод, устанавливаем на него BPM и делаем RUN.

Bueno ahora traceemos hasta el siguiente opcode, a ver si ingresa el nombre.

Ок, теперь трассируем до следующего опкода, чтобы посмотреть, что будет происходить с именем.

Дошли до следующего опкода, смотрим стек, чтобы узнать, что там находится

Код (Text):
  1.  
  2. 401D4C: 0d VCallHresult            get__ipropTEXTEDIT
  3. 401D51: 3e FLdZeroAd               local_008C

Как видим, продолжается работа с локальной переменной 8c (или EBP-8C). Проверим, что там сохранено. На моей машине в ebp-8c содержит 12f454.

Busco en el stack esa dirección a ver si esta allí mi nombre

Ищем этот адрес в стеке и видим, что там находится моё имя.

Конечно же, оно находится здесь, так что всё идёт хорошо. Раз здесь находится моё имя, то логично предположить, что в следующем будет идти работа с серийником, поэтому устанавливаем на второй опкод BPM ON ACCESS.

Код (Text):
  1.  
  2. 401DFB: 0d VCallHresult            get__ipropTEXTEDIT

Готово, теперь жмём RUN, чтобы оказаться рядом с этим опкодом.

Как и в предыдущем случае, трассируем до следующего опкода.

И смотрим, сохранён ли в используемой переменной неправильный серийный номер.

Код (Text):
  1.  
  2. 401DFB: 0d VCallHresult            get__ipropTEXTEDIT
  3. 401E00: 3e FLdZeroAd               local_008C

Как и в прошлый раз используется EBP-8C.

Хорошо, вот мы и дошли до места, куда помещён наш неправильный серийник. Видим, что зная опкоды, не обязательно трассировать всю программу, можем просто установить BPM и оказаться в нужной части программы. В прошлой главе мы трассировали всё подряд, чтобы понять механизмы, согласно которым работает PCODE, но как правильно, нам не нужно делать это. Как мы увидим в следующей главе, когда исследуем большую программу, будем локализовывать интересующую нас часть программы и работать именно с ней.

Код (Text):
  1.  
  2. 401E0F: Lead0/ef ConcatVar        
  3. 401E13: Lead0/40 NeVarBool        
  4. 401E15: 1a FFree1Ad                local_0088
  5. 401E18: 36 FFreeVar         local_00CC local_00AC
  6. 401E1F: 1c BranchF:                401E59

Далее видим, что здесь есть все признаки сравнения, потом освобождение локальных переменных с помощью FREE, а затем условный переход, который ведёт в 401e59, где вызывается rtcMsgBox с сообщением о правильном серийном номере, а если перехода не происходит, то отображается сообщение о том, что серийник неверен.

Тут всё совершенно понятно. Вероятное сравнение и условный переход, в зависимости от которого отображается окошко с соответствующим сообщением, так что устанавливаем сюда BPM ON ACCESS.

Код (Text):
  1.  
  2. 401E0F: Lead0/ef ConcatVar        
  3. 401E13: Lead0/40 NeVarBool

Ок, делаем RUN.

Останавливаемся тут, в первом опкоде и трассируем до второго, который производит некую операцию.

Второй опкод равен EF.

Смотрим в списке опкодов.

Код (Text):
  1.  
  2. FB EF 6BAB 25AD 2                                                                                                                                                                            
  3. FB F0 6B99 259B 0          vbaStrCat                                                                                                                                                        
  4. FB F1 C423 B981 0          Push [FC0D134]

Что такое FB EF нам ещё не совсем понятно, EXDEC говорит нам что-то о конкатенации переменных, смотрим.

Код (Text):
  1.  
  2. 401E07: 3a LitVarStr:              ( local_009C ) CRK
  3. 401E0C: 04 FLdRfVar                local_018C
  4. 401E0F: Lead0/ef ConcatVar        
  5. 401E13: Lead0/40 NeVarBool

Видим, что прямо до этого опкода идёт работа с двумя локальными переменными, в одной из которых находится строка CRK, а другая является EBP-018C. Выясним, что находится в каждой из вышеупомянутых переменных.

Первая переменная – это EBP-9C, которая на моей машине равна 12f444 и находится там следующее:

Как мы знаем, в случае с переменными сначала идёт байт, указывающий тип, в данном случае это 3, а ещё выше находится сама переменная, которая равна 2EA.

Входим в опкод.

Здесь читаются параметры.

После сложения с EBP получается 12f434.

Доходим до API-функции vbaVarCat, у которой три аргумента в стеке.

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

Это первый аргумент.

Во втором сначала идёт 3, а потом 02EA, задающее значение.

А в третьем в начале 8, означающее, что 4017648 – это указатель на строку CRK.

Ок, у нас тут мешанина из переменных, посмотрим, что останется. Если войдём в функцию vbaVarCat, до окажемся у внутренней API-функции, которая ясно покажет нам, что будет объединяться.

То есть предстоит объединение CRK с 746. А теперь выясним, что значит параметр 02EA.

Lo transforma a string ya que 02EA es

Он конвертируется в строку. 02EA – это:

То есть vbaVarCat в данном случае получила строку и численную переменную, которая конвертируется в строку, после чего обе объединяются.

Продолжаем трассировать с помощью F8.

Дойдя до RET’а из функции, видим:

Обе переменных объединились в одну строку.

И, как и раньше, до начала следующего опкода это значение сохраняется в качестве первого аргумента.

Видим, что первый аргумент сейчас имеет тип 8, то есть строку, и указывает на 15d88c, то есть на сконкатенированную строку.

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

Код (Text):
  1.  
  2. 401E13: Lead0/40 NeVarBool

Это FB40, и он двойной. Трассируем, пока не дойдём до считывания второго опкода.

Конечно, список опкодов от Микрософта ничего нам о нём не говорит, так что трассируем опкод, чтобы узнать, что он делает.

Видим, что в опкоде всего один вызов, после которого сразу следует завершение. Смотрим параметры вызова.

Первый равен нулю, а второй 12f434. Смотрим, что там находится.

Ок, 08 говорит нам, что это строка, теперь осталось посмотрим, на что указывает 15d88c.

Вот строка, смотрим следующий аргумент.

В данном случае 15ca94 указывает на строку с нашим неправильным серийным номером.

Похоже, что это сравнение двух строк.

Чтобы рассеять сомнения, устанавливаем BP, минуем вызов с помощью f8 и идём к следующему опкоду.

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

Нажимаем на кнопку “Registrar”.

Снова оказались у этого вызова, проходим его с помощью F8 и идём к следующему опкоду, как в прошлый раз.

Видим, что в данном случае результатом является ноль, так как обе строки одинаковы.

Как мы увидели, не обязательно трассировать всё подряд. Нужно найти подозрительную область и трассировать только неизвестные опкоды. Этого оказалось достаточным, чтобы найти серийный номер исследуемой программы.

Для заинтересованных – более детализированный список, где изложены сведения, которые нам удалось узнать.

Код (Text):
  1.  
  2. 401CC0: 04 FLdRfVar                local_008C
  3. 401CC3: 21 FLdPrThis                                ; Load reference pointer into item pointer. Загрузка ссылочного указателя в указатель на элемент
  4. 401CC4: 0f VCallAd                 text         ; Доступ к методу ITEM DESCRIPTOR TABLE
  5. 401CC7: 19 FStAdFunc               local_0088
  6. 401CCA: 08 FLdPr                   local_0088
  7. 401CCD: 0d VCallHresult            get__ipropTEXTEDIT       ; Читаем содержимое из текстового поля
  8. 401CD2: 6c ILdRf                   local_008C           ; Имя   
  9. 401CD5: 1b LitStr:                 &                ; Поместить строку в стек
  10. 401CD8: Lead0/30 EqStr                              ; Сравнить две строки
  11. 401CDA: 2f FFree1Str               local_008C
  12. 401CDD: 1a FFree1Ad                local_0088
  13. 401CE0: 1c BranchF:                401CE6               ; Переход, если сравнение не удалось
  14. 401CE3: 1e Branch:                 401e8c               ; Безусловный переход
  15. 401CE6: 04 FLdRfVar                local_008C
  16. 401CE9: 21 FLdPrThis              
  17. 401CEA: 0f VCallAd                 text         ; Доступ к методу ITEM DESCRIPTOR TABLE
  18. 401CED: 19 FStAdFunc               local_0088
  19. 401CF0: 08 FLdPr                   local_0088
  20. 401CF3: 0d VCallHresult            get__ipropTEXTEDIT       ; Читаем содержимое текстового поля
  21. 401CF8: 6c ILdRf                   local_008C           ; Имя
  22. 401CFB: 4a FnLenStr              
  23. 401CFC: f5 LitI4:                  0x6  6  (....)       ; Передаём элемент из 4-ёх байт
  24. 401D01: d1 LtI4                                     ; Сравнение меньше чем (?)
  25. 401D02: 2f FFree1Str               local_008C
  26. 401D05: 1a FFree1Ad                local_0088
  27. 401D08: 1c BranchF:                401D3F               ; Переход если ложноSalta si falso (>= 6)
  28. 401D0B: 27 LitVar_Missing        
  29. 401D0E: 27 LitVar_Missing        
  30. 401D11: 3a LitVarStr:              ( local_00BC ) P-Code
  31. 401D16: 4e FStVarCopyObj           local_00CC
  32. 401D19: 04 FLdRfVar                local_00CC
  33. 401D1C: f5 LitI4:                  0x40  64  (...@)
  34. 401D21: 3a LitVarStr:              ( local_009C ) Минимум 6 символов
  35. 401D26: 4e FStVarCopyObj           local_00AC
  36. 401D29: 04 FLdRfVar                local_00AC
  37. 401D2C: 0a ImpAdCallFPR4:          _rtcMsgBox
  38. 401D31: 36 FFreeVar         local_00AC local_00CC local_00EC local_010C
  39. 401D3C: 1e Branch:                 401e8c               ;Если < 6 символов в строке
  40. 401D3F: 04 FLdRfVar                local_008C
  41. 401D42: 21 FLdPrThis              
  42. 401D43: 0f VCallAd                 text
  43. 401D46: 19 FStAdFunc               local_0088
  44. 401D49: 08 FLdPr                   local_0088
  45. 401D4C: 0d VCallHresult            get__ipropTEXTEDIT       ; Читаем содержимое текстового поля
  46. 401D51: 3e FLdZeroAd               local_008C           ; Имя
  47. 401D54: 46 CVarStr                 local_00AC
  48. 401D57: 04 FLdRfVar                local_00CC
  49. 401D5A: 0a ImpAdCallFPR4:          _rtcLowerCaseVar     ; Конвертируем в строчные символы
  50. 401D5F: 04 FLdRfVar                local_00CC
  51. 401D62: 04 FLdRfVar                local_00EC
  52. 401D65: 0a ImpAdCallFPR4:          _rtcTrimVar
  53. 401D6A: 04 FLdRfVar                local_00EC
  54. 401D6D: Lead1/f6 FStVar            local_011C
  55. 401D71: 1a FFree1Ad                local_0088
  56. 401D74: 36 FFreeVar         local_00AC local_00CC
  57. 401D7B: 04 FLdRfVar                local_011C
  58. 401D7E: Lead0/eb FnLenVar        
  59. 401D82: Lead1/f6 FStVar            local_012C
  60. 401D86: 28 LitVarI2:               ( local_00BC ) 0x1  (1)
  61. 401D8B: 04 FLdRfVar                local_013C
  62. 401D8E: 04 FLdRfVar                local_012C
  63. 401D91: Lead3/68 ForVar:           (when done) 401DE0       , Начало цикла for next
  64. 401D97: 28 LitVarI2:               ( local_00AC ) 0x1  (1)
  65. 401D9C: 04 FLdRfVar                local_013C
  66. 401D9F: Lead1/22 CI4Var          
  67. 401DA1: 04 FLdRfVar                local_011C
  68. 401DA4: 04 FLdRfVar                local_00CC
  69. 401DA7: 0a ImpAdCallFPR4:          _rtcMidCharVar       ; Загрузка символов из...
  70. 401DAC: 04 FLdRfVar                local_00CC           ; ... имени
  71. 401DAF: Lead2/fe CStrVarVal        local_008C
  72. 401DB3: 0b ImpAdCallI2             _rtcAnsiValueBstr        ; конвертируем значения символов в  hexadec
  73. 401DB8: 44 CVarI2                  local_00BC
  74. 401DBB: Lead1/f6 FstVar       local_016C
  75. 401DBF: 2f FFree1Str              local_008C
  76. 401DC2: 36 FFreeVar                local_00AC local_00CC
  77. 401DC9: 04 FLdRfVar                local_017C
  78. 401DCC: 04 FLdRfVar                local_016C
  79. 401DCF: Lead0/94 AddVar            local_00AC
  80. 401DD3: Lead1/f6 FStVar            local_017C
  81. 401DD7: 04 FLdRfVar                local_013C
  82. 401DDA: Lead3/7e NextStepVar:      (continue) 401D97        ; Конец цикла for-next?
  83. 401DE0: 04 FLdRfVar                local_017C
  84. 401DE3: 04 FLdRfVar                local_012C
  85. 401DE6: Lead0/94 AddVar            local_00AC
  86. 401DEA: Lead1/f6 FStVar            local_018C
  87. 401DEE: 04 FLdRfVar                local_008C
  88. 401DF1: 21 FLdPrThis              
  89. 401DF2: 0f VCallAd                 text
  90. 401DF5: 19 FStAdFunc               local_0088
  91. 401DF8: 08 FLdPr                   local_0088
  92. 401DFB: 0d VCallHresult            get__ipropTEXTEDIT       ; Читаем содержимое текстового поля
  93. 401E00: 3e FLdZeroAd               local_008C           ; Серийный номер
  94. 401E03: 46 CVarStr                 local_00CC
  95. 401E06: 5d HardType              
  96. 401E07: 3a LitVarStr:              ( local_009C ) CRK
  97. 401E0C: 04 FLdRfVar                local_018C
  98. 401E0F: Lead0/ef ConcatVar        
  99. 401E13: Lead0/40 NeVarBool        
  100. 401E15: 1a FFree1Ad                local_0088
  101. 401E18: 36 FFreeVar         local_00CC local_00AC
  102. 401E1F: 1c BranchF:                401E59
  103. 401E22: 27 LitVar_Missing        
  104. 401E25: 27 LitVar_Missing        
  105. 401E28: 3a LitVarStr:              ( local_00BC ) P-Code
  106. 401E2D: 4e FStVarCopyObj           local_00CC
  107. 401E30: 04 FLdRfVar                local_00CC
  108. 401E33: f5 LitI4:                  0x10  16  (....)
  109. 401E38: 3a LitVarStr:              ( local_009C ) Серийный номер неверен!
  110. 401E3D: 4e FStVarCopyObj           local_00AC
  111. 401E40: 04 FLdRfVar                local_00AC
  112. 401E43: 0a ImpAdCallFPR4:          _rtcMsgBox
  113. 401E48: 36 FFreeVar         local_00AC local_00CC local_00EC local_010C
  114. 401E53: 1e Branch:                 401e8c
  115. 401E56: 1e Branch:                 401e8c
  116. 401E59: 27 LitVar_Missing        
  117. 401E5C: 27 LitVar_Missing        
  118. 401E5F: 3a LitVarStr:              ( local_00BC ) P-Code
  119. 401E64: 4e FStVarCopyObj           local_00CC
  120. 401E67: 04 FLdRfVar                local_00CC
  121. 401E6A: f5 LitI4:                  0x30  48  (...0)
  122. 401E6F: 3a LitVarStr:              ( local_009C ) Серийный номер верен!!
  123. 401E74: 4e FStVarCopyObj           local_00AC
  124. 401E77: 04 FLdRfVar                local_00AC
  125. 401E7A: 0a ImpAdCallFPR4:          _rtcMsgBox
  126. 401E7F: 36 FFreeVar         local_00AC local_00CC local_00EC local_010C
  127. 401E8A: Lead1/c8 End              
  128. 401E8C: 13 ExitProcHresult

Отсюда ясно, как работает крэкми.

Полезно знать, как работать с P-CODE в OllyDbg, так как есть программы, которые защищены от WKT и EXDEC, но в случае с OllyDbg мы можем использовать плагины, которые спрячут её практически ото всех, кроме очень редких исключений.

Загружаем прилагающийся крэкми nags1, который просит нас убрать первоначальное наг-окно. Смотрим его листинг в EXDEC.

Код (Text):
  1.  
  2. Proc: 401a40
  3. 401A14: 27 LitVar_Missing        
  4. 401A17: 27 LitVar_Missing        
  5. 401A1A: 27 LitVar_Missing        
  6. 401A1D: f5 LitI4:                  0x0  0  (....)
  7. 401A22: 3a LitVarStr:              ( local_0094 ) NAG
  8. 401A27: 4e FStVarCopyObj           local_00A4
  9. 401A2A: 04 FLdRfVar                local_00A4
  10. 401A2D: 0a ImpAdCallFPR4:          _rtcMsgBox
  11. 401A32: 36 FFreeVar         local_00A4 local_00C4 local_00E4 local_0104
  12. 401A3D: 13 ExitProcHresult
  13.  
  14. Proc: 401958
  15.  
  16. 401954: Lead1/c8 End              
  17. 401956: 13 ExitProcHresult

Видим, что знаменитый NAG – это просто rtcMsgBox. В P-Code нет NOP’ов, хе-хе, поэтому нам нужно забить эту функцию опкодами, которые не изменят хода выполнения программы.

Устанавливаем BPM на опкоде, вызывающем rtcMsgBox, и запускаем программу.

Код (Text):
  1.  
  2. 401A2D: 0a ImpAdCallFPR4:          _rtcMsgBox

Останавливаемся, когда считывается опкод.

Видим, что в стеке находится 12f9e8. Идём к следующему опкоду. Сначала, конечно, выскочит наг-окошко, поэтому надо будет нажать «Aceptar».

Здесь мы доходим до следующего опкода после CALL EAX, который вызывал API-функцию rtcMsgBox.

В стеке находится 12f9fc.

То есть, для того, чтобы оставить равные, нужно сделать различные POP’ы. Сюда мы не вмешиваемся, можем попробовать использовать PUSH с помощью F5.

Код (Text):
  1.  
  2. F5    5CBE 1377 4 1 4      Push imm#4

У нас 4 параметра размером равные 0A. Столько нам нужно заменить.

Код (Text):
  1.  
  2. 0A    664E 1F30 4 2 2 2

Пробуем изменить 0A на F5 и делаем все параметры равными нулю.

Следующий опкод – это 36, как показывает нам EXDEC. Мы всегда должны быть уверенными, что замещающий опкод имеет такое же количество параметров, как и у замещаемого, чтобы не было проблем. Сохраняем изменения.

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

31 часть будет последней посвящённой P-CODE, и в ней будет рассмотрена коммерческая программа.

© Рикардо Нарваха, пер. Aquila


1 3.959
archive

archive
New Member

Регистрация:
27 фев 2017
Публикаций:
532

Комментарии


      1. virtuha 23 май 2017
        Оглавление
        Введение в крэкинг с нуля, используя OllyDbg - Глава 1
        Введение в крэкинг с нуля, используя OllyDbg - Глава 2
        Введение в крэкинг с нуля, используя OllyDbg - Глава 3
        Введение в крэкинг с нуля, используя OllyDbg - Глава 4
        Введение в крэкинг с нуля, используя OllyDbg - Глава 5
        Введение в крэкинг с нуля, используя OllyDbg - Глава 6
        Введение в крэкинг с нуля, используя OllyDbg - Глава 7
        Введение в крэкинг с нуля, используя OllyDbg - Глава 8
        Введение в крэкинг с нуля, используя OllyDbg - Глава 9
        Введение в крэкинг с нуля, используя OllyDbg - Глава 10
        Введение в крэкинг с нуля, используя OllyDbg - Глава 11
        Введение в крэкинг с нуля, используя OllyDbg - Глава 12
        Введение в крэкинг с нуля, используя OllyDbg - Глава 13
        Введение в крэкинг с нуля, используя OllyDbg - Глава 14
        Введение в крэкинг с нуля, используя OllyDbg - Глава 15
        Введение в крэкинг с нуля, используя OllyDbg - Глава 16
        Введение в крэкинг с нуля, используя OllyDbg - Глава 17
        Введение в крэкинг с нуля, используя OllyDbg - Глава 18
        Введение в крэкинг с нуля, используя OllyDbg - Глава 19
        Введение в крэкинг с нуля, используя OllyDbg - Глава 20
        Введение в крэкинг с нуля, используя OllyDbg - Глава 21
        Введение в крэкинг с нуля, используя OllyDbg - Глава 22
        Введение в крэкинг с нуля, используя OllyDbg - Глава 23
        Введение в крэкинг с нуля, используя OllyDbg - Глава 24
        Введение в крэкинг с нуля, используя OllyDbg - Глава 25
        Введение в крэкинг с нуля, используя OllyDbg - Глава 26
        Введение в крэкинг с нуля, используя OllyDbg - Глава 27
        Введение в крэкинг с нуля, используя OllyDbg - Глава 28
        Введение в крэкинг с нуля, используя OllyDbg - Глава 29
        Введение в крэкинг с нуля, используя OllyDbg - Глава 30
        Введение в крэкинг с нуля, используя OllyDbg - Глава 31
        Введение в крэкинг с нуля, используя OllyDbg - Глава 32
        Введение в крэкинг с нуля, используя OllyDbg - Глава 33
        Введение в крэкинг с нуля, используя OllyDbg - Глава 34
        Введение в крэкинг с нуля, используя OllyDbg - Глава 35
        Введение в крэкинг с нуля, используя OllyDbg - Глава 36
        Введение в крэкинг с нуля, используя OllyDbg - Глава 37
        Введение в крэкинг с нуля, используя OllyDbg - Глава 38
        Введение в крэкинг с нуля, используя OllyDbg - Глава 39
        Введение в крэкинг с нуля, используя OllyDbg - Глава 40
        Введение в крэкинг с нуля, используя OllyDbg - Глава 41
        Введение в крэкинг с нуля, используя OllyDbg - Глава 42
        Введение в крэкинг с нуля, используя OllyDbg - Глава 43
        Введение в крэкинг с нуля, используя OllyDbg - Глава 44
        Введение в крэкинг с нуля, используя OllyDbg - Глава 45
        Дополнение к 45-ой главе «Введения в крэкинг, используя OllyDbg»
        Введение в крэкинг с нуля, используя OllyDbg - Глава 46
        Введение в крэкинг с нуля, используя OllyDbg - Глава 47
        Введение в крэкинг с нуля, используя OllyDbg - Глава 48
        Введение в крэкинг с нуля, используя OllyDbg - Глава 49
        Введение в крэкинг с нуля, используя OllyDbg - Глава 50
        Введение в крэкинг с нуля, используя OllyDbg - Глава 51
        Введение в крэкинг с нуля, используя OllyDbg - Глава 52
        Введение в крэкинг с нуля, используя OllyDbg - Глава 53
        Night-san нравится это.