Je me demande si Perl, Python ou Ruby peuvent être utilisés pour écrire un programme afin qu'il recherche 0x12345678 dans la mémoire d'un autre processus (probablement le tas, pour les données de données et de code), puis s'il est trouvé, le changer en 0x00000000? C'est quelque chose de similaire à Cheat Engine, qui peut faire quelque chose comme ça sur Windows.Comment écrire un programme Perl, Python ou Ruby pour changer la mémoire d'un autre processus sous Windows?
Répondre
Je pensais d'abord cela n'a pas été possible, mais après avoir vu le commentaire de Brian, je cherchai CPAN et voilà, il est Win32::Process::Memory:
C:\> ppm install Win32::Process::Info
C:\> ppm install Win32::Process::Memory
Le module utilise apparemment la fonction ReadProcessMemory
: Voici une de mes tentatives :
#!/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 }
sortie:
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
Il existe des moyens de le faire en utilisant l'injection de processus, la bibliothèque de chargement de délai, etc.
Je ne vous vois pas à partir des outils que vous avez listés. C'est pays C et assembleur et commence à vous entrer dans le territoire d'écriture de virus. Une fois que vous l'aurez fait fonctionner, tous les paquets anti-virus mettront leur veto en cours d'exécution et essayeront de l'isoler. Donc tu ferais mieux de vraiment faire ça.
« Avec le pouvoir vient beaucoup .... »
Bonne chance
Eh bien, la partie amusante devient l'accès à la mémoire de l'autre processus. CheatEngine le fait en exécutant votre système d'exploitation entier sous une machine virtuelle qui permet de vaincre la protection de la mémoire. Il y a aussi le modèle 'running under a debugger', qui signifie généralement démarrer l'application cible en tant que processus enfant de l'application de modification, avec des privilèges élevés. Voir le Win32 API pour beaucoup de choses amusantes à ce sujet.
En Perl, une fois que vous avez eu l'accès requis, vous voudrez probablement interagir avec lui en utilisant Win32::Security::Raw.
est-ce que cela signifie que si je lance Cheat Engine et aussi une application tierce ou shareware, l'ordinateur est particulièrement vulnérable parce que l'ordinateur entier a désactivé la protection de la mémoire? (le shareware peut essentiellement modifier le code ou les données du processus IE ou Firefox) –
Non, ce n'est pas aussi grave que ça. CheatEngine fait son affaire grâce à un ensemble d'opérations étendu et authentifie l'accès à l'aide d'une clé de hachage. Il ne s'agit donc pas simplement de désactiver la protection de la mémoire, mais de la contourner à l'aide d'un mécanisme doté d'au moins une certaine protection. – chaos
Il est possible de le faire si vous avez attaché votre programme en tant que débogueur au processus, ce qui devrait être possible dans ces langages si des wrappers autour des API appropriées existent, ou en accédant directement aux fonctions de Windows par quelque chose comme ctypes (pour python). Cependant, il peut être plus facile de le faire dans un langage de plus bas niveau, car dans les langages de plus haut niveau, vous devrez vous préoccuper de la traduction des types de données de haut niveau vers les langages inférieurs. pour déboguer, avec l'accès approprié demandé (vous devrez être un administrateur sur la machine/avoir des privilèges assez élevés pour accéder). Vous devriez alors pouvoir appeler des fonctions comme ReadProcessMemory et WriteProcessMemory pour lire et écrire dans la mémoire de ce processus.
[Modifier] Voici une preuve python rapide du concept d'une fonction qui lit avec succès la mémoire d'un autre espace d'adressage de processus:
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)
Notez que vous aurez besoin de déterminer où en mémoire de chercher choses - la plupart de cet espace d'adressage va être démappé, pensé qu'il y a des décalages standards pour rechercher des choses comme le code du programme, les DLL, etc.
C'est incroyablement cool – UberJumper
Il est possible de mettre en œuvre l'ensemble du processus dans l'une des langues répertoriées, mais un langage compilé serait préférable pour l'analyse de la mémoire (considérations de vitesse si rien d'autre). Il existe un dll (avec source) appelé SigScan disponible qui, bien que conçu pour un jeu spécifique, pourrait probablement être modifié pour répondre à vos besoins avec un minimum d'effort. En se basant sur la bonne réponse de Brian, voici un exemple rapide et sale d'utilisation d'une DLL pour obtenir votre adresse depuis python. Ceci est, bien sûr, spécifique à l'implémentation des DLL. "Nom du module" correspond généralement au nom de la DLL tel qu'affiché dans la boîte de dialogue "Énumérer les DLL et les symboles" dans Cheat Engines. Avec l'exemple de Brian comme ligne directrice et MSDN, vous pouvez facilement étendre ceci avec votre propre méthode 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)
j'ai écrit Proc::Memory et sa bibliothèque sous-jacente libvas à cet effet. Il appelle simplement {Read,Write}ProcessMemory
sous le capot sur Windows, mais il prend également en charge d'autres plates-formes. Exemple:
my $mem = Proc::Memory->new(pid => $$);
$mem->poke(0x12345678, 'L') = 12;
Ce n'est pas vraiment vrai - avec des autorisations appropriées, il est possible d'accéder et de modifier un autre processus mémoire (ce qui est le fonctionnement des débogueurs) Ce n'est pas un trou de sécurité si vous êtes déjà administrateur. – Brian