flat assembler
Message board for the users of flat assembler.

Index > Windows > Create a copy of a struct using HeapAlloc

Author
Thread Post new topic Reply to topic
MUFOS



Joined: 17 Apr 2016
Posts: 47
MUFOS 17 Apr 2016, 12:02
Basically, I have a struct along the lines of:
struct Something
SomeValue1 dd 0
SomeValue2 dd 0
ends

How would I go on about creating an instance of this at runtime using HeapAlloc?

I am quite new to assembly. Thanks for the help.
Post 17 Apr 2016, 12:02
View user's profile Send private message Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1670
Location: Toronto, Canada
AsmGuru62 17 Apr 2016, 13:57
Something like this:
Code:
    ;
    ; ESI = pointer to original 'Something'
    ;
    invoke    GetProcessHeap
    invoke    HeapAlloc, eax, 0, sizeof.Something
    ;
    ; Check if memory was actually allocated
    ;
    test      eax, eax
    jz        .insufficient_memory
    ;
    ; Copy original structure into allocated block
    ;
    mov       edi, eax
    mov       ecx, sizeof.Something
    ;
    ; You can optimize here if you're sure that
    ; structure size is aligned to 4 bytes
    ;
    ;shr       ecx, 2   or you can even replace it with (mov ecx, sizeof.Something shr 2)
    ;rep       movsd
    ;
    rep       movsb
    ;
    ; EAX = pointer to a copy of the original structure
    ;
    
Post 17 Apr 2016, 13:57
View user's profile Send private message Send e-mail Reply with quote
MUFOS



Joined: 17 Apr 2016
Posts: 47
MUFOS 17 Apr 2016, 17:43
AsmGuru62 wrote:
Something like this:
Code:
    ;
    ; ESI = pointer to original 'Something'
    ;
    invoke    GetProcessHeap
    invoke    HeapAlloc, eax, 0, sizeof.Something
    ;
    ; Check if memory was actually allocated
    ;
    test      eax, eax
    jz        .insufficient_memory
    ;
    ; Copy original structure into allocated block
    ;
    mov       edi, eax
    mov       ecx, sizeof.Something
    ;
    ; You can optimize here if you're sure that
    ; structure size is aligned to 4 bytes
    ;
    ;shr       ecx, 2   or you can even replace it with (mov ecx, sizeof.Something shr 2)
    ;rep       movsd
    ;
    rep       movsb
    ;
    ; EAX = pointer to a copy of the original structure
    ;
    


Thank you so much! .... Sincerely Smile
Accomplishing this simple task, in FASM, feels so rewarding to me. Again, I am new to assembly, but the source you provided was easy to understand, and it helped me a lot. Thanks!
Post 17 Apr 2016, 17:43
View user's profile Send private message Reply with quote
MUFOS



Joined: 17 Apr 2016
Posts: 47
MUFOS 18 Apr 2016, 11:05
One more question. How would I implement functions with structures?
Is it possible to define a function (label) directly inside of the struct, and how would I call it by the instance? Once again, thanks in advance.
Post 18 Apr 2016, 11:05
View user's profile Send private message Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1670
Location: Toronto, Canada
AsmGuru62 18 Apr 2016, 15:37
Try this:
Code:
format  PE GUI 4.0
entry   start
stack   4000h, 4000h

include 'Win32A.Inc'
;
; Define the structure with function pointers
;
struct CObject
    func_1 dd ?
    func_2 dd ?
    func_3 dd ?
ends

; ---------------------------------------------------------------------------
section '.data' data readable writeable
;
; Declare a structure named 'glb_VTable' of type 'CObject' and
; initialize the members with labels to functions to be called.
;
glb_VTable  CObject  method1, method2, method3
; ---------------------------------------------------------------------------
lpCaption   db 'Function called by a structure member.',0
lpText1     db 'Calling METHOD1 ...',0
lpText2     db 'Calling METHOD2 ...',0
lpText3     db 'Calling METHOD3 ...',0

; ---------------------------------------------------------------------------
section '.code' code readable executable

align 16
method1:
    invoke    MessageBox, 0, lpText1, lpCaption, MB_ICONINFORMATION
    ret

align 16
method2:
    invoke    MessageBox, 0, lpText2, lpCaption, MB_ICONINFORMATION
    ret

