Tuesday, February 12, 2013

Hacking JOSH O/S Assignment

According to Hacking JOSH – operating system tutorial, the JOSH os is designed to run on USB pen drive with FAT 12 disk architecture. This was achieved according to the steps and commands given in the tutorial.

• First I need to attach USB pen to the existing file system. Therefore I mounted my pen drive as fallows.
< existing folder name >Sudo –s ( go to admin privileges)
<existing folder name>~ # mount –t ext2 /dev/sdb /media/USB

Here USB is a folder which I created inside of media folder in root directory. Ext2 is a UFS format.

• After got mounted I unmounted it.
< existing folder name > ~# umount /media/USB

• Format the USB pen in FAT 32 file system
< existing folder name > ~# /sbin/mkdosfs –F 32 –I /dev/sdb

• Then I converted my USB pen drive to FAT 12 format by creating a floppy image and overriding the USB disk by that floppy image.
< existing folder name > ~# dd if=/dev/zero bs=512 count=2880 of=./floppy.img (Creating empty floppy image)

< existing folder name > ~# /sbin/mkdosfs –F 12 ./floppy.img
(Format the floppy image into FAT 12 file system)

< existing folder name > ~# dd if=./floppy.img of=/dev/sdb
(Override the USB pen drive with newly created floppy disk image file)

 After executed above command pen drive got mounted automatically with have only 1.4MB of storage.





• Then over-ride the first 512 bytes of disk (pen drive) from boot.bin file.
< existing folder name > ~# dd if=./boot.bin of=/dev/sdb

After run above command the name changed into “QUASI BOOT” of the pen drive.



• Next copy given kernel.bin file into data sector of pen drive.

Snapshot of Ubuntu Terminal



• Since it is hard to reboot the computer every time when I need to execute the code, therefore I installed “qemu” to run the virtual device images such as floppy image files. And then I run the floppy image by using qemu as executing fallowing command.


Snapshot of qemu output


Implemented a new command to achieve hardware information

I implemented a new command called “hinfo” for JOSH shell to obtain some hardware information. Now I describe each and every block of codes as fallowing.

1.) Display number of hard drives installed

mov si, strHardDrives
mov al, 0x01
int 0x21
mov ax, 0x0040
push es
mov es,ax
mov al,[es:0x0075]
add al, 48
pop es
mov ah, 0x0e
int 0x10

Here number of hard drives installed can obtain by extracting memory locations 0x0040 to 0x0075. ES register used for stack. Stack used here because after execute the function we have to release registers with its previous stored values. Interrupt 0x10 with 0x0e in ah register prints the text in al register. 

strHardDrives is a string constant that is used to store a string to be displayed.

2.) Display Processor Information

mov si, strProcVendor
mov al, 0x01
int 0x21
mov eax, 0
cpuid
mov eax, ebx
mov ebx, edx
mov edx, 0x00
mov si, strVendor
call _save_string

mov si, strVendor
mov al, 0x01
int 0x21

call _display_endl
mov si, strPreocBrand
mov al, 0x01
int 0x21

mov eax, 0x80000000
cpuid
cmp eax, 0x80000004
jb _not_supported
mov eax, 0x80000002
mov si, strVendor
cpuid
call _save_string
mov eax, 0x80000003
cpuid
call _save_string
mov eax, 0x80000004
cpuid
call _save_string
add si,16
mov si,0x00

mov si, strVendor
mov al, 0x01
int 0x21

Here the value in EAX register tells which information is returned when CUPID executed. CUPID gives processor information. CPUID stores the vendor name of the CPU in registers EAX with 0x00, EBX, ECX and EDX. And I included here a function to obtain the processor model and calling to CPUID to three times while changing the value of EAX to 0x80000002, 0x80000003 and 0x80000004 respectively. I also used _save_string function here, for store the values in EAX, EBX, ECX and EDX as a single string in SI register.

strProcVender, strVender, strPreocBrand are string constants that are used to store strings to be displayed.

3.) Display memory information

xor cx, cx
xor dx, dx
mov ax, 0xe801
int 0x15
jc _hw_mem_err
cmp ah, 0x86
je _hw_mem_err
cmp ah, 0x80
je _hw_mem_err

mov si, strMemInfo
mov al, 0x01
int 0x21

cmp cx, 0x0000
je _hw_mem_cx
jmp _hw_mem_calc

_hw_mem_cx:
mov cx,ax
mov dx,bx

_hw_mem_calc:

shr dx, 4
shr cx, 10
add cx,dx

mov dx, cx
call _print_hex2dec
mov si, strMB
mov al, 0x01
int 0x21

jmp _hw_mem_end

_hw_mem_err:
mov si, strMemErr
mov al, 0x01
int 0x21

Memory can be detected by using the INT 0x15, EAX = 0xE801 command. This stores the extended memory between 1MB and 16MB in kilobytes in AX or BX and extended memory greater than 16MB as number of pages of 64KB in CX or DX. The purpose of comparing ah with 0x86 is to check whether the function is supported on the system and comparing ah with 0x80 is to check whether it is an invalid command.

