CS2 Aimware crack. Объяснение защиты и гайдик на crack

mhalaider

Новичок
Автор темы
2
8
Доброго дня, прекрасный и замечательный форум BlastHack. Хотел бы предоставить Вам небольшую выдержку о том как работает защита аимвара и какие методы есть, чтобы её побороть.

Принцип защиты​

Бинарник чита накрывается собственным протектором, логика которого построена на том, чтобы чит был максимально под одну сессию. То есть проверку исходя из инструкции cpuid, структуры KUSER_SHARED_DATA и мануальных импортов, которые "зашифрованы".

Что касательно проверок через cpuid, то просто я шёл по пути самурая, так как паттерн на них составлять идея говна, то я просто взял поиск по инструкции в x64dbg и проверял, есть ли дальше в коде mov'ы eax, ebx, ecx, edx. В eax регистре передаются параметры для получения строки бренда процессора.

Пример кода:

Код:
00000023B6B81AEE | 66:0F43F2                  | cmovae si,dx                
00000023B6B81AF2 | 66:F7DA                    | neg dx                      
00000023B6B81AF5 | 0FA2                       | cpuid                                ; вызов инструкции
00000023B6B81AF7 | 41:80D9 AF                 | sbb r9b,AF                  
00000023B6B81AFB | 44:0FBFD6                  | movsx r10d,si              
00000023B6B81AFF | 41:0F9FC2                  | setg r10b                  
00000023B6B81B03 | 41:89442A 03               | mov dword ptr ds:[r10+rbp+3],eax     ; помещаем результат выполнения инструкции в стек
00000023B6B81B08 | 4F:8D8409 A6048B25         | lea r8,qword ptr ds:[r9+r9+258B04A6]
00000023B6B81B10 | 41:0FB7C2                  | movzx eax,r10w              
00000023B6B81B14 | 42:895C95 FC               | mov dword ptr ss:[rbp+r10*4-4],ebx   ; и тут
00000023B6B81B19 | 41:C0E1 06                 | shl r9b,6                  
00000023B6B81B1D | 8BDE                       | mov ebx,esi                
00000023B6B81B1F | 42:894C55 FA               | mov dword ptr ss:[rbp+r10*2-6],ecx   ; и так
00000023B6B81B24 | 42:895415 F7               | mov dword ptr ss:[rbp+r10-9],edx     ; и даже так


Чеки на KUSER_SHARED_DATA. Тут уже всё не так однозначно, так как на поиск данной проверки ушёл месяц, а точнее я просто 3 дня поковырял и забил, а потом в последние 3 дня сабки всё нашёл и отломал. Собственно, стоить упомянуть, что все чеки не лежат открыто. Например вот это:

Код:
00000023B69C4F81 | 43:8B8C19 FF1FE9FF | mov ecx,dword ptr ds:[r9+r11-16E001]

r9+r11-16E001 будет равно 0x7ffe0260, а это указатель на KUSER_SHARED_DATA.NtBuildNumber

И последнее, мануальные импорты, отчасти самая весёлая часть, потому что на все импорты ( рассмотрим их чуть ниже ), есть по несколько CRC-check функций, я не подсчитывал сколько их точно, но много и бороться с ними бесполезно, так как проверки выполнены также как и с KUSER_SHARED_DATA.NtBuildNumber. Вызов импорта выглядит так:

Код:
00000023B66F89B8 | 49:BA E038087F722BF97F     | mov r10,7FF92B727F0838E0                  |
00000023B66F89C2 | 48:C1C8 0E                 | ror rax,E                                 |
00000023B66F89C6 | 4D:85D2                    | test r10,r10                              |
00000023B66F89C9 | 49:81C2 EE7D6E2A           | add r10,2A6E7DEE                          |
00000023B66F89D0 | 49:F7D2                    | not r10                                   |
00000023B66F89D3 | 48:39C0                    | cmp rax,rax                               |
00000023B66F89D6 | 49:81EA EA0FD448           | sub r10,48D40FEA                          |
00000023B66F89DD | 48:05 D1D90401             | add rax,104D9D1                           |
00000023B66F89E3 | 48:2D 0F9CD901             | sub rax,1D99C0F                           |
00000023B66F89E9 | 49:C1CA 02                 | ror r10,2                                 |
00000023B66F89ED | 4D:85D2                    | test r10,r10                              |
00000023B66F89F0 | 48:85C0                    | test rax,rax                              |
00000023B66F89F3 | 48:C1C0 06                 | rol rax,6                                 |
00000023B66F89F7 | 49:81F2 F25A8428           | xor r10,28845AF2                          |
00000023B66F89FE | 48:39C0                    | cmp rax,rax                               |
00000023B66F8A01 | 49:81EA A414B543           | sub r10,43B514A4                          |
00000023B66F8A08 | 49:F7D2                    | not r10                                   |
00000023B66F8A0B | 48:F7D0                    | not rax                                   |
00000023B66F8A0E | 49:C1CA 0E                 | ror r10,E                                 |
00000023B66F8A12 | 48:2D E0D3837C             | sub rax,7C83D3E0                          |
00000023B66F8A18 | 4D:39D2                    | cmp r10,r10                               |
00000023B66F8A1B | 48:85C0                    | test rax,rax                              |
00000023B66F8A1E | 48:C1C0 16                 | rol rax,16                                |
00000023B66F8A22 | 50                         | push rax                                  |
00000023B66F8A23 | 41:FFE2                    | jmp r10                                   |

