Assembly pass pointer to function

后端 未结 2 404
失恋的感觉
失恋的感觉 2021-01-21 12:57

I\'m trying to sent DWORD variable into function as pointer paramater

variable1 dd 1
...
push [variable1]  ; push variable adress
call _InitPoiner
...
_InitPoine         


        
相关标签:
2条回答
  • 2021-01-21 13:24

    The main problem is that you are not pushing the address of variable1 onto the stack when you do push [variable1]. That pushes the 32-bit value stored at variable1 which happens to be the value of 1. To push the address you would use push variable1 without the brackets.

    When pushing values onto the stack before a call you need to restore the stack after the call.

    LEA wasn't getting the address stored on the stack but getting the address of the stack location where the address should have been stored. I think you were looking for something like:

    format ELF
    
    extrn printf
    public main
    
    section '.text' executable
    main:
        push variable1         ; push address of variable
        call _InitPointer
        add esp, 4             ; We pushed 4 bytes before calling function
                               ; restore the stack by adding 4
    
        push [variable1]       ; Push the value at address variable1
        push sdigit            ; Format specifier for printf
        call printf
        add esp, 8             ; We pushed 8 bytes of data for call
                               ; restore the stack by adding 8
        ret
    
    _InitPointer:
        push ebp
        mov ebp, esp
    
        mov eax, [ebp+8]       ; There is an address at [ebp+8] that
                               ; was pushed as the 1st parameter. Put the
                               ; address in EAX
    
        add dword [eax], 10    ; Add the value 10 to the DWORD value that is at
                               ; address in EAX
    
        pop ebp
        ret
    
    section '.data' writeable
    variable1 dd 1
    sdigit db '%d', 0x0D, 0x0A, 0
    

    You didn't mention the platform you are on as you didn't supply a minimal complete verifiable example. The code above could be tested on Linux with:

    fasm test.asm
    gcc -o test -m32 test.o
    

    When run you should get:

    11

    The equivalent C code would look like:

    #include <stdio.h>
    
    void _InitPointer (int *ptr)
    {
        *ptr += 10;
        return;
    }
    
    int variable1 = 1;
    
    int main()
    {
        _InitPointer (&variable1);
        printf ("%d\n", variable1);
        return 0;
    }
    

    Note: If on modern versions of Linux, 32-bit programs follow System V i386 ABI that requires the stack be 16-byte (or 32-byte) aligned at the point of a function call. I didn't do that in the code above to keep it simplified but it should be taken into account. I'm unsure if you are on Linux or Windows. Your question doesn't say.


    32-bit Windows Version

    format PE console 4.0
    include 'win32a.inc'
    
    main:
        push variable1         ; push address of variable
        call _InitPointer
        add esp, 4             ; We pushed 4 bytes before calling function
                               ; restore the stack by adding 4
    
        push [variable1]       ; Push the value at address variable1
        push sdigit            ; Format specifier for printf
        call [printf]
        add esp, 8             ; We pushed 8 bytes of data for call
                               ; restore the stack by adding 8
        push 0                 ; Exit with return value 0
        call [ExitProcess]
    
    _InitPointer:
        push ebp
        mov ebp, esp
    
        mov eax, [ebp+8]       ; There is an address at [ebp+8] that
                               ; was pushed as the 1st parameter. Put the
                               ; address in EAX
    
        add dword [eax], 10    ; Add the value 10 to the DWORD value that is at
                               ; address in EAX
    
        pop ebp
        ret
    
    variable1 dd 1
    sdigit db '%d', 0x0D, 0x0A, 0
    
    data import
     library kernel32,'KERNEL32.DLL',\
             msvcrt,'MSVCRT.DLL'
     import msvcrt,\
            printf ,'printf'
     import kernel32,\
            ExitProcess,'ExitProcess'
    end data
    
    0 讨论(0)
  • 2021-01-21 13:27

    You are making sure that you pop your vars when done?

    Looking at your example, I see no way that the variable could ever be 11. It starts as 1 at the dd assignment, then if your math in the lea is correct, it would then be 10. If you were to step this through a debugger, you could check if your lea / mov combo is working right. Either way, I would expect 1 or 10, not 11.

    Maybe you meant to add instead of mov?

    0 讨论(0)
提交回复
热议问题