flat assembler
Message board for the users of flat assembler.

Index > Windows > Dynamic function adding

Author
Thread Post new topic Reply to topic
SC0U7



Joined: 20 Feb 2018
Posts: 23
SC0U7 10 Oct 2019, 06:50
Hello is possible to generate a random function run time inside fasm? When yes how Some tutorials or examples or articles ? Thanks i need some like this

Start program
generate random number ex. 15
use this number for new maximum created function Func1,Func2...Func15
All functions do only simple print like print that random number

and last it add self to start like

start:
Func1
Func2
Func3
...
Func15

Then simple execute it

Any ideas? Thx for any help [/b]
Post 10 Oct 2019, 06:50
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8357
Location: Kraków, Poland
Tomasz Grysztar 10 Oct 2019, 07:51
It might be possible with fasm, but is definitely easier with fasmg. In my text about multi-pass assembly you can see an example of randomly generated code.
Post 10 Oct 2019, 07:51
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8357
Location: Kraków, Poland
Tomasz Grysztar 12 Oct 2019, 09:19
Here comes a self-contained example that generates and assembles some random jumps:
Code:
xorshift = %t

struc rand32
        . = xorshift shr 96
        . = ( . xor (. shl 11) xor (. shr 8) xor (xorshift) xor (xorshift shr 19) ) and 0FFFFFFFFh
        xorshift = (. or xorshift shl 32) and 0FFFFFFFF_FFFFFFFF_FFFFFFFFh
end struc

struc rand limit
        while 1
                . rand32
                . = . and (1 shl (bsr (limit) + 1) - 1)
                if . <= limit
                        break
                end if
        end while
end struc

include 'cpu/80386.inc'

NUMBER_OF_JUMPS := 100

repeat NUMBER_OF_JUMPS, n:0
        randomjump#n:
        R rand NUMBER_OF_JUMPS-1
        repeat 1, target:R
               jmp randomjump#target
        end repeat
end repeat
    

And I also managed to adapt it to fasm 1, though it is not as clean:
Code:
xorshift = %t
xorshiftH = 0

struc rand32
{
        . = xorshiftH shr 32
        . = ( . xor (. shl 11) xor (. shr 8) xor (xorshift) xor (xorshift shr 19) ) and 0FFFFFFFFh
        xorshiftH = (. shr 64 or xorshift shr 32)
        xorshift = (. or (xorshift and 0FFFFFFFFh) shl 32)
}

struc rand limit
{
        while 1
                . rand32
                . = . and (1 shl (bsr (limit) + 1) - 1)
                if . <= limit
                        break
                end if
        end while
}

NUMBER_OF_JUMPS equ 100

macro jmprand target_number
{
        if 0
        rept NUMBER_OF_JUMPS n:0
        \{
                else if n = target_number
                     jmp randomjump\#n
        \}
        end if
}

rept NUMBER_OF_JUMPS n:0
{
        randomjump#n:
        R rand NUMBER_OF_JUMPS-1
        jmprand R
}
    
But because doing this with fasm 1 is tricky, is has much worse performance for larger numbers of jumps.
Post 12 Oct 2019, 09:19
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8357
Location: Kraków, Poland
Tomasz Grysztar 13 Oct 2019, 20:53
Perhaps generating a sequence of completely random jumps was not the best example, as this is not even a code that you could run and test.

So I tried to change the example to generate a random permutation, and then use this permutation to order the jumps. Now this makes a random sequence where every jump is visited exactly once and finally the execution exits at the end point. It is a fun thing to watch it in a debugger.

Implementation in fasmg looks like:
Code:
xorshift = %t

struc rand32
        . = xorshift shr 96
        . = ( . xor (. shl 11) xor (. shr 8) xor (xorshift) xor (xorshift shr 19) ) and 0FFFFFFFFh
        xorshift = (. or xorshift shl 32) and 0FFFFFFFF_FFFFFFFF_FFFFFFFFh
end struc

struc rand limit
        while 1
                . rand32
                . = . and (1 shl (bsr (limit) + 1) - 1)
                if . <= limit
                        break
                end if
        end while
end struc


NUMBER_OF_JUMPS := 100

virtual at 1

        Permutation::

        ; initialize trivial permutation:
        assert NUMBER_OF_JUMPS < 256
        repeat NUMBER_OF_JUMPS
               db %-1
        end repeat

        ; randomize permutation (via Knuth shuffle) except for the last element:

        repeat NUMBER_OF_JUMPS-2
                SWAP rand NUMBER_OF_JUMPS-1-%
                if SWAP
                        load A: byte from %
                        load B: byte from %+SWAP
                        store A: byte at %+SWAP
                        store B: byte at %
                end if
        end repeat

end virtual


include 'cpu/80386.inc'

        jmp     jump0

repeat NUMBER_OF_JUMPS
        load order: byte from Permutation:%
        repeat 1, n:order, m:order+1
                jump#n:
                if m < NUMBER_OF_JUMPS
                        jmp     jump#m
                end if
        end repeat
end repeat    
And this also can be adapted for fasm 1:
Code:
xorshift = %t
xorshiftH = 0

struc rand32
{
        . = xorshiftH shr 32
        . = ( . xor (. shl 11) xor (. shr 8) xor (xorshift) xor (xorshift shr 19) ) and 0FFFFFFFFh
        xorshiftH = (. shr 64 or xorshift shr 32)
        xorshift = (. or (xorshift and 0FFFFFFFFh) shl 32)
}

struc rand limit
{
        local L
        L = limit
        while 1
                . rand32
                . = . and (1 shl (bsr L + 1) - 1)
                if . <= L
                        break
                end if
        end while
}


NUMBER_OF_JUMPS equ 100

virtual at 1

        Permutation::

        ; initialize trivial permutation:
        assert NUMBER_OF_JUMPS < 256
        repeat NUMBER_OF_JUMPS
               db %-1
        end repeat

        ; randomize permutation (via Knuth shuffle) except for the last element:

        repeat NUMBER_OF_JUMPS-2
                SWAP rand NUMBER_OF_JUMPS-1-%
                if SWAP
                        load A byte from %
                        load B byte from %+SWAP
                        store byte A at %+SWAP
                        store byte B at %
                end if
        end repeat

end virtual


        jmp     jump0

repeat NUMBER_OF_JUMPS
        load order byte from Permutation:%
        if 0
        rept NUMBER_OF_JUMPS n:0
        {
                else if n = order
                     jump#n:
        }
        end if
        if 0
        rept NUMBER_OF_JUMPS m:0
        {
                else if m = order+1
                     jmp jump#m
        }
        end if
end repeat    
Post 13 Oct 2019, 20:53
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.