Difference between revisions of "CSC231 Homework 6 Solution"

From dftwiki3
Jump to: navigation, search
(New page: <code><pre> ;;; hw6.asm ;;; Amy Gray ;;; This program reads a bmp file into memory and decodes a secret ;;; message hidden in the pixels via steganography ;;; %include "mytools2.inc" ; f...)
 
Line 1: Line 1:
 
<code><pre>
 
<code><pre>
 
;;; hw6.asm
 
;;; hw6.asm
;;; Amy Gray
+
;;; Ellysha Raelen Recto
;;; This program reads a bmp file into memory and decodes a secret
+
;;;
;;; message hidden in the pixels via steganography
+
;;; This program written from the skeleton program, makegreyBmp.asm, written
 +
;;; by D. Thiebaut. This program reads a bmp file and reads the last bit of
 +
;;; each byte. The bytes read contains a secret msg which is then displayed.
 
;;;  
 
;;;  
 
%include "mytools2.inc" ; for basic printing to the screen
 
%include "mytools2.inc" ; for basic printing to the screen
 
%include "fileio2.inc" ; for basic file operations
 
%include "fileio2.inc" ; for basic file operations
+
 
%assign SYS_EXIT 1
 
%assign SYS_EXIT 1
 
%assign MAXPIXEL 5000000
 
%assign MAXPIXEL 5000000
 +
 +
%assign SYS_WRITE 4
 +
%assign STDOUT 1
  
 
%assign RED            2
 
%assign RED            2
Line 23: Line 28:
 
errorMsg db    "Error accessing file!",0x0A
 
errorMsg db    "Error accessing file!",0x0A
 
errorLen equ    $-errorMsg
 
errorLen equ    $-errorMsg
message  db 0 ;will be used to store decoded byte
+
msg db 0
  
 
section .bss
 
section .bss
filename resb  255 ; reserve 255 chars for filename
+
filename resb  255   ; reserve 255 chars for filename
 
handle  resd 1 ; file descriptor
 
handle  resd 1 ; file descriptor
 
noRead resd 1 ; contains number of bytes read
 
noRead resd 1 ; contains number of bytes read
 
lWidth resd 1 ; the line width rounded to the nearest
 
lWidth resd 1 ; the line width rounded to the nearest
       ; dword boundary lWidth=(((width-1)/4)+1)*4
+
       ; dword boundary lWidth=(((width-1)/4)+1)*4
  
 
;;; ----------------------------------------------------------
 
;;; ----------------------------------------------------------
Line 83: Line 88:
 
cmp al,0
 
cmp al,0
 
jne copy
 
jne copy
+
 
 
;;; --- open file ---
 
;;; --- open file ---
 
         openFile filename, [handle], errorMsg, errorLen
 
         openFile filename, [handle], errorMsg, errorLen
Line 115: Line 120:
  
 
   
 
   
;;; -------------------------------------------------------------
+
;; -----------------------------------
;;; mainloop: Extract message hidden in the image's pixels. Goes
+
;; add your byte-examining loop  below!
;;;     through eight bytes from the image and stores the
+
        ;; you can access the bytes of the pixels as  byte[ebx+pixelBuf]
;;; least significant bit from in a new byte, which is
+
        ;; and increment ebx in the loop to access successive bytes
;;; a character from the message. The message ends with
+
;; -----------------------------------
;;; a zero, so each newly formed byte is checked to see
 
;;; if it is equal to zero.  If yes, the program jumps
 
;;; to the end.  If no, the program prints the character
 
;;; registers modified: eax, ebx, ecx, edx
 
;;; -------------------------------------------------------------
 
 
add ebx, 7 ;moves to eighth byte
 
;bits are stored backwards from 7 to 0
 
 
;; for some reason, when 'jmp mainloop' is called below, the program
 
;; was jumping back to 'add ebx, 7' and adding 7 to ebx (causing everything
 
;; to go wrong).  'add ebx, 0' is put in as a placeholder.  The program
 
;; jumps back to here, does nothing and continues on to mainloop
 
