Roll Your Own Bootloader

assembly_langauge

Here we will be going through the process of creating a very basic boot-loader. There will be no funny options added in the code. Just the bare essentials to get a boot rolling. I have created two source files in x86 assembly: kernel.asm and main.asm. My goal was to learn a little about OS development at more or less the lowest level you can go. I’ve added comments throughout the code to help explain what exactly is going on.

Here is kernel.asm:

mov ax, 0x07C0  ; set up segments
mov ds, ax
mov es, ax

mov si, welcome
call print_string

mainloop:
mov si, prompt
call print_string

mov di, buffer
call get_string

mov si, buffer
cmp byte [si], 0  ; blank line?
je mainloop       ; yes, ignore it

mov si, buffer
mov di, cmd_hi  ; "hi" command
call strcmp
jc .helloworld

mov si, buffer
mov di, cmd_help  ; "help" command
call strcmp
jc .help

mov si,badcommand
call print_string
jmp mainloop

.helloworld:
mov si, msg_helloworld
call print_string

jmp mainloop

.help:
mov si, msg_help
call print_string

jmp mainloop

welcome db 'Welcome to My OS!', 0x0D, 0x0A, 0
msg_helloworld db 'Hello OSDev World!', 0x0D, 0x0A, 0
badcommand db 'Bad command entered.', 0x0D, 0x0A, 0
prompt db '>', 0
cmd_hi db 'hi', 0
cmd_help db 'help', 0
msg_help db 'My OS: Commands: hi, help', 0x0D, 0x0A, 0
buffer times 64 db 0

; ================
; calls start here
; ================

print_string:
lodsb        ; grab a byte from SI

or al, al  ; logical or AL by itself
jz .done   ; if the result is zero, get out

mov ah, 0x0E
int 0x10      ; otherwise, print out the character!

jmp print_string

.done:
ret

get_string:
xor cl, cl

.loop:
mov ah, 0
int 0x16   ; wait for keypress

cmp al, 0x08    ; backspace pressed?
je .backspace   ; yes, handle it

cmp al, 0x0D  ; enter pressed?
je .done      ; yes, we're done

cmp cl, 0x3F  ; 63 chars inputted?
je .loop      ; yes, only let in backspace and enter

mov ah, 0x0E
int 0x10      ; print out character

stosb  ; put character in buffer
inc cl
jmp .loop

.backspace:
cmp cl, 0    ; beginning of string?
je .loop    ; yes, ignore the key

dec di
mov byte [di], 0    ; delete character
dec cl        ; decrement counter as well

mov ah, 0x0E
mov al, 0x08
int 10h        ; backspace on the screen

mov al, ' '
int 10h        ; blank character out

mov al, 0x08
int 10h        ; backspace again

jmp .loop    ; go to the main loop

.done:
mov al, 0    ; null terminator
stosb

mov ah, 0x0E
mov al, 0x0D
int 0x10
mov al, 0x0A
int 0x10        ; newline

ret

strcmp:
.loop:
mov al, [si]   ; grab a byte from SI
mov bl, [di]   ; grab a byte from DI
cmp al, bl     ; are they equal?
jne .notequal  ; nope, we're done.

cmp al, 0  ; are both bytes (they were equal before) null?
je .done   ; yes, we're done.

inc di     ; increment DI
inc si     ; increment SI
jmp .loop  ; loop!

.notequal:
clc  ; not equal, clear the carry flag
ret

.done:
stc  ; equal, set the carry flag
ret

times 510-($-$$) db 0
dw 0AA55h ; some BIOSes require this signature

Last but not least, main.asm:

;Main.asm
BITS 16
ORG 0x7C00

Main:
jmp 0x0000:start
start:

BootDrive:
db 0
cli

xor ax, ax
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax

mov sp, 0x7C00
mov [BootDrive], dl
jmp $
Advertisements

Find Missing Number with Vector

c plus plusThis one is simple, given an array containing all numbers from 1 to N with the exception of one print the missing number to the standard output. My solution makes use of vector. Expected complexity is O(N). As a side note, it has been said that this problem has been asked on Microsoft interviews.

 


#include <iostream>
#include <vector>

using namespace std;

void find_missing_number(const vector<int> &v) {
int total, i;
total  = (v.size()+1)*(v.size()+2)/2;
for (i = 0; i < v.size(); i++)
total -= v[i];
cout <<  total;
}

Finding the Longest Palindrome

