flat assembler
Message board for the users of flat assembler.

Index > Linux > tryed to port "you massive clod" demo

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



Joined: 24 Mar 2012
Posts: 691
Location: Russian Federation, Sochi
ProMiNick 26 May 2022, 02:05
Code:
format binary as ''
use32

;define FULLSCREEN

rva equ -BASE32+
BASE32=0x8048000
org BASE32

ELF_CLASS32=1
ET_EXEC=2
EM_386=3
ELF_PHEADER_ENTRY_SIZE32 = 32
DT_NEEDED=1
DT_HASH=4
DT_STRTAB=5
DT_SYMTAB=6
DT_DEBUG=21
PT_LOAD=1
PT_INTERP=3
PT_DYNAMIC=2
xo=1
wo=2
wx=3
ro=4
rx=5
rw_=6
rwx=7

SDL_INIT_VIDEO  = $20

SDL_OPENGL      = $00000002
SDL_FULLSCREEN  = $80000000

GL_FRAGMENT_SHADER = $8B30



virtual at 0
        r_debug.r_version       dd ?
        r_debug.r_map           dd ? ;Head of the chain of loaded objects
        r_debug.r_brk           dd ? ;DllEntry linux analog
        r_debug.r_state         dd ? ;reason for DllEntry linux analog
        r_debug.r_ldbase        dd ? ;linker instance loaded address
        r_debug.size            =  $
end virtual

virtual at 0
        link_map.l_addr         dd ? ;library instance loaded address
        link_map.l_name         dd ? ;ptr to library name
        link_map.l_ld           dd ? ;ptr to library dynamic
        link_map.l_next         dd ?
        link_map.l_prev         dd ?
        link_map.size           =  $
end virtual

virtual at 0
        hash_table.nbucket      dd ?
        hash_table.nchain       dd ?
        hash_table.bucket       dd ?
       ;hash_table.chain        dd ?
end virtual



macro program_header {label program_header}
macro program_header_entry32 type, location, access, align, size, memsize {
 dd type
 dd rva location, location, 0
 if type <> PT_LOAD
  dd location#.SIZE, location#.MEMSIZE
 else
  dd size, memsize
 end if
 dd access, align
}
macro end_program_header {
 .SIZE=$-program_header
 .MEMSIZE=.SIZE
}

macro string_table {label string_table}
macro string name, str& {
 name=$-string_table
 if str eq
  db 0
 else
  db str, 0
 end if
}
macro end_string_table {
 .SIZE=$-string_table
 .MEMSIZE=.SIZE
}



Elf_EHdr:
db 0x7F, "ELF", ELF_CLASS32, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0  ;
dw ET_EXEC
dw EM_386
dd 1
dd start                                         ;entrypoint
dd rva program_header
dd 0
dd 0
dw Elf_EHdr.SIZE
dw ELF_PHEADER_ENTRY_SIZE32
dw program_header.SIZE/ELF_PHEADER_ENTRY_SIZE32
dw 0, 0, 0
.SIZE=$-Elf_EHdr

program_header
 program_header_entry32 PT_INTERP, _interpreter_name_, ro, 1
 program_header_entry32 PT_LOAD, Elf_EHdr, rwx, 0x1000, FILE.SIZE, FILE.MEMSIZE
 program_header_entry32 PT_DYNAMIC, _dynamic_, rw_, 4
end_program_header

_interpreter_name_ db "/lib/ld-linux.so.2", 0
.SIZE=$-_interpreter_name_
.MEMSIZE=.SIZE

string_table
 string strtab@null
 string strtab@libsdl, "libSDL-1.2.so.0"
 string strtab@libgl, "libGL.so.1"
end_string_table
fragment_shader_source db \
        "float f(vec3 o){", \
                "float a=(sin(o.x)+o.y*.25)*.35;", \
                "o=vec3(cos(a)*o.x-sin(a)*o.y,sin(a)*o.x+cos(a)*o.y,o.z);", \
                "return dot(cos(o)*cos(o),vec3(1))-1.2;", \
        "}", \
        "", \
        "vec3 s(vec3 o,vec3 d){", \
                "float t=0.,a,b;", \
                "for(int i=0;i<75;i++){", \
                        "if(f(o+d*t)<0){", \
                                "a=t-.125;b=t;", \
                                "for(int i=0; i<10;i++){", \
                                        "t=(a+b)*.5;", \
                                        "if(f(o+d*t)<0)b=t;else a=t;", \
                                "}", \
                                "vec3 e=vec3(.1,0,0),", \
                                "p=o+d*t,", \
                                "n=-normalize(vec3(f(p+e),f(p+e.yxy),f(p+e.yyx))+vec3((sin(p*75.)))*.01);", \
                                "return vec3(", \
                                        "mix( ((max(-dot(n,vec3(.577)),0.) + 0.125*max(-dot(n,vec3(-.707,-.707,0)),0.)))*(mod(length(p.xy)*20.,2.)<1.0?vec3(.71,.85,.25):vec3(.79,.93,.4))", \
                                        ",vec3(.93,.94,.85),", \
                                        "vec3(pow(t/9.,5.))", \
                                        ")", \
                                ");", \
                        "}", \
                        "t+=.125;", \
                "}", \
                "return vec3(.93,.94,.85);", \
        "}", \
        "", \
        "void main(){", \
                "float t=dot(gl_Color.xyz,vec3(1,256,65536))*.5;", \
                "gl_FragColor=vec4(s(vec3(sin(t*1.5)*.5,cos(t)*.5,t), normalize(vec3((gl_FragCoord.xy-vec2(512,384))/vec2(512),1))),1);", \
        "}",0

align 4
_dynamic_ :
dd      DT_NEEDED, strtab@libsdl
dd      DT_NEEDED, strtab@libgl
dd      DT_STRTAB, string_table
dd      DT_SYMTAB, 0
..debug_entry:
dd      DT_DEBUG, 0
dd      0                               ;no needed in dd DT_NULL,0, just dd 0 as terminator
.SIZE=$-_dynamic_
.MEMSIZE=.SIZE