Кратко разберём логику, присутствует базовая "обфускация" адреса импорта через разные инструкции ror, rol, xor, not, sub, add. А также в некоторых случаях ( как здесь ) на стек пушится другой также обфусцированный return-адрес. В принципе ничего сложного, ищем по паттерну все jmp r10/r11/rax, потом ищем mov на найденный регистр и параллельно сохраняем все операции с ним, для того, чтобы при фиксе импортов пропатчить лишь первый mov r??, 0x????????????????. Сурса фикса импортов не будет, потому что сами можете написать, Zydis & unicorn в руки и погнали. А вот что касается CRC чеков ? Тут всё интереснее, как я и говорил, тут система такая же, как и с проверкой структуры KUSER_SHARED_DATA. Но при этом проверяемый адрес увеличивается на 4 байта, то есть проверяется прям весь код вызова импорта, так что патчить импорты на ранних этапах нелья и как я это обошёл расскажу дальше.

Принцип кряка​

Первое что нам нужно, так это задампить бинарник. Для этого я использую связку SSDT хуков в кернеле и EfiGuard для отключения патчгуарда и проверки подписей загружаемых драйверов. Поскольку бинарник записывается через кернел драйвер аимвара, то никакие вызовы NtWriteVirtualMemory не проходят, но они всегда создают поток на точке входа с флагом 6 используя NtCreateThreadEx. Соответственно, в хуке на создание потока проверяем флаг и просто возвращаем SUCCESS, таки образом спуфая старт чита и можем легко его задампить через что угодно.

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

Нашли CRC-чек ? Почти финалочка. Выбираем место где будет ставить int3 бряк и сохраняем инструкции. По хорошему стоит для этого написать либу, которая будет копировать инструкцию, которую патчим, аллокать память, записывать её туда и после выполнения джампить на следующую, но мне впадлу и я просто ручками восстановил код. После установки патча, сохраняем то количество, сколько она выполнилась и чекая, когда данное количество отработало, то восстанавливаем все импорты. Но есть закономерный вопрос, а как до этого фиксить импорты ?

А вот тут вступает в силу VEH, чекая что ExceptionCode == STATUS_ACCESS_VIOLATION и проверка, что Rip равен одному из адресов импортов. Меняем Rip на валидный и всё у нас замечательно.

Остаётся только самое тяжкое, это правильно пропатчить cpuid. По каким-то причинам на них CRC никак не распространяется, что даёт нам возможность спокойной их патчить даже пока чит не полностью проинициализировался. Я все это искал ручками, так как это просто надёжнее, нужно учитывать, что после инструкции cpuid, обязательно мувается информация которую и запросили через eax. Ну вы об этом и так знаете из моих слов выше. Просто патчим их на int3 и обрабатываем eax в VEH хендлере.

Вот и всё, инструкция для кряка готова. Грустно конечно, что дошло до того, что я её выпускаю, но надеюсь это сможет кому-то дать новые идеи для секурити или методов кряков. Всю более детальную информацию вы можете найти на репозитории ниже:

P. s. Данный кряк был сделано где-то ~15 ноября и до сих пор работает, в новых версиях, пока что, ничего не изменилось. Также, данный кряк и есть оригинальный от энигмы, просто я там больше не "работаю".

UPD 20.12.24: Кряк был обновлён под последнюю версию игры, хоть и играть с ним крайне больно, но он жизнеспособен вероятнее всего. Ссылка на скачивание готовой DLL |
VT
 
Последнее редактирование:

nver4ick

Новичок
3
0
кряк робит,я нашел какой то кфг,в целом топ хвх,но есть ли кфг с норм банихопом у кого?
1735687183558.png