Author Topic: HeapCreate, HeapAlloc problems  (Read 13918 times)

FlySky

  • Regular Member
  • *
  • Posts: 40
HeapCreate, HeapAlloc problems
« on: October 05, 2013, 05:32:09 PM »
Guys,

Below is a bit of code I am using to allocate memory into my process:

   //Create heap/ allocate memory to use as a buffer, we could also use GetProcessHeap api
   invoke HeapCreate, NULL, 4000h, NULL
   mov [ResultBuffer], eax
   invoke HeapAlloc, [ResultBuffer], HEAP_ZERO_MEMORY, 1000h
   invoke GetLastError
   mov [ResultBufferTemp], eax

HeapCreate returns a handle to the newly created heap just fine.
The problem is that HeapAlloc than refuses to work it always returns 0.
Using GetLastError to determine which error occurs it's also always 0.

Now I've been using google and found an old topic from 2003 from another board link posted:

http://www.asmcommunity.net/forums/topic/?id=10676

The guy in this post also uses GoASM and has the exact same problem.
Although he was using WinNT, I am using Windows 8 Professional 64 bit.
Is this a bug in GoASM or a bug in my code? I can't seem to figure it out.
Using GetProcessHeap instead of HeapCreate the problem is still the same.

jj2007

  • Member
  • *****
  • Posts: 9635
  • Assembler is fun ;-)
    • MasmBasic
Re: HeapCreate, HeapAlloc problems
« Reply #1 on: October 05, 2013, 05:36:10 PM »
   invoke HeapAlloc, [ResultBuffer], HEAP_ZERO_MEMORY, 1000h
   invoke GetLastError
   mov [ResultBufferTemp], eax
   invoke GetLastError

dedndave

  • Member
  • *****
  • Posts: 8823
  • Still using Abacus 2.0
    • DednDave
Re: HeapCreate, HeapAlloc problems
« Reply #2 on: October 05, 2013, 05:42:18 PM »
there's usually no need to create a heap
the OS creates one for each process

Code: [Select]
        .DATA?
hHeap   HANDLE ?
lpBlock LPVOID ?
dwError DWORD  ?
        .CODE

what i generally do is, during program initialization....
Code: [Select]
    INVOKE  GetProcessHeap
    mov     hHeap,eax

then, to allocate memory and set an error condition, you might do something like this...
Code: [Select]
    and     dwError,0
    INVOKE  HeapAlloc,hHeap,HEAP_ZERO_MEMORY,1000h
    mov     lpBlock,eax
    .if !eax
        INVOKE  GetLastError
        mov     dwError,eax
        xor     eax,eax
    .endif
i don't usually store the error condition like that
if the allocation fails, i either provide some other method (like VirtualAlloc)
or give them a MessageBox that says Insufficient Memory and terminate the program

and, to free the allocated block when done...
Code: [Select]
    mov     eax,lpBlock
    .if eax
        xor     ecx,ecx
        mov     lpBlock,ecx
        INVOKE  HeapFree,hHeap,ecx,eax
    .endif

FlySky

  • Regular Member
  • *
  • Posts: 40
Re: HeapCreate, HeapAlloc problems
« Reply #3 on: October 05, 2013, 07:28:13 PM »
Thanks for the answers guys.

I just installed VMWare with WindowsXP and guess what on WindowsXP the code works perfectly fine.
Although the same code refuses to work on Windows 8 64 bit for me.
I guess GoASM needs to get an update for this 'bug', or windows 8 is just really picky.

sinsi

  • Member
  • *****
  • Posts: 1176
Re: HeapCreate, HeapAlloc problems
« Reply #4 on: October 05, 2013, 07:50:25 PM »
   invoke HeapAlloc, [ResultBuffer], HEAP_ZERO_MEMORY, 1000h
   invoke GetLastError
   mov [ResultBufferTemp], eax
   invoke GetLastError