The other day I was doing a programming challenge that required me to find the longest palindrome within a string. The challenge was to do it in at least O(N)2 complexity.  I found this to be fairly interesting. The challenge read like so:

Given a string S, find the longest substring in S that is the same in reverse and print it to the standard output.

So for example, if I had the string given was:  s= “abcdxyzyxabcdaaa” . Then the longest palindrome within it is “xyzyx “. We need to write a function to find this for us.  The nature of the challenge just needed me to write a function for a web back-end, so the example code below does not have main, or a defined string, etc. Also, there are O(N) solutions for this problem if you seek them, but they are a little more complicated.

#include <iostream>
#include <string>

using namespace std;

void longest_palind(const string &s) {
int n = s.length();
int longestBegin = 0;
int maxLen = 1;
bool table[100][100] = {false};

for (int i = 0; i < n; i++)
{
table[i][i] = true;
}
for (int i = 0; i < n-1; i++)
{
if (s[i] == s[i+1]) {
table[i][i+1] = true;
longestBegin = i;
maxLen = 2;
}
}
for (int len = 3; len <= n; len++) {
for (int i = 0; i < n-len+1; i++) {
int j = i+len-1;
if (s[i] == s[j] && table[i+1][j-1]) {
table[i][j] = true;
longestBegin = i;
maxLen = len;
}
}
}
cout << s.substr(longestBegin, maxLen);
}

C++ Primer Plus Chapter 7 Exercise 9

c plus plusChapter 7 ends with a short exercise on function pointers. The simplest way to complete this, which I provided in my source, is to create the two functions add() and calculate(), then call them in main() with a loop. The text mentions if you are feeling adventurous to include other functions in addition to add. For simplicities sake, I did the minimum requirement here. Finally,  we can put this chapter to rest. See my source below:

9. Design a function calculate() that takes two type double values and a pointer to a function that takes two double arguments and returns a double. The calculate() function should also be type double, and it should return the value that the pointed-to function calculates, using the double arguments to calculate(). For example, suppose you have this definition for the add() function: double add(double x, double y){return x + y}. Then, the function call in double q = calculate(2.5, 10.4, add); would cause calculate() to pass the values 2.5 and 10.4 to the add() function and then return the add() return value (12.9). Use these functions and at least one additional function in the add() mold in a program. The program should use a loop that allows the user to enter pairs of numbers. For each pair, use calculate() to invoke add() and at least one other function. If you are feeling adventurous, try creating an array of pointers to add()-style functions and use a loop to successively apply calculate() to a series of functions by using these pointers. Hint: Here’s how to declare such an array of three pointers: double (*pf[3])(double, double); You can initialize such an array by using the usual array initialization syntax and function names as addresses.

#include <iostream>

using namespace std;

double calculate(double x, double y, double (*pf)(double a, double b));
double add(double x, double y);

int main()
{
double x, y;
cout << "Enter two numbers (q to exit): ";
while(cin >> x >> y)
{
if(cin.fail())
break;
calculate(x, y, add);
cout << "The sum is: " << calculate(x, y, add) << "\n\n";
}
return 0;
}

double calculate(double x, double y, double (*pf)(double a, double b))
{
return pf(x, y);
}

double add(double x, double y)
{
return x + y;
}

C++ Primer Plus Chapter 7 Exercise 8

c plus plus Exercise 8 has us re-writing a skeleton program to fill in the missing functions. A combination of structs, pointers, and functions will complete this exercise. Comments describing where and what additions have been made are embedded in the code. See my solution below:

8. This exercise provides practice in writing functions dealing with arrays and structures. The following is a program skeleton. Complete it by providing the described functions:


#include <iostream>

using namespace std;
const int SLEN = 30;
struct student {
char fullname[SLEN];
char hobby[SLEN];
int ooplevel;
};

int getinfo(student pa[], int n);
void display1(student st);
void display2(const student * ps);
void display3(const student pa[], int n);

int main(){
cout << "Enter class size: ";
int class_size;
cin >> class_size;
while (cin.get() != '\n')
continue;
student * ptr_stu = new student[class_size];
int entered = getinfo(ptr_stu, class_size);

for (int i = 0; i < entered; i++) {
display1(ptr_stu[i]);
display2(&ptr_stu[i]);
}
display3(ptr_stu, entered);
delete [] ptr_stu;
cout << "Done\n";

return 0;
}

