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
175
|
section .data
; This is stack of 4KB:
db 4096 dup 0
stackbottom:
; Place to copy msg content into:
msg:
db 1024 dup 0
; And finally our program:
program:
dd bismuth ; We want to use our main interpreter, bismuth.
dd data
dd prog
dd data
dd 0x0a20202e
dd 0x2e2e6948
dd quote, eval, 0, pop
dd quote, eval, 0
dd 0, quote, msg, copywords
dd data, msg, eval, msg, eval, 0, output
dd 0
; The input is in esi, pop dword from it:
%macro bisnext 1
mov %1, dword [esi]
add esi, 4
%endmacro
; Top of the stack is in edi, pop dword from it:
%macro bispop 1
mov %1, dword [edi]
add edi, 4
%endmacro
; Top of the stack is in edi, pop byte from it:
%macro bispopbyte 1
mov %1, byte [edi]
inc edi
%endmacro
; Top of the stack is in edi, push dword onto it:
%macro bispush 1
sub edi, 4
mov dword [edi], %1
%endmacro
; Top of the stack is in edi, push byte onto it:
%macro bispushbyte 1
dec edi
mov byte [edi], %1
%endmacro
; Calling conventions for interpreters:
%macro bisinterpret 1
push esi
mov esi, %1
bisnext eax
add eax, 4
push ebp
mov ebp, esp
call eax
mov esp, ebp
pop ebp
pop esi
%endmacro
section .text
global _start
_start:
mov esi, program ; We will read and execute program
mov edi, stackbottom ; and write results onto stack.
bisnext eax ; Read interpreter
bisinterpret eax ; and start interpretation.
; After execution of program we will exit properly:
mov ebx, 0 ; We have no error (error code = 0)
mov eax, 1 ; and we want to exit.
int 0x80 ; Send this to kernel.
; That's all! =)
bismuth:
dd bismuth
mov esi, [ebp+4]
bismuthloop:
bisnext eax
cmp eax, 0
je bismuthend
bisinterpret eax
jmp bismuthloop
bismuthend:
mov [ebp+4], esi
ret
prog:
dd prog
progloop:
bisnext eax
cmp eax, 0
je progend
bisinterpret eax
jmp progloop
progend:
ret
pop:
dd pop
add edi, 4
ret
copy:
dd copy
mov eax, dword [edi]
sub edi, 4
mov dword [edi], eax
ret
quote:
dd quote
mov esi, [ebp+4]
bisnext eax
bispush eax
mov [ebp+4], esi
ret
eval:
dd eval
mov esi, [ebp+4]
bispop eax
bisinterpret eax
mov [ebp+4], esi
ret
data:
dd data
mov esi, [ebp+4]
push edi
dataloop:
bisnext eax
cmp eax, eval
je dataeval
cmp eax, 0
je dataend
bispush eax
jmp dataloop
dataeval:
bisinterpret eax
jmp dataloop
dataend:
pop eax
sub eax, edi
bispush eax
mov [ebp+4], esi
ret
copywords:
dd copywords
bispop ebx
bispop ecx
sub ebx, 4
copywordsloop:
bispop eax
mov dword [ebx+ecx], eax
sub ecx, 4
jnz copywordsloop
ret
output:
dd output
bispop edx
mov ecx, edi
mov ebx, 1
mov eax, 4
int 0x80
add edi, edx
ret
|