Sorry jj, according to MSDN "NULL indicates failure. If the function fails, it does not call SetLastError"
I can walk on water but stagger on beer bourbon.

dedndave

  • Member
  • *****
  • Posts: 8823
  • Still using Abacus 2.0
    • DednDave
Re: HeapCreate, HeapAlloc problems
« Reply #5 on: October 05, 2013, 07:57:51 PM »
not like a lot can go wrong - lol
GetLastError isn't really necessary
either you have crummy parameters - or there isn't enough memory

jj2007

  • Member
  • *****
  • Posts: 9635
  • Assembler is fun ;-)
    • MasmBasic
Re: HeapCreate, HeapAlloc problems
« Reply #6 on: October 05, 2013, 08:04:20 PM »
   invoke HeapAlloc, [ResultBuffer], HEAP_ZERO_MEMORY, 1000h
   invoke GetLastError
   mov [ResultBufferTemp], eax
   invoke GetLastError
Sorry jj, according to MSDN "NULL indicates failure. If the function fails, it does not call SetLastError"

I didn't check that. I was just a bit worried that using the return value of GetLastError as a buffer address could cause minor problems :greensml:

FlySky

  • Regular Member
  • *
  • Posts: 40
Re: HeapCreate, HeapAlloc problems
« Reply #7 on: October 05, 2013, 08:10:39 PM »
not like a lot can go wrong - lol
GetLastError isn't really necessary
either you have crummy parameters - or there isn't enough memory

I do tend to believe it's a bug with GoASM. The link I posted to the topic from 10 years ago described the same problem using GoASM.
Doing it in XP fixed it for that guy aswell, the same counts for me.
XP it's working fine so parameters are fine aswell.
Something must be causing GoASM to fail and I have no clue what it could be.

Edit:
I just tested the coding using MASM on Windows 8.
The code on Windows 8 using MASM is working perfectly fine, so it has to be a bug in GoASM darn!.

jj2007

  • Member
  • *****
  • Posts: 9635
  • Assembler is fun ;-)
    • MasmBasic
Re: HeapCreate, HeapAlloc problems
« Reply #8 on: October 05, 2013, 08:38:25 PM »
The code on Windows 8 using MASM is working perfectly fine, so it has to be a bug in GoASM darn!.

Nonsense, there is no bug in GoAsm, there is a horrible fat noob error in your copy & paste code.
Reflect a little bit what you are loading into ResultBufferTemp after a call to GetLastError, and stop guessing around. Instead, read replies to your posts more carefully.

   invoke HeapAlloc, [ResultBuffer], HEAP_ZERO_MEMORY, 1000h
   invoke GetLastError
   mov [ResultBufferTemp], eax

FlySky

  • Regular Member
  • *
  • Posts: 40
Re: HeapCreate, HeapAlloc problems
« Reply #9 on: October 05, 2013, 09:07:42 PM »
jj2007 if you don't know what I am seeing, and you can't because you're not here you can stop pretending that I have no clue what I am talking about.
I am not going to make a freaking movie just to prove I am right.
After the call to HeapAlloc the resulting value in EAX = 00000000.

Using the code in MASM: It works fine no errors and the call is going fine -> WindowsXP and Windows 8
Using the code in GoASM: On WindowsXP it works on Windows 8 it does not.

If it's a bug or not fact is the code does not work on Windows 8, and that's what I am asking help with.
You're reactions are just sh*t so stop making them.

It has nothing to do with the GetLastError API I placed there sheeez mister wise guy.

jj2007

  • Member
  • *****
  • Posts: 9635
  • Assembler is fun ;-)
    • MasmBasic
Re: HeapCreate, HeapAlloc problems
« Reply #10 on: October 05, 2013, 11:34:30 PM »
After the call to HeapAlloc the resulting value in EAX = 00000000.

What I see is your code ...
   invoke GetLastError
   mov [ResultBufferTemp], eax
... and under normal circumstances ResultBufferTemp is indeed zero, because that's what GetLastError normally returns in eax after a simple (and normally successful) HeapAlloc.

