| RSS



Меню

Bookmark and Share


Статистика
Ваш IP: 127.0.0.1
Вы используете: v





Сейчас на сайте:

Тех поддержка ->

Облако тэгов
ОС видио Tor Обратная сторона антенна 4.6 php libc rand() эксплоит Windows Server 2008 FreeBSD Jail Elastix QIP Virtual chroot Limit kernel proc sysctl Tune freeBSD bridge Boot LiveCD Disk Bluetooth GEO game DirectX emulator Python Shell червь Conficker вирус троян лаборатория касперского пиратство Apple iPhone Microsoft twitter социальная сеть анонимность лицензия Open Source уязвимость MySQL база данных Закон Франция Пират Skype мобильный Deutsche Telekom хакер trend micro кибератака Германия робот Персональные данные Ноутбук Интернет китай цензура windows vista acer Linux патент браузер Firefox Internet Explorer Opera Safari Intel Oracle патч Банкомат IBM США Dell Ford MAC контроль Internet кибербезопасность приговор Mozilla Chrome безопасность Госдума СМИ Windows 8 взлом Пентагон Украина Facebook Cisco Cloud Windows XP нетбук торрент музыка Биометрический Nokia Hardware Manager ФБР IP-адрес sms RSA java Google Captcha Symantec Спам Антивирус тест Anti-Malware Windows 7 операционная система windows провайдер авторское право rapidshare UNIX свиной грипп шантаж Дети ipod копирайт McAfee HTTPS icann студент Норвегия New York Times YouTube Warner Music КНДР Ubuntu AMD ATI касперский Россия РФ сервер хостинг Wi-Fi суд пароль блог фишинг одноклассники Медведев контрафакт мошенник sony Gps по JavaScript Хакеры Yahoo фас компьютер софт Минкомсвязи Сбой мошенничество Доктор ВЕб Вконтакте ie8 исходный код МВД фильтр порнография свобода слова казахстан Autodesk сисадмин Gmail кредитная карта LiveJournal шифрование Deep Purple банк HTML5 Нанотехнологии wikipedia выборы DNS bind KaZaA Android Basic атака Mac OS X домен ФСБ прокуратура уголовное дело ICQ Sophos Google Voice ошибка DARPA военные сайт турция конференция спамер Полиция Koobface Великобритания IRC белоруссия Грузия Bittorrent Европа Dr.WEB Linux Mint Билл Гейтс спецслужбы Royal Bank of Scotland смартфон Canonical F-Secure Symbian фильм Microsoft Office Новая Зеландия Adobe Австралия IDC Internet Explorer 9 iPad Ирландия поиск GOOGLE EARTH МТС Реклама слежка Mandriva BSD Zeus личные данные eset avast Avira G Data Software защита Defcon виртуализация dll LibreOffice Черный список BlackBerry индия Москва DVD социальные сети flash player paypal BitDefender email сертификат honda MasterCard Anonymous технологии IPv6 Ассанж Оптоволокно передача данных арест Fedora Samsung Иск Apache учетная запись iTunes исследование Cert Санкт-Петербург McDonald's SOPA PIPA Bioshock Infinite: Burial at Sea - ico Megaupload CES hotfile отчет приложение Инвестиции платформа DRM DDoS-атака роскомнадзор

Главная » Статьи » Общие Статьи

Psychometric Expert 7 (ПРОДОЛЖЕНИЕ)

Заглянув в файл Info.ini мы вместо нашего почти честно сгенерированного кода с удивлением обнаружим дефолтовое значение, которое, разумеется, ничего не регистрирует. Все ясно, мы не полностью сгенерировали номер, в каком-то другом месте проверяется остальная часть, которая при обнаружении хака снимает регистрацию. Как можно найти место проверки? Элементарно. Обычным поиском инструкции CPUID убеждаемся, что нужна она только знакомой нам функции GetRawCode, по перекрестным ссылкам к которой мы увидим еще шесть процедур, из которых она вызывается. Проанализируем одну из них по адресу 0052AD84 (назовем ее Checkregistration1).

CODE:0052AF1B call GetRawCompCode
CODE:0052AF20 mov edi, eax
CODE:0052AF22 add edi, 3976Bh
CODE:0052AF28 mov eax, edi
CODE:0052AF2A call GetRawCompCode_2
.............................................
CODE:0052AB4C GetRawCompCode_2 proc near ; CODE XREF: CheckRegistration1+1A6 p
CODE:0052AB4C ; sub_5EBF64+21D p ...
CODE:0052AB4C cmp eax, 0FD1Dh
CODE:0052AB51 jb short locret_52AB5F
CODE:0052AB53
CODE:0052AB53 loc_52AB53: ; CODE XREF: GetRawCompCode_2+11 j
CODE:0052AB53 sub eax, 4381h
CODE:0052AB58 cmp eax, 0FD1Dh
CODE:0052AB5D jnb short loc_52AB53
CODE:0052AB5F
CODE:0052AB5F locret_52AB5F: ; CODE XREF: GetRawCompCode_2+5 j
CODE:0052AB5F retn
CODE:0052AB5F GetRawCompCode_2 endp

Видим, что с нашим RawCode'oм проводятся манипуляции, приводящие его к двухбайтному виду путем вычитания константы.

А после этого, в следующей функции, результат используется для декодирования некоторой строки (метки мои):

CODE:0052AF2F add ax, word ptr [ebp+intRSize]
CODE:0052AF33 mov edi, eax
CODE:0052AF35 mov ax, [ebp+intRTime]
CODE:0052AF39 push eax
CODE:0052AF3A lea eax, [ebp+lpDecriptTestStr]
CODE:0052AF3D push eax
CODE:0052AF3E mov ecx, edi ; sun iRSize+RCC2
CODE:0052AF40 mov dx, [ebp+intRData]
CODE:0052AF44 mov eax, [ebp+lpRName]
CODE:0052AF47 call ShellToDecriptProc
CODE:0052AF4C mov edx, [ebp+lpDecriptTestStr]
CODE:0052AF4F mov eax, ebx
CODE:0052AF51 call System::__linkproc__ LStrAsg(void *,void *)
CODE:0052AF56 push 30FBh
CODE:0052AF5B lea eax, [ebp+lpEtalonDecriptStr]
CODE:0052AF5E push eax
CODE:0052AF5F mov cx, 0B140h
CODE:0052AF63 mov dx, 5557h
CODE:0052AF67 mov eax, offset aEtalonCript ; "|5db2/9((¦("
CODE:0052AF6C call ShellToDecriptProc
..........................................................
CODE:0052ACBE decript: ; CODE XREF: DecriptString+42 j
CODE:0052ACBE movzx ecx, [ebp+intRTime]
CODE:0052ACC2 shr ecx, 8 ; major byte intRTime
CODE:0052ACC5 xor cl, [esi] ; major byte intRTime=mbiRTime^RName[i]
CODE:0052ACC7 mov [eax], cl ; dect[i]=mbiRTime
CODE:0052ACC9 add cl, byte ptr [ebp+intRTime] ; mbiRTime=mbiRTime+minor byte iRTime
CODE:0052ACCC and ecx, 0FFh ; (int)mbiRTime&0xff
CODE:0052ACD2 imul cx, word ptr [ebp+intRData] ; mbiRTime=(mbiRTime*iRData)&0xffff
CODE:0052ACD7 add cx, word ptr [ebp+intRData+2] ; mbiRTime=(mbiRTime+SumRSRCC2)&0xffff
CODE:0052ACDB mov [ebp+intRTime], cx ; iRTime=mbiRTime
CODE:0052ACDF inc esi
CODE:0052ACE0 inc eax
CODE:0052ACE1 dec edx
CODE:0052ACE2 jnz short decript

Как видно, ShellToDecriptProc вызывается дважды, один раз со случайными параметрами, второй раз с эталонными, заглянув в эталонный вызов отладчиком  увидим результат дешифровки: строка состоит из License.txt, который далее по коду конкуется к полному пути в главный каталог, после чего проверяется существование полученного файла:

