News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Create Strings at Runtime

Started by n00b!, January 13, 2009, 03:46:03 PM

Previous topic - Next topic

n00b!

Hi,
as the title says I want to create some strings at runtime like this:
mov dword ptr [eax], "hell"
mov byte ptr [eax +4], "o"


But a little bit more comfortable.
I thought of something like this (pseudocode):
mov bytes ptr [eax], "hello, how are you"
or
mov bytes ptr [var], 1, 2, 3, 4

That you write an array of bytes (like you would write it in the .data-section), which will be written into the memory at the specified address.
Thanks!
Is there any quite nice way to handle strings as imediate values?

donkey

Hi n00b!,

Problem is that the strings that you "create" at runtime would be stored in a section anyway, after all the data to fill the string has to come from somewhere. When GoAsm pushes a literal string like this...

push "Hello there"
pop eax

the address for the string will be in eax, however the string itself is stored in the data section. You can also store constant strings in the code section, const section or in a string table in the RC section.
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

jj2007

Here are some variants for use with the standard Masm32 package.

include \masm32\include\masm32rt.inc

.code
AppName db "A string:", 0

start: mov eax, chr$("Hello World, how are you today?")
MsgBox 0, eax, addr AppName, MB_OK
MsgBox 0, "Thanks, I'm fine, and you?", addr AppName, MB_OK
invoke MessageBox, 0, chr$("Apart from the awful weather..."), addr AppName, MB_OK

exit

end start

qWord

hi,

Quote from: n00b! on January 13, 2009, 03:46:03 PM
Hi,
as the title says I want to create some strings at runtime like this:
mov dword ptr [eax], "hell"
mov byte ptr [eax +4], "o"


eventually this is what you ask for (,otherwise ignore this post  :bg):


; Usage:
;   mov eax,lpDest
;   szmov eax,<Hello World>
; Produce:
;       mov DWORD ptr [eax+0],"lleH"
;       mov DWORD ptr [eax+4],"oW o"
;       mov DWORD ptr [eax+8],"dlr"
szmov macro Register:req,txt:=<>
    szm_size SIZESTR <&txt>
    IF szm_size EQ 0
        mov BYTE ptr [Register],0
        ;;%echo mov BYTE ptr [Register],0
        EXITM
    ELSE
        szm_cntr = 0
        szm_offset = 0
        szm_txt TEXTEQU <>
        FORC char,<&txt>
            IF szm_cntr EQ 3
                szm_txt CATSTR <&char>,szm_txt
                szm_out CATSTR <mov DWORD ptr ![&Register+>,%szm_offset,<!],!">,szm_txt,<!">
                ;;%echo szm_out
                szm_out
                szm_txt TEXTEQU <>
                szm_cntr = 0
                szm_offset = szm_offset + 4
            ELSE
                szm_txt CATSTR <&char>,szm_txt
                szm_cntr = szm_cntr + 1
            ENDIF
        ENDM
    ENDIF

    IF szm_cntr EQ 0
        mov BYTE ptr [Register+szm_offset],0
        ;szm_out CATSTR <mov BYTE ptr ![&Register+>,%szm_offset,<!],0>
        ;%echo szm_out
    ELSE
        szm_out CATSTR <mov DWORD ptr ![&Register+>,%szm_offset,<!],!">,szm_txt,<!">
        szm_out
        ;%echo szm_out
    ENDIF
endm
FPU in a trice: SmplMath
It's that simple!

jj2007

Quote from: qWord on January 13, 2009, 05:05:36 PM
eventually this is what you ask for (,otherwise ignore this post  :bg):

It works, but it's hardly efficient... 47 instead of 26 bytes  :bg

mov eax, offset My$
nop
szmov eax, <Hello World, how are you?>
nop



CPU Disasm
Address    Hex dump                       Command                                     Comments
00401006    ? 90                          nop
00401007    ? C700 48656C6C               mov dword ptr [eax], 6C6C6548
0040100D   ³. C740 04 6F20576F            mov dword ptr [eax+4], 6F57206F
00401014   ³? C740 08 726C642C            mov dword ptr [eax+8], 2C646C72             ; ³
0040101B   ³? C740 0C 20686F77            mov dword ptr [eax+0C], 776F6820
00401022   ³? C740 10 20617265            mov dword ptr [eax+10], 65726120
00401029   ³? C740 14 20796F75            mov dword ptr [eax+14], 756F7920            ; ³
00401030   ³. C740 18 3F000000            mov dword ptr [eax+18], 3F                  ; ÚArg1 => NewCon32.40202E
00401037   ³? 90                          nop
00401038   ³? 68 A0204000                 push offset NewCon32.004020A0

qWord

Quote from: jj2007 on January 13, 2009, 05:21:52 PM
It works, but it's hardly efficient... 47 instead of 26 bytes  :bg

26 or 47 byte .... my computer has ~ 2*10^9 bytes  :green
FPU in a trice: SmplMath
It's that simple!

Mark Jones

Quote from: donkey on January 13, 2009, 03:58:31 PM
...the address for the string will be in eax, however the string itself is stored in the data section. You can also store constant strings in the code section, const section or in a string table in the RC section.

If this is an attempt to obfuscate the string data by embedding it in the code, then this simply won't work.

Also note that anti-virus applications start to think a program "smells funny" when data and code are not in their respective places. As qWord has said, memory and disk real-estate are plentiful; if size is really an issue, simply compress the final executable with UPX or similar. Text compresses really well, so regardless of where its located, it will benefit greatly from compression.
"To deny our impulses... foolish; to revel in them, chaos." MCJ 2003.08

donkey

Hi Mark,

Strings that are stored in the rc, const or code section are read only, I have never encountered anti-virus software that did not allow this or generated any kind of warning because of it, up to and including Windows Vista. All of my code libraries and much of my example code as well as almost every one of my applications store read only text in the code section without issue, it is simply a way to keep a procedures string constants with the procedure for readability. In essence it is simply a string of constants, to disallow it you would also have to disallow mov reg, imm and I don't think that would happen.
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

BlackVortex

Quote from: qWord on January 13, 2009, 05:31:23 PM
Quote from: jj2007 on January 13, 2009, 05:21:52 PM
It works, but it's hardly efficient... 47 instead of 26 bytes  :bg

26 or 47 byte .... my computer has ~ 2*10^9 bytes  :green
You said that in the wrong part of the town !  Get him, boys !

Mark Jones

Quote from: donkey on January 13, 2009, 07:41:33 PM
...In essence it is simply a string of constants, to disallow it you would also have to disallow mov reg, imm and I don't think that would happen.

Yes of course. But undoubtedly, if one started putting strings in the code section as habit, then they some months down the road needed to modify a string at run-time, (forgetting it is in the .code section), then many anti-virus products are going to complain, let alone DEP. I'm just saying that unless there is a specific reason to do so, it is simpler (and safer) to use the predefined sections. And regardless of where text resides, it will both be viewable via debugger, and compress well. (Often, I've seen code and data sections combined to make slightly smaller exectuables, while often a simple UPX will achieve similar or better results on all but the tiniest files.)
"To deny our impulses... foolish; to revel in them, chaos." MCJ 2003.08

donkey

DEP does not prevent you from reading memory in the code section, it prevents executing code in other sections.
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable