flat assembler
Message board for the users of flat assembler.

flat assembler > Main > How to use malloc?

Author
Thread Post new topic Reply to topic
Mino



Joined: 14 Jan 2018
Posts: 133
Hello,
I would like to use malloc (and free) to dynamically allocate space on the stack. I could understand that malloc was moving the address of the allocated memory range into a register. Under x86-64, this register is RAX. Only, it does not exist in FASM. But that's not all I don't understand... How will this be converted for example:
Code:
#include <stdio.h> #include <stdlib.h> void foo() { int *array; int n = 2; array = (int *)malloc(n); array[0] = 4; array[1] = 6; int add = array[0] + array[1]; free(array); }

As much as I understand the dynamic allocation in C, as much I have trouble following in assembler...
Does anyone have anything to propose? Or an explanation that will make me understand a good use of malloc in FASM?
I also found something:
Code:
cinvoke malloc, SizeToAllocate

But I don't understand what it feels like. Allocate directly on the heap? How to use it ?
I thank you!

_________________
The best way to predict the future is to invent it.
Post 21 Jun 2018, 08:01
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 15871
Location: 162173 Ryugu
malloc is a C library function, it is not part of fasm or the CPU. You will need to link your code with the C library to get access to malloc. The C malloc can allocate memory in any way it chooses, probably on the heap, but maybe using virtual memory on some OSes.

All memory allocation functions are OS dependant. You have to know your OS to know how to allocate memory.
Post 21 Jun 2018, 09:42
View user's profile Send private message Visit poster's website Reply with quote
Mino



Joined: 14 Jan 2018
Posts: 133
Okay, thanks, I got a better idea where to go.
However, how does this code can be well compiled? What does he do (I speak about last malloc code I posted)?
Do FASM libraries have a macro or a memory allocation process?
Post 21 Jun 2018, 10:09
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 15871
Location: 162173 Ryugu
Mino wrote:
Do FASM libraries have a macro or a memory allocation process?
fasm doesn't have any libraries. You will need to use the OS APIs to get memory.

You can also use "malloc" from MSVCRT if you use Windows, just link to MSVCRT.DLL and let the C library do the OS interfacing.
Post 21 Jun 2018, 10:54
View user's profile Send private message Visit poster's website Reply with quote
Mino



