HeapCreate是否将堆句柄返回到EAX?

时间:2017-07-24 18:27:34

标签: winapi assembly x86 heap-memory masm

我正在使用masm汇编程序,我正在使用kernel32.lib来创建堆内存,但是在HeapCreate过程的Windows API页面上,它并没有告诉我它的返回值存储在何处。 (即堆的句柄) 我会假设它存储在EAX中?因为大多数程序将其返回值放在EAX中。在我调用HeapCreate之后,我调用HealAlloc在我的堆中分配一些内存:

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

基本上,我不知道存储HeapCreate的返回值的位置。如果有人能澄清在哪里,我会很感激。

由于

2 个答案:

答案 0 :(得分:5)

MSDN page for HeapCreate为该函数提供了以下原型:

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

所有x86调用约定都将返回值保留在R/EAX中,因此生成的HANDLE将在EAX(在32位版本中)或RAX中找到(在64位版本中。)

答案 1 :(得分:3)

这取决于您是编译32位还是64位。

HeapCreate()的声明如下:

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

WINAPI是一个预处理器宏,它解析为__stdcall调用约定,该约定仅在32位有意义,在64位时被忽略。

在32位中,__stdcall存储EAX中最多返回32位的值,EAX:EDX中返回值更大。

在64位中,x64调用约定存储RAX中的返回值(前32位是EAX)。

HANDLE是指针类型,因此在32位编译时大小为32位,在64位编译时大小为64位。但是,MSDN states

  

64位版本的Windows使用32位句柄实现互操作性。在32位和64位应用程序之间共享句柄时,只有低32位是重要的,因此截断句柄(将其从64位传递到32位)或对句柄进行符号扩展是安全的(当它从32位传递到64位时)。可以共享的句柄包括用户对象的句柄,例如windows(HWND),GDI对象的句柄,例如笔和画笔(HBRUSHHPEN),以及命名对象的句柄,例如作为互斥锁,信号量和文件句柄。

因此,单独使用EAX 可能HANDLE在32位和64位编译中返回的HeapCreate()值有效。但是,HANDLE返回的HeapCreate()通常不会跨进程边界共享,因此可能占用超过32位。

最好不要以某种方式冒险。在32位中使用EAX,在64位中使用RAX,因为这是各自的调用约定所规定的。