flat assembler
Message board for the users of flat assembler.

Index > Main > Stack balanced multicat string

Author
Thread Post new topic Reply to topic
hopcode



Joined: 04 Mar 2008
Posts: 563
Location: Germany
hopcode 22 Jan 2009, 06:11
See please,also the updated version in my following post requiring no macro
Hallo All,
starting from this interesting thread,i have got this idea for a multicat string routine to concatenate multiple strings passed on the stack.It could be improved a lot. I think that, starting from this here,a further development
could replace completely the wsprintf API function.
Here the code:
Code:
;;ü------------------------------------------ö
;;|    catstr code for macro @catstr         |
;;|    by hopcode[mrk]                       | 
;;#------------------------------------------ä
catstr: 
 ; ESI = source; EDI = dest;
 xor ebx,ebx
 pop edx
 pop ecx
 pop esi
@@:      
 inc ebx
 lodsb
 test al,al
 jnz @b
 mov edi,esi
 dec ebx
.@1:
 pop esi
 dec edi
@@:
 inc ebx
 lodsb
 stosb
 test al,al
 jnz @b
 dec ebx
 dec ecx
 jnz .@1
 jmp edx

;
;...the macro to preserve ebx/esi/edi
;
macro @catstr destbuf,[args]    {
 common
 local numparams
  numparams = 0
  push ebx
  push edi    
  push esi
 reverse
  push args
  numparams = numparams +1
 common
  push destbuf
  push numparams
  call catstr
  mov eax,destbuf
  mov ecx,ebx
  pop esi
  pop edi
  pop ebx
}
;------usage
;------
 ;.data
 szDestbuffer db 100 dup (0)
 szDir    db "mydir",0
 szSubdir db "mysubdir",0
 szSlash  db "\",0
 szFile   db "myfile",0

 ;.code 

 @catstr szDestbuffer,szDir,szSlash,szSubdir,szSlash,szFile
 ;
 ; return EAX=pointer to destbuffer
 ; return ECX=num chars copied in destbuffer
 ;----------------------------------------------------
    


Enjoy,
hopcode


Last edited by hopcode on 23 Jan 2009, 16:50; edited 2 times in total
Post 22 Jan 2009, 06:11
View user's profile Send private message Visit poster's website Reply with quote
bitRAKE



Joined: 21 Jul 2003
Posts: 4037
Location: vpcmpistri
bitRAKE 22 Jan 2009, 07:02
Maybe this will work (untested):
Code:
catstr:
   pop edx
     pop edi
     push edi
    xor eax,eax
 or ecx,-1
   repne scasb
 pop ecx
     pop esi
     dec edi
     neg ecx
.0:      cmp [esi],al ; 0
    movsb
       jnz .0
      pop esi ; src...
    test esi,esi
        jnz .0
      add ecx,edi
 jmp edx    
PUSH a zero on the stack before the other strings of course. Wink
{edit: I might have fixed it}
Post 22 Jan 2009, 07:02
View user's profile Send private message Visit poster's website Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr 22 Jan 2009, 13:06
bitRAKE,

Inner loop copies NUL terminator for concatenated ASCIIZ inside destination. Wink
Post 22 Jan 2009, 13:06
View user's profile Send private message Reply with quote
bitRAKE



Joined: 21 Jul 2003
Posts: 4037
Location: vpcmpistri
bitRAKE 22 Jan 2009, 16:08
Should prolly add a DEC EDI after the last POP ESI - that'll fix the string length as well (was off by one, counted NUL).
Post 22 Jan 2009, 16:08
View user's profile Send private message Visit poster's website Reply with quote
hopcode



Joined: 04 Mar 2008
Posts: 563
Location: Germany
hopcode 23 Jan 2009, 16:36
Here my working solution using the bitRake's "PUSH 0" hint (thanks).
This solution (anyway not my final) preserves API regs EBX/EDI/ESI
but doesnt require a wrapping macro.Also,it could be cut and copied in a DLL without extra coding.
Added a little (not exaustive) control on the parameters before PUSH 0
Max num stackable strings 0FFh
Follows code and usage.

BTW:/to Anyone/Do you know weather this "double stacking" technik
as a real used name, and/or old and well known related examples ?

Code:
;;ü----------------------------------------------ö
;;|    catstr code to concatenate multi strings  |
;;|    by hopcode[mrk] version 0.1               | 
;;|    Datum 23/01/2009                          | 
;;#----------------------------------------------ä

catstr:
 push ebx
 push edi
 push esi
 call .2
 pop esi
 pop edi
 pop ebx
 pop edx
 add esp,eax
 jmp edx

.2:  
  add esp,0CH+4+4  ; point to params \
  xor ecx,ecx          ; \ = push ebx/edi/esi + \
  pop edi       ; \this proc + callling proc
  xor eax,eax
  push edi
  inc ah
  dec ecx
  repne scasb
  pop ecx
  neg ecx
  jmp .1
.0:  
  lodsb
  stosb
  test al,al
  jnz .0