Here _hw_mem_calc function used to detect memory that has to be calculated MB and converted to decimal from hexadecimal calling to _print_hex2dec.

4.) Display BIOS date

mov si, strBiosDate
mov al, 0x01
int 0x21
push es
mov ax, 0xf000
mov es, ax
mov si, 0xfff5
mov bl,8
_bios_loop:
mov al, [es:si]
mov ah, 0x0e
int 0x10
inc si
dec bl
cmp bl, 0
jne _bios_loop
pop es

Here memory locations 0xf000 to 0xfff5 is used to extract the BIOS date. Since there are 8 characters of date, I used a decrementing register bl in order to take control out of the loop when the date string is printed. Here cmp is used to compare two values jne is a command that follows a cmp command which jumps to a given location if compared values are not equal.

strBiosDate is a string constant that is used to store a string to be displayed.

5.) Display DOS version

call _display_endl
mov si, strDosVer
mov al, 0x01
int 0x21

mov ah, 0x30
int 0x21

mov bx, ax

xor dx, dx
mov dl, bl
add dl, 1
call _print_hex2dec

mov al, '.'
mov ah, 0x0e
int 0x10

mov dl, bh
call _print_hex2dec

6.) Display number of floppy drives available

mov si, strFloppy
mov al, 0x01
int 0x21

int 0x11
and ax, 1
cmp ax, 1
je _hw_floppy_detect
;No floppies
mov ah, 0x0e
mov al, '0'
int 0x10

_hw_floppy_detect:
int 0x11
and ax, 0b11000000
shr ax, 5
add ax, 49
mov ah,0x0e
int 0x10

Interrupt 0x21 with value 0x0e in register ah displays the contents in register SI on the teletype output. 0x11 is an Interrupt which returns the equipment list data stored in BIOS. AX, 0b11000000 is used to mask out bits 6, 7 and 10 which are used to indicate the number of floppy drives available in the computer. Then ax is right shifted by 5 bit positions so that only required bits are remaining in the ax register. If no floppy drives available then it prints ‘0’. Otherwise print number of floppy drives available.

7.) Display number of serial ports

mov si, strSerialPort
mov al, 0x01
int 0x21

int 0x11
and ax, 0x0E00
shr ax, 9
add ax, 48

mov ah, 0x0e
int 0x10

Interrupt 0x21 with value 0x0e in register ah displays the contents in register SI on the teletype output. 0x11 is an Interrupt which returns the equipment list data stored in BIOS. AX, 0x0E00 is used to mask out bits 9, 10 and 11 which are used to indicate the number of serial ports available in the computer. Then ax is right shifted by 9 bit positions so that only required bits are remaining in the ax register. Here 48 added to ax to get the ASCII value of the value stored in ax.

8.) Display number of parallel ports

mov si, strParallelPort
mov al, 0x01
int 0x21

int 0x11
and ax, 0x0C00
shr ax, 14
add ax, 48

mov ah, 0x0e
int 0x10

Interrupt 0x21 with value 0x0c in register ah displays the contents in register SI on the teletype output. 0x11 is an Interrupt which returns the equipment list data stored in BIOS. AX, 0x0C00 is used to mask out bits 10, 14 and 15 which are used to indicate the number of parallel ports available in the computer. Then ax is right shifted by14 bit positions so that only required bits are remaining in the ax register. Here 48 added to ax to get the ASCII value of the value stored in ax.

Additional functionality implemented

1.) Hexadecimal to decimal conversion

_print_hex2dec:

push ax
push bx
push cx
push si
mov ax,dx
mov si,10
xor cx,cx

This function converts the hex stored in dx to decimal and prints it.

2.) Store values as a single string

_save_string:

mov dword [si], eax
mov dword [si+4], ebx
mov dword [si+8], ecx
mov dword [si+12], edx
add si, 16
ret

This function stores value in EAX, EBX,ECX and EDX as a single string in register SI.

3.) Display all commands available in shell (command => “cmdlist”)

_cmd_list:
mov si, strCmd0
mov di, cmdList
mov cx, 8
repe cmpsb
jne _cmd_ver

mov cx, 2
loop1:
call _display_endl
loop loop1
mov si, version
mov al, 0x01
int 0x21
call _display_space
mov si, dash
mov al, 0x01
int 0x21
call _display_space
mov si, cmdVer
mov al, 0x01
int 0x21
call _display_space

call _display_endl
mov si, hardwareinfo
mov al, 0x01
int 0x21
call _display_space
mov si, dash
mov al, 0x01
int 0x21
call _display_space
mov si, cmdHw
mov al, 0x01
int 0x21
call _display_space

call _display_endl
mov si, reboot
mov al, 0x01
int 0x21
call _display_space
mov si, dash
mov al, 0x01
int 0x21
call _display_space
mov si, cmdExit
mov al, 0x01
int 0x21
call _display_space
call _display_endl
jmp _cmd_done

This new command prints the commands available in the shell. It means that when types the ‘cmdlist’ in prompt it display the fallowing output. Fallowing qemu output also display the output of newly implemented command ‘hinfo’.