Stack cook ie Код инструментария обнаружил переполнение буфера на основе стека - PullRequest
0 голосов
/ 14 февраля 2020

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

read<uint64_t>(address);

template<typename T>
inline T read(uint64_t address)
{
    T buffer{ };
    readbuffer(address, &buffer, sizeof(T));
    return buffer;
}

Я отправляю этот буфер через сокет в виртуальная машина, которая затем находит текущий процесс, используя GetCurrentProcessId(), и записывает необходимые мне данные обратно в адрес памяти буфера.

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

Подробнее:

uint32_t readbuffer(uint64_t address, PVOID buffer, size_t size)
{
    if (address == 0)
        return false;
    printf("readbuffer: 0x%X  0x%X  0x%X\n", address, uintptr_t(buffer), size);
    return copy_memory(cached_connection, cached_dwPID, address, GetCurrentProcessId(), uintptr_t(buffer), size);
}

.

static uint32_t copy_memory(
    const SOCKET    connection,
    const uint32_t  src_process_id,
    const uintptr_t src_address,
    const uint32_t  dest_process_id,
    const uintptr_t dest_address,
    const size_t    size)
{
    Packet packet{ };

    packet.header.magic = packet_magic;
    packet.header.type = PacketType::packet_copy_memory;

    auto& data = packet.data.copy_memory;
    data.src_process_id = src_process_id;
    data.src_address = uint64_t(src_address);
    data.dest_process_id = dest_process_id;
    data.dest_address = uint64_t(dest_address);
    data.size = uint64_t(size);

    //printf("src 0x%X dst 0x%X size 0x%X\n", data.src_address, data.dest_address, data.size);

    uint64_t result = 0;
    if (send_packet(connection, packet, result))
        return uint32_t(result);

    return 0;
}

С виртуальной машины:

process->Read(completion_packet.data.copy_memory.src_address, &buffer, completion_packet.data.copy_memory.size);


destProcess->Write(completion_packet.data.copy_memory.dest_address, buffer);

Код, который вызывает чтение / 1 и вылетает

FTransform GetBoneIndex(DWORD_PTR mesh, int index)
{
    DWORD_PTR bonearray = memio->read<DWORD_PTR>(mesh + 0x410);

    return memio->read<FTransform>(bonearray + (index * 0x30));
}

Чтение / Метод записи

template<typename T>
T Read(uint64_t address)
{
    T ret;
    VMemRead(&ctx->process, proc.dirBase, (uint64_t)&ret, address, sizeof(T));
    return ret;
}

template<typename T>
void Write(uint64_t address, const T& value)
{
    VMemWrite(&ctx->process, proc.dirBase, (uint64_t)&value, address, sizeof(T));
}

Я сейчас использую эти:

ssize_t WinProcess::Read(uint64_t address, void* buffer, size_t sz)
{
    return VMemRead(&ctx->process, proc.dirBase, (uint64_t)buffer, address, sz);
}

ssize_t WinProcess::Write(uint64_t address, void* buffer, size_t sz)
{
    return VMemWrite(&ctx->process, proc.dirBase, (uint64_t)buffer, address, sz);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...