start: ;fill imports accorfing to hashes
        lea     esi, [__import]
        mov     edi, esi
        mov     ecx, __num_imports

      .import_symbol_loop:
        lodsd
        mov edx, eax            ;edx=hash

        macro get_symbol { ;args:       hash(edx)
                           ;result:     imported_proc_rva(eax)
                           ;unaffected: edx,edi,esi,ecx (needed for outer circle)
                mov     ebx, [..debug_entry+4]
                mov     ebx, [ebx+r_debug.r_map]        ;ebx==link_map address

              .link_map_loop:
                test    ebx, ebx
                jz      .done          ;link_map address is 0?

                mov     eax, [ebx+link_map.l_name]        ;name address
                mov     al, [eax]          ;name
                test    al, al             ;only check first byte of string
                jz      .next          ;is 0?

              .continue:

                macro find_symbol_in_map \{ ;args:      hash(edx), link_map_address(ebx)
                                            ;result:    imported_proc(eax)
                                            ;unaffected:edx,edi,esi,ecx,ebx (needed for outer circle)
                ;;; ebx=link_map address, edx=hash
                        push    ebx
                        push    ecx
                        push    esi

                        mov     ebx, [ebx+link_map.l_ld]        ;ebx=dynamic

                        macro get_dynamic_sections \\{ ;args:      dynamic(ebx)
                                                       ;result:    hash_table(ecx),symbol_table(esi),string_table(ebx)
                                                       ;unaffected:edx,edi (needed for outer circle)
                        ;;; ebx=dynamic address
                                mov     ecx, DT_HASH

                        .section_loop:
                                mov     esi, ebx            ;esi=dynamic address
                        .entry_loop:
                                lodsd                   ;eax=name
                                cmp     ecx, eax
                                lodsd                   ;eax=address, flags unaffected
                                jne     .entry_loop
                        .found:
                                push    eax                ;address

                                inc     ecx                ; loop throw DT_HASH(4),DT_STRTAB(5),DT_SYMTAB(6)
                                cmp     ecx, DT_SYMTAB
                                jbe     .section_loop

                                pop     esi                 ;symtab address
                                pop     ebx                 ;strtab address
                                pop     ecx                 ;hash address
                        \\}
        
                        get_dynamic_sections    ;macro - now ecx=hash address, esi=symtab address, ebx=strtab address

                        mov     ecx, [ecx+hash_table.nchain]        ;num chains
                      .symbol_loop:
                        lodsd                   ;eax=st_name, esi now points to st_value

                        push    esi
                        lea     esi, [ebx+eax]

                        macro calc_hash \\{ ;args:      string_ptr(esi)
                                            ;result:    string_hash(eax)
                                            ;unaffected:all rest regs
                                push    ebx

                                xor     ebx, ebx            ;ebx=hash
                                xor     eax, eax            ;clear upper bits
                              .char_loop:
                                ;; these 2 lines don't do anything on the first run of the loop
                                imul    ebx, ebx, 33  ;same as ((hash<<5)+hash)?
                                xor     ebx, eax

                                lodsb                   ;next char
                                test    al, al
                                jnz     .char_loop    ;not 0? carry on
                              .hash_done:
                                mov     eax, ebx

                                pop     ebx \\}

                        calc_hash               ;macro
                        pop     esi

                        cmp     eax, edx
                        lodsd                   ;eax=st_value, flags unaffected
                        je      .got_symbol

                        lodsd                   ;skip 8 bytes to next Elf32_Sym
                        lodsd
                        loop    .symbol_loop

                        xor     eax, eax            ;not found, so null
                      .got_symbol:
                        pop     esi
                        pop     ecx
                        pop     ebx
                \}

                find_symbol_in_map      ;macro - ebx=link_map address, edx=hash, eax=returned address
                add     eax, [ebx+link_map.l_addr]          ;returned address+=link map address
                cmp     eax, [ebx+link_map.l_addr]          ;compare return address to link map address
              .next:
                mov     ebx, [ebx+link_map.l_next]       ;ebx=next link_map address - flags unaffected
                je      .link_map_loop ;if returned address+link map address = link map address then returned address = 0, continue
              .done: }

        get_symbol
        stosd
        loop .import_symbol_loop

macro call_next {
        lodsd
        call eax
}


macro invoke proc*,[arg] {
    common
        if ~ arg eq
    reverse
                pushd arg
    common
        end if
        assert ensure@callchainimport=proc
        ensure@callchainimport=proc+4
        call_next }


; actual start
        lea     esi, [SDL_Init]
        ensure@callchainimport=SDL_Init
        invoke  SDL_Init,SDL_INIT_VIDEO

if defined FULLSCREEN
        invoke  SDL_ShowCursor,0
        invoke  SDL_SetVideoMode,1024,768,0,SDL_OPENGL or SDL_FULLSCREEN
else
        invoke  SDL_SetVideoMode,1024,768,0,SDL_OPENGL
end if
        invoke  glCreateProgram
        mov     edi, eax
        invoke  glCreateShader,GL_FRAGMENT_SHADER
        lea     ebx, [esp-4]
        invoke  glShaderSource,eax,1,ebx,0,fragment_shader_source
        invoke  glCompileShader
        invoke  glAttachShader,edi

        invoke  glLinkProgram
        invoke  glUseProgram

if defined FULLSCREEN
        add     esp, 48
else
        add     esp, 44        ;20 from SDL_Init and SDL_SetVideoMode, 24 from create_shader_program
end if

mainloop:
        lea     esi, [SDL_GetTicks]
        ensure@callchainimport=SDL_GetTicks
        invoke  SDL_GetTicks
        invoke  glColor4ubv,esp,eax
        mov     ebx,eax
        neg     ebx
        invoke  glRecti,ebx,ebx,eax,eax
        invoke  SDL_GL_SwapBuffers

        add     esp, 24

get_event:      
        invoke  SDL_PollEvent,sdlevent
        add     esp, 4         ;balance stack
        test    al, al
        jz      mainloop
        sub     esi, 4         ;return function pointer to SDL_PollEvent
                                      ;if no event then loop

        mov     al, [sdlevent]      ;event.type
