Author Topic: Write a string to an adress  (Read 12695 times)

Offline isywum

  • Jr. Member
  • *
  • Posts: 38
Write a string to an adress
« on: July 01, 2012, 05:36:06 PM »
Hi,
I was writing a function that does something with an userdefined string. I do not know how I can transfer the paramter. I can't just push it. I checked up how this problem is solved in C. C just writes the string to an adress and transfers the pointer (char*). So I tried to write the string to an adress thereabout:
Code: [Select]
mov [0x14000], "That's an example."
Of course it does not work. Do you have any suggests to solve that problem?

Offline TightCoderEx

  • Full Member
  • **
  • Posts: 103
Re: Write a string to an adress
« Reply #1 on: July 01, 2012, 06:58:52 PM »
There are a few different ways to do this, but here is one example
Code: [Select]
String         db      'Thats an example.', 0

        push    String
        call      Function

Function:
        push    ebp
        mov     ebp, esp
        mov     edi, [rbp+8]     Now edi = pointer to String
        .... You code
        leave
        ret
Quite a bit is missing from this example, but it's analogous to:
void Function (char *String);

Offline isywum

  • Jr. Member
  • *
  • Posts: 38
Re: Write a string to an adress
« Reply #2 on: July 01, 2012, 07:38:14 PM »
Thanks.
Just a question:
Did you mean 'rbp' or 'ebp'?

Offline TightCoderEx

  • Full Member
  • **
  • Posts: 103
Re: Write a string to an adress
« Reply #3 on: July 01, 2012, 08:44:57 PM »
Did you mean 'rbp' or 'ebp'?

Yes, ebp. I usually work in 64 bit.

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Write a string to an adress
« Reply #4 on: July 01, 2012, 09:28:14 PM »
I thought "push reg32" was invalid in 64-bit code? I'm confused! (what else is new?)

In any case, Isywum, you generally want to pass the address of the string as a parameter - 32-bit or 64-bit... 16-bit if we want to go back to the dark ages. You could subtract "enough" from esp/rsp and copy the actual string onto the stack, but it is not usually useful...

Best,
Frank


Offline TightCoderEx

  • Full Member
  • **
  • Posts: 103
Re: Write a string to an adress
« Reply #5 on: July 01, 2012, 10:24:11 PM »
I thought "push reg32" was invalid in 64-bit code?