// getinfo() has two arguments: a pointer to the first element of
// an array of student structures and an int representing the
// number of elements of the array. The function solicits and
// stores data about students. It terminates input upon filling
// the array or upon encountering a blank line for the student
// name. The function returns the actual number of array elements
// filled.
int getinfo(student pa[], int n)
{
int i;
for(i = 0; i < n; i++)
{
cout << "Student Number: " << (i+1) << "\n";
cout << "Student's Name: ";
cin.getline(pa[i].fullname, SLEN);

cout << "Enter students hobby: ";
cin.getline(pa[i].hobby, SLEN);

cout << "Enter students OOP level: ";
cin >> pa[i].ooplevel;
cin.get();
}
return i;
}

// display1() takes a student structure as an argument
// and displays its contents
void display1(student st)
{
cout << "\n=============Display 1================\n";
cout << "Student name: " << st.fullname << "\n";
cout << "Hobby: " <<  st.hobby << "\n";
cout << "OOP Level: " << st.ooplevel << "\n";
cout << "=============End Display 1==============\n";
}

// display2() takes the address of student structure as an
// argument and displays the structure's contents
void display2(const student * ps)
{
cout << "\n============Display 2================\n";
cout << "Students Name: " << ps->fullname << "\n";
cout << "Hobby: " << ps->hobby << "\n";
cout << "OOP Level" << ps->ooplevel << "\n";
cout << "==========End Display 2================\n";
}

// display3() takes the address of the first element of an array
// of student structures and the number of array elements as
// arguments and displays the contents of the structures
void display3(const student pa[], int n)
{
for(int i = 0; i < n; i++)
{
cout << "\n============Display 3================\n";
cout << "Student: " << (i+1) << "\n";
cout << "Fullname: " << pa[i].fullname << "\n";
cout << "OOP Level: " << pa[i].ooplevel << "\n";
cout << "=============End Display 3============\n";
}
}

Linux Password Cracker

python

python

It has been about a month since I have posted, that does not mean I have stopped coding. Lately I’ve been back on my “security” kick. Although for me it’s more of an obsession rather than just a kick. When it comes to security, a programming language like Python can make many common task a breeze to accomplish. Here I have a basic Linux password cracker that can crack the current SHA-512 shadowed hashes from a user supplied dictionary and detect whether a hash is the lesser used MD5 or SHA-256 format. Enjoy.

import crypt

def testPass(cryptPass):
hashType = cryptPass.split("$")[1]
if hashType == '1':
print "[+] Hash Type is MD5"
elif hashType == '5':
print "[+] Hash Type is SHA-256"
elif hashType == '6':
print "[+] Hash Type is SHA-512"
else:
"[+] Hash Type is Unknown"

salt = cryptPass.split("$")[2]
dictFile = open('dictionary.txt', 'r')
for word in dictFile.readlines():
word = word.strip('\n')
pepper = "$" + hashType + "$" + salt
cryptWord = crypt.crypt(word, pepper)
if cryptWord == cryptPass:
print '[+] Found Password: ' + word + '\n'
return
print '[-] Password Not Found.\n'
return

def main():
passFile = open('passwords.txt')
for line in passFile.readlines():
if ':' in line:
user = line.split(':')[0]
cryptPass = line.split(':')[1].strip(' ')
print '[*] Cracking Password For: ' + user
testPass(cryptPass)

if __name__ == '__main__':
main()

Bubble Sort Algorithm

The Bubble Sort algorithm is one the simplest sorting algorithm to implement. It works by continually looping through pairs in a list and comparing each pair. At each pair, it will perform a swap if the pair happens to be in the wrong order. The order will either be ascending or descending depending on what the programmer wants. This happens until no more swaps are needed. This algorithm apparently gets the name “bubble-sort” because you can imagine the smaller elements bubble to the top of the list. Checkout my bubble sort implementation below. When ran, it will give a good visual reference for the algorithm. It sorts in ascending order, complexity O(n^2). This algorithm approaches O(n) if the elements are already almost in order. Note that is the not the most efficient algorithm for large data sets.

#include <iostream>

using namespace std;

int main()
{
int array[7];
int i, j;

for(i = 0; i <= 6; i++){
cout << "Enter unsorted numbers: " << endl;
cin >> array[i];
}
for(i = 0; i <= 5; i++){ //loop through pair of integers
for(j = i+1; j <= 6; j++){
int temp;
if(array[i] > array[j])
{
temp = array[i]; //swapping mechanisms
array[i] = array[j];
array[j] = temp;
}
}
}
for(i = 0; i <= 6; i++){
cout << array[i]; //sorted output
}
return 0;
}