В Ruby, как я прочитал значения памяти из внешнего процесса?
-
26-09-2019 - |
Вопрос
Так что все, что я просто хочу сделать, это сделать программу Ruby, которая читает некоторые значения из известного адреса памяти в виртуальной памяти другого процесса. Благодаря моим исследованиям и базовым знаниям HEX редактирование сборки бегущего процесса X86 в памяти я нашел базовый адрес и смещения для значений в памяти, которую я хочу. Я не хочу их менять; Я просто хочу их прочитать. Я попросил разработчику редактора памяти, как приблизиться к этому абстрактному языку и предполагая платформу Windows. Он сказал мне, что Win32API требует вызовов OpenProcess, CreateProcess, ReadProcessMemory и WorkProcessMemory - это путь к использованию либо C или C ++. Я думаю, что путь к работе будет просто использовать класс Win32API и сопоставление двух экземпляров этого; Один для OpenProcess или CreateProcess, в зависимости от того, в зависимости от того, если пользователь уже имеет процесс, работающий или нет, и другой экземпляр будет сопоставлен на ReadProcessMemory. Вероятно, мне все еще нужно найти функцию для получения списка запущенных процессов, поэтому я знаю, какой процесс работает тот, который я хочу, если он работает уже.
Это потребовало бы некоторую работу, чтобы поставить все вместе, но я выяснил, что это не было бы неплохо, чтобы кодироваться. Это просто новая область программирования для меня, поскольку я никогда не работал на этом низком уровне с языка высокого уровня (ну, более высокий уровень, чем C в любом случае). Я просто задаюсь вопросом о способах подойти к этому. Я мог бы просто использовать звонки группы или Win32api, но это означает, что именно иметь дело с кучей пакета строки и массива и распаковки, который зависит от системы, я хочу в конечном итоге сделать эту рабочую кросс-платформу, поскольку процесс, который я читаю, от Исполняемый, который имеет несколько сборных платформы, (я знаю, что адрес памяти меняется из системы в систему. Идея состоит в том, чтобы иметь плоский файл, который содержит все сопоставления памяти, поэтому программа Ruby может просто соответствовать текущей среде платформы для соответствующего отображения памяти. ) Но из внешности вещей я просто должен сделать класс, который охватывает все возможное, является текущей системой платформы.
Для всего, что я знаю, уже может существовать драгоценность Ruby, которая заботится обо всем этом для меня, что я просто не нахожу. Я также смогю попробовать редактирование исполняемых файлов для каждой сборки, чтобы сделать его так, когда я хочу прочитать значения памяти, которые я хочу прочитать, написанные по процессу, он также записывает копию нового значения в пространство в общей памяти, которую я как-то Ruby Сделайте экземпляр класса, который является указателем под капотом к этому общему адресу памяти и как-то сигнал в программу Ruby, что значение было обновлено и должно быть перезагружен. В основном система на основе прерываний была бы хорошей, но поскольку цель чтения этих значений - просто отправить табло, транслируемое с центрального сервера, я мог бы просто придерживаться системе на основе опроса, которая отправляет обновления в фиксированные временные интервалы. Я также мог просто отказаться от Ruby в целом и пойти на C или C ++, но я не знаю этих почти. Я на самом деле знаю больше x86, чем C ++, и я знаю только C в качестве независимой системы ANSI C и никогда не имел дело с общими системными библиотеками ранее.
Так есть ли драгоценный камень или менее известный модуль, который уже сделал это? Если нет, то какая-то дополнительная информация о том, как выполнить это было бы хорошей. Я думаю, длинная история короткая, как мне все это делать?
Спасибо заранее, ГРГ
PS: также подтверждение того, что эти вызовы Win32API должны быть нацелены на библиотеку Kernel32.dll было бы неплохо.
Решение
Взгляни на Win32utils.. Отказ Я думаю, что, по крайней мере, заставит вас на ноги, и дайте вам примеры того, как копать в себе API, если сами драгоценные камня не работают для вас. Вам может потребоваться кусать пулю и написать модуль в C.
Другие советы
Используйте Ruby-FFI:
Если вы знаете C и API Win32, то вам может быть легче использовать Ruby-FFI
драгоценность Ruby-FFI
Обертывает функции C прозрачно, позволяя вам использовать любую функцию Win32.
Для именованной общей памяти Win32 предоставляет CreateFileMapping( )
а также MapViewOfFile( )
.
У них есть заголовки
# WINBASEAPI HANDLE WINAPI CreateFileMappingA(HANDLE,LPSECURITY_ATTRIBUTES,DWORD,DWORD,DWORD,LPCSTR);
# WINBASEAPI PVOID WINAPI MapViewOfFile(HANDLE,DWORD,DWORD,DWORD,DWORD);
Проходя в неверной обработке файлов 0xFFFFFFFF
в CreateFileMapping
, вы можете избежать борьбы с файлами вообще и просто определить свою общую память, используя массивы и указатели.
Ниже приведен упрощенный пример, который читает от общей памяти. (Версия качества производства будет использовать семафоры в читателе и писателю, а круговой буфер, чтобы обоим процессам протекать асинхронно, когда все еще гарантируют, что писатель не перезаписывает буфер, пока читатель не будет читать его.)
Упрощенный пример рубина:
require 'ffi'
module Win32
extend FFI::Library
ffi_lib 'kernel32' # see winbase.h
attach_function :CreateFileMapping,
:CreateFileMappingA,[ :uint, :pointer, :long, :long, :long, :pointer ], :pointer
# suffix A indicates the ASCII version
attach_function :MapViewOfFile,
:MapViewOfFile,[ :pointer, :long, :long, :long, :long ], :pointer
end
memoryName = "Share Memory Name"
sz_buf = 1000 # bytes (250 ints, 4 bytes each)
num_ints = sz_buf / 4
# Windows constants
PAGE_READWRITE = 0x0004
FILE_MAP_WRITE = 2
# Get handle to shared memory
hMemory = Win32.CreateFileMapping(0xFFFFFFFF, nil, PAGE_READWRITE, 0, sz_buf, memoryName)
# Create pointer into shared memory in the reader's memory space
pMemory = FFI::MemoryPointer.new(:int, num_ints )
pMemory = Win32.MapViewOfFile(hMemory, FILE_MAP_WRITE, 0, 0, sz_buf)
# Read from shared memory buffer
puts pMemory.read_array_of_int(sz_buf).join(" ")
Несколько полезной информации:
- Хорошая работа Пример совместно используемого кода памяти (как выше) в C / WIN32. На самом деле, вы можете использовать модуль Writer, представленный здесь, чтобы проверить вышеуказанный код - просто измените тип из
char *
кint
. - Семафоры для синхронизации доступа