Statistics

Members: 1927
News: 293
Web Links: 1
Visitors: 3961978

Who's Online

We have 2 guests online
Damn Vulnerable LinuxDamn Vulnerable Linux (DVL) is a Linux-based (modified Damn Small Linux) tool for IT-Security & IT-Anti- Security and Attack & Defense. [CLICK HERE FOR MORE INFOS! ]

Featured Conference Video

T16-Recon2006-Joe_Stewart-OllyBonE.gif OllyBone - Semi-Automatic Unpacking on IA-32. View the conference video here!
Using ioctl()
User Rating: / 0
PoorBest 
Written by Mammon   


One of the most famous Unix maxims reads 'everything is a file'; directories are files, pipes are files, hardware devices are files, even files are files. This provided a transparent means or reading and writing hardware or software constructs such as modems and sockets; yet the lack of interrupts or device driver routines is sometimes confusing for those not used to Unix programming. In linux, handling device parameters through the character and block 'special file' interface is handled through ioctl().

 

 

The ioctl() system call takes a file descriptor and a request type as its primary arguments, along with an optional third argument referred to as "argp" which contains any arguments that must be passed along with the request. The possible ioctl() requests can be found by poking around in the $INCLUDE/asm and $INCLUDE/linux header files, although a somewhat dated list of requests can be viewed by typing 'man ioctl_list'.

One of the most useful devices to program with ioctl() for the applications programmer will be the console; in linux terms, this consists of the keyboard and display, such that all 63 of the Virtual Consoles can be controlled with ioctl(). This can be useful if one wants to output debugging information to a non-visible console, or to transfer STDIN and STDOUT to a newly-allocated console while disabling virtual console switching, effectively tying the user to a single console [e.g., in a walkup workstation].

Information on console ioctl requests can be found with 'man console_ioctl'. Bringing up this man page instantly displays the following text:

       WARNING: If you use  the  following  information  you  are
going to burn yourself.
WARNING:  ioctl's are undocumented Linux internals, liable
to be changed without warning.  Use POSIX functions.

This is ancient asm coderspeak meaning 'you are on the right track, keep going.'

Perusing the listed requests will provide enough information to code that first exercise from DOS-ASM 1o1: generating a tone on the PC speaker.

       KDMKTONE
Generate  tone  of  specified length.  The lower 16
bits of argp specify the period  in  clock  cycles,
and  the  upper  16 bits give the duration in msec.
If the duration is zero, the sound is  turned  off.
Control  returns  immediately.  For example, argp =
(125<<16) + 0x637 would specify the  beep  normally
associated  with  a  ctrl-G.   (Thus since 0.99pl1;
broken in 2.1.49-50.)

This should not be too terribly hard to implement -- a call to open the file descriptor, and a single call to ioctl() to sound the tone. First things first, open() is called on /dev/tty to create a handle for the current console: #-------------------------------------------------------------------beep.asm

%define O_RDWR 2                                        ;grep O_RDWR /usr/include/asm/*
%define KDMKTONE 0x4B30                 ;grep KDMKTONE /usr/include/linux/*

EXTERN open
GLOBAL main

section .data
szTTY db '/dev/tty',0

section .text
main:

                  push dword O_RDWR
push dword szTTY
call open
add esp, 8

#--------------------------------------------------------------------BREAK

Next, calculate the frequency and duration of the tone to be played: #---------------------------------------------------------------------CONT

                  mov dx, 666                   ;duration
shl edx, 16
or dx, 1199                   ;tone

#--------------------------------------------------------------------BREAK

Now, normally one might call ioctl as so:

                  push edx
push dword KDMKTONE
push eax
call ioctl
add esp, 12

However, ioctl is a systemcall, and we can save a bit of time by going straight through the syscall gate at 0x80: #---------------------------------------------------------------------CONT

                  mov ebx, eax
mov ecx, KDMKTONE
mov eax, 54                           ;ioctl func defined in /usr/include/asm/unistd.h
int 0x80
ret

#----------------------------------------------------------------------EOF

So much for the simple beep. Another ASM 101 favorite is the 'blinking LED' trick, where students learn to make the keyboard LEDs blink on and off in any number of psychedelic patterns. A quick tour through the man page shows the requests needed for this sample as well:

       KDGETLED
Get state of LEDs.  argp points to a long int.  The
lower  three  bits of *argp are set to the state of
the LEDs, as follows:
LED_CAP       0x04   caps lock led
LED_NUM       0x02   num lock led
LED_SCR       0x01   scroll lock led
KDSETLED
Set the LEDs.  The LEDs are set  to  correspond  to
the lower three bits of argp.  However, if a higher
order bit is set, the LEDs revert to  normal:  dis-
playing the state of the keyboard functions of caps
lock, num lock, and scroll lock.

The file descriptor must be opened as with the previous example. From there, we must get the current LED state:
#--------------------------------------------------------------------led.asm

%define KDGETLED        0x4B31         ;grep KDGETLED /usr/include/linux/*
%define KDSETLED        0x4B32         ;grep KDSETLED /usr/include/linux/*
xor edx, edx
mov ecx, KDGETLED
mov ebx, eax
mov eax, 54
int 0x80

#--------------------------------------------------------------------BREAK

Next, all of the LEDs will be turned on and then off 10 times. It is vital to the success of the algorithm that a delay be present between the off and on transitions; otherwise the LEDs will appear to be steadily lit, and that is much less of a programming achievement: #---------------------------------------------------------------------CONT

mov ecx, 10
.here:

                  push ecx                                              ;save counter
or edx, 0x07                                  ;set all of 'em
mov ecx, KDSETLED
mov eax, 54
int 0x80
mov ecx, 0xFFFFFF                     ;delay counter
.delay:
loop .delay
and edx, 0                                    ;turn all of them off
mov ecx, KDSETLED
mov eax, 54
int 0x80
mov ecx, 0xFFFFFF                     ;next delay counter
.delay2:
loop .delay2
pop ecx
loop .here
ret

#----------------------------------------------------------------------EOF Blinking the LEDs in succession and achieving hypnotic frequency via ioctl() will be left as an exercise to the reader.

This should provide a quick introduction to using ioctl(). There are many more possibilities available for scan codes, screen painting, and virtual console control; further opportunities for console amusement exist also within the realm of escape-sequence programming. The examples presented here can be compiled with the standard

nasm -f elf file.asm

gcc -o file file.o
combination, or by using a Makefile:
#----------------------------------------------------------------------Makefile TARGET =beep #TARGET is the variable storing the base filename

ASM = nasm                   #ASM contains the name of the assembler
ASMFILE = $(TARGET).asm      #ASMFILE contains the full name of the source file
OBJFILE = $(TARGET).o        #OBJFILE contains the full name of the object file
LINKER = gcc                 #LINKER contains the full name of the linker
LIBS =                       #LIBS contains any library flags
LIBDIR =                     #LIBDIR contains any library location flags
all:                         #the 'all:' section applies to all targets
$(ASM) -o $(OBJFILE) -f elf $(ASMFILE)
$(LINKER) -o $(TARGET) $(OBJFILE) $(LIBDIR) $(LIBS)

#---------------------------------------------------------------------------EOF As with all Makefiles, with the target correctly set the source will be compiled and linked simply by typing 'make' in the directory where the Makefile is located.