Wie ein Perl, Python oder Ruby-Programm zu schreiben, um die Erinnerung an einem anderen Prozess auf Windows ändern?

StackOverflow https://stackoverflow.com/questions/1013828

Frage

Ich frage mich, ob Perl, Python, Ruby oder verwendet werden kann, ein Programm zu schreiben, so dass es für 0x12345678 im Speicher eines anderen Prozesses (wahrscheinlich der Heap, für Daten und Code-Daten) aussehen wird und dann, wenn festgestellt wird, , ändern sie ihn auf 0x00000000? Es ist etwas ähnlich wie Motor Cheat, die so etwas wie die auf Windows tun.

War es hilfreich?

Lösung

Ich dachte zunächst dies nicht möglich war, aber nach Brians Kommentar zu sehen, suchte ich CPAN und siehe da, es ist Win32 :: Process :: Speicher :

C:\> ppm install Win32::Process::Info
C:\> ppm install Win32::Process::Memory

Das Modul offenbar verwendet die ReadProcessMemory Funktion: Hier ist eine der meine Versuche:

#!/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 }

Ausgabe:

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

Andere Tipps

Es ist möglich, dies zu tun, wenn Sie Ihr Programm als Debugger an den Prozess angeschlossen hat, die in dieser Sprache möglich sein sollen, wenn Wrapper um die entsprechenden APIs existieren, oder direkt die Fenster Funktionen durch so etwas wie ctypes Zugriff (für Python). Jedoch kann es einfacher sein, in einer Low-Level-Sprache zu tun, da in höheren Ebene diejenigen werden Sie mit werden müssen besorgt, wie High-Level-Datentypen zu übersetzen diejenigen etc zu senken.

Starten Sie durch den Aufruf Open auf den Prozess zu debuggen, mit dem entsprechenden Zugriff angefordert (Sie ein Admin an der Maschine / haben ziemlich hohe Privilegien um Zugang zu erhalten müssen sein). Sie sollten dann in der Lage sein, Funktionen zu nennen wie Readprocessmemory und Write lesen und schreiben, die dem Prozess der Speicher.

[Bearbeiten] Hier ist eine schnelle Python proof of concept einer Funktion, die Speicher von einem anderen Prozess-Adressraum erfolgreich lautet:

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)

Beachten Sie, dass Sie benötigen, wo im Speicher zu bestimmen, für Dinge zu finden -. Die meisten dieser Adressraum nicht zugeordnet sein wird, dachte, dass es einige Standard-Offsets für Dinge wie den Programmcode zu sehen sind, dlls etc

Nun, das Spaßteil wird immer Zugriff auf den Speicher des anderen Prozesses. Cheatengine tut es, indem das gesamte OS unter einer virtuellen Maschine ausgeführt wird, der Speicherschutz besiegt werden kann. Es gibt auch den ‚unter einem Debugger läuft‘ -Modell, das heißt im Allgemeinen die Zielanwendung als Kindprozess der modifizierenden Anwendung starten, mit erhöhten Rechten. Sehen Sie sich die Win32 API für viel Spaß Zeug darüber.

In Perl, sobald Sie den erforderlichen Zugang hatte, würden Sie wahrscheinlich zu interagieren wollen es mit Win32 :: Sicherheit :: Raw .

Es gibt Möglichkeiten, dies mit Prozess Injektion zu tun tun, verzögern Ladebibliothek usw.

Ich sehe nicht, dass Sie es von den Werkzeugen tun Sie aufgeführt haben. Dies ist C und Assembler Land und beginnen Sie in dem Schreiben von Viren Gebiet zu erhalten. Sobald Sie es an die Arbeit, Antivirus-Pakete Veto es laufen und versuchen, es zu isolieren. Also besser Sie wirklich wollen, dies zu tun.

"Mit Macht kommt viel ...."

Viel Glück

Es ist möglich, den gesamten Prozess in einem der aufgeführten Sprachen zu implementieren, aber eine kompilierte Sprache würde für Speicherabtastsignal (Geschwindigkeit Überlegungen, wenn nichts anderes) besser sein. Es gibt eine DLL (mit Quelle) genannt SigScan zur Verfügung, die, während für ein bestimmtes Spiel zugeschnitten, wahrscheinlich modifiziert werden könnte, Ihre Bedürfnisse mit minimalem Aufwand Hotel.

Aufbauend auf Brians richtigen Antwort ist hier ein schnelles und schmutziges Beispiel einer DLL verwendet Ihre Adresse aus Python zu bekommen. Dies ist, natürlich, die spezifisch für die DLLs Implementierung. „Modulname“ im Allgemeinen die dll Namen wie angezeigt wäre in Cheat Engines „Auflisten von DLLs und Symbolen“ Dialog.

Mit Brians Beispiel als Richtlinie und MSDN könnte dies leicht mit Ihrem eigenen Write Verfahren verlängern.

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)

Ich schrieb Proc :: Speicher und die ihr zugrunde liegenden Bibliothek libvas für diesen Zweck . Er fordert nur {Read,Write}ProcessMemory unter der Haube auf Windows, unterstützt aber auch andere Plattformen. Beispiel:

my $mem = Proc::Memory->new(pid => $$); 
$mem->poke(0x12345678, 'L') = 12;
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top