-
Notifications
You must be signed in to change notification settings - Fork 5
/
dev.asm
174 lines (143 loc) · 8.96 KB
/
dev.asm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
; Last Digital Common Ancestor (LDCA)
;
; Self-replicating, self-modifying Assembly program that can evolve into
; every possible computer program in the universe.
;
; Author: M. Mert Yildiran <me@mertyildiran.com>
; Licensed under the GNU General Public License v2.0
;
; Target architecture: Linux x86
; Compile with: nasm -f bin -o 0000000000000000000000000000000000000000000000000 ldca.asm
%include "macros.asm"
BITS 32
org 0x00010000
ehdr: ; Elf32_Ehdr
db 0x7F, "ELF", 1, 1, 1, 0 ; e_ident
times 8 db 0
dw 2 ; e_type
dw 3 ; e_machine
dd 1 ; e_version
dd _start ; e_entry
dd phdr - $$ ; e_phoff
dd 0 ; e_shoff
dd 0 ; e_flags
dw ehdrsize ; e_ehsize
dw phdrsize ; e_phentsize
dw 1 ; e_phnum
dw 0 ; e_shentsize
dw 0 ; e_shnum
dw 0 ; e_shstrndx
ehdrsize equ $ - ehdr
phdr: ; Elf32_Phdr
dd 1 ; p_type
dd 0 ; p_offset
dd $$ ; p_vaddr
dd $$ ; p_paddr
dd filesize ; p_filesz
dd filesize ; p_memsz
dd 7 ; p_flags
dd 0x1000 ; p_align
phdrsize equ $ - phdr
fname: times 49 db '0' ; Apparently 49 is the filename length limit
dw 0
programstart equ $
program: mov eax, 4 ; 5 = sys_write
mov ebx, 1 ; 1 = stdout
push 'A'
mov ecx, esp ; esp now points to your char
mov edx, 1 ; edx should contain how many characters to print
int 0x80 ; sys_write(1, 'A', 1)
add esp, 4
programend equ $
times 200 nop
noopend equ $
ret
programsize equ programend - programstart
endoffset dd 0
do_inc_fname: inc byte [ebx] ; Increment the filename
ret
loop_inc_fname: cmp byte [ebx], 57 ; Compare char to 9
jne do_inc_fname ; if it's not 9, jump
mov byte [ebx], '0' ; if it's 9, replace it with 0
dec ebx ; increase the digit
call loop_inc_fname ; repeat
ret
inc_fname: mov ebx, fname ; Move the pointer to filename into ebx
add ebx, 48 ; move cursor into the last character of the filename
call loop_inc_fname ; Increment the filename
mov ebx, fname ; Fix ebx into beginning of filename
ret
rand_byte: mov ebx, program ; Move the cursor to the beginning of the program
mov ecx, programsize - 1 ; Random Number Generator (customized to supply the true programsize)
add ecx, [endoffset] ; find the true size of the program by adding the end offset
rdtsc ; Generate random bytes using CPU's clock (Read Time-Stamp Counter)
xor edx, edx ; there's no division of eax
div ecx ; edx:eax / ecx --> eax quotient, edx remainder
inc ecx ; possible values
mov eax, edx ; eax = [0, %1 - 1]
add ebx, eax ; go N instructions forward (N = random offset in the eax register)
rdtsc ; generate random bytes using CPU's clock (Read Time-Stamp Counter)
mov byte [ebx], al ; replace the byte with a randomly generated byte
ret
left_shift: mov ebx, eax ; Copy delete offset to ebx
inc ebx ; increment ebx
mov ecx, [ebx] ; move the byte pointed by ebx into ecx (left shift - first half)
mov byte [eax], cl ; move the byte pointed by ecx into eax (left shift - second half)
inc eax ; go one byte forward
cmp eax, programend - 1 ; compare eax to filesize
jng left_shift ; if eax not greater than the filsize then repeat
ret
shrink: mov eax, 1 ; 1 = delete offset
add eax, programstart ; add programstart offset to delete offset to find the true address
call left_shift ; left shift the whole program starting from the delete offset
ret
shrink_if: mov eax, 1 ; 1 = delete size
cmp eax, programend - 1 ; compare delete size to programsize
jl shrink ; shrink if delete size is less than programsize
call grow ; otherwise grow
ret
grow: mov eax, 1 ; Grow size
mov ebx, programend - 1 ; mov program's end to eax
add ebx, eax ; go "Grow size" instructions forward
add ebx, [endoffset] ; find the true end of the program by adding the end offset
rdtsc ; generate random bytes using CPU's clock (Read Time-Stamp Counter)
mov byte [ebx], al ; replace the byte with a randomly generated byte
inc byte [endoffset] ; increment the end offset
ret
grow_if: mov eax, programend ; mov program's end to eax
add eax, [endoffset] ; find the true end of the program by adding the end offset
cmp eax, noopend - 1 ; compare program's end to NOOP section's end
jl grow ; grow if programsize is less than NOOP section size
call rand_byte ; otherwise random byte
ret
mutate: rndNum 0, 99 ; Generate random number between 0 and 99
cmp eax, 80 ; compare eax (random number) with 80
jl rand_byte ; 80% : change a random byte without growing or shrinking the program
cmp eax, 85 ; compare eax (random number) with 85
jl shrink_if ; 5% : shrink the program randomly
jmp grow_if ; 15% : grow the program randomly
ret
replicate: call mutate ; mutate
mov eax, 5 ; 5 = sys_open
call inc_fname ; increment the filename
mov ecx, 65 ; 65 = O_WRONLY | O_CREAT
mov edx, 777q ; file mode (octal)
int 0x80 ; sys_open(fname, 65, 777)
lea edx, [filesize] ; load effective address of filesize
xchg eax, ebx ; move the file descriptor in eax to ebx
xchg eax, ecx ; swap eax and ecx
mov cl, 0 ; point out to the beginning of the program by removing first 8 bits
mov al, 4 ; 4 = sys_write
int 0x80 ; sys_write(file_descriptor, *content, filesize)
mov eax, 6 ; 6 = sys_close
int 0x80 ; sys_close(file_descriptor)
call replicate ; run the offspring with forking
ret
exit: mov bl, 0 ; 0 = Exit code
mov al, 1 ; 1 = sys_exit
int 0x80 ; sys_exit(0)
_start: ; call program
call replicate ; replicate subroutine must not fail!
call exit
filesize equ $ - $$
fileend equ $