2010-03-23 3 views
1

S'il vous plaît ne pas avoir peur, mais le code suivant, si vous êtes familier avec ctypes ou C il devrait être facile à lire.Python Ctypes Read/WriteProcessMemory() - Erreur 5/998 Aide!

J'ai essayé de faire fonctionner mes fonctions ReadProcessMemory() et WriteProcessMemory() depuis si longtemps et j'ai essayé presque toutes les possibilités mais la bonne.

Il lance le programme cible, retourne son PID et le gère très bien. Mais je reçois toujours un code d'erreur de 5 - ERROR_ACCESS_DENIED. Quand je cours la fonction de lecture (oubliez l'écriture pour l'instant). Je lance ce programme comme ce que je crois être un processus CHILD avec PROCESS_ALL_ACCESS ou CREATE_PRESERVE_CODE_AUTHZ_LEVEL.

J'ai également essayé PROCESS_ALL_ACCESS et PROCESS_VM_READ lorsque j'ouvre le handle.

Je peux également dire que c'est un emplacement de mémoire valide parce que je peux le trouver sur le programme en cours d'exécution avec CheatEngine. En ce qui concerne VirtualQuery(), j'obtiens un code d'erreur de 998 - ERROR_NOACCESS qui confirme encore une fois que je soupçonne qu'il s'agit d'un problème de sécurité/privilège.

Toute aide ou idée serait très appréciée, encore une fois, c'est tout mon programme jusqu'à présent, ne vous laissez pas effrayer = P.

from ctypes import * 
from ctypes.wintypes import BOOL 
import binascii 


BYTE  = c_ubyte 
WORD  = c_ushort 
DWORD  = c_ulong 
LPBYTE = POINTER(c_ubyte) 
LPTSTR = POINTER(c_char) 
HANDLE = c_void_p 
PVOID  = c_void_p 
LPVOID = c_void_p 
UNIT_PTR = c_ulong 
SIZE_T = c_ulong 

class STARTUPINFO(Structure): 
    _fields_ = [("cb",   DWORD),   
       ("lpReserved", LPTSTR), 
       ("lpDesktop",  LPTSTR), 
       ("lpTitle",  LPTSTR), 
       ("dwX",   DWORD), 
       ("dwY",   DWORD), 
       ("dwXSize",  DWORD), 
       ("dwYSize",  DWORD), 
       ("dwXCountChars", DWORD), 
       ("dwYCountChars", DWORD), 
       ("dwFillAttribute",DWORD), 
       ("dwFlags",  DWORD), 
       ("wShowWindow", WORD), 
       ("cbReserved2", WORD), 
       ("lpReserved2", LPBYTE), 
       ("hStdInput",  HANDLE), 
       ("hStdOutput", HANDLE), 
       ("hStdError",  HANDLE),] 

class PROCESS_INFORMATION(Structure): 
    _fields_ = [("hProcess", HANDLE), 
       ("hThread",  HANDLE), 
       ("dwProcessId", DWORD), 
       ("dwThreadId", DWORD),] 

class MEMORY_BASIC_INFORMATION(Structure): 
    _fields_ = [("BaseAddress", PVOID), 
       ("AllocationBase", PVOID), 
       ("AllocationProtect", DWORD), 
       ("RegionSize", SIZE_T), 
       ("State", DWORD), 
       ("Protect", DWORD), 
       ("Type", DWORD),] 

class SECURITY_ATTRIBUTES(Structure): 
    _fields_ = [("Length", DWORD), 
       ("SecDescriptor", LPVOID), 
       ("InheritHandle", BOOL)] 

class Main(): 
    def __init__(self): 
     self.h_process = None 
     self.pid = None 

    def launch(self, path_to_exe): 
     CREATE_NEW_CONSOLE = 0x00000010 
     CREATE_PRESERVE_CODE_AUTHZ_LEVEL = 0x02000000 

     startupinfo = STARTUPINFO() 
     process_information = PROCESS_INFORMATION() 
     security_attributes = SECURITY_ATTRIBUTES() 

     startupinfo.dwFlags = 0x1 
     startupinfo.wShowWindow = 0x0 


     startupinfo.cb = sizeof(startupinfo) 
     security_attributes.Length = sizeof(security_attributes) 
     security_attributes.SecDescriptior = None 
     security_attributes.InheritHandle = True 

     if windll.kernel32.CreateProcessA(path_to_exe, 
            None, 
            byref(security_attributes), 
            byref(security_attributes), 
            True, 
            CREATE_PRESERVE_CODE_AUTHZ_LEVEL, 
            None, 
            None, 
            byref(startupinfo), 
            byref(process_information)): 

      self.pid = process_information.dwProcessId 
      print "Success: CreateProcess - ", path_to_exe 
     else: 
      print "Failed: Create Process - Error code: ", windll.kernel32.GetLastError() 

    def get_handle(self, pid): 
     PROCESS_ALL_ACCESS = 0x001F0FFF 
     PROCESS_VM_READ = 0x0010 
     self.h_process = windll.kernel32.OpenProcess(PROCESS_VM_READ, False, pid) 
     if self.h_process: 
      print "Success: Got Handle - PID:", self.pid 
     else: 
      print "Failed: Get Handle - Error code: ", windll.kernel32.GetLastError() 
      windll.kernel32.SetLastError(10000) 

    def read_memory(self, address): 
     buffer = c_char_p("The data goes here") 
     bufferSize = len(buffer.value) 
     bytesRead = c_ulong(0) 
     if windll.kernel32.ReadProcessMemory(self.h_process, address, buffer, bufferSize, byref(bytesRead)): 
      print "Success: Read Memory - ", buffer.value 
     else: 
      print "Failed: Read Memory - Error Code: ", windll.kernel32.GetLastError() 
      windll.kernel32.CloseHandle(self.h_process) 
      windll.kernel32.SetLastError(10000) 

    def write_memory(self, address, data): 
     count = c_ulong(0) 
     length = len(data) 
     c_data = c_char_p(data[count.value:]) 
     null = c_int(0) 
     if not windll.kernel32.WriteProcessMemory(self.h_process, address, c_data, length, byref(count)): 
      print "Failed: Write Memory - Error Code: ", windll.kernel32.GetLastError() 
      windll.kernel32.SetLastError(10000) 
     else: 
      return False 

    def virtual_query(self, address): 
     basic_memory_info = MEMORY_BASIC_INFORMATION() 
     windll.kernel32.SetLastError(10000) 
     result = windll.kernel32.VirtualQuery(address, byref(basic_memory_info), byref(basic_memory_info)) 
     if result: 
      return True 
     else: 
      print "Failed: Virtual Query - Error Code: ", windll.kernel32.GetLastError() 


