flat assembler
Message board for the users of flat assembler.

Index > Windows > Is wsprintfA redundant?

Goto page 1, 2  Next
Author
Thread Post new topic Reply to topic
FlierMate



Joined: 21 Jan 2021
Posts: 219
FlierMate 01 Apr 2021, 15:34
As I haven't written useful Assembly code since decades ago, I am slowly relearning such as 32-bit registers and Win32 API.

I just ran a quick test, and found copying buffer from one to another can either be using wsprintfA or my own.

As you see, I use wsprintfA to copy from newmessage to buffer, but use REP MOVSB to copy from title to str1. Both works!

So is wsprintfA redundant? Any consequence from using it (MS docs discourages the use of wsprintfA)

Code:
section '.data' readable writable
       title       db 'Title',0
       newmessage    db 'newmessage',0
       fmt         db '%s',0


section '.code' code readable executable

        buffer  rb 256
        str1    rb 64

start:
       push newmessage
       push fmt
       push buffer
       call [wsprintf]

       lea ebx,[title]
       mov esi, ebx
       lea edx,[str1]
       mov edi, edx
       mov ecx, 6
       rep movsb

       push 0x40
       push str1
       push buffer
       push 0
       call [MessageBox]
.......
    

[/i]
Post 01 Apr 2021, 15:34
View user's profile Send private message Reply with quote
Overclick



Joined: 11 Jul 2020
Posts: 669
Location: Ukraine
Overclick 01 Apr 2021, 15:51
wsprintf reproduces movsb operation for high-level languages. You don't really need it for assembly. As any high-level api function it is not enough clean and it uses extra code to make this call.
Post 01 Apr 2021, 15:51
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: 20303
Location: In your JS exploiting you and your system
revolution 01 Apr 2021, 15:52
wsprintfA can do a lot more than just copying memory buffers. You can't use rep movsb to format a decimal number inside the string.

So, no, it isn't redundant.
Post 01 Apr 2021, 15:52
View user's profile Send private message Visit poster's website Reply with quote
Overclick



Joined: 11 Jul 2020
Posts: 669
Location: Ukraine
Overclick 01 Apr 2021, 16:00
Quote:

to format a decimal number inside the string

That what I'm saying -- a lot of extra code inside that function. It can be easily done by own choice.
Post 01 Apr 2021, 16:00
View user's profile Send private message Visit poster's website Reply with quote
Furs



Joined: 04 Mar 2016
Posts: 2493
Furs 02 Apr 2021, 11:48
Replace fmt from %s to %u and see what happens Wink
Post 02 Apr 2021, 11:48
View user's profile Send private message Reply with quote
FlierMate



Joined: 21 Jan 2021
Posts: 219
FlierMate 02 Apr 2021, 12:06
Furs wrote:
Replace fmt from %s to %u and see what happens Wink


It is unsigned integer. Surprised

Given fmt ='%u'
Code:
       mov eax,1234
       push eax
       push fmt
       push buffer
       call [wsprintf]
.....      


I got '1234' in buffer.

So I understand wsprintfA does more than copying memory buffers, because it has format specifier also.

Thanks @Overclick, @revolution and @Furs.
Post 02 Apr 2021, 12:06
View user's profile Send private message Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1619
Location: Toronto, Canada
AsmGuru62 02 Apr 2021, 14:37
Also, need to be aware that wsprintfA/wsprintfW will not convert floating point numbers.
So, if you have a value like 3.1415926..... -- you cannot put it into a string with wsprintf.
You need to import MSVCRT.DLL and use sprintf() from it.
Post 02 Apr 2021, 14:37
View user's profile Send private message Send e-mail Reply with quote
bitRAKE



Joined: 21 Jul 2003
Posts: 4024
Location: vpcmpistri
bitRAKE 02 Apr 2021, 19:10
wsprintfA/wsprintfW can also combine byte-strings and wide-strings. (%s and %S)

_________________
¯\(°_o)/¯ “languages are not safe - uses can be” Bjarne Stroustrup
Post 02 Apr 2021, 19:10
View user's profile Send private message Visit poster's website Reply with quote
Overclick



