SentinelLM!SDK_Keygen — Архив WASM.RU
В предыдущей главе мы славно потрудились и получили VId нашей жертвы. Наша следующая цель -- подсунуть этот VId инсталлеру Sentinel SDK (вы уже скачали 80-тонный архивчик?) и получить генератор лицензионных цепочек ИМЕННО для нашей жертвы. Правда, тут возникает одно НО, которое и служит темой для данной главы. Дело в том, что установщик не запрашивает VId напрямую, а вместо него просит ввести некий серийник (Serial Number)...
Отладчик сразу проясняет ситуацию:
- Инсталлятор разжимает библиотеку MODBIN.DLL
- Введённый серийник передаётся функции MODBIN!GetVendorId (не смейтесь
- Функция возвращает VId соответствующий серийнику или -1, если таковой не найден.
Мммда... таким образом VId косвенно передаётся инсталлеру. Значит, если хотите играть по правилам, тогда соизвольте подобрать серийник для нашего VId. В противном случае можете попробовать обойти стадию с MODBIN и насильно запихнуть VId прямо в SDK. Я, честно говоря, такого делать не пробовал и вам не советую! Итак, приступим к написанию ключегенератора для SentinelLM SDK 7.1.
Внимание! Не спешите компилировать прилагаемые исходники, сначала дочитайте главу!
Во-первых, покопайтесь над установщиком и вытяните из него MODBIN.DLL. При желании можете дизассемблировать библиотеку и постараться понять принцип хеширования (серийник -> VId). Таким образом вы убедитесь в сложности построения обратной функции (VId -> серийник). Гораздо проще обойтись прямым перебором всех возможных комбинаций до получения искомого VId. На самом деле время перебора не так уж и велико (1,5 - 2 часа на среднестатистическом компе), но я предлагаю несколько иной подход, а именно: сгенерировать файл со всеми ВАЛИДНЫМИ парами (VId, серийник) для использования в ключегенераторе в качестве словаря. Размер такого файла, в зависимости от формата, может составить около 382Кб. Далее приводится исходник первой стадии генератора:
Код (Text):
.386 .model flat, stdcall option casemap:none include windows.inc include kernel32.inc includelib kernel32.lib include user32.inc includelib user32.lib .DATA modbin db "modbin",0 ; Имя библиотеки GetVendorId db "GetVendorId",0 ; Импортируемая ф-ция Err1 db "MODBIN.DLL не найден",0 Err2 db "GetVendorId не найден",0 Err3 db "Ошибка при создании файла",0 sLog db "slm_gen",0 ; Имя файла-словаря sOK db "Программа готова к старту!",0 sDone db "Программа завершилась успешно!",0 sCaption db "MODBIN кряк",0 seed dd 0FFFFFFFFh ; текущий серийник .DATA? hLib dd ? ; Хендл 'MODBIN.DLL' procAddr dd ? ; Адрес ф-ции 'MODBIN!GetVendorId' hFile dd ? ; Хендл файла-словаря VId dw ? ; Текущий VId strBuf db 128 dup (?) .CODE start: ; 1. Задать текущий каталог ; ------------------------- invoke GetModuleFileName,0,OFFSET strBuf,128 test eax,eax jz @F mov edi,OFFSET strBuf add edi,eax xchg eax,ecx mov al,'\' std repnz scasb jnz @F mov BYTE PTR [edi + 1],0 cld ; <- это важно в NT invoke SetCurrentDirectory,OFFSET strBuf @@: ; 2. Загрузить MODBIN.DLL ; ----------------------- invoke LoadLibraryEx,OFFSET modbin,0,0 test eax,eax jnz @F invoke MessageBox,eax,OFFSET Err1,eax,MB_ICONSTOP jmp _end_1 @@: mov hLib,eax invoke GetProcAddress,eax,OFFSET GetVendorId test eax,eax jnz @F invoke MessageBox,eax,OFFSET Err2,eax,MB_ICONSTOP jmp _end_2 @@: mov procAddr,eax ; 3. Создать файл-словарь ; ----------------------- invoke CreateFile,OFFSET sLog,GENERIC_WRITE,\ FILE_SHARE_READ,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0 cmp eax,INVALID_HANDLE_VALUE jne @F invoke MessageBox,0,OFFSET Err3,0,MB_ICONSTOP jmp _end_2 @@: mov hFile,eax invoke MessageBox,0,OFFSET sOK,OFFSET sCaption,MB_ICONINFORMATION ; 4. Приступим! ; ------------- _mainloop: ; Переводим текущий серийник в строку ; Содрано из DWTOA + чуть-чуть подоптимизировано dec seed jz _end_3 mov eax,seed mov edi,OFFSET strBuf mov ecx,429496730 mov esi,edi _wloop: mov ebx,eax mul ecx mov eax,edx lea edx,[edx*4+edx] add edx,edx sub ebx,edx add bl,'0' mov [edi],bl inc edi test eax,eax jnz _wloop mov BYTE PTR [edi],0 .WHILE (esi < edi) dec edi mov al,[esi] mov ah,[edi] mov [edi],al mov [esi],ah inc esi .ENDW push OFFSET strBuf call procAddr ; Вызываем MODBIN!GetVendorId pop ecx ; Выравниваем стек test eax,eax js _mainloop ; -1 значит левый серийник mov VId,ax push seed pop DWORD PTR strBuf ; Добавляем в файл пару (VId, серийник) invoke WriteFile,hFile,OFFSET VId,6,OFFSET modbin,0 jmp _mainloop _end_3: invoke CloseHandle,hFile ; Усё... справились! invoke MessageBox,0,OFFSET sDone,OFFSET sCaption,MB_ICONINFORMATION _end_2: invoke FreeLibrary,hLib _end_1: invoke ExitProcess,eax END startПо-моему, разбирать предыдущий исходник не стоит во избежание личных обид В общем, запускайте его и ожидайте... ожидайте... ожидайте сообщения об успешном завершении программы. Полученный 382-килобайтный словарь (slm_gen) послужит нам многие годы и внесённый в него труд даром не пропадёт (надеюсь). Следующий шаг -- написать парсер для нашего словаря:
Код (Text):
.386 .model flat, stdcall option casemap:none include windows.inc include kernel32.inc includelib kernel32.lib include user32.inc includelib user32.lib DlgProc PROTO :DWORD,:DWORD,:DWORD,:DWORD .DATA file_not_found db "Словарь не найден!",0 dwFormat db "%u",13,10,0 .DATA? hInst dd ? hSN dd ? ; Хендл edit'а с серийником hFile dd ? ; Хендл словаря hMap dd ? ; Хендл словаря в памяти hView dd ? ; Указатель на маппированные данные fSize dd ? ; Размер словаря szBuf db 128 dup (?) .CODE start: invoke GetModuleHandle,0 mov hInst,eax invoke DialogBoxParam,eax,200,0,OFFSET DlgProc,0 invoke ExitProcess,eax DlgProc PROC hDlg:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD mov eax,uMsg cmp eax,WM_COMMAND jne no_wm_comm mov eax,wParam cmp ax,102 je @F xor eax,eax ret @@: ; 1. Получаем введённый VId ; ------------------------- mov DWORD PTR szBuf,0 invoke SetDlgItemText,hDlg,101,OFFSET szBuf invoke GetDlgItemText,hDlg,100,OFFSET szBuf,5 test eax,eax jnz @F ret @@: ; 2. Переводим VId из шестнадцатиричной строки в 16-битное слово ; -------------------------------------------------------------- mov edx,DWORD PTR szBuf mov ecx,4 xor eax,eax hex2bin: test dl,dl jz endloop shl eax,4 sub dl,48 cmp dl,9 jle @F sub dl,7 cmp dl,0Fh jle @F sub dl,32 @@: or al,dl shr edx,8 loop hex2bin endloop: ; 3. Ищем VId в словаре ; --------------------- mov ecx,fSize shr ecx,1 jecxz endsrch push ebx ; Сохранить EBX (для NT) push edi ; Сохранить EDI (для 9x) mov edi,hView cld search: scasw jne @F ; 4. Добавляем очередной серийник и продолжаем поиск ; -------------------------------------------------- call appendSN @@: dec ecx dec ecx jle done ; наш словарь кто-то обрезал :) add edi,4 loop search done: pop edi pop ebx endsrch: ret no_wm_comm: cmp eax,WM_INITDIALOG jne no_wm_init invoke GetModuleFileName,hInst,OFFSET szBuf,127 ; Убираем расширение add eax,OFFSET szBuf - 4 mov BYTE PTR [eax],0 invoke CreateFile,OFFSET szBuf,GENERIC_READ,\ FILE_SHARE_READ,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0 cmp eax,INVALID_HANDLE_VALUE jne @F invoke MessageBox,0,OFFSET file_not_found,0,MB_ICONSTOP invoke EndDialog,hDlg,0 ret @@: mov hFile,eax invoke GetFileSize,eax,0 mov fSize,eax ; Отображаем словарь в память invoke CreateFileMapping,hFile,0,PAGE_READONLY,0,0,0 mov hMap,eax invoke MapViewOfFile,eax,FILE_MAP_READ,0,0,0 mov hView,eax invoke GetDlgItem,hDlg,101 mov hSN,eax ret no_wm_init: cmp eax,WM_CLOSE jne no_wm_close invoke UnmapViewOfFile,hView invoke CloseHandle,hMap invoke CloseHandle,hFile invoke EndDialog,hDlg,0 ret no_wm_close: xor eax,eax ret DlgProc ENDP ; Показать найденный серийник appendSN PROC uses edi ecx eax mov eax,[edi] invoke wsprintf,OFFSET szBuf,OFFSET dwFormat,eax invoke SendMessage,hSN,WM_GETTEXTLENGTH,0,0 invoke SendMessage,hSN,EM_SETSEL,eax,eax invoke SendMessage,hSN,EM_REPLACESEL,0,OFFSET szBuf ret appendSN ENDP END startНу всё, компилируем вместе с RC-скриптом и наш новый генератор серийных номеров для SentinelLM SDK готов к употреблению!
Попробуйте задать ему 2A0A (это последний VId в нашем словаре) и получите целых ДВА результата (8561314 и 8430250). Почему два? Видимо SDK разделяет все VId на две категории:
- [0000 - 7FFF] для обычных клиентов
- [8000 - FFFF] для крутых разработчиков (вроде нас с вами)
Первый серийник соответсвует обычному VId (2A0A) а второй наделяет SDK дополнительными фичами. Так как большинству клиентским программам (например, нашей жертве) совершенно безразличен MSB (старший бит) её VId, вам будет всё равно какой из этих серийников использовать. Кстати, иногда может быть вплоть до восьми серийных номеров на один VId (больше восьми я ещё не встречал).
Далее, просто ставим SDK и проверяем, что VId соответствует нами заданному. Только не спрашивайте: "А как это проверить?" Медитируйте над первой главой. Обратите внимание на то, что SDK отказывается на нас работать... Не переживайте -- в следующей главе мы его уломаем © Quantum
SentinelLM!SDK_Keygen
Дата публикации 4 июл 2003