Now if HeapAlloc really returns zero, fine, apologies for the misunderstanding, but again, blaming GoAsm is legitimate only if you put an int 3 in front of the HeapAlloc and tell us, according to Olly or WinDbg, what was wrongly assembled by GoAsm. If it assembles fine under Masm, then it shouldn't be too difficult to produce the two disassemblies and post them here so that we can compare them.
 :icon14: ?

dedndave

  • Member
  • *****
  • Posts: 8823
  • Still using Abacus 2.0
    • DednDave
Re: HeapCreate, HeapAlloc problems
« Reply #11 on: October 06, 2013, 12:39:19 AM »
let's view the complete snippet that you originally posted
Code: [Select]
   //Create heap/ allocate memory to use as a buffer, we could also use GetProcessHeap api
   invoke HeapCreate, NULL, 4000h, NULL
   mov [ResultBuffer], eax
   invoke HeapAlloc, [ResultBuffer], HEAP_ZERO_MEMORY, 1000h
   invoke GetLastError
   mov [ResultBufferTemp], eax

the problem with that snippet is that the EAX result of HeapAlloc is destroyed when the call is made to GetLastError
and, as the HeapAlloc result is not stored first, we can safely assume the code will not work
it doesn't matter if you run it under XP, win 7, or win 8   :P

it may be a successful call, but the allocated memory is unusable because you don't have the address
and - you won't be able to free the allocated block for the same reason

wjr

  • Member
  • **
  • Posts: 207
    • WJR's website
Re: HeapCreate, HeapAlloc problems
« Reply #12 on: October 06, 2013, 04:49:02 AM »
This may be related to a bug which I recently uncovered while working on the next GoLink update. On the 64-bit side, the application would generally crash, but I saw that under certain circumstances there could be a 32-bit problem as well. This occurs with a forwarded function in a DLL which has the Export Directory Tables not in the .text section (typically the case now for 64-bit system DLLs using .rdata instead).

If you use a tool such as, oh let's see now, how about PEview... on Windows 8, does the SysWOW64 32-bit Kernel32.dll have the "EXPORT Address Table" in the .rdata section?

jj2007

  • Member
  • *****
  • Posts: 9635
  • Assembler is fun ;-)
    • MasmBasic
Re: HeapCreate, HeapAlloc problems
« Reply #13 on: October 06, 2013, 05:04:00 AM »
how about PEview

Wayne, excellent tool indeed, but you should read the forum's Product Placement Rules :eusa_naughty:
 ;)

FlySky

  • Regular Member
  • *
  • Posts: 40
Re: HeapCreate, HeapAlloc problems
« Reply #14 on: October 07, 2013, 12:28:06 AM »
This may be related to a bug which I recently uncovered while working on the next GoLink update. On the 64-bit side, the application would generally crash, but I saw that under certain circumstances there could be a 32-bit problem as well. This occurs with a forwarded function in a DLL which has the Export Directory Tables not in the .text section (typically the case now for 64-bit system DLLs using .rdata instead).

If you use a tool such as, oh let's see now, how about PEview... on Windows 8, does the SysWOW64 32-bit Kernel32.dll have the "EXPORT Address Table" in the .rdata section?

I did some more testings aswell, it has indeed to to with the forwarded functions.
When I follow the code inside a debugger it never jumps into the proper kernel32 function.
The HeapAlloc function is forwarded from kernel32.dll to ntdll.dll and it seems GoASM isn't properly building the jump table for it.
So when the call goes to the jump table to read the API, the program does not call HeapAlloc but picks the next API from the Import Address Table.

On Windows 8 (64 bit) the SysWow64 kernel32.dll has the following in the .rdata section:
Export Directory: 000E1D70
Import Directory: 000D9EFC

I solved it by dynamicly linking ntdll.dll to the project and invoke HeapAlloc by using invoke RtlAllocateHeap instead.