if defined FULLSCREEN
        cmp     al, byte 0x2        ;SDL_KEYDOWN
else
        cmp     al, byte 0xC
end if
        jne     get_event           ;get next event if current is not SDL_KEYDOWN

quit:
if defined FULLSCREEN
        invoke  SDL_ShowCursor2,1
        add     esp, 4
end if
        
        invoke  SDL_Quit               ;SDL_Quit

        xor     eax, eax
        inc     eax
        int     0x80

if defined FULLSCREEN
        __num_imports = 17
else
        __num_imports = 15
end if

struc elf_hash string {
        local h,idx,c
        h = 0
        idx=0
        virtual at 0
                db string,0
                while 1
                        load c from idx
                        if ~c
                                break
                        end if
                        h=((h*33) and $FFFFFFFF) xor c
                        idx=idx+1
                end while
        end virtual
        . dd h }

align 4
__import:
SDL_Init elf_hash "SDL_Init"
if defined FULLSCREEN
SDL_ShowCursor elf_hash "SDL_ShowCursor"
end if
SDL_SetVideoMode elf_hash "SDL_SetVideoMode"
glCreateProgram elf_hash "glCreateProgram"
glCreateShader elf_hash "glCreateShader"
glShaderSource elf_hash "glShaderSource"
glCompileShader elf_hash "glCompileShader"
glAttachShader elf_hash "glAttachShader"
glLinkProgram elf_hash "glLinkProgram"
glUseProgram elf_hash "glUseProgram"
SDL_GetTicks elf_hash "SDL_GetTicks"
glColor4ubv elf_hash "glColor4ubv"
glRecti elf_hash "glRecti"  ;glRecti
SDL_GL_SwapBuffers elf_hash "SDL_GL_SwapBuffers"
SDL_PollEvent elf_hash "SDL_PollEvent"
if defined FULLSCREEN
SDL_ShowCursor2 elf_hash "SDL_ShowCursor2"
end if
SDL_Quit elf_hash "SDL_Quit"



FILE.SIZE = rva $

sdlevent        rb $14

FILE.MEMSIZE = rva $    

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


Last edited by ProMiNick on 26 May 2022, 22:03; edited 1 time in total
Post 26 May 2022, 02:05
View user's profile Send private message Send e-mail Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 18948
Location: In your JS exploiting you and your system
revolution 26 May 2022, 11:24
Searching for "you massive clod" on DDG turns up only this thread for me.

What is the "you massive clod" demo?
Post 26 May 2022, 11:24
View user's profile Send private message Visit poster's website Reply with quote
bitRAKE



Joined: 21 Jul 2003
Posts: 3515
Location: vpcmipstrm
bitRAKE 26 May 2022, 12:57

_________________
¯\(°_o)/¯ unlicense.org
Post 26 May 2022, 12:57
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: 18948
Location: In your JS exploiting you and your system
revolution 26 May 2022, 15:38
Okay, thanks bitRAKE. DDG is a bit crap.

ProMiNick: Does this code work? Are you asking for assistance?

I can't try it here. But it looks interesting.
Post 26 May 2022, 15:38
View user's profile Send private message Visit poster's website Reply with quote
ProMiNick



Joined: 24 Mar 2012
Posts: 691
Location: Russian Federation, Sochi
ProMiNick 26 May 2022, 16:54
thanks revolution. someone already helped me to extract elf from form they packed in sh (with 7zip). By the way even exctracted elf not launched in my linux VM environment.
not test4 - as my port to fasm, not clod-windowed - unpacked sh
are both segmentation fault. for comparison couple of successfuly executed between them


Description:
Filesize: 39.62 KB
Viewed: 2653 Time(s)

osboxes.JPG



_________________
I don`t like to refer by "you" to one person.
My soul requires acronim "thou" instead.
Post 26 May 2022, 16:54
View user's profile Send private message Send e-mail Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 18948
Location: In your JS exploiting you and your system
revolution 27 May 2022, 04:42
My system doesn't have any library with SDL or GL in the name. So even if I could run arbitrary exe files any attempt to run it would fail with a missing library error.
Code:
~ find /lib* -name '*GL*' | wc
      0       0       0
~ find /lib* -name '*SDL*' | wc
      0       0       0
~    
Post 27 May 2022, 04:42
View user's profile Send private message Visit poster's website Reply with quote
ProMiNick



Joined: 24 Mar 2012
Posts: 691
Location: Russian Federation, Sochi
ProMiNick 27 May 2022, 05:52
my linux environment has both but it not helps. Why? they present in some ubnormal form/place? Why demo dosn`t launch even official one? may be linux requirement from times that it was published was changed?


Description:
Filesize: 34.72 KB
Viewed: 2627 Time(s)

libGL.JPG