add ebx, 0
 
  
mainloop:
+
;; -----------------------------------
call decode1byte
+
;; mainFor: main section for reading secret bytes
cmp byte[message], 0
+
        ;; written by: Ellysha Raelen Recto
je theEnd
+
        ;; registers modified: none
 
+
;; -----------------------------------
push ebx ;ebx needs to be saved for accessing pixels
 
mov ecx, message
 
mov eax, SYS_WRITE
 
mov ebx, STDOUT
 
mov edx, 1
 
int 0x80
 
pop ebx ;restore ebx
 
jmp mainloop ;repeat
 
 
 
 
 
 
 
  
 +
mainFor:
 +
call decode1byte ; calls method to decode 1 byte of secret msg
 +
cmp dl, 0 ; if 1 byte is zero, end of secret msg
 +
je exit ; go to exit if end of msg is found
 +
call printByte ; print byte
 +
jmp mainFor ; decode more bytes if end of msg isnt found
  
 
;; -----------------------------------
 
;; -----------------------------------
 
;; end of pixel loop area
 
;; end of pixel loop area
 
;; -----------------------------------
 
;; -----------------------------------
theEnd:
+
 
 
;;; --- position file pointer back to beginning of file ---
 
;;; --- position file pointer back to beginning of file ---
 
  seek0 [handle]
 
  seek0 [handle]
Line 166: Line 151:
 
;;; --- close file ---
 
;;; --- close file ---
 
close [handle]
 
close [handle]
+
 
 
;;; --- exit() ---
 
;;; --- exit() ---
 
exit:
 
exit:
Line 204: Line 189:
 
ret 8
 
ret 8
  
 
+
;;; -------------------------------------------------------------
;;; --------------------------------------------------------
+
;;; decode1byte: decodes 1 byte of secret msg, first bit of the byte
;;; decode1byte: runs through a series of eight bytes
+
;;; is from the last bit of first 8th byte of image
;;; and extracts the last bit from each.
+
;;; registers modified: edx, ecx, eax, ebx
;;; Starts at the eighth bit and works backward
+
;;; written by: Ellysha Raelen Recto
;;; Each extracted bit is stored in edx as
+
;;; -------------------------------------------------------------
;;; a new byte. This byte is transferred into
 
;;; the variable 'message'
 
;;; registers modified: ebx
 
;;; -------------------------------------------------------
 
 
 
decode1byte:
 
decode1byte:
push edx
+
mov dl, 0
push eax
+
mov ecx,7 ; reads first 7 bits
push ecx
+
for: call read1bit ; call method to read 1 bit with shifting
+
dec ebx ; goes to next bit
mov edx, 0 ;will hold secret byte
+
loop for
mov eax, 0 ;will hold byte to extract from
+
mov al, byte[ebx+pixelBuf+7] ; reads last bit
mov ecx, 7
+
and al, 1
 +
or dl, al
 +
add ebx, 15
 +
ret
  
;; the loop runs 7 times.  At the end of each run, the
+
;;; -------------------------------------------------------------
;; secret byte is shifted to the left to make room for
+
;;; printByte: prints 1 byte of secret msg
;; the next new bit. The eighth bit is then extracted
+
;;; registers modified: edx, ecx, eax, ebx
;; outside the loop, so that no shift happens.  An
+
;;; written by: Ellysha Raelen Recto
;; eighth shift would cause the first bit to be lost
+
;;; -------------------------------------------------------------
;; and an extraneous zero to appear at the end.
+
printByte:
forbyte:
+
pushad ; pushes registers to stack
mov al, byte[ebx+pixelBuf] ;byte to extract from
+
mov byte[msg], dl ; moves byte read from image to msg
and al, 1 ;clear all but least significant bit
+
mov eax, SYS_WRITE
or dl, al ;add new bit to dl
+
mov ebx, STDOUT
shl dl, 1 ;make room for next bit
+
mov ecx, msg ; prints msg
dec ebx ;move to next byte
+
mov edx, 1
loop forbyte
+
int 0x80
 +
popad ; retrieves values of registers from stack
 +
ret
  
