flat assembler
Message board for the users of flat assembler.

flat assembler > Windows > `HeapFree` error: the parameter is incorrect

Author
Thread Post new topic Reply to topic
Tabaci



Joined: 26 Apr 2018
Posts: 6
Location: Sweden
I am attempting to utilize the Windows heap by first creating the heap using `HeapCreate`, then allocating a string using `HeapAlloc`. The problem arises when I attempt to free that memory from the heap using `HeapFree`. I get back error code 87, which according to the Windows API states: The parameter is incorrect.

This is what I use to put a string on the heap:
Code:
; HeapCreate
push 0
push 0
push 0
call [HeapCreate]
mov [hHeap], eax ; Pointer to newly created heap
add esp, 12

; HeapAlloc
push 32 ; Allocate 32 bytes
push 0
push [hHeap]
call [HeapAlloc]
mov [namePtr], eax ; Pointer to the allocated memory block
add esp, 12

; Write name onto the heap at pointer location
push name    ; Write this
push sFormat ; %s
push namePtr ; into this "pointer"
call [wsprintf]
add esp, 12
    


This from my understanding allocates 32 bytes on the heap that we can use for some data. I am, as you can see, then using `wsprintf` to write the data onto that location on the heap (which happens to be a name).

For freeing memory, I thought it was as simple as the following:

Code:
; HeapFree
push [namePtr]  ; Pointer to free
push 0          ; No dwFlags
push [hHeap]    ; The heap handle
call [HeapFree]
add esp, 12
    


Is this not the parameters the `HeapFree` function is after? Did I somehow mess up the `[namePtr]` vs `namePtr` syntax and sending in data instead of a pointer? I tried every single combination of those brackets.

Here is my data section, in case you are wondering about the types of various things:

Code:
hHeap dd 0
sFormat db '%s', 0
namePtr dd 0h
dwError dd 0h
name db "Jeff Shawn", 0
s2 db "Hello, %s", 0
errorString db 0dh, 0ah, "Error freeing data, error code %d!", 0
    


The error string is how I am aware of the error code. Just after calling `HeapFree` I am checking the return value and jumping to an error clause accordingly. The error clause uses the `GetLastError` to check what the error was.

Any pointers in the right direction would be highly helpful! I would also love to be corrected on errors I have made in theory regarding my explanation on various things! Wink

Best regards,

_________________
My sandwich: it was reduced to dust, I tell you. It was pulverized!
Post 26 Apr 2018, 10:53
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 15905
Location: SDSS J140821.67+025733.2
I suspect your problem is that the stack is getting trashed. With only one (or two) exception(s) all of the Windows APIs are stdcall convention. That means you shouldn't put the "add esp,value" lines.
Post 26 Apr 2018, 11:02
View user's profile Send private message Visit poster's website Reply with quote
Tabaci



Joined: 26 Apr 2018
Posts: 6
Location: Sweden
Ah. I completely neglected that their API uses the stdcall convention.

Unfortunately in cleaning that up, the error still remains.

Does the `printf` function from `msvcrt` count towards the Windows API as well? I tried without the `add esp, x` there too, but the same error remains.

Just to be completely sure: I am not doing something I should not be doing as for the "checking to see if an error occurred", right?

Code:
; EAX contains the return value from the call to `HeapFree`

mov ecx, eax
mov edx, 0
cmp ecx, edx
jne _success

; Retrieve and print error message here

_success:

; It was successful, carry on execution!
    


As the API states: If the function succeeds, the return value is nonzero.
Post 26 Apr 2018, 12:32
View user's profile Send private message Reply with quote
Tabaci



Joined: 26 Apr 2018
Posts: 6
Location: Sweden
Oh wait, as for `printf`, it must be cdecl, as it is a varargs function. Ah!
Post 26 Apr 2018, 12:34
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 15905
Location: SDSS J140821.67+025733.2
The entire MSVCRT library is ccall. It is the C interface to the Windows API. It is not a part of the Windows API.

The only Windows API that is ccall is wsprintf. Or if you consider the A and W versions as separate then there are two APIs that are ccall, wsprintfA & wsprintfW.
Post 26 Apr 2018, 12:42
View user's profile Send private message Visit poster's website Reply with quote
Tabaci



Joined: 26 Apr 2018
Posts: 6
Location: Sweden
So I might have fixed it, but would love for someone to clarify that what I am doing is actually the way it was intended to be used.

Let me do a slight recap of the code mentioned in the first post. When I allocate memory onto the heap, I use `HeapAlloc`. This returns an address for that heap in EAX. I put the result of that into the memory address of `namePtr`.

In order to put a string on that location, what I was doing before was this:

Code:
; Write name onto the heap in pointer
push name    ; Write this
push sFormat ; %s
push namePtr ; to this pointer's location
call [wsprintf]
    


Now this code would theoretically write the string to the location where the location to the heap is stored, correct? Thus overwriting the pointer to the heap with a string. What I did instead:

Code:
; Write name onto the heap in pointer
push name    ; Write this
push sFormat ; %s
push [namePtr] ; to this pointer's location
call [wsprintf]
    


Now I am writing the string to the location of the heap allocated memory, right? Since the address of the heap is stored at the location `namePtr` points to. Then to access the char pointer for printing this, I would now instead need to use `[namePtr]`, as that would return the pointer to the first char stored at the heap.

It all appears to be working: no errors appear to be arising and the printing works fine! Very Happy
Post 26 Apr 2018, 13:22
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 15905
Location: SDSS J140821.67+025733.2
Tabaci wrote:
Now I am writing the string to the location of the heap allocated memory, right?
Yes.

It might also help to follow things through with a debugger. You will get a much better understanding of what is happening.
Post 26 Apr 2018, 13:26
View user's profile Send private message Visit poster's website Reply with quote
Tabaci



Joined: 26 Apr 2018
Posts: 6
Location: Sweden
Thank you for your pointers, rev.

I will make sure to get a debugger going: you're very much correct, I don't doubt for a moment it would help seeing what goes on in memory at all times, as well as the things that are in each and every single one of the registers. I guess my entry into FASM has been a slight bit compulsive as of yet! Wink
Post 26 Apr 2018, 13:51
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2018, Tomasz Grysztar.

Powered by rwasa.