Вопрос по perl, ruby, python, winapi – Как написать программу на Perl, Python или Ruby, чтобы изменить память другого процесса в Windows?

8

Интересно, можно ли использовать Perl, Python или Ruby для написания программы, чтобы она искала 0x12345678 в памяти другого процесса (возможно, кучи данных и кода), а затем, если она найдена, измените ее до 0x00000000? Это что-то похожее наЧит двигатель, который может сделать что-то подобное в Windows.

Ваш Ответ

6   ответов
0

но скомпилированный язык будет лучше для сканирования памяти (соображения скорости, если ничего больше). Существует dll (с исходным кодом) под названием SigScan, который, хотя и предназначен для конкретной игры, вероятно, может быть изменен для соответствия вашим потребностям с минимальными усилиями.

Основываясь на правильном ответе Брайана, это быстрый и грязный пример использования DLL для получения вашего адреса из Python. Это, конечно, специфично для реализации DLL. & quot; Имя модуля & quot; обычно это будет имя dll, отображаемое в Cheat Engines & quot; Перечислять DLL и символы & quot; Диалог.

Примером Брайана в качестве руководства и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)
13

что это невозможно, но, увидев комментарий Брайана, я поискал в 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
Error: User Rate Limit Exceeded
4

используя внедрение процесса, задержку загрузки библиотеки и т. Д.

Я не вижу, чтобы вы делали это с помощью инструментов, которые вы перечислили. Это C и страна ассемблера, и вы начинаете втягивать вас в область написания вирусов. Как только вы включите его, любые антивирусные пакеты наложат вето на него и попытаются изолировать его. Так что тебе лучше действительно захотеть это сделать.

"С силой приходит много ...."

Удачи

8

если вы прикрепили свою программу в качестве отладчика к процессу, что должно быть возможно в этих языках, если существуют обертки вокруг соответствующих API, или путем прямого доступа к функциям Windows через что-то вроде ctypes (для python). Однако это может быть проще сделать на более низкоуровневом языке, поскольку на высокоуровневых языках вам придется задуматься о том, как переводить высокоуровневые типы данных в низшие и т. Д.

Начните с вызоваOpenProcess в процессе отладки с соответствующим запрошенным доступом (вам необходимо быть администратором на машине / иметь достаточно высокие привилегии для получения доступа). После этого вы сможете вызывать такие функции, какReadProcessMemory а такжеWriteProcessMemory читать и записывать в память этого процесса.

[Edit]  Вот быстрое подтверждение на 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)

Обратите внимание, что вам нужно определить, где в памяти искать объекты - большая часть этого адресного пространства будет не отображена, хотя существуют стандартные смещения для поиска таких вещей, как программный код, библиотеки DLL и т. Д.

Error: User Rate Limit Exceeded
0

Proc :: Память и лежащая в его основе библиотекаlibvas для этого. Это просто звонки{Read,Write}ProcessMemory под капотом на Windows, но он также поддерживает другие платформы. Пример:

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

самое интересное - это доступ к памяти другого процесса. CheatEngine делает это, запуская всю свою ОС под виртуальной машиной, которая позволяет защитить защиту памяти. Там также "работает под отладчиком" Модель, как правило, означает запуск целевого приложения как дочернего процесса модифицирующего приложения с повышенными привилегиями. УвидетьWin32 API для многих забавных вещей об этом.

В Perl после получения необходимого доступа вы, вероятно, захотите взаимодействовать с ним, используяWin32 :: Безопасность :: Raw.

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded 太極者無極而生

Похожие вопросы