2017-07-24 2 views
-2

J'utilise l'assembleur masm et j'utilise kernel32.lib pour créer la mémoire heap, mais sur la page de l'API Windows pour la procédure HeapCreate, il ne me dit pas où sa valeur de retour est stockée. (c'est-à-dire la poignée vers le tas) Je suppose qu'il est stocké dans EAX? puisque la plupart des procédures placent leur valeur de retour dans EAX. Après que j'appelle HeapCreate, j'appelle HealAlloc d'allouer de la mémoire dans mon tas:HeapCreate renvoie-t-il le handle de segment dans EAX?

INCLUDE \masm32\include\kernel32.inc 
INCLUDELIB \masm32\lib\kernel32.lib 
.CODE 

PUSH DWORD PTR 00h ;max size 
PUSH DWORD PTR 00h ;initial size 
PUSH DWORD PTR 04h ;flOption 
CALL HeapCreate 

PUSH DWORD PTR 04h ;dwBytes (the size in bytes) 
PUSH DWORD PTR 04h ;dwFlag 
PUSH EAX ;I am not sure if the heap handle is stored in EAX or not? 
CALL HeapAlloc 

END 

Essentiellement, je ne sais pas où la valeur de retour à HeapCreate est stocké. Si quelqu'un pouvait clarifier où, je l'apprécierais.

Merci

+3

Familiarisez-vous avec la convention d'appel stdcall, qui est la valeur par défaut utilisée pour les appels d'API Windows. Voir [ici] (https://msdn.microsoft.com/en-us/library/984x0h58.aspx) et [ici] (https://msdn.microsoft.com/fr-fr/library/zxk0tw93.aspx) . –

Répondre

5

Le MSDN page for HeapCreate donne le prototype suivant pour la fonction:

HANDLE WINAPI HeapCreate(
    _In_ DWORD flOptions, 
    _In_ SIZE_T dwInitialSize, 
    _In_ SIZE_T dwMaximumSize 
); 

Tous les x86 conventions d'appel quittent la valeur de retour dans R/EAX, de sorte que le HANDLE résultant se trouvent dans les deux EAX (en 32 -bit builds) ou RAX (dans les versions 64 bits).

3

Cela dépend si vous compilez pour 32 bits ou 64 bits.

La déclaration de HeapCreate() est la suivante:

HANDLE WINAPI HeapCreate(
    _In_ DWORD flOptions, 
    _In_ SIZE_T dwInitialSize, 
    _In_ SIZE_T dwMaximumSize 
); 

WINAPI est une macro préprocesseur qui décide de la __stdcall convention d'appel, qui n'a de sens que dans 32 bits et est ignoré dans 64 bits. Dans 32 bits, __stdcall enregistre des valeurs allant jusqu'à 32 bits dans EAX et des valeurs de retour plus grandes dans EAX:EDX.

En 64 bits, la convention d'appel x64 stocke les valeurs de retour dans RAX (dont les 32 premiers bits sont EAX).

HANDLE est un type de pointeur, il a donc une taille de 32 bits pour une compilation 32 bits et une taille de 64 bits pour une compilation 64 bits. Cependant, MSDN states:

versions 64 bits de Windows utilisent 32 bits gère l'interopérabilité. Lorsque vous partagez un handle entre des applications 32 bits et 64 bits, seuls les 32 bits inférieurs sont significatifs. Il est donc prudent de tronquer le handle (lors du passage de 64 bits à 32 bits) ou de prolonger la poignée (lors du passage de 32 bits à 64 bits). Les poignées pouvant être partagées incluent des poignées vers des objets utilisateur tels que Windows (HWND), des poignées vers des objets GDI tels que des stylos et des pinceaux (HBRUSH et HPEN) et des poignées vers des objets nommés tels que mutex, sémaphores et descripteurs de fichiers.

En raison de cela, en utilisant EAX seul peut être valide pour HANDLE valeurs renvoyées par HeapCreate() dans les deux compilations 32 bits et 64 bits. Toutefois, le HANDLE renvoyé par HeapCreate() n'est généralement pas partagé à travers les limites de processus, de sorte qu'il peut prendre plus de 32 bits.

Mieux vaut ne pas prendre de risques dans un sens ou dans l'autre. Utilisez EAX en 32 bits et RAX en 64 bits, puisque c'est ce que dictent les conventions d'appel respectives.