align 16
method3:
    invoke    MessageBox, 0, lpText3, lpCaption, MB_ICONINFORMATION
    ret

; ---------------------------------------------------------------------------
; PROGRAM ENTRY POINT
; ---------------------------------------------------------------------------
align 32
start:
    ;
    ; Load structure address into EBX
    ;
    mov       ebx, glb_VTable
    ;
    ; Call functions defined within a structure
    ;
    call      [ebx + CObject.func_3]
    call      [ebx + CObject.func_2]
    call      [ebx + CObject.func_1]
    ;
    ; Of course, these functions have no parameters.
    ; If you need to use parameters, then you can pass parameters
    ; in registers and still use same CALL instruction as above.
    ; However, if you decide to PUSH values on stack, then you need
    ; to use 'stdcall' macro to call the function. Also, you need
    ; to use a proper function definition - not just a label, like I did here,
    ; but a 'proc'/'endp' macros - see the FASM manual for more details.
    ;
    invoke    ExitProcess, 0

; ---------------------------------------------------------------------------
section '.idata' import data readable writeable

    library kernel32,'KERNEL32.DLL',user32,'USER32.DLL',gdi32,'GDI32.DLL'

    include 'API\Kernel32.Inc'
    include 'API\User32.Inc'
    include 'API\Gdi32.Inc'
    
Post 18 Apr 2016, 15:37
View user's profile Send private message Send e-mail Reply with quote
MUFOS



Joined: 17 Apr 2016
Posts: 47
MUFOS 18 Apr 2016, 17:25
AsmGuru62 wrote:
Try this:
Code:
format  PE GUI 4.0
entry   start
stack   4000h, 4000h

include 'Win32A.Inc'
;
; Define the structure with function pointers
;
struct CObject
    func_1 dd ?
    func_2 dd ?
    func_3 dd ?
ends

; ---------------------------------------------------------------------------
section '.data' data readable writeable
;
; Declare a structure named 'glb_VTable' of type 'CObject' and
; initialize the members with labels to functions to be called.
;
glb_VTable  CObject  method1, method2, method3
; ---------------------------------------------------------------------------
lpCaption   db 'Function called by a structure member.',0
lpText1     db 'Calling METHOD1 ...',0
lpText2     db 'Calling METHOD2 ...',0
lpText3     db 'Calling METHOD3 ...',0

; ---------------------------------------------------------------------------
section '.code' code readable executable

align 16
method1:
    invoke    MessageBox, 0, lpText1, lpCaption, MB_ICONINFORMATION
    ret

align 16
method2:
    invoke    MessageBox, 0, lpText2, lpCaption, MB_ICONINFORMATION
    ret

align 16
method3:
    invoke    MessageBox, 0, lpText3, lpCaption, MB_ICONINFORMATION
    ret

; ---------------------------------------------------------------------------
; PROGRAM ENTRY POINT
; ---------------------------------------------------------------------------
align 32
start:
    ;
    ; Load structure address into EBX
    ;
    mov       ebx, glb_VTable
    ;
    ; Call functions defined within a structure
    ;
    call      [ebx + CObject.func_3]
    call      [ebx + CObject.func_2]
    call      [ebx + CObject.func_1]
    ;
    ; Of course, these functions have no parameters.
    ; If you need to use parameters, then you can pass parameters
    ; in registers and still use same CALL instruction as above.
    ; However, if you decide to PUSH values on stack, then you need
    ; to use 'stdcall' macro to call the function. Also, you need
    ; to use a proper function definition - not just a label, like I did here,
    ; but a 'proc'/'endp' macros - see the FASM manual for more details.
    ;
    invoke    ExitProcess, 0

; ---------------------------------------------------------------------------
section '.idata' import data readable writeable

    library kernel32,'KERNEL32.DLL',user32,'USER32.DLL',gdi32,'GDI32.DLL'

    include 'API\Kernel32.Inc'
    include 'API\User32.Inc'
    include 'API\Gdi32.Inc'
    


Wow this board is full of awesome people! Very Happy

Thanks!
Post 18 Apr 2016, 17:25
View user's profile Send private message Reply with quote
MUFOS



