nop*_*ole 8 ruby python perl winapi readprocessmemory
我想知道是否可以使用Perl,Python或Ruby来编写程序,以便它在另一个进程的内存中查找0x12345678(可能是堆,对于数据和代码数据)然后如果找到它,则更改它到0x00000000?它类似于Cheat Engine,可以在Windows上执行类似的操作.
Sin*_*nür 13
我最初认为这是不可能的,但在看到Brian的评论之后,我搜索了CPAN并且看到,有Win32 :: Process :: Memory:
C:\> ppm install Win32::Process::Info
C:\> ppm install Win32::Process::Memory
Run Code Online (Sandbox Code Playgroud)
模块显然使用了这个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 }
Run Code Online (Sandbox Code Playgroud)
输出:
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
Run Code Online (Sandbox Code Playgroud)
如果您已将程序作为调试程序附加到进程,则可以执行此操作,如果存在适当API的包装,则可以使用这些语言,或者通过类似ctypes(用于python)直接访问Windows函数.但是,使用更低级别的语言可能更容易,因为在更高级别的语言中,您必须关注如何将高级数据类型转换为较低级别的语言.
首先调用要调试的进程上的OpenProcess,并请求相应的访问权限(您需要成为计算机上的管理员/具有相当高的权限才能获得访问权限).然后,您应该能够调用ReadProcessMemory和WriteProcessMemory等函数来读取和写入该进程的内存.
[编辑] 这是一个快速python概念的功能概念,成功从另一个进程的地址空间读取内存:
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)
Run Code Online (Sandbox Code Playgroud)
请注意,您需要确定在内存中查找内容的位置 - 大多数地址空间将被取消映射,认为有一些标准偏移量可用于查找程序代码,dll等内容.
好吧,有趣的部分是访问其他进程的内存.CheatEngine通过在虚拟机下运行整个操作系统来实现这一点,该虚拟机可以防止内存保护.还有"在调试器下运行"模型,通常意味着将目标应用程序作为修改应用程序的子进程启动,并提升权限.有关这方面的许多有趣的东西,请参阅Win32 API.
在Perl中,一旦你获得了必要的访问权限,你可能想要使用Win32 :: Security :: Raw与它进行交互.