_________________
I don`t like to refer by "you" to one person.
My soul requires acronim "thou" instead.
Post 27 May 2022, 05:52
View user's profile Send private message Send e-mail Reply with quote
Furs



Joined: 04 Mar 2016
Posts: 1951
Furs 27 May 2022, 13:19
revolution wrote:
My system doesn't have any library with SDL or GL in the name. So even if I could run arbitrary exe files any attempt to run it would fail with a missing library error.
Code:
~ find /lib* -name '*GL*' | wc
      0       0       0
~ find /lib* -name '*SDL*' | wc
      0       0       0
~    
Look in /usr/lib as that's where most are, also /usr/local/lib (or just look in /usr in general). Not having SDL is reasonable but not having libGL is unbelievable. Every graphics driver comes with it.

/lib is for very few very essential libraries, in case of emergencies where rest of system isn't available (e.g. recovery console). Same with /bin.
Post 27 May 2022, 13:19
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 18948
Location: In your JS exploiting you and your system
revolution 27 May 2022, 13:42
You are correct.
Code:
~ find /usr/lib* -name '*GL*' | wc
     51      51    2518
~ find /usr/lib* -name '*SDL*' | wc
     21      21     919
~    
Maybe it could work. I just need to figure out how to fake the hash.
Post 27 May 2022, 13:42
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: 18948
Location: In your JS exploiting you and your system
revolution 27 May 2022, 13:46
Oops, I take that back. I only have a 64-bit version for SDL.
Code:
~ find /usr -name 'libSDL-1.2.so.0'
/usr/lib/x86_64-linux-gnu/libSDL-1.2.so.0
~ find /usr -name 'libGL.so.1'
/usr/lib/x86_64-linux-gnu/mesa/libGL.so.1
/usr/lib/i386-linux-gnu/mesa/libGL.so.1    
Maybe if the code was converted to 64-bit then it can run successfully.
Post 27 May 2022, 13:46
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: 18948
Location: In your JS exploiting you and your system
revolution 27 May 2022, 17:13
Someone has pointed out to me that the shader is probably failing to compile because of an implicit type conversion failure.

The suggestion is to change this in two places:
Code:
From: if(f(o+d*t)<0)   ; <--- integer 0 will fail
To:   if(f(o+d*t)<0.0) ; <--- make this a float value 0.0    
I have no idea if it helps.
Post 27 May 2022, 17:13
View user's profile Send private message Visit poster's website Reply with quote
macomics



Joined: 26 Jan 2021
Posts: 675
Location: Russia
macomics 27 May 2022, 17:23
Code:
; From
sub 0x3FF00000, 0
jl lower

; To
fsub 0x3FF00000, 0.0
jl lower    
That's why
Post 27 May 2022, 17:23
View user's profile Send private message Reply with quote
ProMiNick



Joined: 24 Mar 2012
Posts: 691
Location: Russian Federation, Sochi
ProMiNick 27 May 2022, 21:46
or mem(0x3FF00000),0
js lower

test REG,REG
js lower

would be more universal for sign check - works for int & float both
sad that shader in C code and not in assembly.
Is shader could raise segmentation fault?
Post 27 May 2022, 21:46
View user's profile Send private message Send e-mail Reply with quote
macomics



Joined: 26 Jan 2021
Posts: 675
Location: Russia
macomics 27 May 2022, 22:28
Only I just took into account the features of the C code generator and gave an example not of an assembler sequence, but clearly wanted to demonstrate the difference in comparisons generated by the C compiler.

Agree that the implementation of sub (integer subtraction) and fsub (real subtraction) operations are different. The constants 0x3FF00000 demonstrate the result of the f function - float. And 0 and 0.0 are constants from the conditions.

With an integer comparison, it turns out that the range of values (-1; 1) will be equal to 0, and the result will be incorrect.
Post 27 May 2022, 22:28
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 18948
Location: In your JS exploiting you and your system
revolution 29 May 2022, 06:20
This is a 64-bit conversion. It assembles, but I can't test it.

I changed the shader code a small amount. I couldn't see how the z-based rotation as shown in the screen shot would be possible with the shader as given. Anyhow, if it all goes badly, you can change it back to the original.

I included error checking at each main stage. It should also allow you to see the log of errors if the shader won't compile. Instead of blindly spinning through the code and assuming it all works you at least get a chance to diagnose the problem.

If you want full screen then just put in a command line argument, it can be anything. No argument will give a windowed display.
Code:
x_res           = 640
y_res           = 480
buffer_size     = 2000

SDL_INIT_VIDEO          = 0x20
SDL_OPENGL              = 0x00000002
SDL_FULLSCREEN          = 0x80000000
SDL_KEYDOWN             = 2
GL_FRAGMENT_SHADER      = 0x8b30
GL_NO_ERROR             = 0

format ELF64 executable 3

entry start

segment gnustack
segment executable

functions equ

macro invoke proc, [arg] {
        common
                regs equ rdi, rsi, rdx, rcx, r8, r9, -, -
                if ~ arg eq
        forward
                match reg =, shift, regs \{
                        regs equ shift
                        if ~ reg eq arg
                                mov reg, arg
                        end if
                \}
        common
                end if
                call [proc]
                found equ 0
                match a =proc b,x functions y \{
                        found equ 1
                \}
                match =0, found \{
                        functions equ functions, proc
                \}
}

start:
        invoke  SDL_Init,SDL_INIT_VIDEO
        test    rax,rax
        mov     ebp,1
        jnz     .err
        mov     rbx,SDL_OPENGL
        cmp     qword[rsp],1                            ;full screen?
        jbe     .set_mode
        mov     rbx,SDL_OPENGL or SDL_FULLSCREEN
        invoke  SDL_ShowCursor,0
    .set_mode:
        invoke  SDL_SetVideoMode,x_res,y_res,0,rbx
        test    rax,rax
        mov     ebp,2
        jz      .err
        invoke  glCreateProgram
        test    rax,rax
        mov     ebp,3
        jz      .err
        mov     r15,rax                                 ;r15 = program
        invoke  glCreateShader,GL_FRAGMENT_SHADER
        test    rax,rax
        mov     ebp,4
        jz      .err
        mov     r14,rax                                 ;r14 = shader
        lea     rbx,[fragment_shader_source]
        push    rbx
        invoke  glShaderSource,r14,1,rsp,0
        pop     rbx
        invoke  glGetError
        cmp     rax,GL_NO_ERROR
        mov     ebp,5
        jnz     .err
        invoke  glCompileShader,r14
        invoke  glGetError
        cmp     rax,GL_NO_ERROR
        mov     ebp,6
        jnz     .err
        call    .shader_log
        invoke  glAttachShader,r15,r14
        invoke  glGetError
        cmp     rax,GL_NO_ERROR
        mov     ebp,7
        jnz     .err
        invoke  glLinkProgram,r15
        invoke  glGetError
        cmp     rax,GL_NO_ERROR
        mov     ebp,8
        jnz     .err
        call    .program_log
        invoke  glUseProgram,r15
        invoke  glGetError
        cmp     rax,GL_NO_ERROR
        mov     ebp,9
        jnz     .err
        lea     rsi,[WindowSize]
        invoke  glGetUniformLocation,r15,rsi
        mov     r13,rax                                 ;r13 = WindowSize
        invoke  glGetError
        cmp     rax,GL_NO_ERROR
        mov     ebp,10
        jnz     .err
        invoke  glUniform2i,r13,x_res,y_res
        invoke  glGetError
        cmp     rax,GL_NO_ERROR
        mov     ebp,11
        jnz     .err
    .loop:
        invoke  SDL_GetTicks
        push    rax
        invoke  glColor4ubv,rsp
        pop     rax
        invoke  glGetError
        cmp     rax,GL_NO_ERROR
        mov     ebp,12
        jnz     .err
        invoke  glRecti,-1,-1,1,1
        invoke  glGetError
        cmp     rax,GL_NO_ERROR
        mov     ebp,13
        jnz     .err
        invoke  SDL_GL_SwapBuffers
    .get_event:
        lea     rdi,[sdlevent]
        invoke  SDL_PollEvent,rdi
        test    al,al
        jz      .loop
        cmp     byte[sdlevent],SDL_KEYDOWN              ;event.type
        jne     .get_event
        xor     ebp,ebp
    .quit:
        cmp     qword[rsp],1                            ;full screen?
        jbe     .close
        invoke  SDL_ShowCursor,1
    .close:
        invoke  SDL_Quit
        mov     eax,SYS_EXIT
        mov     edi,ebp
        syscall
    .err:
        call    print_hex
        mov     eax,ebp
        call    print_hex
        jmp     .quit
    .program_log:
        lea     rdx,[sdlevent]
        lea     rcx,[sdlevent+8]
        invoke  glGetProgramInfoLog,r15,buffer_size,rdx,rcx
        jmp     .log
    .shader_log:
        lea     rdx,[sdlevent]
        lea     rcx,[sdlevent+8]
        invoke  glGetShaderInfoLog,r14,buffer_size,rdx,rcx
    .log:
        mov     rdx,qword[sdlevent]
        test    rdx,rdx
        jz      .ret
        lea     rsi,[sdlevent+8]
        mov     eax,SYS_WRITE
        mov     edi,STD_OUTPUT
        syscall
        pop     rax
        jmp     .quit
    .ret:
        ret

print_hex:
        sub     rsp,28
        mov     rsi,rsp
        call    write_hex
        mov     byte[rsi],10
        lea     rdx,[rsi+1]
        mov     rsi,rsp
        sub     rdx,rsi
        mov     eax,SYS_WRITE
        mov     edi,STD_OUTPUT
        syscall
        add     rsp,28
        ret

write_hex:
        ;rsi = address
        ;rax = value
        mov     ecx,15
    .next_nibble:
        mov     edx,eax
        and     edx,0xf
        mov     dl,[hex_table+rdx]
        mov     [rsi+rcx],dl
        shr     rax,4
        dec     ecx
        jns     .next_nibble
        add     rsi,16
        ret

        db      (-$) and 7 dup 0

SYS_WRITE       = 1
SYS_EXIT        = 60
STD_OUTPUT      = 1

DT_NULL         = 0
DT_NEEDED       = 1
DT_STRTAB       = 5
DT_SYMTAB       = 6
DT_RELA         = 7
DT_RELASZ       = 8
DT_RELAENT      = 9
DT_STRSZ        = 10
DT_SYMENT       = 11
DT_BIND_NOW     = 24
DT_FLAGS        = 30
DT_FLAGS_1      = 0x6ffffffb
STB_GLOBAL      = 1
STT_FUNC        = 2
R_X86_64_64     = 1
DF_BIND_NOW     = 0x00000008
DF_1_NOW        = 0x00000001
DF_1_PIE        = 0x08000000

macro Elf64_Sym name,value,size,bind,type,other,shndx {
        dd name+0
        db (bind+0) shl 4 + (type+0)
        db other+0
        dw shndx+0
        dq value+0
        dq size+0
}
macro Elf64_Rela offset,symbol,type,addend {
        dq rva offset+0
        dq (symbol+0) shl 32 + (type+0)
        dq addend+0
}
virtual at 0
        Elf64_Sym
        sizeof.Elf64_Sym = $
        Elf64_Rela
        sizeof.Elf64_Rela = $ - sizeof.Elf64_Sym
end virtual

segment dynamic readable
        dq DT_NEEDED,_sdl - strtab
        dq DT_NEEDED,_gl - strtab
        dq DT_STRTAB,rva strtab
        dq DT_STRSZ,strsz
        dq DT_SYMTAB,rva symtab
        dq DT_SYMENT,sizeof.Elf64_Sym
        dq DT_RELA,rva rela
        dq DT_RELASZ,relasz
        dq DT_RELAENT,sizeof.Elf64_Rela
        dq DT_BIND_NOW,1
        dq DT_FLAGS,DF_BIND_NOW
        dq DT_FLAGS_1,DF_1_NOW or DF_1_PIE
        dq DT_NULL,0
        symtab:
                Elf64_Sym
                match =,funcs,functions { irp f,funcs \{ if used f
                        Elf64_Sym _\#f - strtab,0,0,STB_GLOBAL,STT_FUNC,0,0
                end if \}}
        rela:
                num = 1
                match =,funcs,functions { irp f,funcs \{ if used f
                        Elf64_Rela f,num,R_X86_64_64
                        num = num + 1
                end if \}}
        relasz  = $ - rela
                match =,funcs,functions { irp f,funcs \{ if used f
                        f rq 1
                end if \}}

segment interpreter readable
                                db '/lib64/ld-linux-x86-64.so.2'
        strtab:                 db 0

        _sdl                    db 'libSDL-1.2.so.0',0
        _gl                     db 'libGL.so.1',0
        match =,funcs,functions { irp f,funcs \{ if used f
                _\#f db \`f,0
        end if \}}
        strsz   = $ - strtab

segment readable writeable

hex_table       db      '0123456789abcdef'
WindowSize      db      "WindowSize",0

fragment_shader_source:
db      "uniform ivec2 WindowSize;"
db      "float f(vec3 o){"
db              "float a=sin(o.z)*.3927,s=sin(a),c=cos(a);"             ; pi/8 ~= 0.3927
db              "o=cos(vec3(c*o.x-s*o.y,s*o.x+c*o.y,o.z));"
db              "return dot(o,o)-1.2;"
db      "}"
db      "vec3 s(vec3 o,vec3 d){"
db              "float t=0.,a,b;"
db              "for(int i=0;i<75;i++){"
db                      "if(f(o+d*t)<.0){"
db                              "a=t-.125;b=t;"
db                              "for(int i=0;i<10;i++){"
db                                      "t=(a+b)*.5;"
db                                      "if(f(o+d*t)<.0)b=t;else a=t;"
db                              "}"
db                              "vec3 e=vec3(.1,0,0),"
db                              "p=o+d*t,"
db                              "n=normalize(vec3(f(p+e),f(p+e.yxy),f(p+e.yyx))+sin(p*75.)*.01);"
db                              "return mix(((max(dot(n,vec3(.577)),0.)+0.125*max(dot(n,vec3(-.707,-.707,0.)),0.)))*(mod(length(p.xy)*20.,2.)"
db                                      "<1.0?vec3(.71,.85,.25):vec3(.79,.93,.4))"
db                                      ",vec3(.93,.94,.85),vec3(pow(t*0.111,5.))"
db                              ");"
db                      "}"
db                      "t+=.125;"
db              "}"
db              "return vec3(.93,.94,.85);"
db      "}"
db      "void main(){"
db              "vec2 hws=vec2(WindowSize)*.5;"
db              "float t=dot(gl_Color.xyz,vec3(1,256,65536))*.5;"
db              "gl_FragColor=vec4(s(vec3(sin(t*1.5)*.5,cos(t)*.5,t),normalize(vec3(gl_FragCoord.xy-hws,hws.x))),1);"
db      "}",0

align 8
sdlevent rb buffer_size    
Post 29 May 2022, 06:20
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: 18948
Location: In your JS exploiting you and your system
revolution 26 Jun 2022, 15:40
It is possible to make a 64-bit version also that is under 1K. Using the standard fasm elf formatter without any special tricks the interpreter header can be eliminated, leaving just two: the LOAD and DYNAMIC headers.

When combined with a small amount of abuse in the dynamic header, and the external zcat, the final executable is 1019 bytes. Instructions for making are in the first line.
Code:
;fasm clod64.asm clod64 && (echo 'a=/tmp/I;tail -n+2 $0|zcat>$a;chmod +x $a;$a;rm $a;exit' ; gzip -9 < clod64) > clod && chmod +x clod && ./clod
;output size is 1019 bytes

check_errors    = 0
half_x_res      equ 320
half_y_res      equ 240
buffer_size     = 2000

;Versions
;OpenGL GLSL
;2.0    1.10    <--- this code
;2.1    1.20
;3.0    1.30
;3.1    1.40
;3.2    1.50
;3.3    3.30

SDL_INIT_VIDEO          = 0x20
SDL_OPENGL              = 0x00000002
SDL_KEYDOWN             = 2
SDL_QUIT                = 12

GL_FRAGMENT_SHADER      = 0x8b30
GL_COMPILE_STATUS       = 0x8b81
GL_VALIDATE_STATUS      = 0x8b83
GL_NO_ERROR             = 0
GL_FALSE                = 0

SYS_WRITE               = 1
SYS_EXECVE              = 59
SYS_EXIT                = 60
STD_OUTPUT              = 1
DT_NULL                 = 0
DT_NEEDED               = 1
DT_STRTAB               = 5
DT_SYMTAB               = 6
DT_DEBUG                = 21
DT_GNU_HASH             = 0x6ffffef5

functions equ

macro invoke proc, [arg] {
        common
                regr equ rdi, rsi, rdx, rcx,  r8,  r9, -, -
                rege equ edi, esi, edx, ecx, r8d, r9d, -, -
                if ~ arg eq
        forward
                match rreg =, shiftr =| ereg =, shifte, regr | rege \{
                        regr equ shiftr
                        rege equ shifte
                        if arg eqtype 0 & 0 = arg
                                xor ereg, ereg
                        else if arg eqtype 0 & 0x80 > arg & -0x80 <= arg
                                push arg
                                pop rreg
                        else if arg eqtype 0 & 1 shl 32 > arg & 0 <= arg
                                mov ereg, arg
                        else if ~ rreg eq arg
                                if arg in <rax,rbx,rcx,rdx,rsi,rdi,rbp,rsp>
                                        push arg
                                        pop rreg
                                else
                                        mov rreg, arg
                                end if
                        end if
                \}
        common
                end if
                call [rbp+proc-procs]
                found equ 0
                match a =proc b,x functions y \{
                        found equ 1
                \}
                match =0, found \{
                        functions equ functions, proc
                \}
}
; invoke with error check
macro einvoke proc, [arg] { common
        local .okay, .proc_name
        invoke  proc,arg
        if check_errors
                invoke  glGetError
                assert  GL_NO_ERROR = 0
                test    rax,rax
                jz      .okay
                push    rax
                mov     edx,.okay - .proc_name
                lea     esi,[.proc_name]
                push    STD_OUTPUT SYS_WRITE
                pop     rax rdi
                syscall
                pop     rax
                jmp     error
            .proc_name:
                db      `proc,10
            .okay:
        end if
}
; invoke with return value check
macro rinvoke proc, [arg] { common
        local .okay, .proc_name
        invoke  proc,arg
        if check_errors
                test    rax,rax
                jnz     .okay
                push    rax
                mov     edx,.okay - .proc_name
                lea     esi,[.proc_name]
                push    STD_OUTPUT SYS_WRITE
                pop     rax rdi
                syscall
                pop     rax
                jmp     error
            .proc_name:
                db      `proc,10
            .okay:
        end if
}

virtual
        org 0
        struc r_debug {
                .r_version      rq 1    ; version number for this protocol
                .r_map          rq 1    ; head of the chain of loaded objects
                .r_brk          rq 1    ; breakpoint for debugger to monitor .so mapping changes
                .r_state        rq 1    ; object mapping state
                .r_ldbase       rq 1    ; base address the linker is loaded at
        }r_debug r_debug

        org 0
        struc link_map {
                .l_addr         rq 1    ; library load address
                .l_name         rq 1    ; file name of library
                .l_ld           rq 1    ; dynamic section of library
                .l_next         rq 1    ; next in chain
                .l_prev         rq 1    ; previous in chain
        }link_map link_map

        org 0
        struc gnu_hash {
                .bucket_count   rd 1
                .symbol_offset  rd 1
                .bloom_size     rd 1
                .bloom_shift    rd 1
                .bucket_list    rb 0
        }gnu_hash gnu_hash

        org 0
        struc Elf64_Sym {
                .st_name        rd 1
                .st_info        rb 1
                .st_other       rb 1
                .st_shndx       rw 1
                .st_value       rq 1
                .st_size        rq 1
        }Elf64_Sym Elf64_Sym
        sizeof.Elf64_Sym        = $
end virtual

format ELF64 executable 3 at 0x10000

entry begin

segment dynamic

        dq DT_NEEDED,GL - $$
        dq DT_NEEDED,SDL - $$
        dq DT_STRTAB,rva $$
        dq DT_DEBUG
                dt_debug dq ?
        dq DT_SYMTAB;,0
        ;dq DT_NULL,0

interpret:
        mov     al,SYS_EXECVE
        assert procs = interpreter
        push    rsp rbp
        pop     rdi rsi rdx
        push    rdi
segment readable writeable executable
        lea     rdx,[rsi+(rdx+2)*8]
        syscall
        if check_errors
                jmp     link_quit
        end if

begin:
        mov     ebp,procs
        push    proc_count-1
        pop     r13
        push    [dt_debug]
    .link_loop:
        pop     rax
        test    rax,rax
        jz      interpret
        mov     rdi,[rax+r_debug.r_map]
        push    rax
    .library_loop:
        mov     rsi,[rdi+link_map.l_name]
        cmp     byte[rsi],0
        jz      .next_library
        mov     rsi,[rdi+link_map.l_ld]                 ; rsi = dynamic section
    .find_tables_loop:
        lodsq
        cmp     eax,DT_GNU_HASH
        cmovz   rbx,[rsi]                               ; rbx = gnu hash table
        cmp     eax,DT_SYMTAB
        cmovz   r14,[rsi]                               ; r14 = symbol table
        test    eax,eax
        lodsq
        jnz     .find_tables_loop
        xchg    edx,eax                                 ; rdx = 0
        mov     eax,[rbp+r13*4-procs+hashes]
        mov     ecx,[rbx+gnu_hash.bucket_count]         ; rcx = bucket count
        div     ecx                                     ; rdx = target bucket
        mov     eax,[rbx+gnu_hash.bloom_size]
        lea     rax,[rbx+rax*8+gnu_hash.bucket_list]    ; rax = bucket list
        lea     rcx,[rax+rcx*4]                         ; rcx = hash chains
        mov     edx,[rax+rdx*4]                         ; rdx = chain/symbol index
        sub     edx,[rbx+gnu_hash.symbol_offset]        ; adjust symbol offset
        jb      .next_library
    .find_symbol_loop:
        mov     eax,[rbp+r13*4-procs+hashes]
        mov     esi,[rcx+rdx*4]
        xor     eax,esi
        shr     eax,1
        jz      .found_symbol
        inc     edx
        shr     esi,1                                   ; bit 0 = set, marks the end of the chain
        jnc     .find_symbol_loop
    .next_library:
        mov     rdi,[rdi+link_map.l_next]
        if check_errors
                test    rdi,rdi
                jnz     .library_loop
                jmp     link_quit
        else
                jmp     .library_loop
        end if
    .found_symbol:
        add     edx,[rbx+gnu_hash.symbol_offset]
        imul    edx,edx,sizeof.Elf64_Sym
        mov     rax,[r14+rdx+Elf64_Sym.st_value]
        add     rax,[rdi+link_map.l_addr]
        mov     [rbp+r13*8-procs+hashes],rax
        dec     r13
        jns     .link_loop
        ;
        invoke  SDL_Init,SDL_INIT_VIDEO
        if check_errors
                test    rax,rax
                jnz     error
        end if
        rinvoke SDL_SetVideoMode,half_x_res * 2,half_y_res * 2,0,SDL_OPENGL
        rinvoke glCreateProgram
        push    rax                                     ; [rsp] = program
        rinvoke glCreateShader,GL_FRAGMENT_SHADER
        xchg    rdi,rax
        push    rdi                                     ; [rsp] = shader
        push    shader
        einvoke glShaderSource,rdi,1,rsp,0
        pop     rax rdi
        push    rdi
        einvoke glCompileShader,rdi
        if check_errors
                pop     rdi
                push    rdi
                call    shader_log
                pop     rdi
                push    rdi
                push    GL_FALSE
                invoke  glGetShaderiv,rdi,GL_COMPILE_STATUS,rsp
                pop     rax
                cmp     rax,GL_FALSE
                jz      error
        end if
        pop     rsi rdi
        push    rdi
        einvoke glAttachShader,rdi,rsi
        pop     rdi
        push    rdi
        einvoke glLinkProgram,rdi
        if check_errors
                pop     rdi
                push    rdi
                invoke  glValidateProgram,rdi
                pop     rdi
                push    rdi
                call    program_log
                pop     rdi
                push    rdi
                push    GL_FALSE
                invoke  glGetProgramiv,rdi,GL_VALIDATE_STATUS,rsp
                pop     rax
                cmp     rax,GL_FALSE
                jz      error
        end if
        pop     rdi
        push    rdi                                     ; not required, but gzip finds this favourable
        einvoke glUseProgram,rdi
    .animation_loop:
        invoke  SDL_GetTicks
        push    rax
        einvoke glColor4ubv,rsp
        pop     rdi
        mov     edx,edi
        neg     edi
        einvoke glRecti,rdi,rdi,rdx,rdx
        invoke  SDL_GL_SwapBuffers
    .get_event:
        lea     edi,[rbp-procs+SDL_Event]
        invoke  SDL_PollEvent,rdi
        test    eax,eax
        jz      .animation_loop
        mov     al,[rbp-procs+SDL_Event]
        cmp     al,SDL_QUIT
        je      quit
        cmp     al,SDL_KEYDOWN
        jne     .get_event
quit:
        invoke  SDL_Quit
        xor     edi,edi
link_quit:
        push    SYS_EXIT
        pop     rax
        syscall

if check_errors
        error:
                sub     rsp,20
                mov     rsi,rsp
                push    15
                pop     rcx
            .next_nibble:
                mov     edx,eax
                and     edx,0xf
                mov     dl,[hex_table+rdx]
                mov     [rsi+rcx],dl
                shr     rax,4
                dec     ecx
                jns     .next_nibble
                mov     byte[rsi+16],10
                push    STD_OUTPUT SYS_WRITE 17
                pop     rdx rax rdi
                syscall
                add     rsp,20
                jmp     quit

        program_log:
                lea     edx,[log_buffer]
                lea     ecx,[rdx+8]
                push    0
                pop     qword[rdx]
                invoke  glGetProgramInfoLog,rdi,buffer_size,rdx,rcx
                jmp     log
        shader_log:
                lea     edx,[log_buffer]
                lea     ecx,[rdx+8]
                push    0
                pop     qword[rdx]
                invoke  glGetShaderInfoLog,rdi,buffer_size,rdx,rcx
        log:
                mov     rdx,qword[log_buffer]
                test    rdx,rdx
                jz      .ret
                lea     esi,[log_buffer+8]
                push    STD_OUTPUT SYS_WRITE
                pop     rax rdi
                syscall
            .ret:
                ret
end if

shader:
        db      "float f(vec3 o){"
        db              "float a=sin(o.z)*.3927,s=sin(a),c=cos(a);"             ; pi/8 ~= 0.3927
        db              "o=cos(vec3(cos(a)*o.x-sin(a)*o.y,sin(a)*o.x+cos(a)*o.y,o.z));"
        db              "return dot(o,o)-1.2;"
        db      "}"
        db      "vec3 s(vec3 o,vec3 d){"
        db              "float t=0.,a,b,z=t;"
        db              "for(int i=0;i<75;i++){"
        db                      "if(f(o+d*t)<z){"
        db                              "a=t-.125;b=t;"
        db                              "for(int i=0;i<10;i++){"
        db                                      "t=(a+b)*.5;"
        db                                      "if(f(o+d*t)<z)b=t;else a=t;"
        db                              "}"
        db                              "vec3 e=vec3(.1,z,z),"
        db                              "p=o+d*t,"
        db                              "n=normalize(vec3(f(p+e),f(p+e.yxy),f(p+e.yyx))+sin(p*75.)*.01);"
        db                              "return mix(((max(dot(n,vec3(.577)),z)+.125*max(dot(n,vec3(-.707,-.707,z)),z)))*"
        db                                      "(mod(length(p.xy)*20.,2.)"
        db                                      "<1.?vec3(.71,.85,.25):vec3(.79,.93,.4))"
        db                                      ",vec3(.93,.94,.85),vec3(pow(t/9.,5.))"
        db                              ");"
        db                      "}"
        db                      "t+=.125;"
        db              "}"
        db              "return vec3(.93,.94,.85);"
        db      "}"
        db      "void main(){"
        db              "float t=dot(gl_Color,vec4(1,256,65536,0))*.5;"
        db              "gl_FragColor=vec4(s(vec3(sin(t*1.5)*.5,cos(t)*.5,t),normalize(vec3((gl_FragCoord.xy-"
match hx hy, half_x_res half_y_res {
        db              "vec2(",`hx,",",`hy,"))/vec2(",`hx,"),1))),1);"
}
        db      "}",0

