SentinelLM!SDK_Keygen

Дата публикации 4 июл 2003

SentinelLM!SDK_Keygen — Архив WASM.RU

В предыдущей главе мы славно потрудились и получили VId нашей жертвы. Наша следующая цель -- подсунуть этот VId инсталлеру Sentinel SDK (вы уже скачали 80-тонный архивчик?) и получить генератор лицензионных цепочек ИМЕННО для нашей жертвы. Правда, тут возникает одно НО, которое и служит темой для данной главы. Дело в том, что установщик не запрашивает VId напрямую, а вместо него просит ввести некий серийник (Serial Number)...

Отладчик сразу проясняет ситуацию:

  1. Инсталлятор разжимает библиотеку MODBIN.DLL
  2. Введённый серийник передаётся функции MODBIN!GetVendorId (не смейтесь :smile3:
  3. Функция возвращает VId соответствующий серийнику или -1, если таковой не найден.

Мммда... таким образом VId косвенно передаётся инсталлеру. Значит, если хотите играть по правилам, тогда соизвольте подобрать серийник для нашего VId. В противном случае можете попробовать обойти стадию с MODBIN и насильно запихнуть VId прямо в SDK. Я, честно говоря, такого делать не пробовал и вам не советую! Итак, приступим к написанию ключегенератора для SentinelLM SDK 7.1.

Внимание! Не спешите компилировать прилагаемые исходники, сначала дочитайте главу!

Во-первых, покопайтесь над установщиком и вытяните из него MODBIN.DLL. При желании можете дизассемблировать библиотеку и постараться понять принцип хеширования (серийник -> VId). Таким образом вы убедитесь в сложности построения обратной функции (VId -> серийник). Гораздо проще обойтись прямым перебором всех возможных комбинаций до получения искомого VId. На самом деле время перебора не так уж и велико (1,5 - 2 часа на среднестатистическом компе), но я предлагаю несколько иной подход, а именно: сгенерировать файл со всеми ВАЛИДНЫМИ парами (VId, серийник) для использования в ключегенераторе в качестве словаря. Размер такого файла, в зависимости от формата, может составить около 382Кб. Далее приводится исходник первой стадии генератора:

Код (Text):
  1.  
  2. .386
  3. .model flat, stdcall
  4. option casemap:none
  5.  
  6. include    windows.inc
  7. include    kernel32.inc
  8. includelib kernel32.lib
  9. include    user32.inc
  10. includelib user32.lib
  11.  
  12. .DATA
  13. modbin      db "modbin",0                   ; Имя библиотеки
  14. GetVendorId db "GetVendorId",0              ; Импортируемая ф-ция
  15. Err1        db "MODBIN.DLL не найден",0
  16. Err2        db "GetVendorId не найден",0
  17. Err3        db "Ошибка при создании файла",0
  18. sLog        db "slm_gen",0                  ; Имя файла-словаря
  19. sOK         db "Программа готова к старту!",0
  20. sDone       db "Программа завершилась успешно!",0
  21. sCaption    db "MODBIN кряк",0
  22. seed        dd 0FFFFFFFFh                   ; текущий серийник
  23.  
  24. .DATA?
  25. hLib        dd ?   ; Хендл 'MODBIN.DLL'
  26. procAddr    dd ?   ; Адрес ф-ции 'MODBIN!GetVendorId'
  27. hFile       dd ?   ; Хендл файла-словаря
  28. VId         dw ?   ; Текущий VId
  29. strBuf      db 128 dup (?)
  30.  
  31. .CODE
  32. start:
  33.   ; 1. Задать текущий каталог
  34.   ; -------------------------
  35.   invoke GetModuleFileName,0,OFFSET strBuf,128
  36.   test eax,eax
  37.   jz @F
  38.   mov edi,OFFSET strBuf
  39.   add edi,eax
  40.   xchg eax,ecx
  41.   mov al,'\'
  42.   std
  43.   repnz scasb
  44.   jnz @F
  45.   mov BYTE PTR [edi + 1],0
  46.   cld      ; <- это важно в NT
  47.   invoke SetCurrentDirectory,OFFSET strBuf
  48. @@:
  49.   ; 2. Загрузить MODBIN.DLL
  50.   ; -----------------------
  51.   invoke LoadLibraryEx,OFFSET modbin,0,0
  52.   test eax,eax
  53.   jnz @F
  54.   invoke MessageBox,eax,OFFSET Err1,eax,MB_ICONSTOP
  55.   jmp _end_1
  56. @@:
  57.   mov hLib,eax
  58.   invoke GetProcAddress,eax,OFFSET GetVendorId
  59.   test eax,eax
  60.   jnz @F
  61.   invoke MessageBox,eax,OFFSET Err2,eax,MB_ICONSTOP
  62.   jmp _end_2
  63. @@:
  64.   mov procAddr,eax
  65.   ; 3. Создать файл-словарь
  66.   ; -----------------------
  67.   invoke CreateFile,OFFSET sLog,GENERIC_WRITE,\
  68.     FILE_SHARE_READ,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0
  69.   cmp eax,INVALID_HANDLE_VALUE
  70.   jne @F
  71.   invoke MessageBox,0,OFFSET Err3,0,MB_ICONSTOP
  72.   jmp _end_2
  73. @@:
  74.   mov hFile,eax
  75.   invoke MessageBox,0,OFFSET sOK,OFFSET sCaption,MB_ICONINFORMATION
  76.   ; 4. Приступим!
  77.   ; -------------
  78. _mainloop:
  79.   ; Переводим текущий серийник в строку
  80.   ; Содрано из DWTOA + чуть-чуть подоптимизировано
  81.   dec seed
  82.   jz _end_3
  83.   mov eax,seed
  84.   mov edi,OFFSET strBuf
  85.   mov ecx,429496730
  86.   mov esi,edi
  87. _wloop:
  88.   mov ebx,eax
  89.   mul ecx
  90.   mov eax,edx
  91.   lea edx,[edx*4+edx]
  92.   add edx,edx
  93.   sub ebx,edx
  94.   add bl,'0'
  95.   mov [edi],bl
  96.   inc edi
  97.   test eax,eax
  98.   jnz _wloop
  99.   mov BYTE PTR [edi],0
  100.   .WHILE (esi < edi)
  101.     dec edi
  102.     mov al,[esi]
  103.     mov ah,[edi]
  104.     mov [edi],al
  105.     mov [esi],ah
  106.     inc esi
  107.   .ENDW
  108.   push OFFSET strBuf
  109.   call procAddr       ; Вызываем MODBIN!GetVendorId
  110.   pop ecx             ; Выравниваем стек
  111.   test eax,eax
  112.   js _mainloop        ; -1 значит левый серийник
  113.   mov VId,ax
  114.   push seed
  115.   pop DWORD PTR strBuf
  116.   ; Добавляем в файл пару (VId, серийник)
  117.   invoke WriteFile,hFile,OFFSET VId,6,OFFSET modbin,0
  118.   jmp _mainloop
  119. _end_3:
  120.   invoke CloseHandle,hFile
  121.   ; Усё... справились!
  122.   invoke MessageBox,0,OFFSET sDone,OFFSET sCaption,MB_ICONINFORMATION
  123. _end_2:
  124.   invoke FreeLibrary,hLib
  125. _end_1:
  126.   invoke ExitProcess,eax
  127. END start

По-моему, разбирать предыдущий исходник не стоит во избежание личных обид :smile3: В общем, запускайте его и ожидайте... ожидайте... ожидайте сообщения об успешном завершении программы. Полученный 382-килобайтный словарь (slm_gen) послужит нам многие годы и внесённый в него труд даром не пропадёт (надеюсь). Следующий шаг -- написать парсер для нашего словаря:

Код (Text):
  1.  
  2. .386
  3. .model flat, stdcall
  4. option casemap:none
  5.  
  6. include    windows.inc
  7. include    kernel32.inc
  8. includelib kernel32.lib
  9. include    user32.inc
  10. includelib user32.lib
  11.  
  12. DlgProc PROTO :DWORD,:DWORD,:DWORD,:DWORD
  13.  
  14. .DATA
  15. file_not_found db "Словарь не найден!",0
  16. dwFormat       db "%u",13,10,0
  17.  
  18. .DATA?
  19. hInst  dd ?
  20. hSN    dd ?   ; Хендл edit'а с серийником
  21. hFile  dd ?   ; Хендл словаря
  22. hMap   dd ?   ; Хендл словаря в памяти
  23. hView  dd ?   ; Указатель на маппированные данные
  24. fSize  dd ?   ; Размер словаря
  25. szBuf  db 128 dup (?)
  26.  
  27. .CODE
  28. start:
  29.   invoke GetModuleHandle,0
  30.   mov hInst,eax
  31.   invoke DialogBoxParam,eax,200,0,OFFSET DlgProc,0
  32.   invoke ExitProcess,eax
  33.  
  34. DlgProc PROC hDlg:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD
  35.   mov eax,uMsg
  36.   cmp eax,WM_COMMAND
  37.   jne no_wm_comm
  38.   mov eax,wParam
  39.   cmp ax,102
  40.   je @F
  41.   xor eax,eax
  42.   ret
  43. @@:
  44.   ; 1. Получаем введённый VId
  45.   ; -------------------------
  46.   mov DWORD PTR szBuf,0
  47.   invoke SetDlgItemText,hDlg,101,OFFSET szBuf
  48.   invoke GetDlgItemText,hDlg,100,OFFSET szBuf,5
  49.   test eax,eax
  50.   jnz @F
  51.   ret
  52. @@:
  53.   ; 2. Переводим VId из шестнадцатиричной строки в 16-битное слово
  54.   ; --------------------------------------------------------------
  55.   mov edx,DWORD PTR szBuf
  56.   mov ecx,4
  57.   xor eax,eax
  58. hex2bin:
  59.   test dl,dl
  60.   jz endloop
  61.   shl eax,4
  62.   sub dl,48
  63.   cmp dl,9
  64.   jle @F
  65.   sub dl,7
  66.   cmp dl,0Fh
  67.   jle @F
  68.   sub dl,32
  69. @@:
  70.   or al,dl
  71.   shr edx,8
  72.   loop hex2bin
  73. endloop:
  74.   ; 3. Ищем VId в словаре
  75.   ; ---------------------
  76.   mov ecx,fSize
  77.   shr ecx,1
  78.   jecxz endsrch
  79.   push ebx      ; Сохранить EBX (для NT)
  80.   push edi      ; Сохранить EDI (для 9x)
  81.   mov edi,hView
  82.   cld
  83. search:
  84.   scasw
  85.   jne @F
  86.   ; 4. Добавляем очередной серийник и продолжаем поиск
  87.   ; --------------------------------------------------
  88.   call appendSN
  89. @@:
  90.   dec ecx
  91.   dec ecx
  92.   jle done      ; наш словарь кто-то обрезал :)
  93.   add edi,4
  94.   loop search
  95. done:
  96.   pop edi
  97.   pop ebx
  98. endsrch:
  99.   ret
  100. no_wm_comm:
  101.   cmp eax,WM_INITDIALOG
  102.   jne no_wm_init
  103.   invoke GetModuleFileName,hInst,OFFSET szBuf,127
  104.   ; Убираем расширение
  105.   add eax,OFFSET szBuf - 4
  106.   mov BYTE PTR [eax],0
  107.   invoke CreateFile,OFFSET szBuf,GENERIC_READ,\
  108.     FILE_SHARE_READ,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0
  109.   cmp eax,INVALID_HANDLE_VALUE
  110.   jne @F
  111.   invoke MessageBox,0,OFFSET file_not_found,0,MB_ICONSTOP
  112.   invoke EndDialog,hDlg,0
  113.   ret
  114. @@:
  115.   mov hFile,eax
  116.   invoke GetFileSize,eax,0
  117.   mov fSize,eax
  118.   ; Отображаем словарь в память
  119.   invoke CreateFileMapping,hFile,0,PAGE_READONLY,0,0,0
  120.   mov hMap,eax
  121.   invoke MapViewOfFile,eax,FILE_MAP_READ,0,0,0
  122.   mov hView,eax
  123.   invoke GetDlgItem,hDlg,101
  124.   mov hSN,eax
  125.   ret
  126. no_wm_init:
  127.   cmp eax,WM_CLOSE
  128.   jne no_wm_close
  129.   invoke UnmapViewOfFile,hView
  130.   invoke CloseHandle,hMap
  131.   invoke CloseHandle,hFile
  132.   invoke EndDialog,hDlg,0
  133.   ret
  134. no_wm_close:
  135.   xor eax,eax
  136.   ret
  137. DlgProc ENDP
  138.  
  139. ; Показать найденный серийник
  140. appendSN PROC uses edi ecx eax
  141.   mov eax,[edi]
  142.   invoke wsprintf,OFFSET szBuf,OFFSET dwFormat,eax
  143.   invoke SendMessage,hSN,WM_GETTEXTLENGTH,0,0
  144.   invoke SendMessage,hSN,EM_SETSEL,eax,eax
  145.   invoke SendMessage,hSN,EM_REPLACESEL,0,OFFSET szBuf
  146.   ret
  147. appendSN ENDP
  148.  
  149. END start

Ну всё, компилируем вместе с RC-скриптом и наш новый генератор серийных номеров для SentinelLM SDK готов к употреблению!

Попробуйте задать ему 2A0A (это последний VId в нашем словаре) и получите целых ДВА результата (8561314 и 8430250). Почему два? Видимо SDK разделяет все VId на две категории:

  1. [0000 - 7FFF] для обычных клиентов
  2. [8000 - FFFF] для крутых разработчиков (вроде нас с вами)

Первый серийник соответсвует обычному VId (2A0A) а второй наделяет SDK дополнительными фичами. Так как большинству клиентским программам (например, нашей жертве) совершенно безразличен MSB (старший бит) её VId, вам будет всё равно какой из этих серийников использовать. Кстати, иногда может быть вплоть до восьми серийных номеров на один VId (больше восьми я ещё не встречал).

Далее, просто ставим SDK и проверяем, что VId соответствует нами заданному. Только не спрашивайте: "А как это проверить?" Медитируйте над первой главой. Обратите внимание на то, что SDK отказывается на нас работать... Не переживайте -- в следующей главе мы его уломаем :smile3: © Quantum


0 1.001
archive

archive
New Member

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