Yes it is, but to excuse it by saying I usually work in 64 bit was just another way of saying I wasn't paying attention  :'(

32 bit cdecl
Code: [Select]
        push      String
        call      Function
        add      esp, 4

Function:
        push    ebp
        mov     ebp, esp
        mov     edi, [rbp+8]     Now edi = pointer to String
        .... You code
        leave
        ret

32 bit stdcall
Code: [Select]
        push      String
        call      Function

Function:
        push    ebp
        mov     ebp, esp
        mov     edi, [rbp+8]     Now edi = pointer to String
        .... You code
        leave
        ret     4

64 bit  using EDI is not an error.  32 bit registers are sign extended to 64 and I know, or at least on my system all segments except stack are below 32 bit boundary.
Code: [Select]
        mov    edi, String
        call      Function

Function:
         .... You code  and RDI points to string
        ret

Hopefully this doesn't thoroughly confuse the issue isywum, but in principal these are equivalent. The thing to remember is, the arguments you pass to procedure start @ word width * 2. above base pointer being either RBP or EBP.  As Frank pointed out IF you are working in 16 bit then remove "E"'s and in the first two examples, 4's are replace with 2's

NOTE: When asking a question, it is always a good idea to qualify which platform you're working in and how many bits.  This gives us the opportunity to narrow the answer exactly to your criteria.
« Last Edit: July 01, 2012, 10:29:04 PM by TightCoderEx »

Offline isywum

  • Jr. Member
  • *
  • Posts: 38
Re: Write a string to an adress
« Reply #6 on: July 02, 2012, 12:21:35 PM »
Thank you. This helps me but is it also possible to write the string to an user-defined address?
EDIT:
I use Bits 32.
« Last Edit: July 02, 2012, 12:52:08 PM by isywum »

Offline Arq

  • Jr. Member
  • *
  • Posts: 9
Re: Write a string to an adress
« Reply #7 on: July 02, 2012, 01:14:30 PM »
Thank you. This helps me but is it also possible to write the string to an user-defined address?

Here again it's important than you specify your platform target since the best practice in this case is reserving dinamic memory(if user input the string, how long will be?) then is the operating system who decides where alloc memory through api call GlobalAlloc,LocalAlloc wrappers of HeapAlloc / VirtualAlloc on windows, brk system function under unix-like, etc. This functions return a pointer to the allocated memory so you can now pass it to your function and write the string.

Code: [Select]
(Alloc memory)
push    String
push eax ;pointer to memory
call      Function


Function:
        push    ebp
        mov     ebp, esp
        mov     esi, [ebp+8]     ;Now esi = pointer to String
mov     edi, [ebp+c]     ;Now edi = pointer to Memory
cld
rep movsb ; copy string
        .... You code
        leave
        ret

remember to free the reserved memory after done.

Answering your question yes it can be achieved but would be impractical after all the user doesnt mind where is the string in memory

Regards.
« Last Edit: July 02, 2012, 01:17:33 PM by Arq »

Offline isywum

  • Jr. Member
  • *
  • Posts: 38
Re: Write a string to an adress
« Reply #8 on: July 02, 2012, 01:21:00 PM »
I forgot to tell you ... I write a little OS myself. So it is important ...

Offline TightCoderEx

  • Full Member
  • **
  • Posts: 103
Re: Write a string to an adress
« Reply #9 on: July 02, 2012, 03:34:14 PM »
I write a little OS myself. So it is important ...

Essentially no, as what we are talking about here is a method by which memory is addressed and/or its contents.  So to move a byte from a memory location to AL is the same no matter the system so long as it's using the same processor and not only that, but there are usually several different ways of doing it.

Here's an example in pure binary format
Code: [Select]
     1                                  [BITS 32]
     2                                 
     3 00000000 A0[0D000000]            mov al, [Msg]           AL = 54H
     4                                 
     5 00000005 BE[0D000000]            mov esi, Msg             ESI = 000DH
     6 0000000A 8A06                    mov al, [esi]           AL = 54H again
     7                                 
     8 0000000C AC                      lodsb                        AL = 54H, but ESI = 000EH
     9                                 
    10 0000000D 546861747320616E20-     Msg db 'Thats an example'
    11 00000016 6578616D706C65     
What will probably be a lot of help to you is to study all the commonly used opcodes by tracing through a program you understand and watch what's happening through GDB, OLLYDBG etc.

Here's the exact same thing, with stuff moved around a little
Code: [Select]
     1                                  [BITS 32]
     2                                 
     3 00000000 A0[07000000]            mov al, [Msg]
     4 00000005 EB10                    jmp Do
     5                                 
     6 00000007 546861747320616E20-     Msg db 'Thats an example'
     7 00000010 6578616D706C65     
     8                                 
     9                                  Do:
    10 00000017 BE[07000000]            mov esi, Msg
    11 0000001C 8A06                    mov al, [esi]
    12                                 
    13 0000001E AC                      lodsb

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Write a string to an adress
« Reply #10 on: July 02, 2012, 08:30:00 PM »
Is this what you're trying to do? (approximately)
Code: [Select]
; nasm -f elf isy.asm
; ld -o isy isy.o

global _start

section .data
string db "A user defined string" ; 21 bytes
string_size equ $ - string

section .text
_start:
    nop
    mov eax, [string]
    mov [0x8049500], eax ; a "known" good address
    mov eax, [string + 4]
    mov [0x8049504], eax
    mov eax, [string + 8]
    mov [0x8049508], eax
    mov eax, [string + 12]
    mov [0x804950C], eax
    mov eax, [string + 16]
    mov [0x8049510], eax
    mov al, [string + 20]
    mov [0x8049514], al
; did it work?   
    mov edx, string_size
    mov ecx, 0x8049500
    mov ebx, 1
    mov eax, 4
    int 0x80
exit:
    mov bl, 0
    mov eax, 1
    int 0x80

Best,
Frank


Offline isywum

  • Jr. Member
  • *
  • Posts: 38
Re: Write a string to an adress
« Reply #11 on: July 12, 2012, 03:30:27 PM »
Thank you. It works perfect as always. :)