Перейти к содержанию

imaginary

Помогаторы
  • Постов

    319
  • Зарегистрирован

  • Посещение

  • Победитель дней

    43

Сообщения, опубликованные imaginary

  1. 3 минуты назад, MasterGH сказал:

    Это точно верно?

    Всё верно, эти скрипты не предполагают совместной работы, и включаются отдельно друг от друга, libopus.haar1 используется просто как место для хранения

  2. Нужно найти функцию которая вызывает субтитры, наверняка они по какому то адресу вызываются, а вообще зависит от игры, где то могут вообще сделать что все субтитры вызывают разные функции (например функции в миссии), тогда нецелесообразно так читать.
    И потом, ты же озвучивать хочешь, зачем тебе озвучка не в момент игры, как ты будешь передавать эмоции? (если такая цель стоит), а то получится у тебя озвучка, вроде такого:
    Люди кричат, город горит, и мимо пробегающий житель спокойно говорит: Тут город горит, у нас половина населения пострадало *весёлым голосом* ?

  3. Cheat Engine сервер предназначен для удалённого взлома каких либо приложений, сервер располагается на целевом устройстве, а клиент подключается к нему по IP, после этого становятся доступны почти все функции стандартного Cheat Engine ☺️.

    Установка Cheat Engine сервера на Android:

    Спойлер

    Для установки и использования вам потребуются:

    • root права в системе.
    • Приложение - терминал, скачать можно например из Google play.
    • Сам сервер, который можно скачать с официального сайта, в разделе Download снизу, под вашу версию Android.


    После того, как у вас есть все эти компоненты, можно приступать к установке.
    Сначала, вам нужно найти системную папку с файлом sh, у меня это /system/bin:

    Спойлер

    image.thumb.png.d1bdf571ee8525432dffb744ee97c09c.png


    После, нужно распаковать файлы из скачанного архива сервера в эту папку (файлы могут называться иначе):

    Спойлер

    image.thumb.png.e00c5478a6dda8afce214fabde6fbf16.png


    После распаковки, останется только запустить сервер. Сделать это можно с помощью приложения терминал.
    Команды:

    
    su                                      		--Дать терминалу права суперпользователя.
    system/bin/ceserver_x86 	   		--Путь к файлу сервера. (какой у вас файл, и путь, вводите свой)


    При успешном запуске, вы увидите сообщение от сервера, в котором он пишет что ожидает подключения клиента:

    Спойлер

    image.thumb.png.fe1e3194fab649cf8d94004aa59397e3.png


    Что бы подключиться к серверу, вам нужно открыть клиент CE, и ввести ip адрес сервера, и порт (стандартный 52736), не забывайте что для подключения вне локальной сети порт должен быть открыт.

    Спойлер

    1224157773_.thumb.png.d592c15203d4de7a908528f7b62aff07.png


    После подключения вы увидите список процессов на устройстве, и сможете взаимодействовать с ними:

    Спойлер

    image.thumb.png.8456722241c5c28ba6f0a90006ea5a46.png

     

     

    Особенности использования, написание скрипта:

    Спойлер

    CE сервер нестабилен.
    При работе с CE сервером нужно соблюдать осторожность, не замораживайте слишком много значений, с маленьким интервалом заморозки, при просмотре списка символов, не замораживайте, не совершайте много действий сразу... Проще говоря, сервер может от этого зависнуть в любой момент☺️.
    Так же не доступно выделение памяти, по крайней мере на моей версии сервера, и версии для linux, у других я думаю всё так же. При попытке выделить память, написав alloc() или иначе, сервер навечно зависнет, и клиент тоже. Поэтому, не выделяйте память.

    Для написания скриптов, если вам нужно использовать выделенную память с прыжком на неё и обратно, используйте какую либо существующую память, например найдите неиспользуемую игрой функцию (в .so модулях, с помощью отладчика) и делайте прыжок на неё, например такую:

    Спойлер

    image.thumb.png.d1cb8b93d7dd837c0331db0ff23afb22.png


    Рассмотрим написание скрипта без alloc, с использованием подобной функции.
    Я возьму для примера, прыжок с функции здоровья игрока в игре Terraria:

    Спойлер

    image.thumb.png.d7cebd100378e16c12d993c837b42bfa.png


    Напишем простой скрипт, который должен будет постоянно восстанавливать здоровье игрока:

    Спойлер
    
    
    [ENABLE]
    aobscan(PlayerL, 8B 9B A4 04 00 00) //Поиск инструкции по сигнатуре
    registersymbol(PlayerL)
    
    libopus.haar1: //Код в выбранном месте
    mov [ebx+000004A4],#500 //Установить 500 здоровья
    
    originalcode: //Оригинальный код (просто метка)
    mov ebx,[ebx+000004A4] //Оригинальная инструкция
    
    jmp returnhere //Возврат в код после прыжка
    
    PlayerL:
    jmp libopus.haar1 //Прыжок на наш код
    nop //nop 1 байт, так как прыжок 5 байт, а инструкция 6
    
    returnhere:
     
    [DISABLE]
    PlayerL:
    db 8B 9B A4 04 00 00 //Восстановление оригинальной инструкции
    unregistersymbol(PlayerL)

     


    Теперь персонаж постоянно получает 500 здоровья, и урон не заметен:

    Спойлер

    image.thumb.png.25a185b40062031eb5b82fb56bc51e25.png


    Но как поступить, если вам нужно делать метки, записывать что либо в них, например, если вы хотите автоматически искать адрес игрока?
    Тут 2 варианта, или найти участок памяти в которой есть права на запись (выдать не вариант, CE server так не умеет), или использовать LUA и отладчик.

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

    Спойлер
    
    
    {$lua}
    [ENABLE]
    Adr = AOBScan('8B 9B A4 04 00 00','+X')[0] --Поиск сигнатуры
    debug_setBreakpoint(Adr, 6, bptExecute, givePlayer) --Установка брякпоинта на найденный адрес, с параметром срабатывания при исполнении, и вызываемая при срабатывании функция.
    function givePlayer() --Вызываемая функция
      print(EBX) --Вывести адрес игрока (из EBX)
      debug_removeBreakpoint(Adr) --Убрять брякпоинт
    end
    [DISABLE]
    

     


    После включения, в выводе мы сразу получим адрес игрока, в десятичной системе исчисления:

    Спойлер

    image.thumb.png.79af64d413f1d18b5b1523588be8180c.png


    Но это не удобно, хочется увидеть адрес в виде указателя, в таблице, но память выделять мы не можем.
    Снова воспользуемся "libopus.haar1" и запишем адрес в него, добавив в таблицу.

    Спойлер
    
    
    --Заменим print на следующий код:
    writeInteger('libopus.haar1', EBX) --Записать адрес игрока в память игры, по метке libopus.haar1
    
    --Этим можно было бы и ограничиться, но оно не стало работать нормально, записывая какую то ерунду, даже если сохранить EBX ранее.
    --Вместо нужного кода, туда каким то образом попадает mov [ebx+000004A4],000001F4 (500), инструкция из предыдущего скрипта, хотя он уже удалён из таблицы...
    --Не помог даже перезапуск клиента и сервера, чистая магия, иначе не скажешь. В следующие попытки вообще перестала работать запись куда либо..
    --Возможно это как то связано с инструкциями записи, которые используются в Android..
    --Потом, внутри функции небыло записи, возможно это как то связано с владельцем и правами потока, только такой код смог заработать верно:
    
    {$lua}
    [ENABLE]
    Adr = AOBScan('8B 9B A4 04 00 00','+X')[0] --Поиск сигнатуры
    debug_setBreakpoint(Adr, 6, bptExecute, givePlayer) --Установка брякпоинта на найденный адрес, с параметром срабатывания при исполнении, и вызываемая при срабатывании функция.
    function givePlayer() --Вызываемая функция
      --Ненужный код+
      timer = createTimer(getMainForm()) --Таймер с владельцем
      timer.Interval = 20 --Время до срабатывания
      timer.OnTimer = function(timer) --Функция
         timer.destroy() --Убрать таймер
         writeInteger('libopus.haar1', EBX) --Записать адрес игрока
      end
      --Ненужный код-
    
      debug_removeBreakpoint(Adr) --Убрять брякпоинт
    end
    [DISABLE]

    image.png.7e475d6e956197d657d14ab48f7bdaed.png


    После чего мы получим адрес игрока в таблице:

    Спойлер

    image.thumb.png.7d10454fc5a8b8e48cf4eccf464a145f.png

     

    Используем его как указатель, и попробуем добавить здоровье в таблицу:

    Спойлер

    image.png.6077b829a6dba4e7354e96428b0e65c0.pngimage.thumb.png.7d51b423bed8b5b675ff0b5b7a2ff1d6.png


    Так же можно добавить и другие параметры игрока, зная смешения:

    Спойлер

    image.thumb.png.da0d8bed2ba81cb5fad64ed65e7f7523.png


    Как вывод можно сказать, что Cheat Engine сервер ещё не очень стабилен, и при использовании вам скорей всего придётся иногда его перезапускать (клиент перезапускать не нужно, даже если он завис, достаточно сервера, клиент сразу присоединится к нему). Lua в общих чертах работает, а самое главное - работает отладчик, который в таком виде очень даже удобен для использования ?.
    Надеюсь что эта статья вас чему то научила ?



     

    • Понравилось 1
    • Спасибо 1
    • Плюс 5
  4. 11 часов назад, NickSpirit сказал:

    Однако, если я не хочу доводить дело до выполнения данной инструкции зная ,что в регистре не то число что мне нужно - мне нужно знать это число не выполняя действие в игре. 

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

  5. 25 минут назад, NickSpirit сказал:

    Вот как мне получить значение регистра eax до срабатывания данной инструкции?

    Изучать как работает отладчик в CE
    Ну или...

    Спойлер

    Встать на выделенную тобой инструкцию, нажать F5, включится отладка, сделать в игре действие, с которым связана эта инструкция, игра остановится, а в CE у тебя справа появятся все регистры, на момент остановки, как раз до этой инструкции. Нажми снова F5 стоя на той же инструкции, и F9, игра запустится, ты будешь знать значение. ?


     

  6. Какую тему интересную снекропостили ?
    @Garik66 , ты написал рабочий скрипт, но он очень сложный как мне кажется, и вот тут например

    В 27.03.2018 в 09:43, Garik66 сказал:

    timer:setEnabled(false)

    таймер не уничтожается, а просто выключается, то есть как элемент он остаётся и занимает место, потому лучше писать timer.destroy(), и для других элементов в CE тоже, если нужно выключить не включая ?
     

    47 минут назад, Pitronic сказал:

    У меня не включается


    Попробуй вот такую вставку, вставлять можно в любое место в asm скрипте в разделе [ENABLE], всё прокомментировано

    Спойлер
    
    {$lua}
    memrec = getAddressList().getMemoryRecordByDescription("AA") --поиск по имени скрипта
    timer = createTimer(nil, false) --создание выключенного таймера
    timer.Interval = 2000 --Время, в милисекундах до отключения
    timer.OnTimer = unf --функция исполняемая таймером
    timer.Enabled = true --включение таймера
    
    function unf(timer)
     memoryrecord_unfreeze(memrec) --отключение скрипта
     timer.destroy() --уничтожение таймера
    end
    {$asm}

     

     

    • Плюс 2
  7. 4 часа назад, Nikitich сказал:

    CE находит только инструкцию сравнения CMP

    Скорей всего другие и не обращаются, и что тебе не нравится? cmp игра сравнивает номер твоей анимации, и уже действует в зависимости от этого, всё правильно и так как должно быть ?

  8. Если у тебя в игре адреса появляются только при открытии инвентаря, то может там и список предметов динамически генерируется, и там много зависимых функций, возьми для начала что то простое, как в статье той.

  9. Наверняка многим было интересно как же всё таки работает SpeedHack предоставляемый Cheat Engine, в этом видео рассказывается об этом:

    Спойлер

     


    Кратко для тех, кто не хочет смотреть:

    Спойлер

    Speed Hack в Cheat engine основан на трёх функциях, GetTickCount, GetTickCount64 и QueryPerfomanceCounter.
    Все эти функции возвращают количество каких либо единиц времени с определённого момента, например количество миллисекунд со старта системы.
    Игры используют эти функции с целью стабилизации своей скорости, так как в ином случае на медленных устройствах игры бы работали очень медленно, персонаж бы медленно ходил, и тд, а на быстрых наоборот, слишком быстро, вплоть до того что было бы невозможно поспеть за игрой.
    Таким образом, игра обращается к функции, и сохраняет полученные такты. На следующий "кадр" снова обращается, и сравнивает значение, новое, со старым. В зависимости от величины разности между ними, игра просчитывает своё состояние вперёд, таким образом стабилизируя скорость и устраняя последствия зависаний.
    Cheat engine загружает своё dll, в котором прописаны изменённые функции времени, и создаёт в оригинальных функциях прыжки, на изменённые. В изменённых использует умножение настоящих тактов на какой либо множитель, который указывается ползунком под галочкой SpeedHack, и возвращает это игре, таким образом увеличивается промежуток между старыми и новыми значениями, и игра ускоряется, или наоборот, замедляется, если множитель меньше единицы.


     

    • Понравилось 1
    • Плюс 4
  10. В 18.03.2020 в 17:16, koul сказал:

    TestSignature():

    Спойлер
    
    while (*mask)
    	{
    		if (*mask == '?')
    		{
    			mask++; 
    			Signature++;
    			Buffer++;
    			continue;
    		}
    		if (*Buffer++ != *Signature++)
    			return false;
    	}
    	return true;

    А разве этот цикл не будет бесконечно выполняться?, я не вижу что бы тут совпадало условие на '?' хоть раз, хотя может я что то не вижу ?

    А всё я нашла, тогда не знаю что не так.

     

     

     

     

  11. 23 часа назад, Lucky7 сказал:

    А теперь главный вопрос, где мне тогда искать мое значение

    У меня эта сигнатура тоже не в модуле, находится просто поиском по страницам с использованием VirtualQueryEx.
    А ещё как я вижу это записываемая память, попробуй написать простой перебор страниц, с проверкой, если записываемая память, то проверять, если иная, например исполняемая, то не трогать, проверяй всё с начального адреса до последней страницы, последнюю страницу можно определить если VirtualQueryEx вернёт ту же самую страницу после прибавления её размера, а не следующую. В CE как раз реализован умный поиск, там есть галочка Writable.

     

  12. 1 час назад, Lucky7 сказал:

    Base address, Scan Size из плагина Sig Maker к OllyDbg 1.0, то все успешно заработает

    Как сказал @Xipho у тебя вероятно сканирование происходит не в области модуля, Terraria.exe это тоже модуль. То есть есть процесс - Terraria.exe, а в нём есть модуль Terraria.exe, на равне с dll и другими. А я вижу что ты пишешь NULL при поиске модуля, попробуй укажи там Terraria.exe.

  13. 16 часов назад, Alex2411 сказал:

    получаеться если  адрес должен  делиться на 4 значит можно было  поставить align 4 ? или обязательно  надо ставить  align 10  потому что  метка целиком занимает 16 байт ? как понять ?

    Зависит от кода до метки, если не хочешь выравнивать ничего, то занеси массив умножаемый в другой xmm, например:

    movups xmm2,[metka]

    или если у тебя все заняты xmm, то сохрани сначала из xmm какого то, например:

    Спойлер
    
    movups [metka],xmm2 //Сохранение
    movups xmm2,[muller]
    mulps xmm1,xmm2 //умножение
    movups xmm2,[metka] //Восстановление
    
    metka: //место сохранения
    dq 0 0
    
    muller: //твой множитель
    dd (float)2 (float)5 (float)3 (float)2

     


    или считай байты в инструкциях, и добавляй allign сколько не хватает до нужного адреса, но тогда при изменении скрипта его нужно будет менять, если размер изменился.

    А ещё есть вариант, выделить память отдельную для твоего множителя, тогда всё будет всегда выравнено:

    Спойлер
    
    alloc(code,200) //то что уже у тебя подставлено в скрипте
    alloc(muller,200) //любое число, выделится всё рано страница
    
    code:
    mulps xmm0,[muller]
    
    jmp returnhere //
    
    muller:
    dd (float)2 (float)4 (float)3 (float)5

     

     

    • Плюс 1
  14. Это работа с массивами вообще, тут ps, mulps умножает массив, когда ты пишешь mulps [что то тут], у тебя не 4 байта умножаются, а все 16, потому если тебе надо первое значение (4 байта) из xmm умножить, то просто напиши mulss xmm, [на что умножить, float], и будет всё работать без аллигнов.

    Вот например:

    Спойлер
    
    code:
    mulss xmm1,[muller]
    
    muller:
    dd (float)5

     


    А вылетает потому что movaps и тому подобные команды работы с массивами, кроме movups должны быть выравнены по шестнадцетиричным границам, то есть число должно ровно делиться на 4, число адреса из которого берутся значения, иначе будет ошибка и исключение.

    • Плюс 1
  15. Если в CE, то выдели память, потом сделай проверку на соответствие со счётчиком и нулём, записывай новые адреса в выделенную память, пока они не иссякнут, вот пример, создаёшь поток на code, и в foadr по порядку записываются eax регистры создаваемых потоков, на инструкцию приспособить не сложно.

     

    Спойлер
    
    [ENABLE]
    //в eax новый адрес
    alloc(code,200) //исполняемый код
    registersymbol(code)
    
    alloc(foadr,2048) //код для сохранения адресов
    registersymbol(foadr)
    
    code:
    //mov [eax],ecx //оригинальная инструкция какая у тебя
    
    //код проверки
    push ebx
    push edx //счётчик
    xor edx,edx //обнуление счётчика
    mov ebx, foadr //адрес выделенной памяти
    teststart:
    cmp edx,#512 //проверка на переполнение места
    jge nows
    cmp [ebx],eax //проверка на уникальность
    je nows
    cmp [ebx], 0 //проверка на ноль
    je writed
    inc edx
    add ebx,4
    jmp teststart
    
    nows:
    pop edx
    pop ebx
    ret
    
    writed:
    mov [ebx], eax //запись
    jmp nows
    
    [DISABLE]
    unregistersymbol(code)
    unregistersymbol(foadr)
    dealloc(foadr)
    dealloc(code)

     


    А ещё можно нажать на инструкцию, и там выбрать "Показать все адреса с которыми работает эта инструкция".

     


     

     

  16. В 07.01.2020 в 18:13, Dorirn сказал:

    Что не так с моим скриптом триггером

    То что он ничем не исполняется
    Вот

    можешь посмотреть, как тут скрипт исполняется новым потоком

    • Плюс 1
×
×
  • Создать...

Важная информация

Находясь на нашем сайте, Вы автоматически соглашаетесь соблюдать наши Условия использования.