flat assembler
Message board for the users of flat assembler.
Index
> Windows > `HeapFree` error: the parameter is incorrect |
Author |
|
Tabaci 26 Apr 2018, 10:53
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! Best regards, _________________ My sandwich: it was reduced to dust, I tell you. It was pulverized! |
|||
26 Apr 2018, 10:53 |
|
Tabaci 26 Apr 2018, 12:32
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. |
|||
26 Apr 2018, 12:32 |
|
Tabaci 26 Apr 2018, 12:34
Oh wait, as for `printf`, it must be cdecl, as it is a varargs function. Ah!
|
|||
26 Apr 2018, 12:34 |
|
revolution 26 Apr 2018, 12:42
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. |
|||
26 Apr 2018, 12:42 |
|
Tabaci 26 Apr 2018, 13:22
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! |
|||
26 Apr 2018, 13:22 |
|
revolution 26 Apr 2018, 13:26
Tabaci wrote: Now I am writing the string to the location of the heap allocated memory, right? It might also help to follow things through with a debugger. You will get a much better understanding of what is happening. |
|||
26 Apr 2018, 13:26 |
|
Tabaci 26 Apr 2018, 13:51
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! |
|||
26 Apr 2018, 13:51 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.