mov al, byte[ebx+pixelBuf] ;get 8th bit
+
;;; -------------------------------------------------------------
and al, 1
+
;;; read1bit: used to read a bit if it's one of the first 7 bits of
or dl, al
+
;;; a byte from the image
mov byte[message], dl ;store decoded byte in 'message'
+
;;; registers modified: edx, eax
 +
;;; written by: Ellysha Raelen Recto
 +
;;; -------------------------------------------------------------
 +
read1bit:
 +
mov al, byte[ebx+pixelBuf+7]  
 +
and al, 1 ; get the last bit of byte from image
 +
or dl, al ; saves the values of the bits from
 +
; the bytes of already read to dl
 +
shl dl, 1 ; shifts bits to make room for next bit
 +
; to be read
 +
ret
  
add ebx, 15 ;jumps to next set of eight bytes
 
 
pop ecx
 
pop eax
 
pop edx
 
 
ret
 
  
 
</pre></code>
 
</pre></code>

Revision as of 17:11, 4 November 2008

;;; hw6.asm
;;; Ellysha Raelen Recto
;;;
;;; This program written from the skeleton program, makegreyBmp.asm, written
;;; by D. Thiebaut. This program reads a bmp file and reads the last bit of
;;; each byte. The bytes read contains a secret msg which is then displayed.
;;; 
%include "mytools2.inc"		; for basic printing to the screen
%include "fileio2.inc"		; for basic file operations
	
%assign SYS_EXIT	1
%assign MAXPIXEL	5000000

%assign SYS_WRITE	4
%assign STDOUT		1

%assign RED             2
%assign GREEN           1
%assign BLUE            0       



;;; ---------------------------------------------------------
;;; data segments
;;; ---------------------------------------------------------
        section .data
errorMsg db     "Error accessing file!",0x0A
errorLen equ    $-errorMsg
msg	db	0

	section	.bss
filename resb   255   		; reserve 255 chars for filename
handle   resd	1		; file descriptor
noRead	 resd	1		; contains number of bytes read
lWidth	 resd	1		; the line width rounded to the nearest
      				; dword boundary lWidth=(((width-1)/4)+1)*4 	

;;; ----------------------------------------------------------
;;; bmp buffer starts here
;;; ----------------------------------------------------------
bmpBuf	equ	$
type	resw	1		; header
size	resd	1
resvd1	resw	1
resvd2	resw	1
offset	resd	1
;;;
size2	resd	1		; information header
width	resd	1
height	resd	1
planes	resw	1
xbits	resw	1
compr	resd	1
imgsize	resd	1
xres	resd	1
yres	resd	1
nocol	resd	1
impcol	resd	1
headLen equ	$-bmpBuf	; length of header
	
pixelBuf resb	MAXPIXEL*3	; times 3 bytes (RGB)

	
;;; ---------------------------------------------------------
;;; code area
;;; ---------------------------------------------------------
	section	.text
	global	_start

_start:
;;; --- check that user entered more than 1 argument on command line ---
	pop	ebx		; get # of arguments on command line
	cmp	ebx,1
	jg	process		; if user forgot file name, exit
	dumpStr "Syntax: progName filename"
	jmp	exit

;;; --- get filename from command line ---
process:	
	pop	ebx		; pointer to argv[0] (name of program)
	pop	ebx		; pointer to argv[1]
	mov	edi,filename	; pointer to filename
copy:	mov	al,[ebx]	; copy name of file from argv[1] to
	mov	[edi],al	; filename string, until \0 is copied
	inc	ebx
	inc	edi
	cmp	al,0
	jne	copy

;;; --- open file ---
        openFile filename, [handle], errorMsg, errorLen
        

;;; --- read file in buffer ---
        readFile [handle], bmpBuf, MAXPIXEL, noRead
        
;;; --- compute length of a line of pixel:
;;; line length = (( byte width+3)/4)*4 where
;;; byte width = 3 * width, since we have 3 bytes per pixel
;;; 
	mov	eax,[width]
	add	eax,[width]
	add	eax,[width]	; eax <-- 3 x width
	dec	eax		; eax
	shr	eax,2		; 
	inc	eax
	shl	eax,2
	mov	[lWidth],eax

