1 of 32

Secure OS Lab

Cyber Lab S23 - Week 1

2 of 32

Announcements

  • Psi Beta Rho Practice: Number Theory
    • Tuesday 6-8 pm
    • Ackerman 3517
  • Cyber Academy: Intro to Reverse Engineering
    • Wednesday 6-8 pm
    • MATH SCI 5200
  • Cyber x Studio Social: Mario Kart Tournament
    • Friday 6-8 pm
    • Kerckhoff 131+133+135
  • Cyber DEFCON 31 Trip Interest Form
    • bit.ly/cyber-defcon-31-trip

3 of 32

Overview

4 of 32

Meet the Team

Daniel Yang

Secure OS Project Lead

Michelle Zhao

Officer

Victoria Choi

Officer

Benson Liu

Co-President

Aaron Yoo

Mentor & SWE @ Apple

You

MVP

5 of 32

✨Social Engineering Time ✨

  • Introduce Yourself!
    • Name
    • Year
    • Major
    • Hometown
    • Favorite shoe? (since boot? idk)

6 of 32

Goal

  • Develop an operating system from scratch
  • Learn & practice low-level & systems software development
  • TWO Parts
    • (1) Guided development of a UNIX-like bootloader & kernel
    • (2) Design & develop your own operating system feature (ex. file system, secure boot, etc)

7 of 32

Timeline

Part 1: (Guided) Developing the Bootloader & Kernel

  • Week 3: Boot Process
  • Week 4: 32-bit Protected Mode & Kernel + Feature Design
  • Week 5: Break for Midterms

Part 2: Design Your Own Feature

  • Week 6: Aaron Yoo’s Talk & Work Session
  • Week 7: Work Session
  • Week 8: Work Session
  • Week 9: Presentation & Demo
    • Wednesday - May 31, 6-8 pm
    • MATH SCI 5200

8 of 32

Logistics

  • Weekly meetings
    • Thursdays 7-9 pm
    • Boelter 4760
  • Need Additional Help?
    • Malware Lab meets Mondays 6-8 pm in Kerckhoff 131+133+135
    • If you’re stuck during the week, feel free to show up to ask officers there for help!
    • Messaging on Discord works as well!

9 of 32

Environment Setup

10 of 32

Installation

  1. Get a Linux Environment
  2. Install Qemu (emulates x86-64 CPU)
  3. Install NASM (compile asm to a raw binary)

Setup

11 of 32

Boot Process

12 of 32

Boot Steps

  1. BIOS finds a bootable device
  2. Loads the Master Boot Record in the first sector and runs the small boot loader code in the MBR, which loads the rest of the boot loader into memory address 0x7c00
  3. Control is then transferred to the actual bootloader, which then loads the rest of the OS

13 of 32

Ruling the Boot Sector

14 of 32

Basic Commands

$ qemu-system-x86_64 -drive format=raw,file=boot-sect.bin

  • runs the qemu CPU emulator and loads the raw bootloader binary

$ od -t x1 -A n boot-sect.bin

  • outputs the raw bytes of the binary file, can see if its in the right format

$ nasm boot-sect.asm -f bin -o boot-sect.bin

  • compiles the assembly source to binary

15 of 32

What is a boot sector?

  • Bunch of machine code instructions to boot your operating system
  • Loaded by the Master Boot Record located the start address of the persistent storage device, which is then loaded into memory.
  • MBR has some bootloader code, which loads the rest of the bootloader into memory address 0x7c00
  • Beginning of memory is then loaded with the Interrupt Vector Table of the BIOS and now the OS can be loaded up
  • Last two bytes of the boot sector is 0x55 0xaa so BIOS knows it is a boot sector and not holding some random data

16 of 32

17 of 32

How do we interface with devices?

  • Interrupts: we can call pre existing BIOS machine code functions to perform rudimentary tasks like printing to screen
  • Table of pointers to interrupt handlers at address 0x0
  • Interrupt routines are multiplexed
    • calling an interrupt with a specific value can lead to multiple interrupt service routines
    • specific routine for the interrupt code also depends on the value in the registers