Joined: 11 Jul 2020
Posts: 669
Location: Ukraine
Overclick 03 Apr 2021, 01:10
Assembly dies Crying or Very sad
Why don't you use macro to get the same result?

For example:
Code:
macro movs Dest_addr,Source_addr,n 
        {
        if Dest_addr eq 
                movs
        else
                if ~ n eq
                        mov                     rcx,n
                end if
                mov                     rsi,Source_addr
                mov                     rdi,Dest_addr
                rep                     movsb   
        end if  
}    
Post 03 Apr 2021, 01:10
View user's profile Send private message Visit poster's website Reply with quote
bitRAKE



Joined: 21 Jul 2003
Posts: 4024
Location: vpcmpistri
bitRAKE 03 Apr 2021, 04:14
Overclick wrote:
Assembly dies Crying or Very sad
It need not be so serious. People have different levels of commitment to assembly. For example, in the past I'd argue not to include MSVCRT.DLL just for float output - the code to split an integer/fraction is so small. Presently, the past DLL boundaries aren't relevant in Win10 as APIs have been moved around. String instructions are getting faster in newer processors.

_________________
¯\(°_o)/¯ “languages are not safe - uses can be” Bjarne Stroustrup
Post 03 Apr 2021, 04:14
View user's profile Send private message Visit poster's website Reply with quote
Overclick



Joined: 11 Jul 2020
Posts: 669
Location: Ukraine
Overclick 03 Apr 2021, 04:27
I understand where you need something huge to be done but use winapi for simple string operations is ridiculous
Post 03 Apr 2021, 04:27
View user's profile Send private message Visit poster's website Reply with quote
Roman



Joined: 21 Apr 2012
Posts: 1769
Roman 03 Apr 2021, 04:38
Quote:

macro movs Dest_addr,Source_addr,n
{
if Dest_addr eq
movs
else
if ~ n eq
mov rcx,n
end if
mov rsi,Source_addr
mov rdi,Dest_addr
rep movsb
end if
}

What mean this and why you writed this ?
if Dest_addr eq
movs

Would be nice have one macro for asc2 and unicode text.


Last edited by Roman on 03 Apr 2021, 06:05; edited 1 time in total
Post 03 Apr 2021, 04:38
View user's profile Send private message Reply with quote
Overclick



Joined: 11 Jul 2020
Posts: 669
Location: Ukraine
Overclick 03 Apr 2021, 04:46
Crying or Very sad Crying or Very sad Crying or Very sad
It's a byte operation as CPU understand it. Unicode or ascii whatever. Do you want to convert it or what?
Post 03 Apr 2021, 04:46
View user's profile Send private message Visit poster's website Reply with quote
Roman



Joined: 21 Apr 2012
Posts: 1769
Roman 03 Apr 2021, 06:05
Simple copy asc or unicode text.
But some times i dont know text len. For rcx,bytes copy.
Post 03 Apr 2021, 06:05
View user's profile Send private message Reply with quote
Overclick



Joined: 11 Jul 2020
Posts: 669
Location: Ukraine
Overclick 03 Apr 2021, 06:48
Quote:

some times i dont know text len

Sometimes it's zero ended. wsprintf doesn't do any magic Smile
Post 03 Apr 2021, 06:48
View user's profile Send private message Visit poster's website Reply with quote
bitRAKE



Joined: 21 Jul 2003
Posts: 4024
Location: vpcmpistri
bitRAKE 03 Apr 2021, 11:33
String length is:
Code:
        lea rdi,[input_buffer]
        or ecx,-1
        xor eax,eax
        repnz scasb ; RDI points to byte after zero byte!
        not ecx
        sub ecx,1    
SCASW for wide-char of course, but we get byte length and not character length because characters can be 2 or 4 bytes.
Post 03 Apr 2021, 11:33
View user's profile Send private message Visit poster's website Reply with quote
FlierMate



Joined: 21 Jan 2021
Posts: 219
FlierMate 03 Apr 2021, 13:19
bitRAKE wrote:
String length is:
Code:
        lea rdi,[input_buffer]
        or ecx,-1
        xor eax,eax
        repnz scasb ; RDI points to byte after zero byte!
        not ecx
        sub ecx,1    