;;; --------------------------------------------------------------
;;; Find the address of the first byte of the image and put
;;; it in ebx
;;; --------------------------------------------------------------

        mov	eax,0
        push 	eax
        push 	eax
        call  	hw2index

 
	;; -----------------------------------
	;; add your byte-examining loop  below!
        ;; you can access the bytes of the pixels as  byte[ebx+pixelBuf]
        ;; and increment ebx in the loop to access successive bytes
	;; -----------------------------------

	;; -----------------------------------
	;; mainFor: main section for reading secret bytes
        ;; written by: Ellysha Raelen Recto
        ;; registers modified: none
	;; -----------------------------------

mainFor:
	call	decode1byte	; calls method to decode 1 byte of secret msg
	cmp	dl, 0		; if 1 byte is zero, end of secret msg
	je	exit		; go to exit if end of msg is found
	call	printByte	; print byte
	jmp	mainFor		; decode more bytes if end of msg isnt found

	;; -----------------------------------
	;; end of pixel loop area
	;; -----------------------------------

;;; --- position file pointer back to beginning of file ---
 	seek0	[handle]
	
;;; --- write contents back to file ---
 	writeBuf [handle], bmpBuf, noRead
	
;;; --- close file ---
	close	[handle]

;;; --- exit() ---
exit:	
	mov	eax,SYS_EXIT
	mov	ebx,0
	int	0x80		; final system call


	
;;; -------------------------------------------------------------
;;; hw2index:	converts height and width to pixel index
;;;             index returned in ebx.  Note that computation is
;;;             performed with lWidth which must be computed
;;;             separately and is the number of bytes in one line
;;;             of pixel, such that number of byte is a multiple of
;;;             4.
;;; registers modified:	 ebx
;;; -------------------------------------------------------------
hw2index:
	push	ebp
	mov	ebp,esp
	
	push	eax		; save eax and edx
	push	edx
	mov	eax,[lWidth]	
	xor	edx,edx
	mul	dword[ebp+12]	; eax = lWidth * h
	add	eax,[ebp+8]	; eax += 3*w
	add	eax,[ebp+8]
	add	eax,[ebp+8]
	mov	ebx,eax		; pass result in ebx
	
	pop	edx
	pop	eax
	pop	ebp
	
	ret	8

;;; -------------------------------------------------------------
;;; decode1byte: decodes 1 byte of secret msg, first bit of the byte
;;; 	is from the last bit of first 8th byte of image
;;; registers modified:	 edx, ecx, eax, ebx
;;; written by: Ellysha Raelen Recto
;;; -------------------------------------------------------------
decode1byte:
	mov	dl, 0
	mov	ecx,7		; reads first 7 bits
for:	call	read1bit	; call method to read 1 bit with shifting
	dec	ebx		; goes to next bit
	loop	for
	mov	al, byte[ebx+pixelBuf+7] ; reads last bit
	and	al, 1
	or	dl, al
	add	ebx, 15
	ret

;;; -------------------------------------------------------------
;;; printByte: prints 1 byte of secret msg
;;; registers modified:	 edx, ecx, eax, ebx
;;; written by: Ellysha Raelen Recto
;;; -------------------------------------------------------------
printByte:
	pushad			; pushes registers to stack
	mov	byte[msg], dl	; moves byte read from image to msg
	mov	eax, SYS_WRITE
	mov	ebx, STDOUT
	mov	ecx, msg	; prints msg
	mov	edx, 1
	int 	0x80
	popad			; retrieves values of registers from stack
	ret

;;; -------------------------------------------------------------
;;; read1bit: used to read a bit if it's one of the first 7 bits of
;;; 	a byte from the image
;;; registers modified:	 edx, eax
;;; written by: Ellysha Raelen Recto
;;; -------------------------------------------------------------
read1bit:
	mov	al, byte[ebx+pixelBuf+7] 
	and	al, 1		; get the last bit of byte from image
	or	dl, al		; saves the values of the bits from
				; the bytes of already read to dl
	shl	dl, 1		; shifts bits to make room for next bit
				; to be read
	ret