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

MasterGH

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

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

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

    129

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

  1. Если я правильно понял требуется найти базовый адрес hw.dll, тогда достаточно:


    var someModuleName = "hw.dll";

    >> может так?

    Можно и так. Ошибки не должно быть при выводе имени. Нам важно задать имя модуля в someModuleName.

    Я думаю дальше не будет сложностей с чтением адреса по цепочке указателей начиная от базового адреса модуля или начиная от базового адреса процесса. Надо просто прибавлять смещения к базовому адресу и читать адреса.

  2. Столкнулся с интересной ситуацией.

    Пользователь может удалить пост о прошлой версии трейнера и создать пост заново. Это хорошо, что пользователь честный и напишет, что это обновлённая версия трейнера. А если пользователь взял да и забыл написать, что версия обновлённая (при этом не понятен объём обновления).

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

    Я не знаю может быть запретить изменять и удалять посты из форумов создания Трейнеров и Таблиц? И насколько это будет неудобно самим Авторам трейнеров?

    Вот конкретный пример (последний пост). Только что ставил пользователю 24K репу и уже забыл сколько у него было ранее и непонятно какие обновления теперь. А впечатление, что репутацию как-будто и не ставили вообще.

  3. Ой, что-то я совсем не то посоветовал o_0. "GetModuleBaseName не возвращает адрес модуля, а возвращает имя модуля по его уже известному описателю (хендлу).

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


    Поскольку я посоветовал не то что нужно и наверно заставил искать в ненужном направлении, вот решение.

    Допустим имеем процесс с названием test.exe и модуль user32.dll. И нам нужно найти базовые адреса и того и того.


    using System;
    namespace ModuleBase
    {
    class Program
    {
    static void Main(string[] args)
    {
    var processName = "test"; // не пишем расширение "*.exe"
    var someModuleName = "user32.dll";
    var arrayProcesses = System.Diagnostics.Process.GetProcessesByName(processName);
    if (arrayProcesses == null || arrayProcesses.Length < 1){
    Console.WriteLine("Process not found");
    return;
    }

    var currentProcess = arrayProcesses[0];
    Console.WriteLine("Address prosess: " + processName + ".exe" + " = " + "0x" + currentProcess.MainModule.BaseAddress.ToString("X"));

    var modules = currentProcess.Modules;
    var max = modules.Count;
    for (int i = 0; i < max; i++)
    if ( String.Compare(modules[i].ModuleName, someModuleName, false) == 1){
    Console.WriteLine("Address module: " + modules[i].ModuleName + " = " + "0x" + modules[i].BaseAddress.ToString("X"));
    break;
    }

    Console.Read();
    }
    }
    }

    Вывод будет:

    Address prosess: test.exe = 0x400000

    Address module: USER32.dll = 0x77270000

    Желаю успехов!

  4. Для получения базового адреса на C# можешь поискать код примеров в поисковике "C# GetModuleBaseName". Получишь базовый адрес, а далее прибавляешь к нему смещения какие нужные для чтения адреса и конечного значения. Если не найдёшь примеров, то поищи исходники трейнеров на C# или других языков .NET, и в них работу с GetModuleBaseName.

  5. -1 Поставил поставил Kvazimado. Я точно не знаю по какой причине Kvazimado поставил -1, но наверно это было оправдано. Я поставил +1, т.к. у меня тоже есть право голоса. Ещё один голос за Xipho остался свободным.

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

  6. Версия плагина 1.1

    Plagin_MenuDisassembler_GenericAA.rar

    Добавлены:

    1) Добавлена функция * Get signature info

    2) Добавлена функция * Create AA-aobsan (без пропускающих байтов 'xx', сработает только, если выбранная сигнатура уникальна)

    См. скриншот.

    post-3-0-01662100-1336142937_thumb.png

    3) В шаблон сканирования сигнатуры добавлены маркеры

    ->>comment - комментарии вида 00454658 = Test.exe+54658. Не забудьте включить модульную адресацию в дизассемблере (об этом я уже писал). Иначе получите только

    00454658 = 00454658

    ->>NscriptCount - маркер текущего номера созданного скрипта. Это инкрементирующее значение при добавлении нового сгенерированного скрипта. Для сканирования сигнатур, чтобы оно не повторялось пришлось ввести этот маркер. Кажется Дарк Байт ввёл новые ограничения в АА-скрипты, поэтому без регистрации уникальный меток с автоинкрементным символьным присоединяемым значением не обойтись.

    Сам дополнительный шаблон:


    [ENABLE]
    AOBSCAN(signatureAddress, ->>arrayOfbyte)
    alloc(newMem, 2048)
    label(returnHere)
    label(address->>NscriptCount)
    registersymbol(address->>NscriptCount)
    newMem:
    ->>cheatCode
    ->>originalCode
    jmp returnHere
    signatureAddress: //->>comment
    address->>NscriptCount:
    jmp newMem
    ->>nops
    returnHere:
    [DISABLE]
    address->>NscriptCount:
    ->>originalCode
    dealloc(newMem)
    unregistersymbol(address->>NscriptCount)
    ]]
    AOBSCANCodeTemplate = [[

    Как пользоваться?

    1. Находим нужную инструкцию в дизассемблере;

    2. Выделяем эту инструкцию и несколько нижних, и по нижней правым кликом вызываем контестное меню и далее Create AA-aobsan

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

    4. Если скрипт не добавился или мы хотим посмотреть уникальна или нет сигнатура, то вызываем "Get signature info". Тем самым мы получаем информацию, о том уникальна ли сигнатура или нет, сколько раз она повторяется. Если не уникальная, то выделяем ещё инструкцию ниже или несколько инструкций. Опять узнаём, уникальна она или нет вызывая * Get signature info

    Дополнительная информация

    Сигнатура кода для этой версии плагина берётся без пропускающих байтов "xx". В другой версии плагина будет и новая функция с пропускающими байтами. Но это уже будет не для AA, а для Lua+AA для более опытных пользователей.

    Хочу так же напомнить и специально обратить внимание. Что сигнатура кода не даст Вам 100% результат работы читов на патчах.

    Сигнатуру нужно уметь составлять. Как минимум стараться чтобы в коде инъекции и оригинальном коде не было статических адресов вида mov eax,[адрес]

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

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

  7. у меня предложение (Но вам решать нужно делать её или нет): во флудильной создать "Общая флудильная" или "Курилка" незнаю как сформулировать правельнее, и зафиксировать, туда будут писать все, общаться, или задавать и отвечать на вопросы других (Это нужно для того чтобы не создавать отдельные темы) и естественно создать правила

    Я думаю это лишнее, потому что у обсуждения должна быть тема. Конкретную тему и обсуждают. Если на какой-то полезный вопрос ответят полезным ответом (даже во флудильне), то найти ответ может быть и будет возможным через поиск, однако отследить всю ветвь общения будет тем сложнее чем больше сообщений в этой теме будет. Если подразумевать, что в новой "особенной теме" будут совсем неполезные обсуждения "типа какая завтра погода", то в этом случае я не знаю как быть. Последнее слово за Xipho и Kvazimado.

  8. >> сделал бы кто плагин чтоб формировался АА скрипт с проверочными байтами

    Эта поддержка скоро появится. Возможно сегодня.


    Чтобы в скрипте вы видели базовый адрес как символьное имя например

    "game.exe + смещение:"

    В CE зайдите в дизассемблер и нажмите на Ctrl+M или через меню View->Show Module Addresses.

    После этого в ваших скриптах вы смоежете понять в dll-ке ваш код или нет.

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

  9. Версия 1.0

    Plagin_MainWindow_CompactView.rar

    Плагин добавляет новое меню, которое может делать компактным главное окно CE и отменять изменения.

    post-3-0-44537900-1336059049_thumb.png

    Код плагина можно использовать в своих *.CETAINER-ах или *.CT-таблицах. Таким образом окно Cheat Eninge превращается почти в "трейнер" в котором может быть очень много записей различной вложенности. Также записи могут быть сгруппированы, активироваться и деактивироваться по группам.

  10. Внимание! Новые версии плагина искать в конце темы

     

    Последняя версия плагина - здесь

    Видео инструкция для новичков - здесь

     

    Версия плагина 1.0

    Plagin_MenuDisassembler_GenericAA.rar

    1. Создаёт АА-код аналогично шаблону Дарк Байта

    2. Без комментариев

    3. Без часто лишней метки Exit

    4. Высвобождение памяти помещено в самый низ.

    5. Можно выделить строку в дизассемблере и нажать на горячие клавиши "CTRL+SHIFT+A". Тут же увидите новую запись в главной таблице CE.

    6. Для тех кто не хочет запоминать горячие клавиши функцию создания АА я разместил в контекстном меню с названием "* Create AA"

    post-3-0-56212000-1336056036_thumb.png

    К сожалению редактор АА-скрипта автоматически открыть через Lua нельзя. Но я написал об этой проблеме Дакр Байту, возможно он добавит эту поддержку.

    Как пользоваться скриптом

     

    Скрытый текст

    Скрипт кладём в папку Autorun находящуюся в директории CE. Я тестировал его на CE 6.2 Beta 6.Если у вас нет этой версии, то ссылку на неё можно поискать на нашем форуме или дождаться официального реализа.

    Далее. Ищем инструкцию которая нам нужна. Выделяем её в дизассемблере и нажимаем горячие клавиши "CTRL+SHIFT+A". Тут же добавится новая запись в главную таблицу. Переименовываем эту запись. Открываем скрипт и в пустую область пишем свою инъекцию кода. Далее всё как обычно.

    Как пользоваться шаблоном. Внимание!

     

    Скрытый текст

    У вас есть супер возможность поменять шаблон АА-скрипта под свои предпочтения. Давайте рассмотрим этот шаблон открыв файл *.lua текстовым редактором.

     


    [ENABLE]
    alloc(newMem, 2048)
    label(returnHere)
    newMem:
    ->>cheatCode
    ->>originalCode
    jmp returnHere
    ->>address:
    jmp newMem
    ->>nops
    returnHere:
    [DISABLE]
    ->>address:
    ->>originalCode
    dealloc(newMem)
    ]]
    
    
    AACodeTemplate = [[

     

    1) Мы можем поменять отступы задавая новые строки

    2) Можно поменять отступы от левого края

    3) Можно добавить свои метки и регистрацию своих символов и снятие этой регистрации

    4) Можно изменить текущие надписи меток и символов

    5) Можно добавить свои копирайты или иную форму авторства

    6) Можно добавить информацию о версии CE, на которой был написан текущий скрипт (cм. документацию по CE Lua)

    7) Можно добавить дату создания скрипта (см. руководства по Lua)

     

    Если вы нашли ошибку в скрипте, то вы можете сообщить о ней здесь. Тоже самое касается пожеланий по новым возможностям или исправлениям.

  11. 1. Условимся в публикации Lua расширений для версий не ниже CE 6.2.

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

    2. Условимся в том, что плагины, т.е. файлы lua мы будем размещать в папке "autorun". Любые lua файлы в этой папке запускаются автоматически при запуске CE. Во вложенных папках не запускаются, поэтому придётся указывать путь к файлу во вложенной папке.

    3. По публикациям плагинов пока никаких правил особых нет. По возможности меньше флуда и больше дела.

    Спасибо всем за участие и внимание.

  12. Поверь мне. Он сам прекрасно знает об этой проблеме и не хочет ей заниматься, т.к. она менее приоритетная. Поэтому я намекать ему не буду.

    Могу тебе посоветовать написать подгружаемую при старте системы dll-ку c хуком, которая

    1) перехватывает функцию запуска приложения,

    2) сверяет его имя со словами "Cheat Engine' (ну или другие слова...)

    3) сверяет данные из реестра о последнем запуске CE

    4) если версия запускаемой от той которая в реестре отличается, то запускаем сначала ceregreset.exe из той директории CE, которую пытаемся запустить, ждём завершения ceregreset.exe

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

    Вот и всё, если конечно ОС позволит делать хук. И будет конец, твоим мучениям.

  13. У меня на компе установлен СЕ 6.1; СЕ 6.0 и СЕ 5.6.1. После установки Cheat Engine 6.2 RC 1 когда открываю любую старую версию выходит ошибка: "Invalid data type for "MemoryBrowser Position". <_< Удалил CЕ 6.2 RC 1 такой ошибки больше не выходит.

    Каждый раз при такой ошибке я использую программу ceregreset.exe. Находится в директории с программой. К сожалению этот момент Дарк Байт не продумал.

  14. >>Комменты в профилях в данной версии двига не предусмотрены по умолчанию

    Если бы они были не предусмотрены по умолчанию, то их вообще бы не было. Так что это не просто отключенные комментарии, это какой-то неверный скрипт-запрос к данным "Изменения сатусов" с похожим условием запроса между базой сатусов и базой комментариев.

  15. 1) Выдаётся ли какая-нибудь ошибка с причиной почему не можешь написать личное сообщение. Кому ты писал. Желательно привести пару пользователей. Это может быть полезная информация.

    2) Тут видимо какие-то глюки случились либо при смене скина, либо при переезде на новый хостинг. Будем надеяться что Xipho поправит, т.к. я в дебрях P.Board скриптов имею малое удовольствия копаться. И делал лишь это один раз когда убирал правую пустую область старого скина.

  16. Cheat Engine 6.2 Release Candidate 1 (Sun Apr 29, 2012)

    Fixed the crash when using global debug in 64-bit (with dbvm)

    Made dbvm bootable with a few more systems (make sure your bios controller supports setting a usb stick as forces fdd)

    If you've booted up with dbvm the driver can now load without having to disable signing

    A few gui improvements (structure spider for one. Tip: Lock two stackviews and scan the stack for pointer paths to known strings, it's a great help for scripted languages)

    Trainers now can use TrainerOrigin to find out the path that launched the trainer.

    When ce is properly installed, tiny trainers should work now

    Раз начали появляться реализ кондидаты, то возможно совсем скоро появится и финальная версия CE6.2. Будем надеяться.

  17. >>И куда это пихать?

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

  18. Часть 3

    Ещё один способ решения задачи. Спасибо Дарк Байту.

    Суть здесь в следующем. У панели есть событие OnResize. Это событие задал разработчик Cheat Engine. Это событие уже обрабатывается машинным кодом скомпилированной программы CE. Так вот мы можем перехватить это событие, обработать его и вернуть на обработку машинному коду.

    Код который находится ниже сразу сложно понять даже мне. Дело в том что setMethodProperty и getMethodProperty это совершенно новые функции и их работу хорошо знает только Дарк Байт, потому что он сам их создавал. Да и синтаксис Lua может резать глаз я имею ввиду таблицу MoveAllExtension...


    MoveAllExtension =
    {
    HasExecuted = false, -- Ensure we only run this once..
    OrigOnResize = nil, -- Original OnResize function..
    OrigOnResizeCode = nil, -- If orig was native this will hold the Code field, if lua, nil
    OrigOnResizeData = nil, -- " " "
    btnMoveAll = nil, -- Our new button..
    };
    function MoveAllExtension.OnMoveAllClicked( sender )
    memscan = getCurrentMemscan()
    foundlist = memscan_getAttachedFoundlist(memscan)
    addresslist = getAddressList()
    max = foundlist_getCount(foundlist) - 1
    for index=0, max do
    addr = foundlist_getAddress(foundlist, index)
    createTableEntry = addresslist_createMemoryRecord(addresslist)
    memoryrecord_setDescription(createTableEntry, "Some Address")
    memoryrecord_setAddress(createTableEntry,addr)
    end
    end
    function MoveAllExtension.OnResizeOverride( sender )
    local mainForm = getMainForm();
    local mainPanel = wincontrol_getControl( mainForm, 3 );
    local mainPanelWidth, mainPanelHeight = control_getSize( mainPanel );
    control_setPosition( MoveAllExtension.btnMoveAll, mainPanelWidth - 345, mainPanelHeight - 75 );
    control_setSize( MoveAllExtension.btnMoveAll, 22, 22 );
    -- Call original..
    if (MoveAllExtension.OrigOnResizeCode==nil) then
    --lua call
    MoveAllExtension.OrigOnResize( sender );
    else
    --native call
    MoveAllExtension.OrigOnResize(MoveAllExtension.OrigOnResizeCode, MoveAllExtension.OrigOnResizeData, sender );
    end
    end
    if (MoveAllExtension.HasExecuted == false) then
    local mainForm = getMainForm();
    local mainPanel = wincontrol_getControl( mainForm, 3 );
    MoveAllExtension.btnMoveAll = createButton( mainPanel );
    control_setCaption( MoveAllExtension.btnMoveAll, '>>' );
    control_onClick( MoveAllExtension.btnMoveAll, MoveAllExtension.OnMoveAllClicked );
    MoveAllExtension.OrigOnResize, MoveAllExtension.OrigOnResizeCode, MoveAllExtension.OrigOnResizeData = getMethodProperty( mainPanel, 'OnResize' );
    setMethodProperty( mainPanel, 'OnResize', MoveAllExtension.OnResizeOverride );
    end

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

  19. Адреса лучше выводить в hex виде. Я бы так написал:


    function CheckAOBScan(signature)
    local sl = AOBScan(signature);
    if(sl == nil) then
    print("No code found!");
    else
    local count = stringlist_getCount(sl);
    print("Found:",count);

    local maxIndex = count-1;
    for i = 0, maxIndex do
    local line = stringlist_getString(sl,i)
    local line2 = string.format("%3d) 0x%08x: ", i+1, line )
    print(line2);
    end

    object_destroy(sl);
    end
    end

    CheckAOBScan("68 DC 7D 40 01 64 A1 00 00 00 00 50 64 89 25 00 00 00 00 83 EC 58 53")
    CheckAOBScan("68 DC 7D 40 01 64 A1 00 00 00 00 50 64 89 25 00 00 00 00 83 EC 58 53")
    CheckAOBScan("68 DC 7D 40 01 64 A1 00 00 00 00 50 64 89 25 00 00 00 00 83 EC 58 53")
    CheckAOBScan("68 DC 7D 40 01 64 A1 00 00 00 00 50 64 89 25 00 00 00 00 83 EC 58 53")
    CheckAOBScan("68 DC 7D 40 01 64 A1 00 00 00 00 50 64 89 25 00 00 00 00 83 EC 58 53")

  20. Спасибо за комментарий.

    ---

    Часть2

    Сегодня мы продолжим исследовать и учиться программировать расширяя функционал Cheat Engine. Очевидно, что запоминать горячие клавиши лень, так же не айс лезть в попап меню рис.2 ("(1)"). Т.е. было бы круто иметь дополнительную супер-пупер кнопочку рис.2("(2)") при нажатии на которою все найденные адреса переместились бы вниз.

    Мы сталкиваемся со сверхсложными проблемами не для программистов. Такие как как создать кнопку не понятно где, как её позиционировать и как сделать реакцию. Позиционирование отдельная проблема. Итак всё по порядку.

    1. Узнать имя визуального компонента на котором будем позиционировать кнопку.

    Самый простой способ это скачать исходники CE и среду разработки Lazarus и найти в ней эту панельку Panel5 выделив её мышкой.

    post-3-0-99161700-1335415162_thumb.png

    рис.1

    Вот такое вот простое название панели "Panel5" нам пригодится. Будем надеяться, что во всех будущих версиях CE это название не изменится. Если изменится, то выход тоже есть. Но о нём пока рано думать.

    Другой способ найти название панели это перебрать все компоненты окна CE и напечатать их названия. Это уже сложнее - через CE Lua. Я этот способ делал, но писать не буду, чтобы не путать.

    2. Как будем позиционировать?

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

    post-3-0-00403000-1335415169_thumb.png

    рис.2

    Готовый исходник:


    memscan = getCurrentMemscan()
    foundlist = memscan_getAttachedFoundlist(memscan)
    addresslist = getAddressList()
    max = foundlist_getCount(foundlist) - 1
    for index=0, max do
    addr = foundlist_getAddress(foundlist, index)
    createTableEntry = addresslist_createMemoryRecord(addresslist)
    memoryrecord_setDescription(createTableEntry, "Some Address")
    memoryrecord_setAddress(createTableEntry,addr)
    end
    end
    function OnUpdateTimer()
    widthPanel5, heightPanel5 = control_getSize(Panel5)
    if(lastWidth~=widthPanel5 or lastHeight~= heightPanel5) then
    lastWidth = widthPanel5
    lastHeight = heightPanel5
    control_setPosition(btnMoveAllAddresses, widthPanel5 - 345,heightPanel5 - 75)
    control_setSize(btnMoveAllAddresses, 22,22)
    end
    end
    lastWidth = 0
    lastHeight = 0

    controlMainForm = getMainForm()
    Panel5 = wincontrol_getControl(controlMainForm,3)

    btnMoveAllAddresses = createButton(Panel5)
    control_setCaption(btnMoveAllAddresses, '>>')
    control_onClick(btnMoveAllAddresses, OnBtnMoveAllAddressesClick)
    guiTmer = createTimer(controlMainForm)
    timer_setInterval(guiTmer, 10)
    timer_onTimer(guiTmer, OnUpdateTimer)
    function OnBtnMoveAllAddressesClick()

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


    wincontrol_getControl(controlMainForm,3)

    В данном случае индекс панели Panel5 это 3. Просто запомните. Если индекс панели поменяется, т.е. кнопка будет не там где надо, то можете проверить название панели таким образом


    print(component_getName(wincontrol_getControl(controlMainForm,3)))

    Сейчас эта строка выведет название панели "Panel5". Перебор всех названий компонентов писать не буду, т.к. будет больше путаницы.

    3. Куда этот код вставлять чтобы он всегда работал при запуске CE?

    1) В папке autorun находящуюся в директории с программой CE создадим текстовый файл.

    MoveAllAddressButton.txt

    2) Откроем этот файл программой Notepad++, вставим код и перекодируем текст в UTF(без BOM). Это позволит нам в будущем корректно видеть русские символы. Сейчас их нет, но лучше на всякий случай. Вдруг решим добавить русские слова.

    post-3-0-67492600-1335416025_thumb.jpg

    рис.3

    3) Сохраним файл. И переименуем в MoveAllAddressButton.lua

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

  21. Переместить все найденные адреса в главную таблицу по горячим клавишам. CE 6.2 (r1368)

    post-3-0-09637300-1335369871_thumb.png

    Наша задача не только выполнить цель, но и исследовать как работать с компонентами. Это позволит получить некоторое представление о том, как автоматизировать то, что обычно мы делаем множеством действий.


    function OnHotKeysCtrlB()
    if isKeyPressed(VK_CONTROL) and isKeyPressed(VK_ then
    memscan = getCurrentMemscan()
    foundlist = memscan_getAttachedFoundlist(memscan)
    addresslist = getAddressList()
    max = foundlist_getCount(foundlist) - 1
    for index=0, max do
    addr = foundlist_getAddress(foundlist, index)
    createTableEntry = addresslist_createMemoryRecord(addresslist)
    memoryrecord_setDescription(createTableEntry, "Some Address")
    memoryrecord_setAddress(createTableEntry,addr)
    end
    end
    end
    CEUpdaterTimer = getUpdateTimer()
    timer_onTimer(CEUpdaterTimer, OnHotKeysCtrlB)

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

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

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