if check_errors
        hex_table db '0123456789abcdef'
end if

hashes:
        match =,funcs,functions { irp f,funcs \{ if used f
                hash = 5381
                virtual at 0
                        db \`f
                        while % <= $
                                load c byte from % - 1
                                hash = (hash * 33 + c) and 0xffffffff
                        end while
                end virtual
                label f qword at $ + $ - hashes
                dd hash
        end if \}}
proc_count = ($ - hashes) shr 2
procs:
interpreter:    db '/lib64/ld-linux-x86-64.so.2',0
GL              db 'libGL.so',0
SDL             db 'libSDL.so'

                rb proc_count * 4 + procs - $

SDL_Event       rb 8
SDL_key         rb 1
if check_errors
        log_buffer      rb buffer_size
end if    
Post 26 Jun 2022, 15:40
View user's profile Send private message Visit poster's website Reply with quote
sylware



Joined: 23 Oct 2020
Posts: 182
Location: Marseille/France
sylware 27 Jun 2022, 00:40
you may consider a vulkan3D port, with a native spir-v shader.
Post 27 Jun 2022, 00:40
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 18948
Location: In your JS exploiting you and your system
revolution 27 Jun 2022, 03:54
Perhaps one day. But there is currently less support for SPIR-V than GLSL

I am more interested in the ELF and assembly parts, then the shader HLL part. Razz
Post 27 Jun 2022, 03:54
View user's profile Send private message Visit poster's website Reply with quote
FlierMate1



Joined: 31 May 2022
Posts: 118
FlierMate1 27 Jun 2022, 06:07
revolution wrote:
This is a 64-bit conversion. It assembles, but I can't test it.


It can compile, but it complained an error.


Description: After referencing to libSDL2-2.0.so, this is the new error message.
Filesize: 52.72 KB
Viewed: 2152 Time(s)

clod2.png


Description: SDL shared libs on my Debian 11 x64
Filesize: 45.72 KB
Viewed: 2153 Time(s)

sdl1.png


Description:
Filesize: 124.17 KB
Viewed: 2156 Time(s)

clod.png


Post 27 Jun 2022, 06:07
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 18948
Location: In your JS exploiting you and your system
revolution 27 Jun 2022, 06:41
What is your SDL called?
Code:
ls /usr/lib/x86_64-linux-gnu/libSDL*    
Post 27 Jun 2022, 06:41
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-2020, Tomasz Grysztar. Also on GitHub, YouTube, Twitter.

Website powered by rwasa.