GameHackLab[RU]
    • Категории
    • Последние
    • Метки
    • Популярные
    • Пользователи
    • Группы
    • Зарегистрироваться
    • Войти
    1. Главная
    2. Antonshka
    A
    • Профиль
    • Подписки 0
    • Подписчики 0
    • Темы 2
    • Сообщения 7
    • Группы 0

    Antonshka

    @Antonshka

    0
    Репутация
    1
    Просмотры профиля
    7
    Сообщения
    0
    Подписчики
    0
    Подписки
    Регистрация
    Последнее посещение

    Antonshka Отписаться Подписаться

    Недавние сообщения Antonshka

    • RE: Сохранение значения регистра на С++

      @__fastcall Нашел это видео
      Проверил, работает нормально. Спасибо за совет.

      написал в Взлом игр (вопросы и ответы)
      A
      Antonshka
    • RE: Сохранение значения регистра на С++

      @__fastcall Я видел как люди пишут AsmJit библиотеки. Но такой вариант не вариант. Мне не хочется подключать стороннюю библиотеку. Я даже не стал использовать ни MinHook ни PolyHook ни им подобные.

      Хотя нет, я все же посмотрел как работает MinHook и написал нечто похожее. Чисто для себя. Без авто-дизасемблера. С ручным заданием офсетов и длин.

      std::unordered_map<std::string, std::unique_ptr<Hook::Signature>> Camera::createSignatures() {
         std::unordered_map<std::string, std::unique_ptr<Signature>>signatures;
      
         Hook::Instruction instruction{};
         instruction.instructionsCount = 1;
         instruction.totalByteLength = 5;
         instruction.byteLengthPerInstruction.push_back(5);
         signatures.emplace("FreezeFOV", std::make_unique<Signature>("FreezeFOV",
      	"F3 0F 11 4B 14 41 B6 01",
      	instruction, 0));
      
         instruction.instructionsCount = 2;
         instruction.totalByteLength = 6;
         instruction.byteLengthPerInstruction.clear();
         instruction.byteLengthPerInstruction.push_back(2);
         instruction.byteLengthPerInstruction.push_back(4);
         signatures.emplace("CheckPlayerInCar", std::make_unique<Signature>("CheckPlayerInCar",
      	"40 53 48 83 EC 30 80 79 60 00",
      	instruction, 0));
         return signatures;
      }
      

      Моя идея состоит в том, чтобы написать класс генерирующий байты регистровых инструкций. Например в signatures записывается нужный регистр и имя поля класса (переменной) с ним связанным. Далее этот класс в месте трамплина, сразу за ним, запишет эти байты регистровых инструкций. Занес в signatures три регистра и три поля, значит будет три инструкции, сразу за трамплином. А после третьей инструкции, будет jmp на трамплин, из которого будет jmp на hook функцию, из которой будет потом jmp на трамплин до jmp на hook, выполниться пролог, и наконец jmp обратно в оригинальный код плюс оффсет на пролог.

      написал в Взлом игр (вопросы и ответы)
      A
      Antonshka
    • RE: Сохранение значения регистра на С++

      @__fastcall Насколько мне известно, Visual Studio не поддерживает вставки для x64.

      Вообще, у меня есть одна идея, но я хотел узнать и другие варианты.

      написал в Взлом игр (вопросы и ответы)
      A
      Antonshka
    • Сохранение значения регистра на С++

      Привет, подскажите, каким способом вы сохраняете значение регистра используя С++?

      Речь идет о 64 битной архитектуре.
      К регистрам (RCX, RDX, R8, R9), которые связаны со входными параметрами функции, получить доступ просто. Но как быть с другими регистрам, R10, R11?

      Не использовать же приостановку потока со взятием его контекста.

      К примеру есть игровая функция из пяти строк. В этой функции нужно получить значение R13 и сделать свои дела.
      Искать ли место выше где R13 принимает нужное значение? Но там могут быть такие глубокие дебри.

      написал в Взлом игр (вопросы и ответы)
      A
      Antonshka
    • RE: Об указателе на метод класса в С++

      @Antonshka
      Можно без readProcessMemory так

      template <typename T> requires EventConnectConcept<T>
      VOID Event::connect(EventStatus(T::* method)(EventMessage*), T* listener, BOOL mustSkipIfDuplicate) {
      ...
      CONST auto* CONST methodAddress = *reinterpret_cast<VOID**>(&method);
      ...
      }
      
      class MyWindow : public Window {
      MyWindow () :
         openSomething(new SButton(TRUE, 0, 0, L"Open Something", 10, 10, 100, 30, this))
      {
         openSomething->onLButtonUp->connect(&MyWindow ::someMethod, this);
       ...
      }
      ...
      private:
      EventStatus someMethod(EventMessage* message);
      private:
      SButton* CONST openSomething{};
      }
      
      
      написал в Общий
      A
      Antonshka
    • Об указателе на метод класса в С++

      Привет всем.
      Подскажите, нормально ли то, что я читаю указатель на метод класса с помощью ReadProcessMemory?
      Более подходящего способа идентифицировать метод класса я не нашел и не придумал.

      Я заметил при разных тестах, при использовании Cheat Engine и его memory view, что адрес в параметре method - (VOID connect(VOID(T::* method)(VOID), T* object)), в разных проектах имеет разную вложенность. Например, в одном проекте этот method указывает на jmp инструкцию, перейдя по которой, я попадаю на метод класса, в другом проекте, method указывает на адрес, который содержит этот же jmp . Я честно говоря не понял, почему там так, а здесь иначе.

      Вот псевдокод. Это самодельная система сигналов//слотов

      #include <iostream>
      #include <utility>
      #include <type_traits>
      #include <Windows.h>
      #include <vector>
      
      
      class Button;
      class Widget;
      
      
      class Slot {
      public:
          virtual VOID call() = 0;
          virtual BOOL isContain(DWORD_PTR methodAddress, DWORD_PTR objectAddress) = 0;
      };
      
      
      template <typename T>
      class SlotMethod : public Slot {
      public:
          SlotMethod(VOID(T::* method)(VOID), T* object, DWORD_PTR methodAddress, DWORD_PTR objectAddress) :
              method(method),
              object(object),
              methodAddress(methodAddress),
              objectAddress(objectAddress)
          {}
      public:
          virtual VOID call() override {
              ((*object).*method)();
          }
          virtual BOOL isContain(DWORD_PTR methodAddress, DWORD_PTR objectAddress) {
              return (this->methodAddress == methodAddress && this->objectAddress == objectAddress);
          }
      private:
          VOID(T::* method)(VOID);
          T* object;
          DWORD_PTR methodAddress{ 0 };
          DWORD_PTR objectAddress{ 0 };
      };
      
      
      class Event {
      public:
          template <class T>
          requires (std::is_base_of_v<Widget, std::remove_pointer_t<T>>)
              VOID connect(VOID(T::* method)(VOID), T* object) {
              if (method && object) {
                  DWORD_PTR methodAddress{ 0 };
                  ReadProcessMemory(GetCurrentProcess(), &method, &methodAddress, sizeof(methodAddress), NULL);
                  DWORD_PTR objectAddress{ reinterpret_cast<DWORD_PTR>(object) };
                  SlotMethod<T>* slotMethod{ new SlotMethod<T>{ method, object, methodAddress, objectAddress } };
                  listeners.emplace_back(slotMethod);
              }
          }
      
          template <class T>
          requires (std::is_base_of_v<Widget, std::remove_pointer_t<T>>)
          VOID disconnect(VOID(T::* method)(VOID), T* object) {
              if (method && object) {
                  DWORD_PTR methodAddress{ 0 };
                  ReadProcessMemory(GetCurrentProcess(), &method, &methodAddress, sizeof(methodAddress), NULL);
                  DWORD_PTR objectAddress{ reinterpret_cast<DWORD_PTR>(object) };
                  listeners.erase(std::remove_if(listeners.begin(), listeners.end(), [&](auto& listener) {
                      Slot* slot{ listener };
                      BOOL isContain{ slot->isContain(methodAddress, objectAddress) };
                      if (isContain) {
                          delete slot;
                      }
                      return isContain;
                      }), listeners.end());
              }
          }
      
          VOID callListeners() {
              for (auto& listener : listeners) {
                  listener->call();
              }
          }
      private:
          std::vector<Slot*> listeners;
      };
      
      
      class Widget {};
      
      
      class Button : public Widget {
      public:
          VOID onLButtonDown(VOID) {
              std::cout << "Button class - onLButtonDown method executed" << std::endl;
              onLButtonDownEvent.callListeners();
          }
      public:
          Event onLButtonDownEvent{};
      };
      
      
      class ButtonCustom : public Button {
      public:
          VOID print(VOID) {
              std::cout << "I am a ButtonCustom method print" << std::endl;
          }
      };
      
      
      int main() {
          Button* button = new Button{};
          ButtonCustom* custom = new ButtonCustom{};
          button->onLButtonDownEvent.connect(&ButtonCustom::print, custom);
          button->onLButtonDown();
          button->onLButtonDownEvent.disconnect(&ButtonCustom::print, custom);
          return 0;
      }
      
      написал в Общий
      A
      Antonshka
    • RE: Mafia II-DE v.1.0.1 вращение колёс

      Предполагаю что ошибка в отсутствии pushfq и popfq.
      Инструкция cmp меняет флаги. По правильному нужно всегда сохранять/восстанавливать регистр EFLAGS.

      newmem:
      pushfq 
        cmp [hot_key],01
        jne short @F
        mov [r14+000003BC],(float)1000
        mov [hot_key],00
      @@:
      popfq
        mulss xmm14,[r14+000003BC]
        jmp return
      
      написал в Общий
      A
      Antonshka