18 of 32

Persistent storage

  • Head->Cylinder->Sector
  • Important sectors are at the beginning of the disk: Head 0, Cylinder 0
  • Sector 0: Master Boot Record
  • Sector 1: Boot Sector
  • Sector 2 and Beyond: File system and other data

19 of 32

Objectives

20 of 32

Steps

Setup: https://docs.google.com/document/d/1JvdaxarsJOU5kWM5vpZ45n2pSuzxb5zVRgtiNZiWCMA/edit#heading=h.o2ij8pbp2qf6

  1. Print a message to BIOS screen
  2. Print a message stored at a memory location in the bootloader binary
    1. Write a function that can be called with the “call” assembly instruction
    2. Write a function to print a 16 bit register in hex (ie “0xadad”)
  3. Read data from disk

https://github.com/danieltherealyang/PreOS-Skeleton.git

21 of 32

  1. Printing a message

Just call the BIOS routine for printing a character and run…

Shouldn’t be many issues here.

22 of 32

23 of 32

2. Print a message stored at a memory location

Next, modify your boot-sect.asm file and add a label marking a string such as “Hello World!”. You can define the string as db “Hello World!”

Make sure its before your 0x55 0xaa bytes otherwise it will be outside of the boot sector and not loaded into memory.

Don’t forget a null 0x00 byte after the string.

Now, see if you can print the string marked by your label.

Remember, labels are offsets from the start of your code. The actual location of the boot sector in memory is at 0x7c00! (Hint: check the “org directive”)

24 of 32

2a. print_string function

Move your code printing a string into a function. The function is located in print_string.asm.

Understand what is happening when you use “call” and “ret” in regards to the process stack.

Also understand why we want to use “pusha” and “popa” when calling the function.

25 of 32

2b. print_hex function

Now that you know how to call BIOS routines and how to use functions, can you create a function to print the value of a 16 bit register as hex?

Write this function in print_hex.asm.

26 of 32

ASM bonus knowledge time

Register: cs, ds, ss, and es

  • stand for the code, data, stack, and extended segments

These registers provide a base address so that the CPU can calculate the absolute addresses using an offset

ex: set ds to <base>, then run mov ax, [<var addr>]. The absolute address of the data moved into ax will be <base>*16+<var addr>.

Usually only want to modify the es register in your code.

then just mov <reg>, [es:<addr>] to fetch using the es as a base address.

27 of 32

3. Read data from disk

First, to understand a bit more about segment registers, store a single character at a label and try to print it in your main boot-sect.asm program using the es register as the base address.

Now, look through the disk_load.asm file to see how to read disk. FYI int 0x13 loads the sectors to the address [es:bx]

In your main boot-sect.asm, first mov dl, [label] to save the boot drive number. Then move the stack to a high address like 0x8000 to avoid overwriting the loaded boot sector.

28 of 32

3. Read data part 2

Now, add two sectors (512 bytes/sector) worth of data after the 0x55 0xaa bytes in your boot sector code.

Even though these sectors are stored in your asm file, they will not be loaded into memory when the MBR loads the boot loader since they are after the 0x55 0xaa, which marks the end of the boot sector. In other words, the bytes will stay on persistent storage.

Now, read from disk and load to memory at an address higher than the stack. Make sure parameters for the 0x13 interrupt are correct.

Try to print the data in the memory sectors you loaded. Are they what you expected? If not review the code and debug.

29 of 32

x86 Print character routine

mov ah, 0x0e ; Tells BIOS to print in teletype mode

mov al, “x” ; Loads the character to be printed, in this case its an “x”

int 0x10 ; BIOS interrupt that manages graphics

30 of 32

Useful NASM directives/features

% include “asm_file.asm” ;include another assembly source file

[org <address>] ;provide reference point for all addresses

31 of 32

Extra Info

32 of 32

Check out our linktree:

linktr.ee/uclacyber