main = Main() 
address = None 
main.launch("C:\Program Files\ProgramFolder\Program.exe") 
main.get_handle(main.pid) 
#main.write_memory(address, "\x61") 
while 1: 
    print '1 to enter an address' 
    print '2 to virtual query address' 
    print '3 to read address' 
    choice = raw_input('Choice: ') 
    if choice == '1': 
     address = raw_input('Enter and address: ') 
    if choice == '2': 
     main.virtual_query(address) 
    if choice == '3': 
     main.read_memory(address) 

Merci!

Répondre

0

Une raison possible de votre erreur d'accès refusé est que l'utilisateur sous lequel vous exécutez WriteProcessMemory doit avoir le privilège DEBUG. A partir de Vista, ce privilège n'est activé que pour les administrateurs, et uniquement lors de l'exécution de l'application avec "Exécuter en tant qu'administrateur".

Vous pouvez ajouter ce privilège à n'importe quel compte.

0

Je vois plusieurs problèmes avec votre code, et il est difficile de savoir qui est la cause sous-jacente de votre problème exact. Par exemple, la ligne:

address = raw_input('Enter and address: ') 

devrait probablement être quelque chose comme:

address = long(raw_input('Enter and address: '), 0) 

Comme le code signifie, chaque fois que vous passez address à une fonction via ctypes ce que vous êtes réellement en train de faire est la création d'un temporaire buffer qui contient exactement la chaîne typée par l'utilisateur et passant dans l'adresse de ce tampon dans le processus Python. Certainement pas ce que tu veux. Si je corrige ce problème, alors votre programme semble fonctionner la plupart du temps.

De mes tests limités, la plupart (tous?) Du reste des échecs peut être fixé en réglant le argtypes correct pour ReadProcessMemory. C'est le plus gros problème que je vois avec le code ctypes, un problème exacerbé en traitant ctypes.c_voidp comme int en Python. Si argtypes n'est pas spécifié, tous les arguments sont considérés comme ctypes.c_int. Tout ce qui n'est pas compris dans la plage de l'entier signé - un pointeur ou un handle avec un nombre de bits élevé, par exemple - est tronqué de manière silencieuse.

pas la cause de vos insectes mais suboptimale sont les lignes:

buffer = c_char_p("The data goes here") 
bufferSize = len(buffer.value) 

Le module ctypes fournit des fonctions pour créer des zones tampons:

bufferSize = 32 
buffer = ctypes.create_string_buffer(bufferSize) 

Espérons que cela vous obtiendrez sur la bonne voie.

2

Vous devez essayer de définir les privilèges de débogage pour votre processus. Utilisez le code suivant une fois avant d'essayer d'ouvrir/créer un processus.

class TOKEN_PRIVILEGES(Structure): 
    _fields_ = [ 
      ('PrivilegeCount', c_uint), 
      ('Luid',   LUID), 
      ('Attributes',  c_uint) ] 

OpenProcessToken = windll.advapi32.OpenProcessToken 
OpenProcessToken.argtypes = [ 
    c_int,  # HANDLE ProcessHandle 
    c_uint,  # DWORD DesiredAccess 
    c_void_p ] # PHANDLE TokenHandle 
OpenProcessToken.restype = ErrorIfZero 

AdjustTokenPrivileges = windll.advapi32.AdjustTokenPrivileges 
AdjustTokenPrivileges.argtypes = [ 
    c_int,  # HANDLE TokenHandle 
    c_int,  # BOOL DisableAllPrivileges 
    c_void_p, # PTOKEN_PRIVILEGES NewState 
    c_uint,  # DWORD BufferLength 
    c_void_p, # PTOKEN_PRIVILEGES PreviousState 
    c_void_p ] # PDWORD ReturnLength 
AdjustTokenPrivileges.restype = ErrorIfZero 

LookupPrivilegeValue = windll.advapi32.LookupPrivilegeValueA 
LookupPrivilegeValue.argtypes = [ 
c_char_p, # LPCTSTR lpSystemName 
c_char_p, # LPCTSTR lpName 
c_void_p ] # PLUID lpLuid 
LookupPrivilegeValue.restype = ErrorIfZero 

access_token = c_int(0) 
privileges = TOKEN_PRIVILEGES() 

OpenProcessToken(GetCurrentProcess(), win32con.TOKEN_QUERY | win32con.TOKEN_ADJUST_PRIVILEGES, byref(access_token)) 
access_token = access_token.value 
LookupPrivilegeValue(None, "SeDebugPrivilege", byref(privileges.Luid)) 
privileges.PrivilegeCount = 1 
privileges.Attributes = 2 
AdjustTokenPrivileges(
     access_token, 
     0, 
     byref(privileges), 
     0, 
     None, 
     None) 
CloseHandle(access_token)