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

MasterGH

Ветераны
  • Постов

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

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

    129

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

  1. В таком случае я проверяю тело чит-кода Olly-дебагером. Сделай сразу пошаговую трассировку. И ты найдёшь ответ. Иначе мы будем гадать :) Кстати CE может не правильно ассемблировать :excl:

  2. Uchiha Sasuke

    Как минимум одна ошибка:

    _cmp:

    dd 0

    Заменить на

    _cmp:

    db 0

    -------

    В главной таблице добавить адрес "_cmp" типа 1 байт. А всё потому что у тебя инструкции cmp byte ... Aliast однажды напоролся на тоже самое )

  3. О, я ещё это дело не тестировал.

    Судя по описанию ДаркБайта этот инструмент часть виртуальной машины dbvm. Устанавливается особым образом...Кажется, ведёт лог call-ов без подключения отладчика.

    --

    Проверил. У меня крашит систему в BSOD с ошибкой 1E. Судя по заголовку главного окна CE это может случится в преАльфа версии, точнее это должно ожидаться.

  4. post-3-1312440160,15_thumb.png

    Ссылка на оригинал темы.

    Код Lua:


    dv_address1=address
    dv_address2=address2
    end

    mv=getMemoryViewForm()
    dv=memoryview_getDisassemblerView(mv)

    dv_address1=disassemblerview_getSelectedAddress(mv)
    dv_address2=dv_address1

    disassemblerview_onSelectionChange(dv, selectiontracker)



    function getAOB(address, length)
    --[[
    suggestion: Extend this script so it watches the disassembled code for a 8 digit
    hexadecimal string whose value is bigger than 0x2000
    Then locate the bytes that define that value and replace by wildcards
    --]]

    local bytestring={}
    local str=''
    bytestring=readBytes(address, length, true) --get the bytes


    for i=0, length-1 do
    str=str..string.format('%x ',bytestring[i])
    end

    return str
    end

    -----

    function aobclose(sender)
    return caHide
    end

    function onGetAOBMenuClick(sender)
    local start=math.min(dv_address1, dv_address2)
    local stop=math.max(dv_address1, dv_address2);
    stop=stop+getInstructionSize(stop)

    local length=stop-start

    local s=getAOB(start, length)

    --spawn a form with memo so the user can easy copy/paste (6.2 will have writeToClipboard)
    if (aobwindow==nil) then
    aobwindow=createForm()
    control_setCaption(aobwindow, 'AOB')
    form_centerScreen(aobwindow)
    form_onClose(aobwindow, aobclose)
    aobmemo=createMemo(aobwindow)
    control_setAlign(aobmemo, alClient)
    else
    form_show(aobwindow)

    end


    local l=memo_getLines(aobmemo)
    -- strings_setText(l, s) , yet another function that didn't get tested in 6.1

    strings_clear(l)
    strings_add(l, s)

    end

    --and now add the menu item to the disassembler
    popupmenu=control_getPopupMenu(dv)
    mi=createMenuItem(popupmenu)
    menuItem_setCaption(mi, 'Get AOB from selection')
    menuItem_onClick(mi, onGetAOBMenuClick)
    menuItem_setShortcut(mi, 'Ctrl+Shift+C');

    menuItem_add(menu_getItems(popupmenu), mi)
    function selectiontracker(disassemblerview, address, address2) 

    Ещё пример (чем эти примеры отличаются, смотрите сами код):


    timer_setInterval( __menu_inject_timer, 1000 );
    timer_onTimer( __menu_inject_timer, function( sender )
    local memView = getMemoryViewForm();
    if( memView == nil or memView == 0 ) then
    return;
    end

    local dasmView = memoryview_getDisassemblerView( memView );
    if( dasmView == nil or dasmView == 0 ) then
    return;
    end

    local popupMenu = control_getPopupMenu( dasmView );
    if( popupMenu == nil or popupMenu == 0 ) then
    return;
    end

    local menuItems = menu_getItems( popupMenu );
    for pos = 0, menuItem_getCount( menuItems ) - 1 do
    local caption = menuItem_getCaption( menuItem_getItem( menuItems, pos ) );
    if( caption == 'Get AOB From Selection' ) then
    return;
    end
    end

    local menuItem = createMenuItem( popupMenu );
    menuItem_setCaption( menuItem, 'Get AOB From Selection' );
    menuItem_setShortcut( menuItem, 'Ctrl+Shift+C' );
    menuItem_onClick( menuItem, onGetAOBMenuClicked );
    menuItem_add( menuItems, menuItem );

    __dasm_address1 = disassemblerview_getSelectedAddress( memView );
    __dasm_address2 = __dasm_address1;

    disassemblerview_onSelectionChange( dasmView, dasmSelectionTracker );

    object_destroy( __menu_inject_timer );
    end );

    function dasmSelectionTracker( disassemblerview, address, address2 )
    __dasm_address1 = address;
    __dasm_address2 = address2;
    end

    function getAOB( address, length )
    local bytestring = { };
    local output = '';

    local readData = readBytes( address, length, true );

    for x = 0, length - 1 do
    output = output .. string.format( '%02X', readData[ x ] );
    if x ~= length - 1 then output = output .. ' '; end
    end

    return output;
    end

    function onGetAOBMenuClicked( sender )
    local start = math.min( __dasm_address1, __dasm_address2 );
    local stop = math.max( __dasm_address1, __dasm_address2 );

    stop = stop + getInstructionSize( stop );

    local length = stop - start;
    local data = getAOB( start, length );

    print( data );
    end
    local __menu_inject_timer = createTimer( getMainForm(), true ); 

  5. Как уже SER[G]ANT написал появилась Pre Alpha v6.2. Однако, есть ещё одна ссылка для скачивания, скачав и распаковав архив по которой, вы получите полный комплект файлов.

    http://cheatengine.o...ne62PAlpha1.rar

    Not much new in this, but it contains the bugfixes for lua and added a autorun

    also for the lucky few that are capable of using dbvm, there is a profiler tool now (ultimap) which can help you find the code that executes at specific events without having to use the debugger

    And if you boot up your system with dbvm but forgot to enable unsigned drivers (I do that often) it can now force load the driver into memory

    also a few new lua commands

    and it contains support for connecting to a ceserver on another system for basic memory reading/writing and scanning.

    I've added the server binaries for 32 and 64-bit linux (2.6 kernel) and for android (also as long as it's on the 2.6+ kernel)

    If you want to use it on android you'll have to load it yourself

    Install the android sdk, install the package that adds adb and then in a command prompt: (be in the folder where the ceserver-linux_arm_android file is)


    adb shell mkdir /data/ceserver
    adb push ceserver-linux_arm_android /data/ceserver
    adb shell
    cd /data/ceserver
    chmod 777 ceserver-linux_arm_android
    ./ceserver-linux_arm_android

    Not sure about that chmod, but it's recommended

    (someday I might make an .apk that launches it for you, for $1000000 in the android market)

    edit2: download should be fine now

    Когда выйдет реализ CE6.2 с убранными багами для Русской кодировки я постараюсь написать тутор по созданию трейнера на Lua-Engine. О багах я уже сообщил. Если кто следил, то предыдущий тутор я удалил из форума по Lua-Engine, т.к. посчитал что он сложен для восприятия и его надо переписать. Тем более CE 6.2 ещё не вышла и не исправлены баги с кодировкой: название трейнера не может быть на русском и пути директорий так же не могут быть на расском языке.
  6. // eax = 7, ebx=5,

    mov esi,[eax+ebx+3]

    При выполнении этой инструкции esi будет равен не 15, а значению располагающемуся по адресу 15. Это все равно что написать

    mov esi,[15]

    Что именно лежит по адресу 15, посмотрите сами.

    И учтите, что я писал пример в десятичной системе для упрощения, а в реальной ситуации всё в 16-ричной системе: и адреса, и смещения, и значения.

  7. Так помрешь и не увидишь трейнеры by gamehacklab team.

    live_4_ever, у нас нет сплочённой команды, которая делала бы трейнеры на языках программирования как это делают хакерские группы. Но те, кто публикуют трейнеры вполне могут написать, что они относятся к команде gamehacklab[RU], т.к. как состоят в группе разработчиков. Ты кстати в этой команде раньше состоял...

    Трейнеры у нас вполне нормальные, т.к. подразумевается, что они работают как минимум к одной версии игры. Факт того, что трейнеры сделаны на CheatEngine не значит, что они ненормальные, т.к. это дело принципа и вкуса. У CheatEngine хорошая функциональная и информационная база для массы всё новых и новых пользователей. Программистские дебри в виде автоассемблреных скритпов более терпимы, чем если писать трейнер на зыке программирования.

    Создание команды это вообще отдельный вопрос и с "нормальностью" трейнера, конечно, никак не связан.

    Трейнеры проще делать на CheatEngine и более доступно для "массового пользователя". И если все с "начального/среднего уровня" начнут писать трейнеры на Lua-engine я буду очень рад. Сложно это или нет каждый может оценить по своим силам взглянув на мой тестовый пример

    intro.png

    для CE 6.2(которая ещё не появилась) и файл документации по которому это было сделано. Этот трейнер смогут запустить только те, кто скомпилит 64-разрядную CheatEngine из комплекта SVN. Последняя ревизия на сегодня не компилируется для 32-разрядной CE.

  8. GodGame, если нужно мнение про "заценить", то моё мнение "неплохо". Только жаль, что ничего нового нет из того, что есть в других программах: CheatEngine, MHS и т.п. В кчаестве чего-то нового и полезного, советую вам создать поддержку скриптов для работы с дизассемблированием и ассемблированием. Как именно уже решайте сами.

    Может быть так для инструкции 0x00410000: mov eax,[ebx+0C] :


    PROCESS game.exe SCRIPT "God-mode" FOR 0x00410000,0x00420000,0x00440000
    TYPE mov reg32,[reg32+varA] WHERE varA=0xC
    ADDNEWASSEMBLE mov [reg32+varA], 0x10000
    ADDNEWASSEMBLE mov [reg32+varA+4], 0x10000

    На всех указанных адресах при условии WHERE будет создана инъекция ADDNEWASSEMBLE, которая если потребуется будет создана в новом блоке памяти с восстановлением оригинальных инструкций. Это новая фишка похожа чем-то на SQL запросы и негде не реализована. И могла быть бичом в Вашей программе, если её хорошо продумать.

    Так же с помощью аналогичных SQL запросов аналогично можно извлекать структуры данных из памяти, фильтровать, соединять и делать какие-то действия.

  9. Не за что.

    Судя по типам защит блоков виртуальной памяти думаю ты ошибаешься с + $41A8, но если работает, то пускай работает.

    Я уверен, что нет кода, который бы обращался к этому адресу через + $41A8. Обращение должно происходить совсем другим образом по другой цепочке указателей. Но как я писал, если работает, то пускай работает. Возможно блоки памяти распределяются "устойчивым" образом и их расположение не меняется. Остаётся только на это надеяться.

  10. >>Адрес 003F0000 я так понял указывает на первый байт в модуле Inter.dll?

    Правильно

    >>Тоесть чтобы мне найти смещение на указатель мне нужно вычесть разницу между адресами 003F41A8 и 003F0000 и потом перевести в десятичную систему? Я правильно мыслю?

    003F41A8+1264

    =

    0x003F4000 + 0x1A8 + 1264

    Если я не ошибаюсь, надо искать указатель на 0x003F4000, а не на 003F0000.

    >> И еще вопросик по программированию... Сразу оговорюсь, что в интернете по подобному информация очень скудная. Собственно как в Делфи прилепить это смещение на Dll?

    Подключиться к процессу, извлечь PID и т.п.

    Найти базовый адрес модуля используя CreateToolHelp32Snapshot...

    Использовать циклически ReadProcessMemory с добавлением смещений.

    Почему скудно написано? Смотри сколько ссылок я нашёл (это я ещё не искал специально на иностранных сайтах)

    Нужная функция: ссылка

    В uses добавь: Windows, Tlhelp32 и может быть SysUtils

    Пример как этой функций пользоваться: ссылка

    Ещё так для размышлений: ссылка

    -----

    Может пригодится, а может нет на языке C: ссылка

  11. В теме 4 страницы идиотских вопросов... и ни одного проблеска на улучшение, не смотря на всю помощь от участников форума.

    На счёт что идиотские вопросы у меня вы правы.

    Администрация пока разрешает задавать вопросы согласно текущим главным правилам форума всем пользователям и тому же mylukov-ову.

    SER[G]ANT, Вы стремитесь к пункту 1.3. Надеюсь, Вы не придёте к тому, чтобы пользователей прямо называть "идиотами". Если вопросы mylukov-ва вызывают раздражение, то лучше дать голый ответ без негатива, либо не отвечать. Я не хочу чтобы новые пользователи боялись задавать свои вопросы, смотря на то, как Вы оцениваете других. Спасибо.

  12. Новое руководство CE6.2 Lua-Engine r969. Июль, 2011 год

    Для тех кто недавно познакомился с Cheat Engine 6.1

    Лучший по удобству способ создания трейнеров - это создание трейнеров сценариями Lua.

    Используйте только формат *.CETRAINER. Не используйте *.exe генерирумые трейнеры и не используйте таблицы *.CT.

    *.CETRAINER - это формат текстового файла с xml разметкой, которую обрабатывает Cheat Engine. Саму Cheat Engine при запуске файла формата *.CETRAINER видно не будет.

    Пользователь может открыть созданный файл .CETRAINER для внесения в него необходимых настроек, которые были описаны автором этого файла.

    Для запуска .CETRAINER пользователю необходимо установить последнюю версию Cheat Engine.

    Вы можете встраивать свои ресурсы в формат *.CETRAINER. Это могут быть модули *dll, *.lua, текстовые и графические файлы, файлы музыки формата "xm" и любые другие файлы.

    Имейте ввиду, что встраиваемые ресурсы в *.CETRAINER увеличивают его размер на величину двухкратную размеру самих этих ресурсов.

    Встраивание графических картинок, музыки, других эффектов обычно считается хорошим тоном для трейнеров, но не обязательно.

    Вы можете создать форму трейнера и расположить на ней картинку, а также сделать музыкальное сопровождение.

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

    Прочитав это руководство вы узнайте как делать трейнеры в формате *.CETRAINER. Узнаете описания всех функций и примеры для версии lua-Engine r969 (июль месяц 2011 года, Cheat Engine 6.2)

    1. Обзор формата *.CETRAINER.

    В следующием примере Вы можете увидеть содержание файла "*.CETRAINER" в упрощённом виде.


    <?xml version="1.0"?>
    <CheatTable CheatEngineTableVersion="11">
    <LuaScript>
    -- Ваш Lua скрипт
    </LuaScript>
    </CheatTable>

    Таким образом вам достаточно создать текстовый файл, написать в нём строки вашего кода с разметкой и сохранить как *.CETRAINER. Размер такого файла получается очень маленьким. А также вы можете в любой момент отредактировать его в текстовом редакторе. Затем вам стоит его опубликовать в Интернете. И те пользователи у кого есть Cheat Engine смогут запустить этот скрипт.

    Скорее всего вам не понадобится писать такую разметку, за вас это сделает CE(Cheat Egnine) когда вы будите работать в CE. Потом вы сможете открыть файл и отредактировать его так как вам будет удобно.

    2. Разметка созданая трейнер-генератором.

    Разметка выше не содержала никакого кода. Давайте посмотрим разметку, которую предлагает ДаркБайт (автор Cheat Engine)

    Прокомментирую как был построен этот скрипт.

    Я подключился к процессу test.exe через значок "Компьютер". Эта программа написана мной для примера. В ней нажимая на кнопку отображаемое значение увеличивается на единицу.

    Далее я нашёл адрес параметра через сканер памяти и назвал его MyFloatValue.

    Я запустил генератор трейнера. Выделил запись MyFloatValue. Поставил горячие клавиши "ctrl+q" для заморозки значения. Данное событие назвал как "Freeze Value".

    И сгенерировал трейнер с интерфейсом по умолчанию в файл *.CETRAINER без шифрования.

    post-3-1311619519,51_thumb.png

    Посмотрим что получилось в файле. Выглядит устрашающе. Скорее всего Вы сейчас ничего не поймете.


    <?xml version="1.0"?>
    <CheatTable CheatEngineTableVersion="12">
    <Forms>
    <CETrainer>7D534B6EDB3014A4A5E81F34D90628D0650B74D11CA192CCC446544BB518F4B32A2DD1B660463428DA4E973D478FD4451745916BF408A5455996DD342BF1919C79F366C4EF2700A0E4EAF214218E8B92F02BC6EF9C1036D54944A6427F63980352CCE642FF0374C496FAB79EF1A1C8C55C7FDBB342BC14052BCD3DE834A40529450BF154DD22E232A4AC22965B7FE461B6B01356155B1AEBD992A51927A40C258470E0A110A64B5A085938294CE0D847F1B8D6A5E587B234A054690600B68425B824D4851FD1D84FFC118C1408FC07941B3E2D66A56562BABDE706644DE8B094F358CE641DB10DE12457BBF14A1CEC3E35B096DB084F629E13AEF5802365052B2158E9F9417C8B825B84E29112A635C2B48BDAE3DF3B615F1A6136A60193D0BBD672C39FB095A8FD941E5A6E5D2A3FDB9E407931BCC333620CDFF9D7F0B09BFE4BD9A0FDDB4D4D61A5821391CD1DD075351C401F755C2D1E77557F00C77C4FFE1D0F60AF5CABDB457842A83788D10DFC14F9C1AE9FBB33EBBC6EE736EA5FB6DE98032616E4AB97602ED9434619B7C19EF1BC0FD3703C4CD0301E7568F3C7695FEC69E1744A327144DB89358CE2147663BD3E8CF5E72ED61BCB2FB339E39567E3850A16EC93552FA44DB6F352BAC99A3217828559A77179E4CCF37A84574D103F24F9F6EE48021D44EE45B6D56E3919ED93295E51E1C0BC101BF5CB36E6996628387DFDDEEB932AE38592A65595AB8E69FD9CCE3A87F5CE67C7CF44B1C682E4F659B39467AA9F91D1B17C46D59C6DE63589E30E70B56D1DB07BDB936BA9325B4C6421E7037F01</CETrainer>
    </Forms>
    <CheatEntries>
    <CheatEntry>
    <ID>0</ID>
    <Description>"MyFloatValue"</Description>
    <Color>80000008</Color>
    <VariableType>4 Bytes</VariableType>
    <Address>Test.exe+5B5A4</Address>
    <Hotkeys>
    <Hotkey>
    <Action>Toggle Activation</Action>
    <Keys>
    <Key>17</Key>
    <Key>81</Key>
    </Keys>
    <Description>Freeze Value</Description>
    <ID>0</ID>
    </Hotkey>
    </Hotkeys>
    </CheatEntry>
    </CheatEntries>
    <UserdefinedSymbols/>
    <LuaScript>--TRAINERGENERATORSTART--
    --This is autogenerated code. Changing code in this block will
    --get erased and rewritten if you regenerate the trainer code

    --Uncomment the following line if this is a Cheat Table format trainer and you don't want CE to show (Tip, save as .CETRAINER alternatively)
    --hideAllCEWindows()
    addresslist=getAddressList()
    memrec0=addresslist_getMemoryRecordByID(addresslist,0)

    memrec0_hotkey0=memoryrecord_getHotkeyByID(memrec0,0)

    function onPostHotkey0(Hotkey)
    --Executed after the "toggle*" cheat got executed
    local memrec=memoryrecordhotkey_getOwner(Hotkey)
    local isActive=memoryrecord_isActive(memrec) --get the state after the hotkey got triggered
    cheatcomponent_setActive(CETrainer_CHEAT0, isActive)
    if gBeepOnAction then
    beep()
    end
    end

    memoryrecordhotkey_onPostHotkey(memrec0_hotkey0,onPostHotkey0)

    control_setVisible(CETrainer_SEPERATOR, false)

    strings_add(getAutoAttachList(), "Test.exe")
    gBeepOnAction=false
    form_show(CETrainer)
    function AboutClick()
    showMessage(gAboutText)
    end
    gAboutText=[[This trainer was made by Cheat Engine
    www.cheatengine.org]]

    function CloseClick()
    closeCE()
    return caFree --onClick doesn't care, but onClose would like a result
    end

    --TRAINERGENERATORSTOP--
    </LuaScript>
    </CheatTable>
    	

    Думаете тут есть что-то сложное? Ничего подобного. Давайте разберёмся как работает этот трейнер чтобы делать свой.


    <Forms>
    <CETrainer>7D534B6EDB3014A4A5E81F34D90628D0650B74D11CA192CCC446544BB518F4B32A2DD1B660463428DA4E973D478FD4451745916BF408A5455996DD342BF1919C79F366C4EF2700A0E4EAF214218E8B92F02BC6EF9C1036D54944A6427F63980352CCE642FF0374C496FAB79EF1A1C8C55C7FDBB342BC14052BCD3DE834A40529450BF154DD22E232A4AC22965B7FE461B6B01356155B1AEBD992A51927A40C258470E0A110A64B5A085938294CE0D847F1B8D6A5E587B234A054690600B68425B824D4851FD1D84FFC118C1408FC07941B3E2D66A56562BABDE706644DE8B094F358CE641DB10DE12457BBF14A1CEC3E35B096DB084F629E13AEF5802365052B2158E9F9417C8B825B84E29112A635C2B48BDAE3DF3B615F1A6136A60193D0BBD672C39FB095A8FD941E5A6E5D2A3FDB9E407931BCC333620CDFF9D7F0B09BFE4BD9A0FDDB4D4D61A5821391CD1DD075351C401F755C2D1E77557F00C77C4FFE1D0F60AF5CABDB457842A83788D10DFC14F9C1AE9FBB33EBBC6EE736EA5FB6DE98032616E4AB97602ED9434619B7C19EF1BC0FD3703C4CD0301E7568F3C7695FEC69E1744A327144DB89358CE2147663BD3E8CF5E72ED61BCB2FB339E39567E3850A16EC93552FA44DB6F352BAC99A3217828559A77179E4CCF37A84574D103F24F9F6EE48021D44EE45B6D56E3919ED93295E51E1C0BC101BF5CB36E6996628387DFDDEEB932AE38592A65595AB8E69FD9CCE3A87F5CE67C7CF44B1C682E4F659B39467AA9F91D1B17C46D59C6DE63589E30E70B56D1DB07BDB936BA9325B4C6421E7037F01</CETrainer>
    </Forms>

    "Forms" содержит формы. В данном случае одну форму "CETrainer". Длинная строка которую вы видите, это ресурсы формы. Иначе говоря это информация о том что на форме находится. Там находится поле для картинки, кнопка About и список читов из одной записи. Данное окно вы не раз видели, если пользовались генератором трейнеров.

    Дальше.


    <CheatEntries>
    <CheatEntry>
    ....
    </CheatEntry>
    </CheatEntries>

    "CheatEntries" это "куст" из "веток" "CheatEntry", где "CheatEntry" это запись в главной таблице CE


    <CheatEntry>
    <ID>0</ID>
    <Description>"MyFloatValue"</Description>
    <Color>80000008</Color>
    <VariableType>4 Bytes</VariableType>
    <Address>Test.exe+5B5A4</Address>
    <Hotkeys>
    ...
    </Hotkeys>
    </CheatEntry>
     

    ID - идентификатор записи CheatEntry

    Description - описание

    Color - цвет

    VariableType - тип данных

    Address - адрес

    Hotkeys - куст содержищий Hotkey


    <Hotkey>
    <Action>Toggle Activation</Action>
    <Keys>
    <Key>17</Key>
    <Key>81</Key>
    </Keys>
    <Description>Freeze Value</Description>
    <ID>0</ID>
    </Hotkey>
    	

    Action - определения способа активации. В данном случае это простая заморозка, а ещё есть 5-видов активации. Их вы сами посмотрите.

    Keys - куст для key-кодов 17 и 81 (CTRL + Q). Кей-коды можно увидеть здесь http://code.google.c...bin/defines.lua

    Description - пользовательское описание

    ID - идентификатор Hotkey

    <UserdefinedSymbols/>

    Пусто. Это зарегистрированные пользовательские метки. На самом деле этот куст можно удалить.

    Ну и наконец. Самое вижное и сложное это ветка Lua -скрипта. Это самое сердце трейнера.


    <LuaScript>--TRAINERGENERATORSTART--
    --This is autogenerated code. Changing code in this block will
    --get erased and rewritten if you regenerate the trainer code

    --Uncomment the following line if this is a Cheat Table format trainer and you don't want CE to show (Tip, save as .CETRAINER alternatively)
    --hideAllCEWindows()
    addresslist=getAddressList()
    memrec0=addresslist_getMemoryRecordByID(addresslist,0)

    memrec0_hotkey0=memoryrecord_getHotkeyByID(memrec0,0)

    function onPostHotkey0(Hotkey)
    --Executed after the "toggle*" cheat got executed
    local memrec=memoryrecordhotkey_getOwner(Hotkey)
    local isActive=memoryrecord_isActive(memrec) --get the state after the hotkey got triggered
    cheatcomponent_setActive(CETrainer_CHEAT0, isActive)
    if gBeepOnAction then
    beep()
    end
    end

    memoryrecordhotkey_onPostHotkey(memrec0_hotkey0,onPostHotkey0)

    control_setVisible(CETrainer_SEPERATOR, false)

    strings_add(getAutoAttachList(), "Test.exe")
    gBeepOnAction=false
    form_show(CETrainer)
    function AboutClick()
    showMessage(gAboutText)
    end
    gAboutText=[[This trainer was made by Cheat Engine
    www.cheatengine.org]]

    function CloseClick()
    closeCE()
    return caFree --onClick doesn't care, but onClose would like a result
    end

    --TRAINERGENERATORSTOP--
    </LuaScript>
     	

    Я напишу тоже самое только с моими комментраиями.


    <LuaScript>
    -- Получить коллекцию записей addresslist в существующих таблицах Cheat Engine
    -- Я не знаю почему getAddressList, когда надо было названить иначе, потому что у вас могут быть не только адреса в таблицах, но и скрипты.
    addresslist=getAddressList()

    -- Получить запись memrec0 по ID из коллекции, где ID равно нулю. Это как раз первая моя запись. Помните выше, была ветвь <CheatEntry>...
    memrec0=addresslist_getMemoryRecordByID(addresslist,0)

    -- Получить горячие клавиши в memrec0_hotkey0 из записи memrec0
    memrec0_hotkey0=memoryrecord_getHotkeyByID(memrec0,0)

    -- Эта функция будет будет связана ниже (её написали здесь заранее). Она будет вызываться, когда пользователь нажмёт горячие клавиши
    function onPostHotkey0(Hotkey)
    -- опять получить запись по владельцу горячих клавиш
    local memrec=memoryrecordhotkey_getOwner(Hotkey)
    -- определить активирована ли запись
    local isActive=memoryrecord_isActive(memrec) --get the state after the hotkey got triggered

    -- повтороно или в первый раз активировать компонент CETrainer_CHEAT0 (надпись станет красной или перестанет быть красной)
    cheatcomponent_setActive(CETrainer_CHEAT0, isActive)
    -- если разрешён звукой сигнал переменной gBeepOnAction (эта переменная будет где-то позже), то произвести звук бипа
    if gBeepOnAction then
    beep()
    end

    -- Важно пояснить.
    -- CETrainer_CHEAT0 это объект Сheatcomponent. Объект генерируется автоматически генератором терйнеров и вы не можете его создавать. Т.е. в своих скриптах, которые вы будите писать без генератора трейнеров, вы не сможете связываться с Сheatcomponent и будите писать код иначе.
    end


    -- Наконец, связать memrec0_hotkey0 с функцией onPostHotkey0, для того чтобы задействовать CETrainer_CHEAT0 - компонент чита сгенерированный CE
    memoryrecordhotkey_onPostHotkey(memrec0_hotkey0,onPostHotkey0)

    -- Спрятать разделительную линию. Просто дизайнерский финт
    control_setVisible(CETrainer_SEPERATOR, false)

    -- Добавить название пройесса в список процессов автоподключения. CE будет автоматически искать процесс по его названию и подключаться к нему
    strings_add(getAutoAttachList(), "Test.exe")
    -- А вот наша переменная активации, можно было вообще обойтись без неё. Он запрещает звуковой сигнал при активации горячих клавиш, но вы можете его включить поставив true.
    gBeepOnAction=false

    -- Показать наконец форму CETrainer, её так уже автоматически назвали и где-то как-то создали без нашего ведома
    form_show(CETrainer)

    -- Обаботчик нажатия на кнопку "О программе"
    function AboutClick()
    -- Показать сообщение в переменной gAboutText
    showMessage(gAboutText)
    end

    -- Собственно самое сообщение
    gAboutText=[[This trainer was made by Cheat Engine
    www.cheatengine.org]]

    -- Обарботчик закрытия окна
    function CloseClick()
    closeCE() -- закрыть CE
    return caFree -- лучше написать именно так, чтобы точно остановить Lua скрипт и завершить работу
    end
    </LuaScript>

    Итак. Какие тут подводные камни и неприятности? Некоторые вещи вы не видите. Вы не знаете как создавался CETrainer_CHEAT0 и CETrainer-форма. Вы не видели как привязались обработчики CloseClick и AboutClick.

    Вы вынуждены видеть этот запутанный, закрученный скрипт часть которого от вас скрыта.

    За вас связывают события заморозки с другой функций грубо и неудобно. Потому что это всего лишь заготовка! И разобраться в ней могут не все. Мы же с вами будем писать другие скрипты. Удобные и более понятные. Надеюсь вы дочитали до этого места. Дальше будет проще. Прочитав то, что вы прочитаете дальше, вы лучше поймёте предыдущий код.

    3. Учимся создавать форму трейнера

    post-3-1311669364,2_thumb.png

    Нашим основным руководством будет страница

    http://code.google.com/p/cheat-engine/source/browse/trunk/Cheat%20Engine/bin/main.lua

    Создадим сначала форму трейнера, которая корректно закрывается если нажать на крестик. В этом случае невидимый процесс Cheat Engine (посмотрите список процессов, там она будет) закроется. Это корректное закрытие.


    <?xml version="1.0"?>
    <CheatTable CheatEngineTableVersion="11">
    <LuaScript>
    -- Обработчик закрытия формы
    -- sender это объект вызывавший обработчик,а в этом случае sender будет равен trainerForm
    function onCloseClick(sender)
    closeCE()
    return caFree
    end

    trainerForm = createForm()
    form_onClose(trainerForm, onCloseClick)
    </LuaScript>
    </CheatTable>

    Дело в том, что в Lua функции должны быть описаны до того как будут использоваться. Именно поэтому onCloseClick расположена выше form_onClose(trainerForm, onCloseClick).

    Если мы запустим этот файл, то в левом верхнем углу появится окно трейнера. При закрытии окно закрывается.

    Теперь сделаем так, что форма располагалась по центру с некоторым названием.


    <?xml version="1.0"?>
    <CheatTable CheatEngineTableVersion="11">
    <LuaScript>
    function onCloseClick(sender)
    closeCE()
    return caFree
    end

    trainerForm = createForm()
    form_onClose(trainerForm, onCloseClick)

    form_centerScreen(trainerForm)
    control_setCaption(trainerForm, "My first Lua-trainer" )
    </LuaScript>
    </CheatTable>

    "My first Lua-trainer" - мой первый Lua-трейнер. На русском писать нельзя иначе форма не запуститься. Мне это тоже не нравиться, но лучше всегда писать заголовок формы на английском.

    Когда мы работаетм с формой, то в руководстве смотрим Form Class. Там вы могли найти описания и form_centerScreen(), и form_onClose(), и createForm(). И воспользоваться этими функциями.

    А так же вы могли найти такую строку:

    Form Class: (Inheritance: ScrollingWinControl->CustomControl->WinControl->Control->Component->Object)

    Это строка ваша подсказка и означает наследование классов.


    ScrollingWinControl наследует CustomControl
    CustomControl наследует WinControl
    WinControl наследует Control
    Control наследует Component
    Component наследует Object

    Описания этих классов вы можете найти там где я писал. Данное наследование позволяет узнать как использовать функции для нашего объекта trainerForm, которые бы мы хотели.

    Поищем функцию которая могла бы установить название формы. И найдем класс Control и функцию:

    control_setCaption()

    Итак мы научились создавать форму и она корректно закрывается закрывая программу Cheat Engine окно которой по умолчанию скрыто.

    4. Создадим кнопку About на форме, нажав на которую пользователь видит описание трейнера на английском языке.

    post-3-1311675581,55_thumb.png

    Итак ищем в руководстве по Lua-Engine информацию, которая поможет осуществить задуманное.

    Вот кое-что про Кнопку:


    Button Class: (Inheritance: ButtonControl->WinControl->Control->Component->Object)
    createButton(owner): Creates a Button class object which belongs to the given owner. Owner can be any object inherited from WinControl

    А вот, что про вывод Сообщения:


    showMessage(text) : shows a messagebox with the given text
    messageDialog(text, type, buttons...) : pops up a messagebox with a specific icon/sound with the specified buttons (mbok, mbyes, ....)


    <?xml version="1.0"?>
    <CheatTable CheatEngineTableVersion="12">
    <LuaScript>
    function onCloseClick(sender)
    closeCE()
    return caFree
    end

    trainerForm = createForm()
    form_onClose(trainerForm, onCloseClick)

    form_centerScreen(trainerForm)
    control_setCaption(trainerForm, "My first Lua-trainer")

    btnAbout = createButton(trainerForm)
    control_setCaption(btnAbout, "About")
    </LuaScript>
    </CheatTable>

    Вы увидите кнопку с названием "About" в верхнем левом углу формы трейнера. Она расположена явно не там где надо и ничего не делает.

    Сделаем так чтобы кнопка размещалась в правом нижнем углу формы.


    <?xml version="1.0"?>
    <CheatTable CheatEngineTableVersion="12">
    <LuaScript>
    function onCloseClick(sender)
    closeCE()
    return caFree
    end

    trainerForm = createForm()
    form_onClose(trainerForm, onCloseClick)

    form_centerScreen(trainerForm)
    control_setCaption(trainerForm, "My first Lua-trainer")

    btnAbout = createButton(trainerForm)
    control_setCaption(btnAbout, "About")

    trFormWidth, trFormHeight = control_getSize(trainerForm)
    btnAboutWidth, btnAboutHeight = control_getSize(btnAbout)

    btnAboutX = trFormWidth - btnAboutWidth - 5
    btnAboutY = trFormHeight - btnAboutHeight - 5

    control_setPosition(btnAbout, btnAboutX, btnAboutY)
    </LuaScript>
    </CheatTable>

    Да, получилось кнопка распалогается там где надо. Но событие нажатия на кнопку не показывает сообщения. Сделаем это.


    <?xml version="1.0"?>
    <CheatTable CheatEngineTableVersion="12">
    <LuaScript>
    function onCloseClick(sender)
    closeCE()
    return caFree
    end

    trainerForm = createForm()
    form_onClose(trainerForm, onCloseClick)

    form_centerScreen(trainerForm)
    control_setCaption(trainerForm, "My first Lua-trainer")

    btnAbout = createButton(trainerForm)
    control_setCaption(btnAbout, "About")

    trFormWidth, trFormHeight = control_getSize(trainerForm)
    btnAboutWidth, btnAboutHeight = control_getSize(btnAbout)

    btnAboutX = trFormWidth - btnAboutWidth - 5
    btnAboutY = trFormHeight - btnAboutHeight - 5

    control_setPosition(btnAbout, btnAboutX, btnAboutY)

    abouTrnString = [[About my Trainer:

    1) God mode: CTRL+1
    2) Infinity ammo : CTRL+2



    GameHackLab[RU], MasterGH(C), 2011]]

    function onBtnAboutClick(sender)
    showMessage(abouTrnString)
    end
    control_onClick(btnAbout, onBtnAboutClick)
    </LuaScript>
    </CheatTable>

    Ну, вот теперь работает. Можно вывести сообщение с иконкой "Информация". Сделаем это.

    Замените showMessage(AboutnString) на messageDialog(AboutnString, 2, 2)

    post-3-1311675596,38_thumb.png

    Вы наверно заметели, что код получается несколько сумбурным. Сделаем более удобнее.


    <CheatTable CheatEngineTableVersion="12">
    <LuaScript>

    aboutTrnString = ""

    function onCloseClick(sender)
    closeCE()
    return caFree
    end

    function onBtnAboutClick(sender)
    messageDialog(aboutTrnString, 2, 2)
    end

    function CreateFormTrainer(captionWindow)
    trainerForm = createForm()
    form_onClose(trainerForm, onCloseClick)

    form_centerScreen(trainerForm)
    control_setCaption(trainerForm, captionWindow)

    btnAbout = createButton(trainerForm)
    control_setCaption(btnAbout, "About")

    trFormWidth, trFormHeight = control_getSize(trainerForm)
    btnAboutWidth, btnAboutHeight = control_getSize(btnAbout)

    btnAboutX = trFormWidth - btnAboutWidth - 5
    btnAboutY = trFormHeight - btnAboutHeight - 5

    control_setPosition(btnAbout, btnAboutX, btnAboutY)
    control_onClick(btnAbout, onBtnAboutClick)
    end

    aboutTrnString = "About my Trainer:\n\r\n\r1) God mode: CTRL+1\n\r2) Infinity ammo : CTRL+2\n\r\n\r\n\rGameHackLab[RU], MasterGH(C), 2011"
    CreateFormTrainer("My first Lua-trainer")
    </LuaScript>
    </CheatTable>
    <?xml version="1.0"?>

    Этот код делает тоже самое. Если вы поняли, что я делал, то вы уже можете что-то делать самостоятельно.

    5. Картинка и музыка в трейнере

    post-3-1311681975,92_thumb.png

    Скачайте после прочтения руководства:

    Trainer.rar

    Для примера у меня есть некоторая картинка и трек музыки.

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

    Сделаем это.

    Файл картинки назовём Trainer.jpeg.

    Файл музыки назовем Trainer.xm.

    Расположим эти файлы в ресурсах нашего файла Trainer.CETRAINER разметку которго мы пишем.

    Для этого запустим Cheat Engine и перетащим в неё Trainer.CETRAINER.

    В главном меню раскроем "Table" и вызовем "Add file" и добавим файл картинки, а затем файл музыки.

    Разметка Trainer.CETRAINER получится следующей:


    <?xml version="1.0"?>
    <CheatTable CheatEngineTableVersion="12">
    <Files>
    <Trainer.jpeg>954E755C14..вырезано..1F</Trainer.jpeg>
    <Trainer.xm>ECBC09985CD5752..вырезано..04</Trainer.xm>
    </Files>
    <CheatEntries/>
    <UserdefinedSymbols/>
    <LuaScript>aboutTrnString = ""

    function onCloseClick(sender)
    closeCE()
    return caFree
    end

    function onBtnAboutClick(sender)
    messageDialog(aboutTrnString, 2, 2)
    end

    function CreateFormTrainer(captionWindow)
    trainerForm = createForm()
    form_onClose(trainerForm, onCloseClick)

    form_centerScreen(trainerForm)
    control_setCaption(trainerForm, captionWindow)

    btnAbout = createButton(trainerForm)
    control_setCaption(btnAbout, "About")

    trFormWidth, trFormHeight = control_getSize(trainerForm)
    btnAboutWidth, btnAboutHeight = control_getSize(btnAbout)

    btnAboutX = trFormWidth - btnAboutWidth - 5
    btnAboutY = trFormHeight - btnAboutHeight - 5

    control_setPosition(btnAbout, btnAboutX, btnAboutY)
    control_onСlick(btnAbout, onBtnAboutClick)
    end

    aboutTrnString = "About my Trainer:\n\r\n\r1) God mode: CTRL+1\n\r2) Infinity ammo : CTRL+2\n\r\n\r\n\rGameHackLab[RU], MasterGH(C), 2011"
    CreateFormTrainer("My first Lua-trainer")

    </LuaScript>
    </CheatTable>

    Я привел разметку не всю, т.к. она получилась бы большой: 51.2 кб. Пока это не окончательный размер Lua-трейнера.

    Выше ссылка на Trainer.CETRAINER.

    Загружаем музыку из ресурсов и проигрываем её следующим образом.


    XMFILE=findTableFile('Trainer.xm')
    xmplayer_playXM(XMFILE)

    Загружаем картинку из ресурсов и отображаем её на трейнере следующим образом.


    trImage=createImage(trainerForm)
    setProperty(trImage, "AutoSize", "true")
    picture=image_getPicture(trImage)
    stream=findTableFile('Trainer.jpeg')
    picture_loadFromStream(picture,stream)

    Как вы могли видеть функция findTableFile() возвращает поток данных из ресурсов.

    Новые изменения коснулись только функции CreateFormTrainer(captionWindow).


    <?xml version="1.0"?>
    <CheatTable CheatEngineTableVersion="12">
    <Files>
    <Trainer.jpeg>954E755C14..вырезано..1F</Trainer.jpeg>
    <Trainer.xm>ECBC09985CD5752..вырезано..04</Trainer.xm>
    </Files>
    <CheatEntries/>
    <UserdefinedSymbols/>
    <LuaScript>
    aboutTrnString = ""

    function onCloseClick(sender)
    closeCE()
    return caFree
    end

    function onBtnAboutClick(sender)
    messageDialog(aboutTrnString, 2, 2)
    end

    function CreateFormTrainer(captionWindow)
    trainerForm = createForm()
    form_onClose(trainerForm, onCloseClick)
    control_setCaption(trainerForm, captionWindow)
    setProperty(trainerForm, "AutoSize", "true")


    trImage=createImage(trainerForm)
    setProperty(trImage, "AutoSize", "true")
    picture=image_getPicture(trImage)
    stream=findTableFile('Trainer.jpeg')
    picture_loadFromStream(picture,stream)

    btnAbout = createButton(trainerForm)
    control_setCaption(btnAbout, "About")
    trFormWidth, trFormHeight = control_getSize(trainerForm)
    btnAboutWidth, btnAboutHeight = control_getSize(btnAbout)
    btnAboutX = trFormWidth - btnAboutWidth - 5
    btnAboutY = trFormHeight - btnAboutHeight - 5
    control_setPosition(btnAbout, btnAboutX, btnAboutY)
    control_onСlick(btnAbout, onBtnAboutClick)

    form_centerScreen(trainerForm)


    XMFILE=findTableFile('Trainer.xm')
    xmplayer_playXM(XMFILE)
    end

    aboutTrnString = "About my Trainer:\n\r\n\r1) God mode: CTRL+1\n\r2) Infinity ammo : CTRL+2\n\r\n\r\n\rGameHackLab[RU], MasterGH(C), 2011"
    CreateFormTrainer("My first Lua-trainer")
    </LuaScript>
    </CheatTable>

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


    <?xml version="1.0"?>
    <CheatTable CheatEngineTableVersion="12">
    <Files>
    <Trainer.jpeg>954E755C14..вырезано..1F</Trainer.jpeg>
    <Trainer.xm>ECBC09985CD5752..вырезано..04</Trainer.xm>
    </Files>
    <CheatEntries/>
    <UserdefinedSymbols/>
    <LuaScript>aboutTrnString = ""

    function OnCloseClick(sender)
    closeCE()
    return caFree
    end

    function OnBtnAboutClick(sender)
    messageDialog(aboutTrnString, 2, 2)
    end

    function OnMusicRunOrStop(sender)
    if (xmplayer_isPlaying()) then
    xmplayer_pause()
    control_setCaption(btnMusic, "Music Off")
    else
    xmplayer_resume()
    control_setCaption(btnMusic, "Music On")
    end
    end

    function CreateFormTrainer(captionWindow)
    trainerForm = createForm()
    form_onClose(trainerForm, OnCloseClick)
    control_setCaption(trainerForm, captionWindow)
    setProperty(trainerForm, "AutoSize", "true")

    trImage=createImage(trainerForm)
    setProperty(trImage, "AutoSize", "true")
    picture=image_getPicture(trImage)
    stream=findTableFile('Trainer.jpeg')
    picture_loadFromStream(picture,stream)

    btnAbout = createButton(trainerForm)
    setProperty(btnAbout, "AutoSize", "true")
    control_setCaption(btnAbout, "About")
    trFormWidth, trFormHeight = control_getSize(trainerForm)
    btnAboutWidth, btnAboutHeight = control_getSize(btnAbout)
    btnAboutX = trFormWidth - btnAboutWidth - 5
    btnAboutY = trFormHeight - btnAboutHeight - 5
    control_setPosition(btnAbout, btnAboutX, btnAboutY)
    control_onСlick(btnAbout, OnBtnAboutClick)

    btnMusic = createButton(trainerForm)
    setProperty(btnMusic, "AutoSize", "true")
    control_setCaption(btnMusic, "Music On")
    btnMusicWidth, btnMusicHeight = control_getSize(btnMusic)
    btnMusicX = btnAboutX - 5 - btnMusicWidth
    btnMusicY = btnAboutY
    control_setPosition(btnMusic, btnMusicX, btnMusicY)
    control_onСlick(btnMusic, OnMusicRunOrStop)

    form_centerScreen(trainerForm)

    XMFILE=findTableFile('Trainer.xm')
    xmplayer_playXM(XMFILE)
    end

    aboutTrnString = "About my Trainer:\n\r\n\r1) God mode: CTRL+1\n\r2) Infinity ammo : CTRL+2\n\r\n\r\n\rGameHackLab[RU], MasterGH(C), 2011"
    CreateFormTrainer("My first Lua-trainer")
    </LuaScript>
    </CheatTable>

    Теперь пользователь может проигрывать и останавливать музыку

    Скачать файл Trainer.CETRAINER можно выше из архива Trainer.rar.

    С интерфейсом трейнера думаю закончили, дальше будем разобраться с функциональностью.

    Продолжение следует...

  13. mylukov, установи CE 6.1 (уже не бета). Сделай таблицу и сгенерируй трейнер с кернел-дебагером. Трейнер получится не меньше 3 мб в *.exe-виде. В формате *..CETRAINER получится меньше, но пользователю нужно будет установить Cheat Engine.

  14. >> Эм... да не, таблица по моему в файле есть, раз он спрашивает оставить ли её. Меня смущает сам факт этого вопроса, ведь если там

    нажать "No", то и изменений не будет.

    Раз вылазит такое сообщение, это странно. Наверняка, эту проблему можно решить.

    >>В общем, я решил, что для exe лучше в самом скрипте адреса считать, что бы не было этого вопроса.

    Как пожелаешь :) Главное, что работает.

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

    >> Про MHS я не в курсе(таких сокращений дико много, я не представляю о чём речь).

    MHS это программа аналогичная Cheat Engine, которая имеет приятные мелочи по исследованию Windows-процессов в частности по указателям... Только жаль не"понимает" инструкции процессора набора SIMD, а самое печальное почему-то давно не обновляется автором.

    По поводу запуска - фиг бы знал.

    В теме всё то же что я уже знаю, и что не работает.

    os.execute хорошо бы, но она запускает только то что записано в системные пути.

    Было бы хорошо считать путь из реестра...

    Кстати, через cmd можно бы его получить, и если выполняемый LUA скрипт может принимать внешние параметры запуска, то передавать через них. Да и вообще, если так делать, то можно на реестр забить, и считывать прям так.

    P.S Или может ну его на фиг, на каком-нить нормальном языке писать?..

    Lua скрипт не может принимать параметры запуска. И зачем это надо? Можно сделать файл настроек и его Lua может читать и что-то делать. А лучше сделать не просто текстовый/бинарный файл настроек, а текстовый файл с .lua cо своими переменными, данными и кодом. По поводу реестра я более чем уверен, что можно читать ветки реестра, но только извратом используя автоассемблер и WinApi.

    << P.S Или может ну его на фиг, на каком-нить нормальном языке писать?..

    Использовать ли тебе Lua для решения подобных задач я не знаю. Это твоё решение. Я Lua использую, потому что этот язык позволяет управлять Cheat Engine, создавать сценарии, формы, "трейнеры", читы и т.п. Всё это можно делать на любом другом языке программирования в Windows.

  15. <<А "return caFree" чего делает?

    Такой код генерирует генератор трейнеров. Поэтому я взял это на заметку.


    function CloseClick()
    closeCE()
    return caFree --onclick doesn't care, but onClose would like a result
    end

    Этот генератор сделал ДаркБайт и только он более точно знает, что делает этот код. Судя по комментариям вызов closeCE() видимо не всегда достаточно. Совершенно точно не скажу, но это вероятно завершение выполнение Lua кода с возвращением кода действия.

    --CloseAction types

    caNone=0;

    caHide=1;

    caFree=2;

    caMinimize=3;

    caFree, очевидно "точно высвобождает все ресурсы" в том числе и exe-трейнер, таймеры и т.п. Можно проверить на практике, но я этого пока не делал.

    И про

    "создать запись "MyFloatValue" в главной таблице CE:

    по шаблону f[[[[process.exe+0x0051E404]+0x24]+0xE4]+0xA0]"

    я не совсем понял.

    В главной таблице можно создать просто адрес с указателями, а f[[...]+..] для меня загадка(в смысле, понятно что это, но куда это писать?)...

    Такой формат можно задать только в программе MHS. Этот формат довольно удобный и мне удобнее его писать. В CE надо задавать так как позволено.

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

    Я свой код не проверял. Я забыл, что при сохранении в exe запись в таблице не сохраняется. Её нужно добавить в генераторе трейнеров из главной таблицы CE и уже обращаться к ней. Попробуй сам разобраться...

    Ну и вдогонку, щас процесс создаётся через createProcess("DISK:/path/process.exe",nil,nil,nil), а надо что-нить типо createProcess("process.exe",nil,nil,nil)

    Как это реализовать? Именно такая запись почему-то не работает, даже если exe лежит в папке с... exe

    Путь-то может быть разный...

    По-моему путь нужно задавать полный и уж точно через формат двойной косой черты. Попробуй поискать свой ответ здесь.
  16. А нельзя ли как-нить сделать из этого .exe ? Типа LaunchNPatch.exe :)

    Ибо основная идея - сделать эту штуку общедоступной, без использования CE

    Можно сделать сохранив данные как .exe файл из меню главного окна. В этом случае будет автоматически выполняться встроенный Lua-код.

    Да, и ещё, вот, собсно, скрипт. Хотелось бы узнать, как можно его улучшить



    function OpenProcessFunc()
    if openProcess("process.exe") then
    timer_onTimer(Timer1, ChangeValue)
    end
    end

    function ChangeValue()
    Address = getAddress("process.exe")
    Address = Address+0x0051E404
    b4,b3,b2,b1 = readBytes(Address,4)
    Address = string.format("%02x%02x%02x%02x",b1,b2,b3,b4)
    Address = getAddress(Address)
    Address = Address+0x24
    b4,b3,b2,b1 = readBytes(Address,4)
    Address = string.format("%02x%02x%02x%02x",b1,b2,b3,b4)
    Address = getAddress(Address)
    Address = Address+0xE4
    b4,b3,b2,b1 = readBytes(Address,4)
    Address = string.format("%02x%02x%02x%02x",b1,b2,b3,b4)
    Address = getAddress(Address)
    Address = Address+0xA0
    Value = readFloat(Address)
    if (b1 ~= 0) or (b2 ~= 0) or (b4 ~= 0) or (b4 ~= 0) then
    if (Value == 5) then
    writeFloat(Address,6)
    timer_setEnabled(Timer1, false)
    closeCE()
    end
    end
    end

    Timer1 = createTimer(nil)
    timer_setInterval(Timer1,1000)
    timer_setEnabled(Timer1, true)
    timer_onTimer(Timer1, OpenProcessFunc)
    createProcess("DISK:/path/process.exe",nil,nil,nil)

    Можно сделать самый просто вариант, но это не значит что он самый лучший.

    Предварительно создать запись "MyFloatValue" в главной таблице CE:

    по шаблону f[[[[process.exe+0x0051E404]+0x24]+0xE4]+0xA0] = 5

    Т.е "f" - значение float.

    [[[[process.exe+0x0051E404]+0x24]+0xE4]+0xA0] - цепочка указателей


    -- Срабатывает при любом открытии процесса
    function onOpenProcess(processid)
    local te = getTableEntry("MyFloatValue") -- f[[[[process.exe+0x0051E404]+0x24]+0xE4]+0xA0] = 5
    memoryrecord_freeze(te, 0) -- 0=freeze, 1=allow increase, 2=allow decrease

    while(true) do
    sleep(500)
    memoryrecord_unfreeze(te)
    local value = memoryrecord_getValue(te)
    if (value == "5") then
    closeCE()
    return caFree
    end
    memoryrecord_freeze(te, 0)
    end
    end

    listProcess = getAutoAttachList()
    stringlist_add(listProcess, "process.exe")

    Цикл который я написал в while обычно не рекоммендуется и заменяется таймером, но это уже на твоё усмотрение. С таймерами ты работать у меешь.

×
×
  • Создать...

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

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