Высер для псевдо-безопасной работы с памятью

Receiver

🥩 Передай meat, всё в скип, я в темпе
Автор темы
Проверенный
597
818
очередной высер
C++:
#pragma once

#include <windows.h>
#include <memory>

namespace memory
{
    class c_unprotect
    {
        void *m_address {nullptr};
        std::size_t m_size {0};
        u_long m_protect {PAGE_EXECUTE_READWRITE};
    public:
        c_unprotect(void *a_address, std::size_t a_size)
            : m_address(a_address), m_size(a_size) {
            VirtualProtect(m_address, a_size, m_protect, &m_protect);
        }
        ~c_unprotect() {
            VirtualProtect(m_address, m_size, m_protect, &m_protect);
        }
    };

    void copy(void *a_dst, void *a_src, std::size_t a_size)
    {
        c_unprotect unprot {a_dst, a_size};
        std::memcpy(a_dst, a_src, a_size);
    }

    void set(void *a_dst, std::uint8_t a_value, std::size_t a_size)
    {
        c_unprotect unprot {a_dst, a_size};
        std::memset(a_dst, a_value, a_size);
    }

    void nop(void *a_dst, std::size_t a_size) {
        memory::set(a_dst, 0x90, a_size);
    }

    void byte(void *a_dst, std::uint8_t a_value) {
        memory::set(a_dst, a_value, 1);
    }

    class c_nop
    {
        std::unique_ptr<std::uint8_t> m_bytes {};
        void *m_pointer {nullptr};
        std::size_t m_size {0};
    public:
        c_nop() = default;
        c_nop(void *a_address, std::size_t a_size) {
            this->install(a_address, a_size);
        }
        c_nop(std::uintptr_t a_address, std::size_t a_size) {
            this->install(a_address, a_size);
        }
        ~c_nop() {
            this->restore();
        }

        void install(void *a_address, const std::size_t a_size)
        {
            m_bytes = std::make_unique<std::uint8_t>(a_size);
            m_pointer = a_address;
            m_size = a_size;

            memory::copy(m_bytes.get(), m_pointer, m_size);
            memory::nop(m_pointer, m_size);
        }

        void install(std::uintptr_t a_address, const std::size_t a_size) {
            this->install(reinterpret_cast<void *>(a_address), a_size);
        }

        void restore() {
            memory::copy(m_pointer, m_bytes.get(), m_size);
        }
    };
}
C++:
memory::c_nop mq {0xAABBCCu, 3}; // ставит 3 нопа на адресе 0xAABBCC
// ваша хуйня
mq.restore(); // ставит ориг. байты

// ещё варик

memory::c_nop mq;
mq.install(0xAABBCCu, 3); // ставит 3 нопа на адресе 0xAABBCC
// ваша хуйня
mq.restore();

// ещё варик

memory::c_nop mq {0xAABBCCu, 3};
// ваша хуйня
delete &mq; // тут вас посылает нахуй (budet CRASH)
1629535168045.png
 
Последнее редактирование:
  • Нравится
  • Bug
Реакции: nnS20 и Vintik