NASM Сервер NASM
17.09.2021, 10:22. Показов 2180. Ответов 0
С частичным использованием функций glibc.
Работать сервер будет только на 32-битном процессоре i686+
Всего нужно 11 частей
Кликните здесь для просмотра всего текста
# Objects
kcall.o:
$(NASM) kcall.asm -o $@ -l $@.lst $(NASM_DBG)
aweb.o:
$(NASM) aweb.asm -o $@ -l $@.lst $(NASM_DBG)
config.o:
$(NASM) config.asm -o $@ -l $@.lst $(NASM_DBG)
consts.o:
$(NASM) consts.asm -o $@ -l $@.lst $(NASM_DBG)
vars.o:
$(NASM) vars.asm -o $@ -l $@.lst $(NASM_DBG)
strings.o:
$(NASM) strings.asm -o $@ -l $@.lst $(NASM_DBG)
procs.o:
$(NASM) procs.asm -o $@ -l $@.lst $(NASM_DBG)
sockets.o:
$(NASM) sockets.asm -o $@ -l $@.lst $(NASM_DBG)
requests.o:
$(NASM) requests.asm -o $@ -l $@.lst $(NASM_DBG)
handler_static.o:
$(NASM) handler_static.asm -o $@ -l $@.lst $(NASM_DBG)
handler_cgi.o:
$(NASM) handler_cgi.asm -o $@ -l $@.lst $(NASM_DBG)
У меня только семь из них. Помогите у кого есть с остальными за вознаграждение.
вот коды не ругайте за тегучесть и нудность это поощряемо в валюте.
Должно быть по коду: количество строк и символов в исходниках:
Total lines in source: 1477
Chars in source: 40455
много много кода. Аккуратнее
aweb.asm
| Assembler | 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
| EXTERN kSysExit, kFork, loadConfig, startupMessage, sock
EXTERN cfgBindIp, cfgBindPort, isDoFork, strProcessForked
SECTION .code
GLOBAL _start ; program start point
_start:
mov eax, dword [isDoFork] ; should we do fork() ?
cmp eax, 0 ; really?
jz .afterFork ; no, just continue loading
.doFork:
call kFork ; do fork()
cmp eax, 0 ; 0 means we are forked
je .afterFork ; run the server
jmp .exitProgram ; parent process should exit
.afterFork:
call loadConfig ; load configuration from file
call startupMessage ; echo startup message to console
call sock ; create and listen network socket
.exitProgram:
call kSysExit ; stop the process
config.asm
; External functions
EXTERN kSysExit
; External C functions
EXTERN fgets, fopen, fclose, feof, printf
EXTERN strchr, strlen, strtok, strcmp, atoi, strcpy
EXTERN inet_addr
; External data
EXTERN strFileNotFound, strTerminating, fOpenRead, fileConfig
; Exported symbols
GLOBAL loadConfig:FUNCTION
GLOBAL cfgBindPort:DATA, cfgBindIp:DATA, cfgDocumentRoot:DATA, cfgRoot:DATA
SECTION .data
cfgBindIp: dd 127 << 0 | 0 << 8 | 0 << 16 | 1 << 24 cfgBindPort: dd 808 cfgRoot: db '/srv/www/local/' times 120 db 0 SECTION .data var: .fHandle dd 0 .num db 'num = %d', 10, 0 .pair db '|%s = %s|', 10, 0 .hint db ' hint = "%s"', 10, 0 .hintd db ' hint = "%d"', 10, 0 .delimiter db '= ', 0 .key dd 0 .value dd 0 .kPort db 'port', 0 .kIp db 'ip', 0 .kRoot db 'root', 0 SECTION .bss buffLen: equ 1024 buff: times buffLen db SECTION .code ; procedure load and parse configuration data loadConfig: push dword fOpenRead ; mode - read push dword fileConfig ; config location CALL fopen ; do fopen() add esp, 2 * 4 ; correct stack mov [var.fHandle], eax ; var.fHandle = eax cmp eax, 0 ; eax ? jne .readFile ; eax != 0 - that's ok! .cantOpen: ; Output error message push dword fileConfig push dword strFileNotFound CALL printf add esp, 2 * 4 push dword strTerminating CALL printf add esp, 4 CALL kSysExit ; quit... jmp .endProc .readFile: .checkEof: ; Check for end of file push dword [var.fHandle] ; push file handle CALL feof ; feof() add esp, 4 ; correct stack head test eax, eax ; eax? jnz .closeFile ; EOF?! .getLine: ; get 1 line from file push dword [var.fHandle] ; push handle again push dword buffLen ; buffer length push dword buff ; buffer pointer CALL fgets ; call fgets() add esp, 4 * 3 ; corrent stack test eax, eax ; check for error jz .readFile ; eax = 0 means error .correctString: ; Correct end of string - where '#' located push dword '#' ; symbol push dword buff ; config string CALL strchr ; call strchr() add esp, 4 * 2 ; stack correct cmp eax, 0 ; eax == 0 ? je .checkLength ; so check length next mov [eax], byte 0 ; set end of string .checkLength: ; check for zero length push dword buff ; string from file CALL strlen ; strlen() add esp, 4 ; esp+=4.. test eax, eax ; what about eax? jz .readFile ; It's empty string!? .removeChr10: ; remove end-of string symbol push dword 10 ; symbol push dword buff ; config string CALL strchr ; call strchr() add esp, 4 * 2 ; stack correct test eax, eax jz .isKeyValuePair mov [eax], byte 0 .isKeyValuePair: ; Search for '=', which split name = value" pair push dword '=' ; symbol push dword buff ; config string CALL strchr ; call strchr() add esp, 4 * 2 ; stack correct test eax, eax ; eax?! jz .readFile ; if eax == 0, read next line .split: ; Splits pair push dword var.delimiter ; push addr to delimiter '=' push dword buff ; string from config file CALL strtok ; strtok() add esp, 4 * 2 ; esp += 8 mov [var.key], eax ; key string push dword var.delimiter; string push dword 0 ; push NULL to retrive next token CALL strtok ; strtok(NULL, delimiter) add esp, 4 * 2 ; esp += 8 mov [var.value], eax ; value string .checkForPort: ; is key == port? push dword [var.key] ; string 1 push dword var.kPort ; string 2 CALL strcmp ; do compare add esp, 4 * 2 ; fix stack test eax, eax ; what about eax? jne .checkForIp ; not equals? next check push dword [var.value] ; addr of string with number CALL atoi ; do calculate integer value add esp, 4 ; correct stack mov [cfgBindPort], ax ; save value jmp .checkEnd ; we are done .checkForIp: ; is key == ip? push dword [var.key] ; string 1 push dword var.kIp ; string 2 CALL strcmp ; do strcmp() add esp, 4 * 2 ; correct stack test eax, eax ; what about eax? jne .checkForRoot ; not equals? next check push dword [var.value] ; ip addr CALL inet_addr ; do transform add esp, 4 ; correct stack mov [cfgBindIp], eax ; save value .checkForRoot: ; is key == root? push dword [var.key] ; string 1 push dword var.kRoot ; string 2 CALL strcmp ; do strcmp() add esp, 4 * 2 ; correct stack test eax, eax ; what about eax? jne .checkEnd ; not equals? next check push dword [var.value] ; copy from push dword cfgRoot ; copy to CALL strcpy ; copy config value item add esp, 4 * 2 ; correct stack .checkEnd: jmp .readFile push dword [var.value] push dword [var.key] push dword var.pair call printf add esp, 4 * 3 jmp .readFile ; read next line .closeFile: push dword [var.fHandle] ; file handle to close CALL fclose ; make fclose() add esp, 4 ; stack.. .endProc: ret |
|
consts.asm
| Assembler | 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
| SEGMENT .rodata
GLOBAL fOpenRead:DATA, fOpenWrite:DATA, fOpenAppend:DATA
fOpenRead: db 'r', 0 ; read only flag
fOpenWrite: db 'w', 0 ; write flag
fOpenAppend: db 'a', 0 ; append file
GLOBAL strFileNotFound:DATA, strTerminating:DATA, strDebugGeneral:DATA
GLOBAL strStartMsg:DATA, strProcessForked:DATA, strHandlerStatic:DATA
strFileNotFound: db 'File "%s" is not found!', 10, 0
strTerminating: db 'Terminating application..', 10, 0
strDebugGeneral: db '%s: %s', 10, 0
strStartMsg: db 10, 'Starting up server, build date: ', \
__DATE__, ' ',__TIME__, \
'. Bind to %s:%d', 10, 0
strProcessForked: db 'Process forked, pid: %d', 10, 0
strHandlerStatic: db 'handlerStatic: %s', 10, 0
GLOBAL fileDebug:DATA, fileConfig:DATA
fileDebug: db './debug.log',0 ; file for debug info
fileConfig: db './aweb.conf',0 ; config file
GLOBAL maxConnections:DATA
maxConnections: dd 1024
GLOBAL maxHeaders:DATA
maxHeaders: dd 1024
GLOBAL cgiBinFolder:DATA
cgiBinFolder: db '/cgi-bin', 0 ; prefix for cgi programs
GLOBAL headerHTTP200:DATA, headerStd:DATA, headerServer:DATA
headerHTTP200: db 'HTTP/1.0 200 OK', 10, 13, 0
headerServer: db "Server: ruX's simple web server written in NASM", 10, 13, 0
headerStd:
db 'Connection: close', 10, 13
db 'Cache-Control: no-cache,no-store,max-age=0,must-revalidate', 10, 13
db 10, 13
db 0
GLOBAL isDoFork:DATA
isDoFork: dd 1 |
|
sockets.asm
| Assembler | 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
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
| EXTERN cfgBindIp, cfgBindPort, maxConnections, headerServer
EXTERN htons, shutdown, fprintf, printf, malloc, free, realloc, strlen
EXTERN kSocketCall, kClose, processRequest
GLOBAL sendServerHeader:FUNCTION
; Constants used for arguments(from kernel source)
%define AF_INET 2
%define IPPROTO_TCP 6
%define SOCK_STREAM 1
%define PF_INET 2
%define MSG_PEEK 2
%define MSG_WAITALL 100h
%define SOL_SOCKET 1
%define SO_REUSEADDR 2
; Function numbers
%define SYS_SOCKET 1
%define SYS_BIND 2
%define SYS_LISTEN 4
%define SYS_ACCEPT 5
%define SYS_SEND 9
%define SYS_RECV 10
%define SYS_SETSOCKOPT 14
; Step increase memory for receive buffer
%define REALLOC_STEP 64
SECTION .data
connect db "We have a connection!", 10, 0 ; First string...
hello db "Hello... =]", 10, 0 ; Second string...
goodbye db "Goodbye... =[", 0 ; Third string...
socksbroke db "ERROR: socket() failed!", 10, 0 ; Fourth string...
bindsbroke db "ERROR: bind() failed!", 10, 0 ; Fifth string...
listensbroke db "ERROR: listen() failed!", 10, 0 ; Sixth string...
acceptsbroke db "ERROR: accept() failed!", 10, 0 ; Seventh string...
retval db "value buffer: %d, recv: %d", 10, 0
retstr db "recived: %s", 10 , 0
html db "HTTP 1.1", 10, 0, '$'
html_len equ $ - html
one dd 1
sa: ; sockaddr_in structure
.sin_family dw 0
.sin_port dw 0
.sin_addr dd 0
sock_args: ; socket() function argument
dd PF_INET, SOCK_STREAM, IPPROTO_TCP
bind_args: ; bind() function arguments
.fd dd 0 ; socket handle
.sockaddr dd sa ; pointer to sockaddr structure
.socklen_t dd 16 ; socklen_t addrlen
listen_args: ; listen() function arguments
.sock dd 0 ; sock handle
.backlog dd maxConnections ; max connections
accept_args: ; accept() arguments
.sockfd dd 0 ; socket handle
.addr dd 0 ; struct sockaddr *addr
.addrlen dd 0 ; socklen_t *addrlen
sockopts_args: ; setsockopt() and getsockopt() args
.sockfd dd 0 ; socket handle
.level dd SOL_SOCKET ; manipulation level
.optname dd SO_REUSEADDR ; option in selected level
.optval dd one ; option value
.optlen dd $ - one ; size of option value
socketfd: dd 0 ; socket handle
section .code ; Section Declaration
GLOBAL sock
sock:
; mov ebp, esp
;int socket(int domain, int type, int protocol);
.doSocket:
mov ebx, SYS_SOCKET ; socket() = int call 1
mov ecx, dword sock_args ; arguments to socket()
CALL kSocketCall
mov [socketfd], eax ; save socket handle
;
cmp eax, -1
je sockerr
;int setsockopt(int s, int level, int optname,
; const void *optval, socklen_t optlen);
.setSockOpt:
; ignoring port in state TIME_WAIT
mov ebx, SYS_SETSOCKOPT
mov eax, dword [socketfd]
mov [sockopts_args.sockfd], eax
mov ecx, dword sockopts_args
CALL kSocketCall
cmp eax, -1
je sockerr
;int bind(int socket, const struct sockaddr *address,
; socklen_t address_len);
.doBind:
; fillup sockaddr
mov [sa.sin_family], word AF_INET ; address family
mov al, byte [cfgBindPort+1] ; reverse bytes hi=>lo
mov ah, byte [cfgBindPort] ; reverse bytes lo=>hi
mov [sa.sin_port], ax ; set port
mov eax, dword [cfgBindIp] ; get ip from config
mov [sa.sin_addr], eax ; set ip to structure
; form arguments
mov eax, dword [socketfd] ; copy socket
mov [bind_args.fd], eax ; handle to struct
mov ebx, SYS_BIND ; require bind()
mov ecx, bind_args ; bind arguments
CALL kSocketCall
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Do a little error-echecking here...
cmp eax, -1
je binderr
; int listen(int socket, int backlog);
.doListen:
mov eax, [socketfd] ; copy socket handle
mov[listen_args.sock], eax ; to structure listen_args
mov ebx, SYS_LISTEN ; require listen()
mov ecx, listen_args ; arguments
CALL kSocketCall
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Do a little error-echecking here...
cmp eax, -1
je listenerr
;accept(fd, NULL, 0);
.doAccept:
mov eax, [socketfd] ; copy socket handle
mov [accept_args.sockfd], eax ; to structure
mov ebx, SYS_ACCEPT ; we need accept() function
mov ecx, accept_args ; ptr to arguments
CALL kSocketCall
; Do a little error-echecking here...
cmp eax, -1
je accepterr
.processConnection: ; here we have a connected socket peer in eax
push eax
CALL connectionHandler
jmp .doAccept
;
;exit_s(0)
exit_s:
; mov esp, ebp
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; These are just to print an error message to stdout should
; one of our socketcall()'s fail.
sockerr:
mov eax, 4
mov ebx, 1
mov ecx, socksbroke
mov edx, 24
int 0x80
jmp exit_s
binderr:
mov eax, 4
mov ebx, 1
mov ecx, bindsbroke
mov edx, 22
int 0x80
jmp exit_s
listenerr:
mov eax, 4
mov ebx, 1
mov ecx, listensbroke
mov edx, 24
int 0x80
jmp exit_s
accepterr:
mov eax, 4
mov ebx, 1
mov ecx, acceptsbroke
mov edx, 24
int 0x80
jmp exit_s
; connection handler function
; get 1 arg - socket handle
connectionHandler:
push ebp
mov ebp, esp ; preserve esp
%define sock dword [ebp+8] ; connected socket
jmp .initVars
.vars: ; declare variables (allocate memory for each)
; begin recv_args structure (argument for recv function)
%define recv_args 8 ; main offset from esp
%define recv_args_sock esp+recv_args
%define recv_args_buffer esp+4+recv_args
%define recv_args_length esp+8+recv_args
%define recv_args_flags esp+12+recv_args
sub esp, 16 ; allocate memory for recv_args
%define send_args 16
%define send_args_sock 16
.initVars:
mov eax, sock
mov [recv_args_sock], eax
mov [recv_args_flags], dword MSG_PEEK
mov [recv_args_length], dword REALLOC_STEP
.code:
.alloc:
push dword [recv_args_length]; count of bytes we need
CALL malloc ; allocate memory from heap
add esp, 4 ; correct stack
mov [recv_args_buffer], eax ; save pointer to buffer
.recvLength:
mov ebx, SYS_RECV ; we need recv()
mov ecx, esp
add ecx, recv_args ; arguments
CALL kSocketCall
cmp eax, dword -11 ; try again code?
je .recvLength ; recieve again
mov edx, eax
mov ebx, dword [recv_args_length]
push edx
push ebx
push retval
call printf
add esp, 8
pop eax
cmp eax, [recv_args_length]
jb .recv
.realoc:
add [recv_args_length], dword REALLOC_STEP
mov eax, dword [recv_args_buffer]
push dword [recv_args_length]
push eax
CALL realloc
add esp, 2 * 4
mov [recv_args_buffer], eax
jmp .recvLength
.recv:
mov ebx, SYS_RECV ; we need recv()
mov [recv_args_flags], dword 0 ; without flags!
mov ecx, esp ; point ecx ..
add ecx, recv_args ; .. to arguments
CALL kSocketCall ; do recv()
mov [recv_args_length], eax ; store received message length
cmp eax, 0 ; is there any error?
jbe .closeSocket ; then cancel request
push dword [recv_args_buffer]
push dword sock
CALL processRequest ; let's process request!
.closeSocket:
push sock
call kClose
.freeMem:
mov eax, dword [recv_args_buffer]
push eax
CALL free
add esp, 8
mov [recv_args_length], dword 0 ; mark block as free
.return:
cmp [recv_args_length], dword 0 ; we used malloc?
jne .freeMem ; yeah, so we need free memory
mov esp, ebp ; restore stack poiter
pop ebp
ret 4
;write(1, "We have a connection!", 22);
mov eax, 4 ; write() syscall
mov ebx, 1 ; stdout
mov ecx, connect ; our string
mov edx, 22 ; 22 characters in length
int 0x80 ; Call the kernel
;
;write(fd, "Hello... =]", 12);
mov eax, 4 ; write() syscall
mov ebx, edi ; sockfd
mov ecx, hello ; our string to send
mov edx, 12 ; 12 characters in length
int 0x80 ; Call the kernel
;push dword hello
;push dword edi
;call fprintf
;add esp, 8
;
;write(fd, "Goodbye... =[", 14);
mov eax, 4 ; write() syscall
mov ebx, edi ; sockfd
mov ecx, goodbye ; our string to send
mov edx, 14 ; 14 charactes in length
int 0x80 ; Call the kernel
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Now we clean up (Close the open file descriptor/s etc.) and exit_s
push dword edi
Call shutdown
pop eax
;close(fd)
push edi
CALL kClose
mov eax, 0
ret
; send to socket 'Server' header
; first argument in stack - sock handle
sendServerHeader:
push ebp
mov ebp, esp
push dword headerServer ; string to send
call strlen ; get string length
add esp, 4 ; correct stack
push dword 0 ; flags
push eax ; length
push dword headerServer ; header string
push dword [ebp+8] ; socket handle
mov ecx, esp ; ptr to struct in stack
mov ebx, 9 ; send() function number
call kSocketCall ; call it
add esp, 4 * 4 ; correct stack space
mov esp, ebp ; restore base stack pointer
pop ebp
ret 4 |
|
helpers.asm
| Assembler | 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
| ; debugLine TYPE, INFO
%macro debugLine 2
EXTERN fileDebug, fopen, fclose, fprintf, fOpenAppend, strDebugGeneral
jmp %%code ; go to code area
%%type: db %1, 0 ; type of message
%%info: db %2, 0 ; message
%%code:
pusha ; save registers
push fOpenAppend ; just 'a\0' string
push fileDebug ; filename
CALL fopen ; call fopen()
add esp, 2 * 4 ; clean stack
push eax ; small trick - push arg for fclose
push %%type ; offset to first %s
push %%info ; second %s
push strDebugGeneral; format string
push eax ; file handle
CALL fprintf ; fprintf()
add esp, 4 * 4 ; correct stack only for fprintf
CALL fclose ; call fclose(), handle pushed before
add esp, 4 ; correct stack
%%endmacro:
popa ; restore back registers
%endmacro
requests.asm
GLOBAL processRequest
EXTERN strlen, printf, fprintf, strtok, malloc, memset, strchr, free, strncmp, send
EXTERN strDebugGeneral, maxHeaders, cgiBinFolder, handlerStatic
EXTERN kSocketCall
SEGMENT .data
header_sep: db 10, 13, 0
juststr: db "%s",10,0
SEGMENT .code
STRUC tRequest, -30
.filename: resd 1
.method: resd 1
.socket: resd 1
.request: resd 1
.requestLen: resd 1
ENDSTRUC
; Process user requests
; arguments: socket/(dword) request(dword,ptr)
processRequest:
push ebp ; preserve ebp
mov ebp, esp ; new local offset
sub esp, 30 ; space for structure in stack
%define lv_offset 30
sub esp, lv_offset
%define headers ebp - 30 - lv_offset + 0
%define i ebp - 30 - lv_offset + 4
%define j ebp - 30 - lv_offset + 8
%define buf ebp - 30 - lv_offset + 12
%define len ebp - 30 - lv_offset + 16
%define str ebp - 30 - lv_offset + 20
mov eax, dword [ebp + 8] ; get socket id from stack
mov dword [ebp + tRequest.socket], eax
mov eax, dword [ebp + 12] ; get request string
mov dword [ebp + tRequest.request], eax
push dword [ebp + tRequest.request] ; calculate
call strlen ; request length
add esp, 4 ; cleanup stack
mov dword [ebp + tRequest.requestLen], eax ; remember length
push dword 0
push '->> '
mov eax, esp
push dword 0
push '<<- ' push esp push eax push strDebugGeneral call printf add esp, 4 * 3 .allocBuffers: ;.. for header line push dword 1 << 14 ; 16Kb call malloc ; requre some memory add esp, 4 ; correct stack mov [buf], eax ; save pointer to memory block mov [eax], dword 0 ; length = 0 ; ..for array of pointers to string(enviroment) mov eax, dword [maxHeaders] mov bl, 4 mul bl push eax call malloc mov [headers], eax push dword 0 push dword [headers] call memset add esp, 4 * 3 ; ..for url buffer push dword 2048 ; maximum url length (rfc) call malloc ; do allocate add esp, 4 ; correct stack mov [ebp + tRequest.filename], eax ; save point to url .breakHeaders: push dword header_sep push dword [ebp + tRequest.request] call strtok add esp, 4 * 2 cmp eax, 0 je .breakHeadersEnd .httpRequest: mov [str], eax ; save pointer to header string mov ebx, [str] mov [ebp + tRequest.method], ebx push dword ' ' push dword [str] call strchr add esp, 4 * 2 mov [eax], byte 0 ; break method and url inc eax mov [ebp + tRequest.filename], eax push dword ' ' push dword [ebp + tRequest.filename] call strchr add esp, 4 * 2 mov [eax], byte 0 ; break url and http push dword header_sep push dword 0 call strtok ; AAAAAA strtok_r add esp, 4 * 2 cmp eax, 0 je .breakHeadersEnd .breakHeadersLoop: mov [str], eax ; save pointer to header string push dword [str] ; get current header length push juststr call printf pop eax pop eax ; jmp .breakHeadersEnd push dword header_sep push dword 0 call strtok ; AAAAAA strtok_r add esp, 4 * 2 cmp eax, 0 jne .breakHeadersLoop .breakHeadersEnd: push dword [ebp + tRequest.filename] push dword juststr call printf mov eax, ebp add eax, tRequest push eax CALL preprocessRequest .endproc: .freeBuffers: push dword [headers] call free push dword [buf] call free mov esp, ebp ; restore base stack pointer pop ebp ret 4 * 2 preprocessRequest: push ebp ; preserve ebp mov ebp, esp ; new local offset %define reqFilename ebp+16 push dword 0 push dword 10 ; count of bytes push dword [reqFilename] push dword [ebp+8] pop eax add eax, 8 push eax call send add esp, 4*4 push dword cgiBinFolder ; get '/cgi-bin' call strlen ; get length of string add esp, 4 ; correct stack push eax ; compare length is a last argument push dword cgiBinFolder ; address of string push dword [reqFilename]; addr of file name call strncmp ; compare start of strings add esp, 4 * 3 ; correct stack cmp eax, 0 ; is start are same in both strings? jz .cgiHere ; hey! there is cgi program! .staticHere: mov ebx, ebp ; filename - first field in structure add ebx, 16 push dword [ebx] call handlerStatic ; call static content processor jmp .endproc .cgiHere: jmp .cgiHereNext .cgiherestring: db 'Hey! There is cgi interface!', 10, 0 .cgiHereNext: push dword .cgiherestring call printf add esp, 4 jmp .endproc .endproc: mov esp, ebp ; restore base stack pointer pop ebp ret 4 |
|
procs.asm
| Assembler | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| EXTERN cfgBindPort, cfgBindIp, strStartMsg
EXTERN inet_ntoa, printf
GLOBAL startupMessage:FUNCTION
; Just output startup message
startupMessage:
xor eax, eax
mov ax, [cfgBindPort]
push eax
push dword [cfgBindIp]
call inet_ntoa
add esp, 4
push eax
push strStartMsg
call printf
add esp, 4 * 3
ret |
|
Добавлено через 10 минут
Автор сея рукоделия не найден, может быть умер.
Кликните здесь для просмотра всего текста
##
# SPbSU IFMO, Zaharov Ruslan, 3156.
##
0
|