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?
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.
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
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
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
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
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.
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.
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 !
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.)
DEP does not prevent you from reading memory in the code section, it prevents executing code in other sections.