CODE:0052AF71 push [ebp+lpMainPathStr]
CODE:0052AF74 push offset aSlash ; "\\"
CODE:0052AF79 push dword ptr [ebx]
CODE:0052AF7B lea eax, [ebp+lpTestLicenseName]
CODE:0052AF7E mov edx, 3
CODE:0052AF83 call System::__linkproc__ LStrCatN(void)
CODE:0052AF88 mov eax, [ebp+lpTestLicenseName]
CODE:0052AF8B call Sysutils::FileExists(System::AnsiString)
CODE:0052AF90 test al, al
CODE:0052AF92 jz short NotRegistration

Видимо, битом хакать этот переход тоже не стоит - где гарантии, что таким же способом в других местах программы не расшифровывается какое-нибудь имя нужной библиотеки? Лучше посмотрим, откуда берутся случайные параметры. RTime, RData и RName мы без труда обнаружим в том же Info.ini. А вот RSize, похоже, является экспортируемой глобальной переменной класса регистрации, которая рассчитывается при инициализации в конструкторе класса, поэтому ее придется поискать, благо разработчик хорошенько наследил. По перекрестной ссылке находим откуда вызывается CheckRegistrarion1:

CODE:0062168F mov edx, [ebx]
CODE:00621691 mov eax, ds:dword_640FC4
CODE:00621696 call InitRSize
CODE:0062169B lea edx, [ebp+var_4]
CODE:0062169E mov eax, [ebx]
CODE:006216A0 call CheckRegistration1
CODE:006216A5 cmp eax, 103BC1Dh
CODE:006216AA jnz short loc_62170A

Видно, что перед вызовом проверочной функции, вызывается некая функция, которую я обозвал InitRSize.

Внутри нее творится вот что:

CODE:0052AA2B lea edx, [ebp+lpTempBuffer]
CODE:0052AA2E mov ecx, offset lpDefis ; "-"
CODE:0052AA33 mov eax, [ebp+lpaArg1]
CODE:0052AA36 call SplitArray
CODE:0052AA3B lea eax, [ebp+lpDefaultValue]
CODE:0052AA3E mov edx, offset a777 ; "777"
CODE:0052AA43 call System::__linkproc__ LStrLAsg(void *,void *)
CODE:0052AA48 mov eax, [ebp+lpTempBuffer]
CODE:0052AA4B call System::__linkproc__ DynArrayLength(void)
CODE:0052AA50 cmp eax, 3
CODE:0052AA53 jl short SetRSize
CODE:0052AA55 lea eax, [ebp+lpRSize]
CODE:0052AA58 mov edx, [ebp+lpTempBuffer]
CODE:0052AA5B mov edx, [edx+8]
CODE:0052AA5E call System::__linkproc__ LStrLAsg(void *,void *)
CODE:0052AA63 mov eax, [ebp+lpRSize]
CODE:0052AA66 call System::__linkproc__ DynArrayLength(void)
CODE:0052AA6B cmp eax, 2
CODE:0052AA6E jl short SetValue
CODE:0052AA70 lea eax, [ebp+var_18]
CODE:0052AA73 call System::__linkproc__ LStrClr(void *)
CODE:0052AA78 mov eax, [ebp+lpRSize]
CODE:0052AA7B cmp byte ptr [eax], 31h
CODE:0052AA7E jnz short loc_52AA8D
CODE:0052AA80 lea eax, [ebp+var_18]
CODE:0052AA83 mov edx, offset lpDefis ; "-"
CODE:0052AA88 call System::__linkproc__ LStrLAsg(void *,void *)
CODE:0052AA8D
CODE:0052AA8D loc_52AA8D: ; CODE XREF: InitRSize+86 j
CODE:0052AA8D lea eax, [ebp+lpRSize]
CODE:0052AA90 mov ecx, 1
CODE:0052AA95 mov edx, 1
CODE:0052AA9A call System::__linkproc__ LStrDelete(void)
CODE:0052AA9F
CODE:0052AA9F SetValue: ; CODE XREF: InitRSize+76 j
CODE:0052AA9F lea eax, [ebp+lpDefaultValue]
CODE:0052AAA2 mov ecx, [ebp+lpRSize]
CODE:0052AAA5 mov edx, [ebp+var_18]
CODE:0052AAA8 call System::__linkproc__ LStrCat3(void)
CODE:0052AAAD
CODE:0052AAAD SetRSize: ; CODE XREF: InitRSize+5B j
CODE:0052AAAD lea eax, [ebp+var_28]
CODE:0052AAB0 mov edx, [ebp+lpDefaultValue]
CODE:0052AAB3 call GetVirtualAddr
CODE:0052AAB8 push [ebp+var_1C]
CODE:0052AABB push [ebp+var_20]
CODE:0052AABE push [ebp+var_24]
CODE:0052AAC1 push [ebp+var_28]
CODE:0052AAC4 push offset aMain_reg_rsize ; "Main.Reg_RSize2"
CODE:0052AAC9 mov eax, [ebp+var_8]
CODE:0052AACC push eax
CODE:0052AACD mov eax, [eax]
CODE:0052AACF call dword ptr [eax+28h]

