$24
Binary Loader (100 points)
You will mimic the job of a binary loader (in a highly simpli ed manner). You will write a program that will load code from a le, and execute the code. You will be provided a function signature and a binary le that contains the raw bytes of the function's code. The function is a pre-compiled 32 bit binary. It is not an elf binary. It contains the raw bytes of a calculator function. It has been tested on remote.cs.binghamton.edu.
File func.bin contains a function with signature int calc(char operator, int num1, int num2);. Implement the main function within loader.c.
NOTE: The below instructions are only pointers to help you get started. You are en-couraged to experiment and try di erent library functions. For example, you may want to experiment with open and read instead of fopen and fread. Or, if you feel adventurous, you may want to allocate memory on the heap, read the raw bytes on to the heap, call mprotect to make the page that contains the raw bytes executable, and execute it.
The main function must accept exactly 4 arguments. Otherwise, main must print \Usage" message and exit. The rst argument is the name of the le that contain the binary function, the second argument and fourth argument are integers, and the third argument is a character that represents an operation.
Main function will open the le with rst argument as the name. (HINT: use fopen. The second argument to fopen is the mode in which the le is opened. Because you are opening a binary le, the mode must be rb. Refer man page for fopen for more details).
Main function will read the contents of the le into a local array that is large enough to contain the entire le. (HINT: use fread. You could either read character by character or rst calculate number of bytes in the le, and read them all in one call to fread. Refer to man page for fread for usage.)
Declare a function pointer type with name Calc fptr with the same signature as calc.
Convert the second and the fourth arguments to integers using function \atoi". Refer to the man page of atoi for usage.
Cast the array to type Calc fptr. Invoke it with the second, third and fourth arguments to main as arguments.
Write a Make le to compile loader.c to generate an executable loader. You will get a segmentation fault when you run loader with the right arguments. This is because, you are trying to execute code that is in the local variable, which is on the stack. Stack is not executable. Now, modify the Make le and include -Wl,-z,execstack ag. This is a linker ag that tells the linker to mark the stack region as executable. This is for demonstration only. DO NOT use it in production code, if you were ever to write code for a profession. Print the result, and return.
Skeleton Code
1
/ l o a d e r . c /
3
/ TODO: I n c l u d e
a p p r o p r i a t e h e a d e r s
/
5
i n t main ( i n t argc ,
c h a r argv [ ] ) f
/ TODO:
D e c l a r e
an a r r a y l a r g e enough
t o
h o l d t h e raw b y t e s . Raw b y t e s a r e
b e s t
s t o r e d i n
byte a d d r e s s a b l e
a r r a y s .
Pick t h e a p p r o p r i a t e
type .
C a l l
i t " r a w b y t e s " /
7
/ TODO:
D e c l a r e
a f u n c t i o n
p o i n t e r
type t h a t matches
t h e c a l c
f u n c t i o n ' s
type .
C a l l i t
" C a l c f p t r "
/
9
FILE f p ;
u n s i g n e d i n t i ;
11
C a l c f p t r c a l c u l a t o r ;
13
/ TODO
i f number
o f arguments i s
not 4
( 5
i n c l u d i n g
program
name )
p r i n t
( "Usage
%s <f i l e n a m e <u i n t <o p e r a t i o n <u i n t nn" ,
argv [ 0 ] )
and
15
e x i t /
/ TODO:
Open and
r e a d t h e b i n a r y
f i l e
i n t o r a w
b y t e s . Use f o p e n and
f r e a d .
17
/
c a l c u l a t o r = ( C a l c f p t r ) r a w b y t e s ;
19
/ TODO:
P r i n t
t h e r e s u l t . R e f e r
t o
sample
i n p u t
and
output .
/
r e t u r n 0 ;
21
g
Sample input and output
$ . / l o a d e r
Usage . / l o a d e r <f i l e n a m e <i n t <o p e r a t i o n <i n t
3
$ . / l o a d e r f u n c . b i n 32 + 11
32 + 11 = 43
5
$ . / l o a d e r f u n c . b i n 3211
3211 = 21
7
$ . / l o a d e r f u n c . b i n 3211
Usage . / l o a d e r <f i l e n a m e <i n t <o p e r a t i o n <i n t
9
$ . / l o a d e r f u n c . b i n 32 n 11
3211 = 352
11
$ . / l o a d e r f u n c . b i n 32 / 11
32 / 11 = 2
13
$ . / l o a d e r f u n c . b i n 32 / 0
F l o a t i n g e x c e p t i o n
Input \32 * 11" is a strange one. The terminal replaces * with all the les in the directory, so you must escape it!
Happy Shell (100 points)
The below program implements a simple version of a shell program that runs programs that accept no arguments:
/ h e l l o s h . c /
2
#i n c l u d e <s t d i o . h
#i n c l u d e <s t d l i b . h
4
#i n c l u d e <s t r i n g . h
#i n c l u d e <e r r n o . h
6
i n t main ( )
f
8
c h a r l i n e [ 1 0 2 4 ] ;
i n t pid ,
i ;
10
c h a r a r g s [ ] = f& l i n e , 0 g;
12
w h i l e ( 1 )
f
p r i n t f ( " H e l l o !! " ) ;
14
i f ( ! f g e t s ( l i n e , 1 0 2 3 , s t d i n ) ) f
break ;
16
g
18
i f ( strcmp ( l i n e , " e x i t nn" ) == 0 ) break ;
4
20
f o r ( i
= 0 ;
i < s t r l e n ( l i n e ) ; i ++) f
i f ( l i n e [ i ] == ' nn ' ) l i n e [ i ] = ' n0 ' ;
22
g
24
p i d = f o r k ( ) ;
26
i f ( p i d == 0 ) f
/
This
i s
t h e
c h i l d
/
28
execvp ( l i n e , a r g s ) ;
f p r i n t f ( s t d e r r , " H e l l o ! ! : %s nn" , s t r e r r o r ( e r r n o ) ) ;
30
e x i t ( e r r n o ) ;
g e l s e f
32
/
This
i s
t h e
p a r e n t
/
w a i t (NULL) ;
34
g
g
36
r e t u r n
0 ;
g
Modify the shell program such that it can execute programs that accept arguments. For example, \ls -l" and \objdump -d -M intel foo foo.disas" are both valid commands to hello! shell.
In your Make le, use your modi ed hellosh.c to build an executable called hellosh when the command make hellosh is given.
Submission
Commit all work to your Github repository, then include the 7-digit SHA hash in your student comment for a MyCourses submission. Do not include any les!
5