How to find the values of the arguments in socket programming in Assembly? - sockets

I am trying socket programming for ARM, however I am not able to understand how the values for the arguments are decided.
For example
this is the link for Azeria Labs
I understand that sys call for ARM register R7 gets it hence its 281 in this case and arguments are passed using R0, R1, R2, R3. But here how do you decide the values for R0(AF_INET) as 2 and R1(SOCK_STREAM) as 1 while creating socket(AF_INET, SOCK_STREAM, 0)
Finding system call was easy
$ grep socket /usr/include/asm/unistd-common.h
#define __NR_socket (__NR_SYSCALL_BASE+281)
#define __NR_socketpair (__NR_SYSCALL_BASE+288)
Similarly is there a way to find the values for the arguments?
I found an another resource which was for X86 Assembly which also has similar approach.
%assign SOCK_STREAM 1
%assign AF_INET 2
%assign SYS_socketcall 102
%assign SYS_SOCKET 1
%assign SYS_CONNECT 3
%assign SYS_SEND 9
%assign SYS_RECV 10
section .text
global _start
;--------------------------------------------------
;Functions to make things easier. :]
;--------------------------------------------------
_socket:
mov [cArray+0], dword AF_INET
mov [cArray+4], dword SOCK_STREAM
mov [cArray+8], dword 0
mov eax, SYS_socketcall
mov ebx, SYS_SOCKET
mov ecx, cArray
int 0x80
ret
Kindly let me know.
Thank you.
Linux alarmpi 4.4.34+ #3 Thu Dec 1 14:44:23 IST 2016 armv6l GNU/Linux

Related

How to set an exception using masm64?