В переводе на русский это означает, что процедура берет из рег кода строку после второго дефиса (если его нет - устанавливается дефолтное значение), проверяет первый символ на равенство 0х31 (десятичная "1"), по-видимому означающее длину поля и записывает его в глобальную переменную RSize.Заметим, что поле RSize хранится в строке рег кода именно в десятичном виде. Таким образом окончательный формат регистрационного кода выглядит так:

хххххх-ххуу-с[z...]

где добавленные поля означают то, что описано выше.С полем RSize можно разобраться двояко. Сгенерировать его методом брута по схеме:

while(result<=0xffff){
    SizeSum=result+rawCC2;
    _asm{
            mov ax,word ptr rawCC2;
            add ax,word ptr result;
            mov word ptr RSizeSum,ax;
        }
    RSizeSum=result;
    DecriptString(iRData,RSizeSum,iRTime,lpRName,lpDectBuff,len);
    a=strcmp(lpLicenseFile,lpDectBuff);
    if(a==0)break;
    result++;
}
.....................
VOID DecriptString(INT RData, INT RSize, INT RTime, LPSTR RName, LPSTR DectBuff, INT len)
{
    int TempRTime=RTime;
    int i=len;

    _asm
    {
        mov esi,RName;
        mov edi,DectBuff;
    }

    while(i>=0)
    {
        _asm
        {
            mov ecx,TempRTime;
            shr ecx,8;
            xor cl,byte ptr[esi];
            mov byte ptr [edi],cl;
            add cl,byte ptr TempRTime;
            and ecx,0xff;
            imul cx,word ptr RData;
            add cx,word ptr RSize;
            mov word ptr TempRTime,cx;
            inc esi;
            inc edi;
        }
        i=i-1;
    }

    return;
}

Соответствующие поля RData, RTime и RName можно вытащить при помощи той же GetPrivateProfileString из Info.ini.Однако, лично я пошел по более короткому пути - при помощи WritePrivateProfileString пишу в нужные поля константы из эталонной функции вместе с эталонной декриптовой строкой. Это избавляет юзверя от проблем с копированием туда-сюда, а результат такой же. К тому же экзешник при этом не трогается - а значит все вполне в юридических рамках, хотя это дело вкуса.Пример достаточно неплохой для новичка, как мне кажется. Хороший опыт по реверсу ООП-кода, простой упаковщик и не слишком сложный алгоритм проверки. Но вот привязка к аппаратуре убила коммерческую реализацию этого проекта - при немалой стоимости лишать себя возможности апдейта компа захочет не каждый психолог (хотя я лично не психолог и что именно делает эта програмулина, хоть убей, не пойму). Так устроен мир: механизм, призванный защитить разработку от злых хакеров загнал ее в гроб, а от хакеров так и не уберег.

P.S. Кстати, варианты замены символов рег кода в зависимости от комплектации Психа реализованы именно в функции, вызывающей InitRsize, думаю в них несложно будет разобраться самостоятельно...

Категория: Общие Статьи | Добавил: aka_kludge (10.12.2010) | Автор: Сигура Мияги
Просмотров: 2868 | Рейтинг: 5.0/1
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
    Главная      
...
На службе : дней

11:18
Обновить


Пользователи
aka_kludge
qwerty
LeadyTOR
aka_Atlantis
AdHErENt
mAss
Sissutr
hiss
DrBio
tHick

Поиск


Copyright tHR - TeAM 2025 г. admin: aka_kludge (ICQ:334449009) Moderator's: LeadyTOR, ... Яндекс.Метрика