Использование raw () или #html_safe все еще не работало для меня.
Я использую вспомогательный метод для создания контента button_to flag. Завершилось использованием следующего в моем вспомогательном методе (путь определен заранее):
form_tag path, :method => :post do
button_tag do
content_tag :i, 'Flag as inappropriate', :class => 'icon-flag flag_content'
end
end
Сначала я подумал, что это невозможно, но, увидев комментарий Брайана, я поискал CPAN и, о чудо, нашел Win32 :: Process :: Memory :
C:\> ppm install Win32::Process::Info
C:\> ppm install Win32::Process::Memory
Модуль, по-видимому, использует функцию ReadProcessMemory
: Вот одна из моих попыток:
#!/usr/bin/perl
use strict; use warnings;
use Win32;
use Win32::Process;
use Win32::Process::Memory;
my $process;
Win32::Process::Create(
$process,
'C:/opt/vim/vim72/gvim.exe',
q{},
0,
NORMAL_PRIORITY_CLASS,
q{.}
) or die ErrorReport();
my $mem = Win32::Process::Memory->new({
pid => $process->GetProcessID(),
access => 'read/query',
});
$mem->search_sub( 'VIM', sub {
print $mem->hexdump($_[0], 0x20), "\n";
});
sub ErrorReport{
Win32::FormatMessage( Win32::GetLastError() );
}
END { $process->Kill(0) if $process }
Вывод:
C:\Temp> proc
0052A580 : 56 49 4D 20 2D 20 56 69 20 49 4D 70 72 6F 76 65 : VIM - Vi IMprove
0052A590 : 64 20 37 2E 32 20 28 32 30 30 38 20 41 75 67 20 : d 7.2 (2008 Aug
0052A5F0 : 56 49 4D 52 55 4E 54 49 4D 45 3A 20 22 00 : VIMRUNTIME: ".
0052A600 : 20 20 66 61 6C 6C 2D 62 61 63 6B 20 66 6F 72 20 : fall-back for
0052A610 : 24 56 : $V
Что ж, самое интересное - получить доступ к памяти другого процесса. CheatEngine делает это, запуская всю вашу ОС на виртуальной машине, что позволяет обойти защиту памяти. Также существует модель «работа под отладчиком», обычно означающая запуск целевого приложения как дочернего процесса изменяющего приложения с повышенными привилегиями. См. Win32 API , чтобы узнать много интересного об этом.
В Perl, получив необходимый доступ, вы:
Это возможно, если вы подключили свою программу в качестве отладчика к процессу, что должно быть возможно на этих языках, если существуют оболочки для соответствующих API-интерфейсов, или путем прямого доступа к окнам функционирует через что-то вроде ctypes (для python). Тем не менее, это может быть проще сделать на более низкоуровневом языке, поскольку на более высоком уровне вам придется заботиться о том, как преобразовать типы данных высокого уровня в более низкие и т. Д.
Начните с вызова OpenProcess в процессе отладки с соответствующим запрошенным доступом (вы должны быть администратором на машине / иметь достаточно высокие привилегии для получения доступа). Затем вы должны иметь возможность вызывать такие функции, как ReadProcessMemory и WriteProcessMemory , для чтения и записи в этот процесс »
[Edit] Вот краткое доказательство концепции функции, которая успешно считывает память из адресного пространства другого процесса:
import ctypes
import ctypes.wintypes
kernel32 = ctypes.wintypes.windll.kernel32
# Various access flag definitions:
class Access:
DELETE = 0x00010000
READ_CONTROL= 0x00020000
SYNCHRONIZE = 0x00100000
WRITE_DAC = 0x00040000
WRITE_OWNER = 0x00080000
PROCESS_VM_WRITE = 0x0020
PROCESS_VM_READ = 0x0010
PROCESS_VM_OPERATION = 0x0008
PROCESS_TERMINATE = 0x0001
PROCESS_SUSPEND_RESUME = 0x0800
PROCESS_SET_QUOTA = 0x0100
PROCESS_SET_INFORMATION = 0x0200
PROCESS_QUERY_LIMITED_INFORMATION = 0x1000
PROCESS_QUERY_INFORMATION = 0x0400
PROCESS_DUP_HANDLE = 0x0040
PROCESS_CREATE_THREAD = 0x0002
PROCESS_CREATE_PROCESS = 0x0080
def read_process_mem(pid, address, size):
"""Read memory of the specified process ID."""
buf = ctypes.create_string_buffer(size)
gotBytes = ctypes.c_ulong(0)
h = kernel32.OpenProcess(Access.PROCESS_VM_READ, False, pid)
try:
if kernel32.ReadProcessMemory(h, address, buf, size, ctypes.byref(gotBytes)):
return buf
else:
# TODO: report appropriate error GetLastError
raise Exception("Failed to access process memory.")
finally:
kernel32.CloseHandle(h)
Обратите внимание, что вам нужно определить, где в памяти искать вещи - большая часть этого адресного пространства не будет отображена, хотя есть некоторые стандартные смещения для поиска таких вещей, как программный код, библиотеки DLL и т. д.
Есть способы сделать это с помощью внедрения процесса, библиотеки отложенной загрузки и т. Д.
Я не вижу, чтобы вы делали это из перечисленных вами инструментов. Это страна C и ассемблера, которая начинает вводить вас на территорию написания вирусов. Как только вы заставите его работать, любые антивирусные пакеты наложат вето на его запуск и попытаются изолировать его. Так что тебе лучше действительно это сделать.
«С силой приходит многое ....»
Удачи
Можно реализовать весь процесс на одном из перечисленных языков, но для сканирования памяти лучше использовать скомпилированный язык (соображения скорости, если ничто иное). Доступна dll (с исходным кодом) под названием SigScan, которая, хотя и предназначена для конкретной игры, вероятно, может быть изменена в соответствии с вашими потребностями с минимальными усилиями.
Основываясь на правильном ответе Брайана, вот быстрый и грязный пример использования dll для получения вашего адреса из Python. Это, конечно, специфично для реализации DLL. «Имя модуля» обычно будет именем dll, отображаемым в диалоговом окне Cheat Engines «Перечислить библиотеки DLL и символы».
Используя пример Брайана в качестве руководства и MSDN , вы можете легко расширить его с помощью собственного метода WriteProcessMemory .
import win32defines
import win32process
import win32gui
from ctypes import *
SigScan = cdll.SigScan
kernel32 = windll.kernel32
addresses = {"Value1" : {"sigArg1" : "b0015ec390518b4c24088d4424005068",
"sigArg2" : 36,
"address" : None,
"size" : 32
},
"Value2" :{"sigArg1" : "3b05XXXXXXXX741285c0",
"sigArg2" : None,
"address" : None,
"size" : 32
}
}
def read_process_mem(pid, address, size):
"""Read memory of the specified process ID."""
buf = create_string_buffer(size)
gotBytes = c_ulong(0)
h = kernel32.OpenProcess(win32defines.PROCESS_VM_READ, False, pid)
try:
if kernel32.ReadProcessMemory(h, address, buf, size, byref(gotBytes)):
return buf
else:
# TODO: report appropriate error GetLastError
raise Exception("Failed to access process memory.")
finally:
kernel32.CloseHandle(h)
if __name__ == "__main__":
pid, id = None, None
## HWND
hwnd = win32gui.FindWindowEx(0, 0, 0, "Window Name here")
## pid
pid = win32process.GetWindowThreadProcessId(hwnd)[-1]
## Initialize the sigscan dll
SigScan.InitializeSigScan(pid, "Module Name")
## Find all the addresses registered
for key in addresses.keys():
addresses[key]["address"] = SigScan.SigScan(addresses[key]["sigArg1"],
addresses[key]["sigArg2"])
## Allow the scanner to clean up
SigScan.FinalizeSigScan()
for key in addresses.keys():
if addresses[key]["address"] != None:
print repr(read_process_mem(pid, addresses[key]["address"],
addresses[key]["size"]).raw)