MasterGH Опубликовано 19 февраля, 2010 Поделиться Опубликовано 19 февраля, 2010 Частые ошибки1) Сначала создайте память под тело и напишите в ней код чит-кода, а затем пишите прыжок на адрес выделенной памяти2) Сначала отмените прыжок, а затем уничтожайте выделенную память3) Если у Вас codecave в уже существующей памяти, то сначала в codecave напишите код, а затем делайте на codecave прыжок4) Будьте внимательны в расчёте количества нопов5) Будьте внимательны с логикой кода, вы не должны вызывать крах игрыРедкие и пакостные моменты при внедрении чит-кодов1) При внедрении чит-кода нужно следить за регистром флагов. Если он потребуется при выходе из выделенной памяти,то условие не будет правильно выполняться. Выход - поставить pushfd перед сравнениями в выделенной памяти и поставить popfd при выходе из выделенной памяти.2) Ещё очень важное редкое явление, когда на затёртые инструкции оригинального кода могут уже быть прыжки. Т.е. на инструкции где вы ставили nop-s могут быть прыжки. Будет крах игры если какое-то условие не выполниться по логике кода.3) Этот касается "острых" моментов, таких где происходят манипуляции со стеком. Учитывайте что call кладёт в стек адрес для обратного вызова по ret. А это значит что сдвигаются смещения по esp внутри тела чит-кода и могут сдвинуться по ebp. У Xipho была статья об этом, точно не помню. Соответственно нужно обращать внимание ещё и когда вы вызываете ret и кладёте в стек что-то.4) Данные помещаемые в регистры XMM должны быть кратны 16 байтам! Иначе могут быть глюки с изображением в игре.5) Если у Вас неправильно работает скрипт и игра тут же закрывается с критической ошибкой, то у вас есть все инструменты (отладчики) чтобы проверить логику и ошибку. Поставьте игру в конный режим (или сделайте его по нашим статьям) и проведите пошаговую отладку. Не знаете как это сделать, то задайте вопрос на форуме. 1 Ссылка на комментарий Поделиться на другие сайты Поделиться
MasterGH Опубликовано 9 июня, 2011 Автор Поделиться Опубликовано 9 июня, 2011 Примеры скриптов с возможными ошибками пользователей.1. Случай.Создание прыжка и разрушение памяти написаны не там где надо, что может привести к вылету из игры с ошибкой при активации по хот-кеям. И не совсем оптимизированный скрипт.Ниже скрипт постоянное, здоровье возвращает герою здоровье.[ENABLE] alloc(newmem,256) label(back) label(code) 019FAB50: jmp newmem back: newmem: push eax cmp byte ptr [ecx],a0 jne code mov eax,[ecx+1a] mov [ecx+16],eax code: pop eax fld dword ptr [ecx+16] ret int 3 jmp back [DISABLE] dealloc(newmem) 019FAB50: fld dword ptr [ecx+16] ret int 3Скорее всего, правильнее написать так (без учёта сохранения/восстановления регистра флагов): alloc(newmem,256) label(code)newmem: cmp byte [ecx],a0 jne code fld dword [ecx+1a] retcode: fld dword [ecx+16] ret019FAB50: jmp newmem[DISABLE]019FAB50: fld dword ptr [ecx+16] ret int 3dealloc(newmem)[ENABLE]С восстановлением флагов было бы так: alloc(newmem,256) label(code)newmem: pushfd cmp byte [ecx],a0 jne code fld dword [ecx+1a] popfd retcode: fld dword [ecx+16] popfd ret019FAB50: jmp newmem[DISABLE]019FAB50: fld dword ptr [ecx+16] ret int 3dealloc(newmem)[ENABLE] Напоминаю, что сохранять и восстанавливать флаги нужно в тех случаях, когда после вашей инъекцией кода и идёт код использующий регистр флагов. Чаще всего это инструкции инструкции cmp и test. Если будут таки команды, то возможно будет вылет из игры. Ссылка на комментарий Поделиться на другие сайты Поделиться
MasterGH Опубликовано 9 июля, 2011 Автор Поделиться Опубликовано 9 июля, 2011 2. Случай.Увлёкшись написанием длинного скрипта можно забыть о корректности типов данных. В этом примере не учтено, что cmp без указания типа данных сравнивает данные как dword. Это касается 32-х разрядных приложений. //code from here to '[DISABLE]' will be used to enable the cheatalloc(newmem,2048) //2kb should be enoughlabel(GM1)label(GM2)label(nocops)label(returnhere)label(originalcode)//label(pBuffer)label(money)label(god)label(armor)label(cops)//registersymbol(pBuffer)registersymbol(money)registersymbol(god)registersymbol(armor)registersymbol(cops)label(exit)newmem: //this is allocated memory, you have read,write,execute access//place your code herecmp ebx,0 //первый фильтр на буфер с розыскомjne originalcodecmp edx,2000 //второй фильтр на буфер с розыскомjne originalcode//mov [pBuffer],ecxcmp esi,3 //третий фильтр на буфер с розыскомjne originalcodecmp [money],01 //+1000000$?jne GM1mov [ecx+90],#100000GM1:cmp [god],01 //беск. здоровье вкл.?jne GM2//mov [ecx+22D0],(float)10000 //столько здоровья хватит, чтобы не взрываться в машинахmov [ecx+510],(float)10000GM2:cmp [armor],01 //беск. броня вкл.?jne nocops//mov [ecx+2290],(float)1000nocops:cmp [cops],01 //убрать звезды розыска вкл.?jne originalcodemov [ecx+10],00 //нет звёздoriginalcode:lea eax,[esp]push eaxpush 00exit:jmp returnhere//pBuffer://db 0money:db 0god:db 0armor:db 0cops:db 0"EFLC.exe"+8F1E3:jmp newmemnopreturnhere:[DISABLE]//code from here till the end of the code will be used to disable the cheatdealloc(newmem)//unregistersymbol(pBuffer)unregistersymbol(money)unregistersymbol(god)unregistersymbol(armor)unregistersymbol(cops)"EFLC.exe"+8F1E3:lea eax,[esp]push eaxpush 00//Alt: db 8D 04 24 50 6A 00[ENABLE]Для того чтобы скрипт работал как надо, проще объявить сравниваемый тип данных не как db, а как dd. Ссылка на комментарий Поделиться на другие сайты Поделиться
MasterGH Опубликовано 7 августа, 2011 Автор Поделиться Опубликовано 7 августа, 2011 3. СлучайИгра вылетает и ошибка в скрипте абсолютная не узнаваема. Что делать?!Используйте отладчик CheatEngine с пошаговым выполнением.Например у вас такой скрипта[ENABLE]alloc(newmem,2048)label(returnhere)label(originalcode)label(exit)newmem:cmp [esi+0000038c],0jne short originalcodemov eax,#999originalcode:mov [edi],eaxmov edi,eaxmov eax,[esp+14]exit:jmp returnhere101337F4:jmp newmemnopnopnopreturnhere: [DISABLE]dealloc(newmem)101337F4:mov [edi],eaxmov edi,eaxmov eax,[esp+14]//Alt: db 89 07 8B F8 8B 44 24 141) Поставить игру в оконный режим2) На инструкции выше адреса 0x101337F4нажать на F5 в дизассемблере. (это установка брейкпоинта на выполнение кода, зелёное выделение)2) Сделать в игре что-нибудь чтобы игра прервалась на брейкпоинте.3) Активировать скрипт Автоассемблера.4) Нажимать F7 и смотреть регистры.5) Запомнить инструкцию перед крахом игры. Проанализировать. Изменить скрипт.Если вылета нет, то при выходе из тела чита нажать F9 чтобы "отпустить" процесс.Чтобы снять брейкпоинт выделить зелёную инструкцию и нажать F5.Стоит запомнить. Отладчик специально создан для того чтобы отлавливать ошибки кода. В том числе и отлавливать ошибки ваших скриптов. Ссылка на комментарий Поделиться на другие сайты Поделиться
MasterGH Опубликовано 28 августа, 2011 Автор Поделиться Опубликовано 28 августа, 2011 Случа4 и Случай5Чтение(или запись) из не существующего адреса (или адреса с протекцией памяти не для чтения) и случай выполнения перемещённой инструкции.ANT' date='27 Май 2011 - 00:04' timestamp='1306440261' post='3117']Можно всегда сразу с ebx (или др. выбранным регистром) сравнивать. Просто я привык по шаблону делать.После внедрения твоего скрипта, текущее здоровье принимает текущее макс. значение, однако, стоит шевельнуться и герой умирает.только такой вариант у меня нормально работает[ENABLE]alloc(newmem,2048)label(vitality)label(returnhere)label(originalcode)newmem:vitality: push ebx mov ebx,[witcher2.exe+022BC5F4] mov ebx,[ebx+14] mov ebx,[ebx+14] mov ebx,[ebx+8] cmp [eax],ebx pop ebx jne short originalcode push esi mov esi,[witcher2.exe+022BC5F4] mov esi,[esi+14] mov esi,[esi+14] mov esi,[esi+0C] mov [eax],esi pop esioriginalcode: fld dword ptr [eax] mov eax,[ebp+08] jmp returnherewitcher2.exe+8CA4: jmp vitalityreturnhere:[DISABLE]dealloc(newmem)witcher2.exe+8CA4: fld dword ptr [eax] mov eax,[ebp+08]Скрипт работает нормально но при переходе в другой уровень игры, (в локации при загрузках) игра вылетает. Возможные причины:1) По этому указателю: mov ebx,[witcher2.exe+022BC5F4] mov ebx,[ebx+14]mov ebx,[ebx+14] // например в скобках оказался не существующий адрес и вызвало крах игры mov ebx,[ebx+8]где-то на уровнях отсутствует указатель, например, там где [ebx+8] бывает ноль. Чтение этого значения вызовет вылет. Чтобы этого не было, нужно проверять указатели. 2) Причина, может быть вызов перемещённой инструкции:witcher2.exe+8CA4: fld dword ptr [eax]mov eax,[ebp+08] // например код пытался вызвать эту перемещённую инструкцию Ссылка на комментарий Поделиться на другие сайты Поделиться
Garik66 Опубликовано 14 января, 2016 Поделиться Опубликовано 14 января, 2016 Частые ошибки Редкие и пакостные моменты при внедрении чит-кодовMasterGH, прекрасная статья, по-моему я уже столкнулся со всеми перечисленными тобой случаями, жаль, что раньше не встречал эту статью. Ссылка на комментарий Поделиться на другие сайты Поделиться
DarkPower2 Опубликовано 6 апреля, 2016 Поделиться Опубликовано 6 апреля, 2016 (изменено) Как бороться с вот этим? Цитата Чтение(или запись) из не существующего адреса (или адреса с протекцией памяти не для чтения) и случай выполнения перемещённой инструкции. Просто бывает, при смерти моего персонажа, указатель на него меняется на несуществующий адрес. Изменено 6 апреля, 2016 пользователем DarkPower2 Ссылка на комментарий Поделиться на другие сайты Поделиться
Garik66 Опубликовано 6 апреля, 2016 Поделиться Опубликовано 6 апреля, 2016 38 минуты назад, DarkPower2 сказал: указатель на него меняется на несуществующий адрес. Выложи свой скрипт, посмотрим что можно сделать. А так - нужно дополнительно фильтровать в скрипте - делать проверку. Ссылка на комментарий Поделиться на другие сайты Поделиться
DarkPower2 Опубликовано 6 апреля, 2016 Поделиться Опубликовано 6 апреля, 2016 6 часов назад, Garik66 сказал: Выложи свой скрипт, посмотрим что можно сделать. А так - нужно дополнительно фильтровать в скрипте - делать проверку. Скрытый текст newmem: originalcode: mov R13, ["server.dll"+01C508B8] //вот тут бывакт mov R13, [R13] mov R13, [R13+48] cmp rbx, [R13] je exit movss [rbx+000007EC],xmm7 exit: movss xmm1, [rbx+7EC] jmp returnhere "server.dll"+884A2A: push RDI mov RDI, newmem jmp RDI nop nop returnhere: pop RDI Ссылка на комментарий Поделиться на другие сайты Поделиться
Garik66 Опубликовано 6 апреля, 2016 Поделиться Опубликовано 6 апреля, 2016 Замечания по скрипту: 1. Ты не сохраняешь регистр R13 в стеке, я имею ввиду: push r13 ...... pop r13 Ты уверен, что значение, которое было в r13 до твоих записей не используется потом? Проверил это? 2. Ты смело пишешь инструкцию: add R13, 590 cmp rbx, [R13] лучше сделать так: cmp rbx, [R13+590] 3. mov R13, ["server.dll"+01C508B8] //вот тут бывакт А какие бывают значения? Адрес же по идее статичный. Нужно найти инструкцию, которая работает с этим адресом, из неё найти адреса с которыми она работает и сделать фильтр только для твоего адреса. Ссылка на комментарий Поделиться на другие сайты Поделиться
DarkPower2 Опубликовано 6 апреля, 2016 Поделиться Опубликовано 6 апреля, 2016 Я изменил код. Ну вобще в конце указателя бывает. Разве не сохраняется R13? Ссылка на комментарий Поделиться на другие сайты Поделиться
Garik66 Опубликовано 6 апреля, 2016 Поделиться Опубликовано 6 апреля, 2016 1 минуту назад, DarkPower2 сказал: Разве не сохраняется R13? В твоём скрипте нет. Ссылка на комментарий Поделиться на другие сайты Поделиться
DarkPower2 Опубликовано 6 апреля, 2016 Поделиться Опубликовано 6 апреля, 2016 Только что, Garik66 сказал: В твоём скрипте нет. Ай, блин... Просто неверный код скинул. Я потерял тот, это тестовый я делал... щас отредактирую... Ссылка на комментарий Поделиться на другие сайты Поделиться
DarkPower2 Опубликовано 6 апреля, 2016 Поделиться Опубликовано 6 апреля, 2016 Вот примерно такой был, но суть в том, что когда персонаж умирал, то окончательный адрес менялся на левый, значение соответственно то ?? то еще какое нибудь. Скрытый текст newmem: push R13 mov R13, ["server.dll"+01C508B8] mov R13, [R13] mov R13, [R13+48] cmp rbx, [R13] je exit movss [rbx+000007EC],xmm7 exit: pop R13 movss xmm1, [rbx+7EC] jmp returnhere "server.dll"+884A2A: push RDI mov RDI, newmem jmp RDI nop nop returnhere: pop RDI Ссылка на комментарий Поделиться на другие сайты Поделиться
Garik66 Опубликовано 6 апреля, 2016 Поделиться Опубликовано 6 апреля, 2016 1. Под спойлер. 2. Выкладывайте лучше весь скрипт (лучше с листингом инструкций внизу скрипта, который делает СЕ). 3. А скрипт у тебя точно рабочий? Просто, если оригинальная инструкция например эта: movss xmm1, [rbx+7EC] то наверное нужно не je exit а jne exit Ладно ещё раз попрощаюсь - поздно уже. Ссылка на комментарий Поделиться на другие сайты Поделиться
DarkPower2 Опубликовано 7 апреля, 2016 Поделиться Опубликовано 7 апреля, 2016 Цитата 3. А скрипт у тебя точно рабочий? Просто, если оригинальная инструкция например эта: Там 2 оригинальных инструкции... просто если персонаж совпадает с моим, то пропускается одна инструкция. Проблема не в коде, проблема в том, что тот регион памяти меняется при смене измерения или при смерти или при выходе из сервера, и не всегда там хранятся мои данные. Когда мой персонаж умирает, то данные стераются или заменяются другим живым персонажем. Вот, можно ли проверить есть ли данные по указоному адресу или еще как-то, что считать их без краха? Ссылка на комментарий Поделиться на другие сайты Поделиться
Рекомендуемые сообщения