flat assembler
Message board for the users of flat assembler.

Index > Windows > C++ vs Assembly: GetTickCount

Author
Thread Post new topic Reply to topic
FlierMate1



Joined: 31 May 2022
Posts: 118
FlierMate1 21 Jul 2022, 09:29
I am explaining to outsider on how an one-liner C++ can be split to multiple functions in Assembly... and I use GetTickCount as an example:

Is the chart enough to explain it all?
MSVC version:
Code:
#include <iostream>
#include <windows.h>

int main()
{
    std::cout << GetTickCount();
}    


FASM version:
Code:
format PE console
entry start

include 'win32a.inc'

section '.data' data readable writable

buf     rb      10
        db      0
fmt     db      '%d'
len     dd      ?
dummy   dd      ?

section '.code' code readable executable

start:
        call    [GetTickCount]
        push    eax
        push    fmt
        push    buf
        call    [wsprintf]
        mov     dword [len], eax
        push    -11
        call    [GetStdHandle]
        push    0
        push    dummy
        push    dword [len]
        push    buf
        push    eax
        call    [WriteConsole]
        push    0
        call    [ExitProcess]

section '.idata' import readable writable

 library kernel32, 'KERNEL32.DLL',\
         user32, 'USER32.DLL'

 import kernel32,\
        GetStdHandle, 'GetStdHandle', \
        WriteConsole, 'WriteConsoleA', \
        GetTickCount, 'GetTickCount', \
        ExitProcess,'ExitProcess'

 import user32,\
        wsprintf, 'wsprintfA'    


Description: A comparison chart
Filesize: 31.5 KB
Viewed: 4687 Time(s)

Screenshot 2022-07-21 171657.png


Post 21 Jul 2022, 09:29
View user's profile Send private message Reply with quote
macomics



Joined: 26 Jan 2021
Posts: 928
Location: Russia
macomics 21 Jul 2022, 10:42
And now stuff this miracle in c++ into the disassembler and be disappointed in this short line.
Everything really will eventually come down to calling these WinAPI, but before that, c++ will do 100500 manipulations and checks with this data.

For example: call [GetStdHandle], -11 (fasm) = stdout (c++)
Post 21 Jul 2022, 10:42
View user's profile Send private message 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 21 Jul 2022, 11:05
I think it would be clearer if the -11 magic value was made into a constant definition.
Code:
descriptive_name_for_value = -11
;...
push descriptive_name_for_value    
What does -11 represent?
Post 21 Jul 2022, 11:05
View user's profile Send private message Visit poster's website Reply with quote
FlierMate1



Joined: 31 May 2022
Posts: 118
FlierMate1 21 Jul 2022, 11:10
macomics wrote:
And now stuff this miracle in c++ into the disassembler and be disappointed in this short line.
Everything really will eventually come down to calling these WinAPI, but before that, c++ will do 100500 manipulations and checks with this data.


I understand what you mean, the output executable would be larger and filled with additional code (although I haven't disassemble one myself Laughing )

revolution wrote:
I think it would be clearer if the -11 magic value was made into a constant definition.
Code:
descriptive_name_for_value = -11
;...
push descriptive_name_for_value    
What does -11 represent?


STD_OUTPUT_HANDLE ((DWORD)-11), The standard output device.

Yeah, my bad practice from the beginning to use the constant value instead of the constant name. Razz
But it is too late, it has been published.
Post 21 Jul 2022, 11:10
View user's profile Send private message 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 21 Jul 2022, 12:33
How does C++ compare to this sequence?
Code:
add eax,ebx
rcr eax,1 ; (eax + ebx) / 2 without failure due to overflow    
Or this?
Code:
mul edx ; use full result in edx:eax    
Or this classic?
Code:
rep movsd    
Post 21 Jul 2022, 12:33
View user's profile Send private message Visit poster's website Reply with quote
FlierMate1



Joined: 31 May 2022
Posts: 118
FlierMate1 21 Jul 2022, 13:56
No idea. I haven't done any real research into "C++ vs Assembly".
I will be glad if someone more knowledgeable could share his/her insights.
Post 21 Jul 2022, 13:56
View user's profile Send private message Reply with quote
FlierMate11



Joined: 13 Oct 2022
Posts: 94
FlierMate11 24 Jan 2023, 15:30
A correction to the code at Post #1, should have used C calling convention for wsprintfA

Code:
        call    [GetTickCount]
        ;push    eax
        ;push    fmt
        ;push    buf
        cinvoke wsprintf,buf,fmt,eax
        mov     dword [len], eax     
    


Thanks @sinsi for your confirmation on the other thread.
Post 24 Jan 2023, 15:30
View user's profile Send private message Visit poster's website Reply with quote
FlierMate11



Joined: 13 Oct 2022
Posts: 94
FlierMate11 24 Jan 2023, 15:38
FlierMate11 wrote:
A correction to the code at Post #1, should have used C calling convention for wsprintfA

Code:
        call    [GetTickCount]
        ;push    eax
        ;push    fmt
        ;push    buf
        cinvoke wsprintf,buf,fmt,eax
        mov     dword [len], eax     
    


Thanks @sinsi for your confirmation on the other thread.


After disassembly, cinvoke is actually

Code:
call [wsprintf]
add esp, 0ch
    


Why can't I use ccall?


Description:
Filesize: 9.41 KB
Viewed: 3768 Time(s)

Screenshot 2023-01-24 233728.png


Post 24 Jan 2023, 15:38
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 24 Jan 2023, 15:42
FlierMate11 wrote:
After disassembly, cinvoke is actually

Code:
call [wsprintf]
add esp, 0ch
    
Kind of. The value 0ch is the three parameters pushed onto the stack beforehand. 3 * 4 = 12 bytes to add to esp.
FlierMate11 wrote:
Why can't I use ccall?
Because it encodes to this:
Code:
 call wsprintf ; <- note there are no square brackets []    
So you end up calling the data pointer, instead of the value stored in the data pointer.
Post 24 Jan 2023, 15:42
View user's profile Send private message Visit poster's website Reply with quote
FlierMate11



Joined: 13 Oct 2022
Posts: 94
FlierMate11 24 Jan 2023, 15:48
revolution wrote:
FlierMate11 wrote:
After disassembly, cinvoke is actually

Code:
call [wsprintf]
add esp, 0ch
    
Kind of. The value 0ch is the three parameters pushed onto the stack beforehand. 3 * 4 = 12 bytes to add to esp.
FlierMate11 wrote:
Why can't I use ccall?
Because it encodes to this:
Code:
 call wsprintf ; <- note there are no square brackets []    
So you end up calling the data pointer, instead of the value stored in the data pointer.


Thank you for the explanation. I see now why I failed to use ccall.
Post 24 Jan 2023, 15:48
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.