SCASW for wide-char of course, but we get byte length and not character length because characters can be 2 or 4 bytes.


It works brilliantly, thanks for the code.

But, sorry for my ignorance, can it be that the input_buffer is greater than 4096MB (I suppose it is the max value of 32-bit uint?).
Post 03 Apr 2021, 13:19
View user's profile Send private message Reply with quote
bitRAKE



Joined: 21 Jul 2003
Posts: 4024
Location: vpcmpistri
bitRAKE 03 Apr 2021, 13:32
If you are working with strings of length 2^32 -1 then your algorithms should require special care. This little snippet is just for common use - not bioinformatics, or an abused log file. It's more important to understand how it works.

_________________
¯\(°_o)/¯ “languages are not safe - uses can be” Bjarne Stroustrup
Post 03 Apr 2021, 13:32
View user's profile Send private message Visit poster's website Reply with quote
ProMiNick



Joined: 24 Mar 2012
Posts: 798
Location: Russian Federation, Sochi
ProMiNick 04 Apr 2021, 20:38
if any will code of representing floats to string to make useless '%f' from sprintf from msvcrt this demo app could help to test behavior
Payload source code displayed by clicking on any window pixel (couple of HLL lines, just a little of assembly lines).

By the way MS itself show floats ugly: for HEX $3E99999A best display value is "0.3" but displayed "0.300000011920929" - so yes sprintf with %f is junk. Needed much better algorithm that returned shortest variant, reverse operation with it that became $3E99999A value etc.


Description:
Filesize: 5.79 KB
Viewed: 13115 Time(s)

изображение_2021-04-07_144846.png



_________________
I don`t like to refer by "you" to one person.
My soul requires acronim "thou" instead.


Last edited by ProMiNick on 07 Apr 2021, 12:02; edited 1 time in total
Post 04 Apr 2021, 20:38
View user's profile Send private message Send e-mail Reply with quote
Overclick



Joined: 11 Jul 2020
Posts: 669
Location: Ukraine
Overclick 07 Apr 2021, 07:13
I didn't see your (thour) example, but I don't see the big deal with it.
Code:
macro   movs Dest_addr,Source_addr,len,key,key2
        {
        if ~ Dest_addr eq
                mov     rdi,Dest_addr
        end if
        if ~ Source_addr eq
                mov     rsi,Source_addr
        end if
        if ~ len eq auto
                if ~ len eq
                        mov     ecx,len
                end if
        end if
        if key eq FloatToString
                if len eq auto
                        local chairBuffer,chairConvert,chairUnload,loopBegin
                        jmp     @F
                                chairBuffer     dd ?
                        @@:
                        cmp     DWORD[rsi],0    ;quad zero to determine the end
                        je @F
                        loopBegin:
                                fld DWORD[rsi]
                                fistp [chairBuffer]
                                xor     rcx,rcx
                                mov eax,[chairBuffer]
                                mov ebx,10
                        chairConvert:
                                xor rdx,rdx
                                div rbx
                                add dl,0x30
                                push rdx
                                inc rcx
                                cmp rax,0
                                jne     chairConvert
                        chairUnload:
                                pop rdx
                                mov     BYTE[rdi],dl
                                inc     rdi
                                dec rcx
                                cmp rcx,0
                                jne chairUnload
                        add rsi,4
                        cmp     DWORD[rsi],0
                        je @F
                        if key2 eq
                                mov     BYTE[rdi],' '
                        else
                                mov     BYTE[rdi],key2
                        end if
                        inc     rdi
                        jmp loopBegin
                        @@:
                        mov BYTE[rdi],0
                else
                        ;calculate loop by rcx or quantity of dwords
                end if
        else if key eq
                if len eq auto
                        ;calculate loop by zero-ended
                else if len eq
                        movs
                end if
        end if  
        }    


Macro not tested yet! Just for example how movs can be improved to use the key FloatToString
Post 07 Apr 2021, 07:13
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:  
Goto page 1, 2  Next

< 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.