Joined: 17 Apr 2016
Posts: 47
MUFOS 20 Apr 2016, 08:53
I have another question,,, again Razz
I am wondering how I can go on about structures declared inside of the structure that I create an instance of. When I try do do
:
Code:
 mov eax, [ebx + Something.SomeOtherStruct]     
(where ebx is the original instance of the struct), it turns eax to 0.
Post 20 Apr 2016, 08:53
View user's profile Send private message Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1670
Location: Toronto, Canada
AsmGuru62 20 Apr 2016, 15:06
Can I see the declaration for both 'Something' and 'SomeOtherStruct'?
Is 'SomeOtherStruct' a pointer or whole structure instance?
Post 20 Apr 2016, 15:06
View user's profile Send private message Send e-mail Reply with quote
MUFOS



Joined: 17 Apr 2016
Posts: 47
MUFOS 20 Apr 2016, 15:58
AsmGuru62 wrote:
Can I see the declaration for both 'Something' and 'SomeOtherStruct'?
Is 'SomeOtherStruct' a pointer or whole structure instance?


A whole structure instance.

Code:

struct SomeStruct
        SomeOtherValue1 dd 0
        SomeOtherValue2 dd 0
ends

struct Something
        SomeValue1 dd 0
        SomeValue2 dd 0
        SomeStruct1 SomeStruct
ends

    


I first declare a variable of Something. e.g.:
SomethingInstance Something

Then I am making the copy that I am going to use using the solution above.

Now I want to access the substruct of the copy and change the values.
Post 20 Apr 2016, 15:58
View user's profile Send private message Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1670
Location: Toronto, Canada
AsmGuru62 21 Apr 2016, 15:10
I think these will work:
Code:
    ;
    ; If EBX is a pointer to 'Something'
    ;
    mov       eax, [ebx + Something.SomeStruct1.SomeOtherValue2]
    ;
    ; Point ESI to the instance inside and then load the value
    ;
    lea       esi, [ebx + Something.SomeStruct1]
    mov       edx, [esi + SomeStruct.SomeOtherValue2]
    
Post 21 Apr 2016, 15:10
View user's profile Send private message Send e-mail Reply with quote
badc0de02



Joined: 25 Nov 2013
Posts: 215
Location: %x
badc0de02 21 Apr 2016, 16:44
it will get more complicated to clone a struct if there are pointers to another variable/struct in it
Post 21 Apr 2016, 16:44
View user's profile Send private message Reply with quote
MUFOS



Joined: 17 Apr 2016
Posts: 47
MUFOS 21 Apr 2016, 17:05
badc0de02 wrote:
it will get more complicated to clone a struct if there are pointers to another variable/struct in it


I guess I should just create a new instance, and instead define a dword for the struct value.

But then again I have a question; how do I access those variables?

Do I use
Code:
mov ebx, [ebx + Something.SomeStruct]    

Then proceed to:
Code:
call [ebx + SomeStruct.SomeFunction]    


or what do I do?
Post 21 Apr 2016, 17:05
View user's profile Send private message Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1670
Location: Toronto, Canada
AsmGuru62 21 Apr 2016, 17:14
Just use a debugger: see where this CALL goes.
If debugger will bring you to your function then code is working correctly.
Post 21 Apr 2016, 17:14
View user's profile Send private message Send e-mail Reply with quote
MUFOS



Joined: 17 Apr 2016
Posts: 47
MUFOS 22 Apr 2016, 13:44
I will! And one more thing; is it possible to create instances of structs without declaring a "starting instance" as done above?
Post 22 Apr 2016, 13:44
View user's profile Send private message Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1670
Location: Toronto, Canada
AsmGuru62 22 Apr 2016, 14:52
I am not clear on your question.
The only other way, other than declaring, is doing dynamic memory allocation, but we've done it already with HeapAlloc.
Post 22 Apr 2016, 14:52
View user's profile Send private message Send e-mail Reply with quote
MUFOS



Joined: 17 Apr 2016
Posts: 47
MUFOS 22 Apr 2016, 20:41
AsmGuru62 wrote:
I am not clear on your question.
The only other way, other than declaring, is doing dynamic memory allocation, but we've done it already with HeapAlloc.


Would allocating memory using HeapAlloc with the size of the struct be the same as creating a struct using the following definition:

Code:
DeclaredStruct SomeStruct    
Post 22 Apr 2016, 20:41
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-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.