.1:
  inc ah
  pop esi
  dec edi
  test esi,esi
  jnz .0

  shr eax,6
  add ecx,edi
  sub esp,eax
  ;mov eax,[esp]    ;dont touch!!: pointer to destBuffer
  sub esp,0CH+4+4
  ret

;--------usage:
;--------------------------------------------
 szDestbuffer db 100 dup (0)
 szDir    db "mydir",0
 szSubdir db "mysubdir",0
 szSlash  db "\",0
 szFile   db "myfile",ß

 ;.code 

 stdcall catstr, szDestbuffer,szDir,szSlash,szSubdir,szSlash,szFile,0
 ; 
 ; return ECX=num chars copied in destbuffer
;----------------------------------------------------
    

Enjoy,
hopcode
Post 23 Jan 2009, 16:36
View user's profile Send private message Visit poster's website Reply with quote
edfed



Joined: 20 Feb 2006
Posts: 4332
Location: Now
edfed 24 Jan 2009, 02:35
using a liked list would be good too.
Code:

reserve many bytes to create the new string

byte from (n)string(i)
byte = nul? 
{
(n) = last? 
{byte = nul}
byte to dest(j)
}
byte to dest(j)
j++
i++
etc etc...
    
Post 24 Jan 2009, 02:35
View user's profile Send private message Visit poster's website Reply with quote
bitRAKE



Joined: 21 Jul 2003
Posts: 4037
Location: vpcmpistri
bitRAKE 24 Jan 2009, 05:16
hopcode, it should be okay in Windows, but common convention specifies memory less than ESP as volatile (undefined) - should be able to "push x1 x2 ... xN/add esp,4*N" between any two instructions without effecting stack usage. Assembly coders know otherwise though. Wink In Windows ESP can be used generally if a stack isn't needed by a thread.

Additionally, on Windows the string address cannot be less than $1000. So, pushing zero first is only one option - could push the argument count, or stack correction value - because the caller knows.
Code:
pop esi
cmp esi,$1000
jnc .0
add esp,esi
retn    
...highly unconventional though. Twisted Evil
Post 24 Jan 2009, 05:16
View user's profile Send private message Visit poster's website Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20333
Location: In your JS exploiting you and your system
revolution 24 Jan 2009, 05:23
When using functions with a variable number of parameters it is common practice for the caller to restore the stack: ccall. I think it complicates things to have the function restore a variable number of parameters.
bitRAKE wrote:
Code:
pop esi
cmp esi,$1000
jnc .0
add esp,esi
retn    
...highly unconventional though. Twisted Evil
Your code should adjust the stack after the retn address is taken from it.
Post 24 Jan 2009, 05:23
View user's profile Send private message Visit poster's website Reply with quote
bitRAKE



Joined: 21 Jul 2003
Posts: 4037
Location: vpcmpistri
bitRAKE 24 Jan 2009, 05:28
Oh, yeah: jmp edx, then.
Post 24 Jan 2009, 05:28
View user's profile Send private message Visit poster's website Reply with quote
hopcode



Joined: 04 Mar 2008
Posts: 563
Location: Germany
hopcode 24 Jan 2009, 06:56
/to edfed/ Hallo edfed,i like your idea. Thanks
/to bitRake/ As i have time i will try exaustively the proc in stacks+threads.Till now in threads, it seems all ok.
.
(Only to the reader's attention...it is important...)
.
Do you know weather this "double stacking" technik
as a real used name, and/or old and well known related examples ?

.
Do you like the matrjoska ? Here...
Prinzip der Matrjoschkas


Description: from wikipedia
Filesize: 46.02 KB
Viewed: 7372 Time(s)

Russian-Matroshka2kleina.jpg


Post 24 Jan 2009, 06:56
View user's profile Send private message Visit poster's website Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr 24 Jan 2009, 21:26
revolution wrote:
When using functions with a variable number of parameters it is common practice for the caller to restore the stack: ccall

…Your code should adjust the stack after the retn address is taken from it.
It's assembly, we don't need high-level mumbo-jumbo every time… Some efforts in register saving could make it almost stdcall. Wink

_________________
"Don't belong. Never join. Think for yourself. Peace." – Victor Stone.
Post 24 Jan 2009, 21:26
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20333
Location: In your JS exploiting you and your system
revolution 25 Jan 2009, 04:36
baldr wrote:
revolution wrote:
When using functions with a variable number of parameters it is common practice for the caller to restore the stack: ccall

…Your code should adjust the stack after the retn address is taken from it.
It's assembly, we don't need high-level mumbo-jumbo every time… Some efforts in register saving could make it almost stdcall. Wink
Haha, mumbo jumbo? I used one term 'ccall', is that what you are referring to? I like macros like ccall, I don't care if the name comes from C, it makes my task easier and clearer to achieve. Let's not get too hung up on the names of things.

Perhaps we should ban all macros because they are too much like going "high-level"? Wink
Post 25 Jan 2009, 04:36
View user's profile Send private message Visit poster's website 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-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.