| RSS



Меню

Bookmark and Share


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





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

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

Облако тэгов
ОС видио Tor Обратная сторона антенна 4.6 PHP Эксплоит Windows Server 2008 qip Virtual chroot kernel proc sysctl tune FreeBSD bridge Boot Disk Bluetooth GEO game directx Emulator Python Shell DDoS червь Conficker вирус троян Лаборатория Касперского пиратство apple iPhone ИТ-отрасль Щеголев Microsoft экономический кризис Twitter социальная сеть анонимность Лицензия Open Source ASP.NET MVC уязвимость MySQL база данных файлообмен закон франция пират Skype мобильный Deutsche Telekom Хакер киберпреступник Trend Micro кибератака Германия робот утечка данных персональные данные ноутбук интернет Китай цензура ядро Linux Торвальдс Windows Vista Acer Linux патент браузер Firefox Internet Explorer Opera Net Applications Safari Intel Linux Foundation Moblin Oracle патч банкомат кардер HSM IBM X-Force Cofee сша кибервойна Эстония Dell ИТ-специалист хакерские атаки Pirate Bay контроль кибербезопасность язык программирования The Pirate Bay Пиратская партия утечка информации приговор Mozilla Chrome безопасность Госдума СМИ Windows 8 Баллмер взлом Пентагон ботнет Украина Facebook Cisco cloud Windows XP нетбук торрент музыка биометрический nokia ФБР IP-адрес CIPAV Comcast sms RSA java Google CAPTCHA Symantec спам конфиденциальная информация инсайдер Perimetrix антивирус тест Anti-Malware Windows 7 операционная система Windows провайдер авторское право RapidShare UNIX свиной грипп шантаж дети EFF BluWiki копирайт экстремизм Panda Security cloud computing McAfee Cybercrime Response Unit Bottle Domains HTTPS ICANN студент шпионское ПО Норвегия школьник New York Times XSS YouTube Warner Music кибершпионаж КНДР Ubuntu свободное ПО AMD ATI касперский Россия РФ сервер хостинг фальшивый антивирус Comodo CA Wi-Fi D-Link суд пароль блог фишинг Одноклассники медведев контрафакт мошенник штраф Sony GPS по Gumblar JAVASCRIPT хакеры вредоносное ПО Yahoo ФАС компьютер Софт MPAA кибероружие PandaLabs Red Hat Минкомсвязи сбой ASUSTeK Computer мошенничество Доктор Веб ВКонтакте Cyber-Arc исходный код PCI DSS МВД фильтр порнография BREIN свобода слова Казахстан GEMA Autodesk сисадмин Gmail кредитная карта кибермошенник LiveJournal шифрование криптография Deep Purple банк нанотехнологии Wikipedia zero-day ColdFusion выборы кража данных DNS BIND Android BASIC атака Black Hat Mac OS X Click Forensics Clampi домен фсб Прокуратура Уголовное дело icq Barrelfish киберпреступность Sophos AT&T ошибка Electa Gamma Knife OpenBSD DARPA военные Сайт Visual Studio 2010 .NET Framework 4 Chrome OS электронная почта турция конференция спамер FTC полиция российская ОС Koobface Великобритания БЕЛОРУССИЯ грузия BSA Bittorrent облачные вычисления Azure Европа Dr.Web Билл Гейтс спецслужбы Cryzip Живой Журнал Royal Bank of Scotland смартфон Canonical Pwn2Own F-Secure Symbian Hotmail фильм

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

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) | Автор: Сигура Мияги
Просмотров: 2595 | Рейтинг: 5.0/1
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
    Главная      
...
На службе : дней

13:02
Обновить


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

Поиск


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