2009-12-21 8 views
0

J'ai essayé de faire fonctionner cette fonction depuis un certain temps sans succès.Pourquoi ctypes WriteProcessMemory() échoue?

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

GetLastError() retourne 87 (0x57), ce qui est ERROR_INVALID_PARAMETER. Pour cette fonction, je l'ai copiée directement à partir de Grey Hat Python par Justin Seitz. Je ne sais pas ce que je fais mal, ReadProcessMemory() fonctionne très bien et renvoie la valeur appropriée.

Pour l'adresse je choisis un emplacement aléatoire à l'heure actuelle, 0x00050000, et transmettant des données comme "\ x61" en lisant l'emplacement avant et après sans changement.

J'ai le sentiment C'est une simple erreur, Merci d'avance pour l'aide. Nav.


Pendant que vous aviez raison C'est un privilège. Je n'arrive toujours pas à comprendre ce que je cherche. Voici mon code de processus de lancement:

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

def launch(self, path_to_exe): 
    CREATE_NEW_CONSOLE = 0x0000010 

    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_NEW_CONSOLE, 
           None, 
           None, 
           byref(startupinfo), 
           byref(process_information)): 

     self.pid = process_information.dwProcessId 
    else: 
     print "Couldnt launch: %d" %path_to_exe 
     print windll.kernel32.GetLastError() 

Ai-je besoin de créer le processus d'une manière différente? Que devrais-je mettre dans la structure SecDescriptor? MSDN n'est pas très utile sur les DACL et ACE? Merci pour toute l'aide jusqu'à présent. PS - Juste une idée, comment un débogueur ou un autre programme ne génère pas un processus et est capable de modifier la mémoire?

+0

J'ai supprimé ma réponse à propos de la chaîne temporaire pouvant être libérée avant d'appeler la routine win32, car une vérification avec sys.getrefcount() montre que c_char_p() conserve une référence interne aux données. –

+0

Merci, j'apprécie l'aide en premier lieu, d'autres idées? – Navanax

+0

quelle version de Windows? Certaines de ces choses ont changé avec WinXP SP2. –

Répondre

0

Il n'y a rien d'anormal dans l'appel. Très probablement il n'y a pas de pages à 0x00050000 ou les pages ne sont pas inscriptibles. Pourquoi n'essayez-vous pas d'écrire un VirtualQuery sur les octets que vous essayez d'écrire et de voir si c'est réellement accessible en écriture? La plupart des adresses aléatoires ne le sont pas.

+0

Je viens d'ajouter une fonction pour VirtualQuery et il a retourné 0, ce qui signifie qu'il a échoué. GetLastError() renvoie 998 qui est ERROR_NOACCESS ou accès non valide à l'emplacement de la mémoire. – Navanax

+0

Y a-t-il quelque chose que je dois faire pour pouvoir écrire aux endroits? Je pensais que l'ouverture du handle de processus avec PROCESS_ALL_ACCESS était suffisante. Ai-je tort? – Navanax

+0

Vous ne pouvez pas écrire là où il n'y a pas de mémoire. Mais si vous obtenez ERROR_NOACCESS, cela signifie probablement que c'est un privilège. L'ouverture du processus avec PROCESS_ALL_ACCESS ne vous convient pas si le processus lui-même n'autorise pas les processus externes à écrire dessus. S'il s'agit d'un processus CHILD (celui que vous avez créé), vous pouvez vous y autoriser en écriture lorsque vous l'avez créé. –