Joined: 14 Jan 2018
Posts: 133
Okay, thanks Smile
So, if we take the example C I gave above, how could we convert it into FASM, and therefore call malloc from MSVCRT, as previously shown?
What I have more trouble understanding is not really how to call malloc, but rather how to use the allocated memory. What is returned from malloc ? (it is of the void type, but it "returns" the address of an allocated memory range isn't it ?)

_________________
The best way to predict the future is to invent it.
Post 21 Jun 2018, 11:35
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 15871
Location: 162173 Ryugu
Mino wrote:
So, if we take the example C I gave above, how could we convert it into FASM, and therefore call malloc from MSVCRT, as previously shown?
Code:
cinvoke malloc, SizeToAllocate ]
Mino wrote:
What I have more trouble understanding is not really how to call malloc, but rather how to use the allocated memory. What is returned from malloc ? (it is of the void type, but it "returns" the address of an allocated memory range isn't it ?)
It returns the address of the first byte of the memory that was allocated. Unless the return value is zero which means it failed for some reason.

And later you should call the function to release the memory when you have finished with it.
Code:
cinvoke malloc, SizeToAllocate test eax,eax jz failed mov byte[eax],0xfe ;the first byte of the allocated memory ;...
Post 21 Jun 2018, 12:13
View user's profile Send private message Visit poster's website Reply with quote
Furs



Joined: 04 Mar 2016
Posts: 1172
Mino wrote:
Okay, thanks Smile
So, if we take the example C I gave above, how could we convert it into FASM, and therefore call malloc from MSVCRT, as previously shown?
What I have more trouble understanding is not really how to call malloc, but rather how to use the allocated memory. What is returned from malloc ? (it is of the void type, but it "returns" the address of an allocated memory range isn't it ?)
Think of the hex editor again.

What it "returns" is the beginning of a "hex editor region", its size (in bytes) is given by what you sent to malloc as its parameter (n in your C code). So since it returns in eax, then byte [eax+0] will access the first byte, etc.

You can access bytes beyond or before it but that's dangerous (buffer underflow/overflow) and you don't know what memory lives there, might cause a crash, or silent corruption.

e.g. [eax-1] is bad, and so is [eax+n] because [eax+n-1] is the last byte you should access (it starts from 0).

Note that dword [eax+n-1] is also bad since you access a dword (4 bytes), so even though the address itself accesses the last byte, there's 3 more bytes you access beyond your allocated buffer, like:
Code:
this is what you access (01 23 45 are beyond the allocated buffer, might crash) || ___||___ / \ AB CD EF 01 23 45 ^ this is last byte at [eax+n-1]


Last edited by Furs on 21 Jun 2018, 12:28; edited 1 time in total
Post 21 Jun 2018, 12:25
View user's profile Send private message Reply with quote
Mino



Joined: 14 Jan 2018
Posts: 133
Thanks a lot, I understand better now Very Happy !
Post 21 Jun 2018, 12:26
View user's profile Send private message Reply with quote
Furs



Joined: 04 Mar 2016
Posts: 1172
I EDITEd with a crude ASCII diagram, see if it helps Wink
Post 21 Jun 2018, 12:29
View user's profile Send private message Reply with quote
Mino



Joined: 14 Jan 2018
Posts: 133
Thanks from you Wink
Post 21 Jun 2018, 12:41
View user's profile Send private message Reply with quote
Picnic



Joined: 05 May 2007
Posts: 1240
Location: Icarian Sea
Hi Mino,
Here is a hint that may be useful for you later.

Keep in mind that a call to a Windows function destroys eax ecx edx values.

Code:
cinvoke malloc, 256 test eax, eax jz failed ; eax = pointer to memory


Code:
cinvoke strcpy, eax, "some text" cinvoke free, eax ; this happens to work because strcpy returns a pointer to the beginning ot data, which is the same as the memory pointer allocated test eax, eax jz failed


Code:
cinvoke strcpy, eax, "some text" cinvoke printf, "%s", eax cinvoke free, eax ; this will fail because printf has clobbered eax value test eax, eax jz failed


So save the pointer before the call.
Code:
cinvoke strcpy, eax, "some text" push eax cinvoke printf, "%s", eax pop eax cinvoke free, eax


Always check the return values. MSDN will be your guide.
Have fun.
Post 21 Jun 2018, 12:56
View user's profile Send private message Reply with quote
Mino



Joined: 14 Jan 2018
Posts: 133
Thank you very much, it will indeed be very useful Smile It is useful to know that the contents of eax, ecx and edx are destroyed after a Windows function call, this explains some little things I did not understand.
I'll check on MSDN and feature calls, thanks again Very Happy
Post 21 Jun 2018, 14:32
View user's profile Send private message Reply with quote
Mino



Joined: 14 Jan 2018
Posts: 133
Hello,
I have some problems with the use of malloc. Initially, everything was fine (at least, it seems to me), but now I'm trying to recover one of the values ​​of the space allocated in memory, but I can not do it. Here is my code:
Code:
main: push ebp mov ebp, esp mov DWORD [ebp-4], edi mov DWORD [ebp-8], esi cinvoke malloc, 50 test eax, eax jz _excpt_MallocFailure ; A label that exit if eax = 0 mov DWORD [ebp-12], eax mov eax, DWORD [ebp-12] add eax, 0 mov DWORD eax, GVUN0 mov eax, DWORD [ebp-12] add eax, 4 mov DWORD eax, GVUN1 sub eax, 4 cinvoke puts, eax mov eax, DWORD [ebp-12] cinvoke free, eax mov esp, ebp pop ebp call _StopProgram ; A label to stop the program ret

Whenever we want to add a value in the allocated space, we write this is not it:
Code:
... mov eax, DWORD CurrentStackAdresse add eax, SizeOfTheValue mov DWORD eax, value ...

So I thought of doing the "opposite way" to access an older value, because as you can see, I add 2 values. Here's what I did:
Code:
sub eax, SizeOfSumOfAllValue+SizeOfValue

What makes me get this:
Code:
sub eax, 4

So I come back to [eax+0]
But, obviously, that does not work. Nothing is displayed in the console. If, on the other hand, the value to be displayed is the address of the last value added ("eax" without anything), the value is displayed in the console.
At first, I thought to store eax in another register, then performed the same operations as mentioned above. Something like this:
Code:
mov ecx, eax sub ecx, 4 cinvoke puts, ecx

I have not had the opportunity to test this, so I'll leave it to your advice in the meantime.

Thank you Very Happy !
Post 26 Jun 2018, 15:48
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 15871
Location: 162173 Ryugu
You haven't allocated space on the stack after "mov ebp,esp". You need to subtract some value from esp:
Code:
mov ebp,esp sub esp,0x20 ;reserve space for your data
Post 26 Jun 2018, 22:28
View user's profile Send private message Visit poster's website Reply with quote
Mino



Joined: 14 Jan 2018
Posts: 133
Thank you for your answer Smile
And so, this line should be put before malloc?
Is this the value that represents the allocated space?
Could I have an example please Smile
Post 27 Jun 2018, 14:47
View user's profile Send private message Reply with quote
Furs



Joined: 04 Mar 2016
Posts: 1172
Mino wrote:
Thank you for your answer Smile
And so, this line should be put before malloc?
Is this the value that represents the allocated space?
Could I have an example please Smile
You don't understand the stack itself.

What you said previously "CurrentStackAdresse" is just simply esp (the register). That's the point of that register, it holds the current stack address. ebp is usually used to point to the "top" of the stack for this function (so-called a "frame pointer") but you can also just use esp directly to address stuff on the stack.

Point is that you don't know the address of the stack, since you don't know where your function got called or how deep it is called, that's the *whole* point of the stack. It's not a "fixed" address: all of it is relative to esp.

For example, imagine this is the stack (remember that the stack grows downwards, so it's like going "back" in our hex editor):
Code:
xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx 00 00 00 00 ^ esp points here before your function (at the zeros)
Please note that the x values should be considered INVALID and INACCESSIBLE since they're "below" esp. In other words, don't touch them unless you subtract esp first.

Now you need some stack "space" for malloc's parameters or whatever, or local variables. If you do a push, this is what happens:
Code:
push 42 xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx 2A 00 00 00 00 00 00 00 ^ esp got subtracted and the value 42 (0x2A in hex) was placed here
We still have x but since push first subtracted esp, it's fine to have 4 more bytes of data. That's what push does.

You can also make further room by subtracting from esp (the ? means unknown data, don't rely on it):
Code:
push 42 sub esp, 8 xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx ?? ?? ?? ?? ?? ?? ?? ?? 2A 00 00 00 00 00 00 00 ^ esp got subtracted by 8, now these values are valid but UNKNOWN now assign something to them (e.g. mov dword [esp], 0xABCDEF01)
Where is ebp? Well, you clearly just did mov ebp, esp so ebp was whatever value esp had.

If you did mov ebp, esp before the push 42, it will be like this:
Code:
mov ebp, esp push 42 sub esp, 8 xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx ?? ?? ?? ?? ?? ?? ?? ?? 2A 00 00 00 00 00 00 00 ^ ^ esp is here ebp is here
So if you do [ebp-12] you access the value at [esp] and if you do [ebp-8] you access the value at [esp+4]. So when we have this code:
Code:
mov ebp, esp push 42 sub esp, 8 mov dword [ebp-8], 0xAAAAAAAA mov dword [esp], 0xCCCCCCCC xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx CC CC CC CC AA AA AA AA 2A 00 00 00 00 00 00 00 ^ ^ esp is here ebp is here
The stack is just a memory region that grows downwards ("left" and "up" in hex editors). The pointer to that memory region is esp. You can derive pointers from it, like ebp, but try to understand how it works instead of learning by rote. It's not magic or anything complicated.

malloc is similar, in that it gives you a region of memory (but returns it in eax, you can of course save its address in another register or a memory location, but it grows up, so what it gives you is the minimum of the address).
Post 27 Jun 2018, 15:29
View user's profile Send private message Reply with quote
Mino



Joined: 14 Jan 2018
Posts: 133
Thanks for your help, I think I understood better now Smile
It is true that I sometimes have some difficulty understanding how the stack works, and I have the impression that malloc makes this even more abstract for me.
So I'll try to get a better understanding the stack before I go on. Do you know of a good resource in relation to that?
Thanks for everything!
Post 29 Jun 2018, 12:15
View user's profile Send private message Reply with quote
Furs



Joined: 04 Mar 2016
Posts: 1172
Uhm sorry no, I learned it with generic asm books (Art of Assembly Language, it's pretty old and doesn't deal with this specifically)... prior to that, pointers were a nightmare due to just how bad most C/C++ books are and the idiot teachers trying to abstract shit away (and they think it's a good thing).

Now I can easily visualize/imagine properly even pointers deep to any level, like 6 levels and so on, thanks to asm (even in C code).
Post 30 Jun 2018, 14:39
View user's profile Send private message Reply with quote
Mino



Joined: 14 Jan 2018
Posts: 133
Okay, that's all right.
I imagine that this is acquired mainly with experience Wink

_________________
The best way to predict the future is to invent it.
Post 30 Jun 2018, 16:42
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 © 2004-2018, Tomasz Grysztar.

Powered by rwasa.