I am trying to teach myself some NASM x86 assembly using some Unix system calls. I am trying to create a simple TCP server and I have the code working up until the send() command. I can connect via telnet but I get a segfault once my code reaches the point where it tries to send a response to the client.
This is the segment of code that is producing a segfault:
; push on to stack for send
push dword 0
push dword [start_len]
push dword [start]
push dword [socket]
; send something back
; THIS IS WHERE THE SEGFAULT OCCURS
mov eax,102
mov ebx,9 ; send is 9
mov ecx,esp
int 80h
Here is the full source code if anyone wants to look at it. Any help would be greatly appreciated!
; constants go here
section .data
start: db 'Starting Socket...',0
start_len: equ $-start
; variables go here
section .bss
socket: resd 1 ; store the fd for the socket
socket_address: resd 2 ; socket address
; starttttt
section .text
global _start
open_socket:
; print we are starting
mov eax,4
mov ebx,1
mov ecx,start
mov edx,start_len
int 80h
; push values to stack to make call
; values go in in opposite order, so when they are popped
; it is the correct order
; below is for a tcp socket
push dword 6
push dword 1
push dword 2
; make call to open socket
mov eax,102 ; 102 is the call to open socket
mov ebx,1 ; sub call, socket()
mov ecx,esp
int 80h
; store the file descriptor for the socket
mov dword[socket],eax
; this is the socket address to bind to
push dword 0x00000000 ; localhost (127.0.0.1)
push dword 0x2823 ; port 9000
push word 2 ; AF_INET (IPv4)
mov [socket_address],esp ; move to our socket address variable
; setup parameters for bind call bind(socket, socket_address, 16)
push dword 16
push dword [socket_address]
push dword [socket]
; call subcall for socket to bind
mov eax,102; sys_socket
mov ebx,2 ; subcall 2 = bind()
mov ecx,esp ; push vars from stack to params
int 80h
; setup parameters for listen()
push byte 20
push dword [socket]
; call listen()
mov eax,102 ; socket call
mov ebx,4 ; subcall listen()
mov ecx,esp ; move stack as variables
int 80h
; now we have to accept incoming connections...
; setup the call
push 0
push 0
push dword [socket]
; call accept()
mov eax,102
mov ebx,5
mov ecx,esp
int 80h
; push on to stack for send
push dword 0
push dword [start_len]
push dword [start]
push dword [socket]
; send something back
; THIS IS WHERE THE SEGFAULT OCCURS
mov eax,102
mov ebx,9 ; send is 9
mov ecx,esp
int 80h
; function to exit the program
exit:
mov eax,1
mov ebx,0
int 80h
; main function to be called
_start:
; open it
call open_socket
Related
assembly language
**main.asm**
%include "lib.asm"
section .text
global _start
_start:
;
; YOUR CODE HERE!
;
; SAMPLE
mov rdi, 65526 ; going to print 65536
call print_num ; print the number
call print_lf ; move to next line
exit:
mov rax, 60 ; exit
mov rdi, 0 ; return code
syscall
this is my Assembly source code for windows socket (ws2)
this program compiled without any problem but on execution time, program crash (for seconds, program do nothing)
what is the problem ? i think the problem is about stack or ...
format PE CONSOLE
entry start
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
section '.bss' writeable readable
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
____STD_OUTPUT_HANDLE RD 1
____SOCKET RD 1
____LPWSADATA RB 400
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
section '.text' code readable executable
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
start:
sub esp, 16 ; struct sockaddr_in
; GetStdHandle
push -11
call [GetStdHandle]
test eax, eax
jz .exit
mov [____STD_OUTPUT_HANDLE], eax
; WSAStartup
push ____LPWSADATA
push 2
call [WSAStartup]
test eax, eax
jnz .init_failed
; SOCKET
push 6
push 1
push 2
call [socket]
test eax, eax
jz .socket_failed
; HTONS (PORT)
push 80
call [htons]
mov [esp+2], WORD ax ; sin_port = htons(port)
; SOCKADDR
mov [esp], WORD 2 ; sin_family = AF_INET
mov [esp+4], DWORD 2130706433 ; sin_addr = 127.0.0.1 (addr in long = (2130706433))
; BIND
push 16
lea eax, [esp]
push eax
push [____SOCKET]
call [bind]
test eax, eax
jnz .bind_failed
; LISTEN
push 5 ; SOMAXCONN
push [____SOCKET]
call [listen]
test eax, eax
jnz .listen_failed
; CLOSE
; ...
; ...
jmp .exit
.init_failed:
push 0
push 0
push DWORD [.err0_len]
push DWORD .err0
push [____STD_OUTPUT_HANDLE]
call [WriteFile]
jmp .exit
.socket_failed:
push 0
push 0
push DWORD [.err1_len]
push DWORD .err1
push [____STD_OUTPUT_HANDLE]
call [WriteFile]
jmp .exit
.bind_failed:
push 0
push 0
push DWORD [.err2_len]
push DWORD .err2
push [____STD_OUTPUT_HANDLE]
call [WriteFile]
jmp .exit
.listen_failed:
push 0
push 0
push DWORD [.err3_len]
push DWORD .err3
push [____STD_OUTPUT_HANDLE]
call [WriteFile]
jmp .exit
.exit:
push 0
call [ExitProcess]
hlt
.err0:
DB 'Socket initialization failed', 0x0A, 0x00
.err0_len:
DD $ - .err0
.err1:
DB 'Socket creation failed', 0x0A, 0x00
.err1_len:
DD $ - .err1
.err2:
DB 'Socket bind failed', 0x0A, 0x00
.err2_len:
DD $ - .err2
.err3:
DB 'Socket listen failed', 0x0A, 0x00
.err3_len:
DD $ - .err3
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
section '.idata' import data readable writeable
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
DD 0,0,0,RVA kernel_name, RVA kernel_list
DD 0,0,0,0,0
DD 0,0,0,RVA ws2_name, RVA ws2_list
DD 0,0,0,0,0
kernel_list:
ExitProcess DD RVA _ExitProcess
GetStdHandle DD RVA _GetStdHandle
WriteFile DD RVA _WriteFile
CloseHandle DD RVA _CloseHandle
DD 0
kernel_name: DB 'KERNEL32.DLL', 0
_ExitProcess: DB 0,0,'ExitProcess',0
_GetStdHandle: DB 0,0,'GetStdHandle',0
_WriteFile: DB 0,0,'WriteFile',0
_CloseHandle: DB 0,0,'CloseHandle',0
ws2_list:
socket DD RVA _socket
htons DD RVA _htons
WSAStartup DD RVA _WSAStartup
WSACleanup DD RVA _WSACleanup
WSAGetLastError DD RVA _WSAGetLastError
getpeername DD RVA _getpeername
bind DD RVA _bind
listen DD RVA _listen
accept DD RVA _accept
recv DD RVA _recv
send DD RVA _send
setsockopt DD RVA _setsockopt
shutdown DD RVA _shutdown
closesocket DD RVA _closesocket
DD 0
ws2_name: DB 'WS2_32.DLL', 0
_socket: DB 0,0,'socket',0
_htons: DB 0,0,'htons', 0
_WSAStartup: DB 0,0,'WSAStartup',0
_WSACleanup: DB 0,0,'WSACleanup',0
_WSAGetLastError: DB 0,0,'WSAGetLastError',0
_getpeername: DB 0,0,'getpeername',0
_bind: DB 0,0,'bind',0
_listen: DB 0,0,'listen',0
_accept: DB 0,0,'accept',0
_recv: DB 0,0,'recv',0
_send: DB 0,0,'send',0
_setsockopt: DB 0,0,'setsockopt',0
_shutdown: DB 0,0,'shutdown',0
_closesocket: DB 0,0,'closesocket',0
Should i use (add esp, x) for each function ... ?? is this the problem?
or the problem is about function linking ?
i found the problem ... the problem is linking ... my linking is wrong because i used the default macro of fASM (for linking) and it's worked without any problem ... now what is the problem of my linking ?!!!!!
I'm working on code to enumerate the PCI bus, but have found that the jz statement for the loop over each device jumps to the wrong location (not even a label). The register function should be getting called for each time cmp ax, 0xffff is inequal, which should be more than once. It is only getting called once.
register: ; eax = edi = config offset of the function
mov dx, ADDR_PRT
add eax, 0x08
in eax, dx
shr eax, 16
mov dx, ax
call checkpoint
mov eax, edi
rmsd: cmp dx, 0x0601 ; mass storage devices
je ahci_register ; register an AHCI controller
ret ; couldn't find it, ignore it
pci_init:
mov edi, 0x80000000
ilp0: mov rax, rdi
mov dx, ADDR_PRT
out dx, eax
mov dx, DATA_PRT
in eax, dx
cmp ax, 0xffff
je ilp0c0
push rdi
mov rax, rdi
call register
pop rdi
ilp0c0: add rdi, 0x100
test edi, 0xff000000 ; code jupms to the line before this
jz ilp0
ret
Code is assembled as a PE file and then linked using lld-link and run using EFI.
I've been trying to learn how to create an IRC bot in assembler from some old sources. Everything is going fine with my learning except for a prefix problem.
The prefix for the bot is:
CommandPrefix equ "^^"
And the length of the prefix is added with:
add eax, 2d
I want to change the prefix to just "^", but I am having trouble with figuring out what "add eax" should be changed too for it to work. Or even if that is the best way to do it. Any help with this would be appreciated.
Here is what the original code looks like to get some idea:
include "win32ax.inc"
entry Bot
CommandPrefix equ "^^"
section '.code' code readable executable
Bot:
invoke WSAStartup,0101h,WSAData
cmp eax, 0
jne Exit
invoke socket,AF_INET,SOCK_STREAM,0
cmp eax, -1
je Exit
mov dword [SocketDesc], eax
invoke inet_addr,IRCServer
mov dword [SockAddr_IP], eax
invoke htons,IRCPort
mov word [SockAddr_Port], ax
invoke connect,dword [SocketDesc],SockAddr,16d
cmp eax, 0
jne Exit
call GenerateNickname
invoke lstrcpy,SendBuffer,"NICK "
invoke lstrcat,SendBuffer,Nickname
call SendLine
invoke lstrcpy,SendBuffer,"USER "
invoke lstrcat,SendBuffer,Nickname
invoke lstrcat,SendBuffer," 8 * :"
invoke lstrcat,SendBuffer,Nickname
call SendLine
GetMotd:
call RecvLine
call HandlePing
mov ecx, 0
IsMotd:
cmp dword [ReturnBuffer + ecx], "MOTD"
je HaveMotd
cmp byte [ReturnBuffer + ecx], 0d
je GetMotd
inc ecx
jmp IsMotd
HaveMotd:
invoke lstrcpy,SendBuffer,"JOIN "
invoke lstrcat,SendBuffer,Channel
invoke lstrcat,SendBuffer," "
call SendLine
RecvCommand:
call RecvLine
call HandlePing
mov ecx, 0
IsCommand:
cmp word [ReturnBuffer + ecx], CommandPrefix
je HaveCommand
cmp byte [ReturnBuffer + ecx], 0
je RecvCommand
inc ecx
jmp IsCommand
HaveCommand:
mov ebx, ReturnBuffer
add ebx, ecx
add ebx, 2d ;add length of command prefix
invoke lstrcpy,CommandBuffer,ebx
call ExecuteCommand
jmp RecvCommand
Suppose I have a block of code like so:
;; outut
mov eax, 4
mov ebx, 1 ; stdout
mov ecx, [ans] ; move biggest element to accumulator
add ecx, 30h ; convert to ascii representation
mov [buff], ecx ; move to memory
mov ecx, buff ; put pointer in ecx for printing
mov edx, 4 ; size, 4 bytes
int 80h ; system call.
When I try to put a comment in the front to comment out a line:
;; outut
;mov eax, 4
mov ebx, 1 ; stdout
mov ecx, [ans] ; move biggest element to accumulator
add ecx, 30h ; convert to ascii representation
mov [buff], ecx ; move to memory
mov ecx, buff ; put pointer in ecx for printing
mov edx, 4 ; size, 4 bytes
int 80h ; system call.
Instead of appearing there where I want it to go, it jumps to here:
;; outut
mov eax, 4 ;
mov ebx, 1 ; stdout
mov ecx, [ans] ; move biggest element to accumulator
add ecx, 30h ; convert to ascii representation
mov [buff], ecx ; move to memory
mov ecx, buff ; put pointer in ecx for printing
mov edx, 4 ; size, 4 bytes
int 80h ; system call.
And no matter what I do, I physically cannot comment out anything.
How can I fix this? It don't remember it always doing this, so i feel like I must have hit some combination of keys and it just happens.
; is bound to asm-comment in assembly mode. You can either do a quoted insert with C-q ; on a case-by-case basis, or remove the binding and just use M-; (comment-dwim) for fancier commenting. If you want to do the latter, set ";" locally to do a self-insert command:
(defun my-hook ()
(local-set-key ";" 'self-insert-command))
(add-hook 'asm-mode-hook 'my-hook)