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: 156
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: 15982
Location: Qo'noS
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: 156
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: 15982
Location: Qo'noS
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: 156
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: 15982
Location: Qo'noS
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: 1227
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: 156
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: 1227
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: 156
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: 1251
Location: Underwater
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: 156
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: 156
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: 15982
Location: Qo'noS
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: 156
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: 1227
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: 156
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: 1227
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: 156
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 © 1999-2018, Tomasz Grysztar.

Powered by rwasa.