How can i access the exception chain (SEH) using masm64?
Using masm32, I get the first exception looking into fs:[0]
But when I checked in Windbg if fs:[0] still pointed at the first exception in x64, I figured that it wasn't.
I'd like to set an exception in x64 the same way I did in x86. Is it feasible (maybe looking at gs register)?
If this is coding related then you use
ml64seh PROC FRAME:ExceptionFilter
this adds your exception handler to .PDATA section RUNTIME_FUNCTION
if this is how to find this exception handler in windbg when the exception has been raised
use !exchain command
or if you want to find it before executing a specific function use .fnent command
a sample for x64 seh and finding it in windbg is as follows
;assemble and link with
;ml64 /Zi ml64seh.asm /link /debug /entry:ml64seh /subsystem:console
.data
safeplace DWORD ?
.code
ExceptionFilter PROC
jmp Handler
ExceptionFilter ENDP
PUBLIC ml64seh
ml64seh PROC FRAME:ExceptionFilter
.ENDPROLOG
mov rax, 0
mov [rax], rax ;access violation
jmp exit
Handler::
lea rax, safeplace
mov [r8+078h], rax ; replacing rax in exception handler so access is possible
mov rax, 0
ret
Exit:
ret
ml64seh ENDP
END
run without stopping in windbg
:\>cdb -g ml64seh.exe
(2aa0.3024): Access violation - code c0000005 (first chance)
ml64seh!ml64seh+0x7:
00007ff7`0e3b1029 488900 mov qword ptr [rax],rax ds:00000000`00000000=????????????????
0:000>
it crashed and broke now locating exception handlers
0:000> .fnent .
Debugger function entry 0000020b`e36c47a8 for:
(00007ff7`0e3b1022) ml64seh!ml64seh+0x7 | (00007ff7`0e3b32b0) ml64seh!$xdatasym
BeginAddress = 00000000`00001022
EndAddress = 00000000`00001042
UnwindInfoAddress = 00000000`000032b0
Unwind info at 00007ff7`0e3b32b0, c bytes
version 1, flags 3, prolog 0, codes 0
handler routine: ml64seh!ILT+0(ExceptionFilter) (00007ff7`0e3b1005), data 0 <<<<<<<<<
0:000> !exchain
3 stack frames, scanning for handlers...
Frame 0x00: ml64seh!ml64seh+0x7 (00007ff7`0e3b1029)
ehandler ml64seh!ILT+0(ExceptionFilter) (00007ff7`0e3b1005) <<<<<<<<<<<<
Frame 0x02: ntdll!RtlUserThreadStart+0x21 (00007ffe`213c26a1)
ehandler ntdll!_C_specific_handler (00007ffe`213fc720)
0:000>
lets see if we go to the handler and return back to re access the faulting place
0:000> bp .
0:000> bp 00007ff7`0e3b1005
0:000> bl
0 e 00007ff7`0e3b1029 0001 (0001) 0:**** ml64seh!ml64seh+0x7
1 e 00007ff7`0e3b1005 0001 (0001) 0:**** ml64seh!ILT+0(ExceptionFilter)
0:000> g
Breakpoint 1 hit
ml64seh!ILT+0(ExceptionFilter):
00007ff7`0e3b1005 e916000000 jmp ml64seh!ExceptionFilter (00007ff7`0e3b1020)
0:000> g
Breakpoint 0 hit
ml64seh!ml64seh+0x7: is accessible now
00007ff7`0e3b1029 488900 mov qword ptr [rax],rax ds:00007ff7`0e3b4000=0000000000000000
0:000>
btw you can use dumpbin or linker to spit out all the unwindinfos in a specific binary using -unwindinfo switch
:\>dumpbin /unwindinfo ml64seh.exe
Microsoft (R) COFF/PE Dumper Version 14.29.30146.0
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file ml64seh.exe
File Type: EXECUTABLE IMAGE
Function Table (1)
Begin End Info Function Name
00000000 00001022 00001042 000032B0 ml64seh
Unwind version: 1
Unwind flags: EHANDLER UHANDLER
Size of prologue: 0x00
Count of codes: 0
Handler: 00001005 #ILT+0(ExceptionFilter)

Can't properly bind socket unless I pass a seemingly incorrect length

The code I've written doesn't work properly unless I pass a seemingly incorrect number to the length argument of bind. It kind of does work; after the accept call I can see it by running netstat, but the port is incorrect. I originally wrote the code in x86 assembly and I then wrote it in C. In both cases, it didn't work.
When calling the function socket, I passed AF_INET (2) as the domain, SOCK_STREAM (1) as the type, and TCP (6) as the protocol.
Here is the code, the one written in C:
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
int main(void) {
unsigned int fd = socket(AF_INET, SOCK_STREAM, 6);
struct sockaddr_in thing = (struct sockaddr_in) {
.sin_family = AF_INET, //2 bytes
.sin_port = 0x2923, //2 bytes
.sin_addr = 0 //4 bytes
};
printf("%zu\n", sizeof thing);
bind(fd, (struct sockaddr*) &thing, 8); //Using 16 instead of 8 fixes the port problem, why?
listen(fd, 1);
accept(fd, 0, 0);
}
To me, 8 looks like the correct length to use. However, 16 seems to be the correct number to use. Why?
Here is the original code written in x86 NASM Assembly:
section .text
global _start
_start:
push byte 6
push byte 1
push byte 2
mov ecx, esp
mov ebx, 1 ;socket
mov eax, 102
int 80h
mov edi, eax ;file descriptor
push dword 0x00000000 ;4 bytes
push word 0x2923 ;2 bytes
push word 2 ;2 bytes
mov ecx, esp
push byte 8 ;Length argument, byte turned into 4 bytes in stack
push ecx
push edi
mov ecx, esp
mov ebx, 2 ;bind
mov eax, 102
int 80h
push byte 1
push edi
mov ecx, esp
mov ebx, 4 ;listen
mov eax, 102
int 80h
push byte 0
push byte 0
push edi
mov ecx, esp
mov ebx, 5 ;accept
mov eax, 102
int 80h
bind(fd, (struct sockaddr*) &thing, 8); //Using 16 instead of 8 fixes the port problem, why?
This code will fail with EINVAL (checked with Linux), but this error is simply ignored by your program. This means no explicit bind will be done.
listen(fd, 1);
accept(fd, 0, 0);
Since the explicit bind failed an implicit bind will be done, effectively meaning that the socket will listen on a random address. That's why it does not seem to work. netstat should show the random port here, not the actually intended one.
Look at the examples in the man page: https://man7.org/linux/man-pages/man2/bind.2.html.
You have to pass the size of the sockaddr_in structure.
bind(fd, (struct sockaddr*) &thing, sizeof(thing));
It's very likely that bind makes an internal check, to ensure that the 3rd parameter is indeed the size of the structure in the 2nd parameter
For AF_INET sockets bind surely knows that the 2nd parameter is a sockaddr_in instance, so it knows what value the 3rd parameter must be.
Really, there's nothing mysterious going on here.

How many CPU operations programming languages use for % and fmod()?

What is the result of C translation for % operator and fmod() function in machine language? What is it's implementation?
For example: Will 61199 % 256 be solved the same way as 61199 % 171?
If the platform supports integer division, like all modern non-embedded processors, it is a single instruction. The division instruction gives the quotient and the remainder.
Consider this C program (https://godbolt.org/z/vxj8fKdjG):
int main() {
int a = 61199;
int b = 171;
int c = a % b;
}
It compiles to:
main:
push rbp
mov rbp, rsp
mov DWORD PTR [rbp-4], 61199
mov DWORD PTR [rbp-8], 171
mov eax, DWORD PTR [rbp-4]
cdq
idiv DWORD PTR [rbp-8]
mov DWORD PTR [rbp-12], edx
mov eax, 0
pop rbp
ret
In this output idiv is the division instruction.

Is it the code, or is it the OS..?

MY CODE IS
.model small
.data
arr db 83h, 12h, 0F0h, 0Bh, 89h
cnt db 05h
.code
mov ax, #data
mov ds, ax
mov si, offset arr
mov cl, cnt
sub bl, bl
sub dl, dl
back:
mov al, [si]
and al, 80h
jz skip
inc bl
skip:
inc dl
inc si
dec cl
jnz back
mov ah, 4cH
int 21H
end
THE ERRORS ARE AS FOLLOWS
1.asm:1: error: attempt to define a local label before any non-local labels
1.asm:1: error: parser: instruction expected
1.asm:2: error: attempt to define a local label before any non-local labels
1.asm:9: error: comma, colon, decorator or end of line expected after operand

Read a sector to address zero

%include "init.inc"
[org 0x0]
[bits 16]
jmp 0x07C0:start_boot
start_boot:
mov ax, cs
mov ds, ax
mov es, ax
load_setup:
mov ax, SETUP_SEG
mov es, ax
xor bx, bx
mov ah, 2 ; copy data to es:bx from disk.
mov al, 1 ; read a sector.
mov ch, 0 ; cylinder 0
mov cl, 2 ; read data since sector 2.
mov dh, 0 ; Head = 0
mov dl, 0 ; Drive = 0
int 0x13 ; BIOS call.
jc load_setup
lea si, [msg_load_setup]
call print
jmp $
print:
print_beg:
mov ax, 0xB800
mov es, ax
xor di, di
print_msg:
mov al, byte [si]
mov byte [es:di], al
or al, al
jz print_end
inc di
mov byte [es:di], BG_TEXT_COLOR
inc di
inc si
jmp print_msg
print_end:
ret
msg_load_setup db "Loading setup.bin was completed." , 0
times 510-($-$$) db 0
dw 0xAA55
I want to load setup.bin to memory address zero. So, I input 0 value to es register (SETUP_SEG = 0). bx, too. But it didn't work. then, I have a question about this issue. My test is below.
SETUP_SEG's value
0x0000 : fail
0x0010 : success
0x0020 : fail
0x0030 : fail
0x0040 : fail
0x0050 : success
I can't understand why this situation was happened. All test was carried out on VMware. Does anyone have an idea ?
I'm not sure if this is your problem, but your trying to load setup.bin in the Real Mode IVT (Interrupt Vector Table). The IVT contains the location of each interrupt, so I'm assuming that your boatloader is overwriting them when it loads setup.bin into memory! Interrupts can be sneaky and tricky, since they can be called even if you didn't call them. Any interrupt vector you overwrote will likely cause undefined behavior when called, which will cause some problems.
I suggest setting SETUP_SEG to a higher number like 0x2000 or 0x3000, but the lowest you could safely go is 0x07E0. The Osdev Wiki and Wikipedia have some helpful information on conventional memory and memory mapping.
I hope this helps!