-->

如何写一个Perl,Python或Ruby程序更改Windows另一个进程的内存?(How to w

2019-06-23 14:30发布

我不知道的Perl,Python或Ruby的可以用来写一个程序,它会寻找0×12345678在另一个进程的内存(可能是堆,对于数据和代码数据),然后一旦发现,将其更改为0x00000000? 这是一个类似的东西作弊引擎 ,它可以做这样的事情在Windows上。

Answer 1:

我最初以为这是不可能的,但看到Brian的评论之后,我搜索CPAN你瞧,还有的Win32 ::过程::记忆 :

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


Answer 2:

它可以这样做,如果你已经连接你的程序的调试器的过程中,这应该是可以在这些语言是否存在绕相应的API包装,或通过类似的ctypes(对于Python)直接访问Windows功能。 但是,它可能更容易在更低级的语言来做,因为在更高层次的人,你就必须去关注如何翻译的高级数据类型到较低等。

通过调用启动OpenProcess上调试进程,与请求相应的访问(你需要成为机器上的管理员/拥有相当高的权限来访问)。 然后,您应该能够调用的功能,如ReadProcessMemory和WriteProcessMemory的读取和写入该进程的内存。

[编辑]这是从另一个进程的地址空间中成功读取记忆功能的概念的快速蟒蛇证明:

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文件等。



Answer 3:

那么,最有趣的部分越来越访问另一个进程的内存中。 CheatEngine由虚拟机,可以让内存保护被击败下运行的整个操作系统做的。 另外还有“一个调试器下运行”的模式,通常意味着启动目标程序的修改应用程序的子进程,以提升的权限。 见的Win32 API的很多有趣的东西有关。

在Perl中,你曾经有过必要的访问,你可能要与它使用互动的Win32 ::安全::原料 。



Answer 4:

有办法做到做到这一点使用进程注入,延迟加载等库

我没有看到你从列出的工具做。 这是C语言和汇编的国家,并开始将你带入病毒编写的领土。 一旦你得到它的工作,任何防病毒程序包将否决它运行,并试图隔离。 所以你最好真的想做到这一点。

“随着电力,就多......”

祝好运



Answer 5:

这是可以实现的全过程中列出的语言之一,但编译语言将是内存扫描更好(速度考虑,如果没有别的)。 有一个名为SigScan可用的,而对于特定游戏量身定做的,很可能被修改,以适合以最小的努力你的需要的DLL(附源码)。

建立在Brian的正确答案下面是一个使用DLL从蟒之内让你的地址的快速和肮脏的例子。 这是当然,具体到执行的DLL。 “模块名”一般将是DLL名称为显示在金手指引擎“枚举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)


Answer 6:

我写PROC ::记忆和其底层库libvas用于这一目的。 它只是调用{Read,Write}ProcessMemory在Windows引擎盖下,但它也支持其他平台。 例:

my $mem = Proc::Memory->new(pid => $$); 
$mem->poke(0x12345678, 'L') = 12;


文章来源: How to write a Perl, Python, or Ruby program to change the memory of another process on Windows?