INCLUDE Irvine32.inc
;KEY = 239     		;암호 키. 원본 소스에 있던 것. 문제풀이에서는 사용하지 않음
BUFMAX = 128     	;버퍼의 최대 사이즈. 어떤 버퍼인가?

.data
sPrompt  BYTE  "Enter the plain text: ",0
sEncrypt BYTE  "Cipher text:          ",0
sDecrypt BYTE  "Decrypted:            ",0

buffer   BYTE   BUFMAX+1 DUP(0)				;문자열의 총 갯수 + 널종료 문자의 갯수
bufSize  DWORD  ?

sUserKey	BYTE "Enter the user key: ",0
userkey		BYTE BUFMAX+1 DUP(0)
userkeysize	DWORD ?
tempKEY	BYTE	?	;키값의 임시저장공간

bufferindex	DWORD ?	;버퍼 인덱스용 변수
keyindex		DWORD ?	;키값 인덱스용 변수

.code
main PROC
	call	Clrscr			;화면 정리
	mov	edx,OFFSET sUserKey	;화면에 "Enter the user key: " 출력 준비
	call	WriteString		;화면에 "Enter the user key: " 출력
	mov	ecx,BUFMAX		;사용자 정의 키의 최대 길이를 지정하는 듯
	mov	edx,OFFSET userkey	;userkey의 오프셋 저장
	call	ReadString		;사용자 정의 키 값 입력
	mov	userkeysize,eax	;userkeysize에 사용자 정의 키의 길이를 저장시킨다
	;call	;사용자 임의의 암호 문자열을 입력받는다.
	call	InputTheString	;문자열 갯수 저장하는 기능만 보이는데 어느새 문자열을 buffer에 저장했을까?
	call	TranslateBuffer	;TranslateBuffer를 호출하여 문자열과 KEY를 XOR하여 암호화한다
	mov	edx,OFFSET sEncrypt	;"Cipher text: "를 화면에 출력할 준비를 한다.
	call	DisplayMessage	;화면에 암호화된 문자열을 출력한다
	call	TranslateBuffer	;TranslateBuffer를 호출하여 암호화된 문자열과 KEY를 XOR하여 복호화한다
	mov	edx,OFFSET sDecrypt	;"Decrypted: "를 출력할 준비
	call	DisplayMessage	;평문 출력.

	exit
main ENDP

;-----------------------------------------------------
InputTheString PROC
;-----------------------------------------------------
	pushad					;32bit 레지스터 푸시
	mov	edx,OFFSET sPrompt
	call	WriteString		;화면에 "Enter the plain text: "를 출력
	mov	ecx,BUFMAX			;ecx에 BUFMAX(=128)를 대입
	mov	edx,OFFSET buffer	;edx에 buffer의 오프셋값을 대입
	call	ReadString		;문자열 입력
	mov	bufSize,eax			;bufsize에 eax값 저장=입력한 문자수를 bufsize에 저장
	call	Crlf			;한줄 아래로 간다.
	popad					;32bit 레지스터 팝
	ret
InputTheString ENDP

;-----------------------------------------------------
DisplayMessage PROC
;-----------------------------------------------------
	pushad					;32bit 레지스터 푸시
	call	WriteString		;"Cipher text: "를 화면에 출력하거나 "Decrypted: "를 화면에 출력
	mov	edx,OFFSET buffer	;buffer에 들어있는 문자열 출력 준비
	call	WriteString		;buffer에 들어있는 문자열을 출력한다(암호화 되있거나 복호화되어있다)
	call	Crlf			;한줄 내려가
	call	Crlf			;또 내려가
	popad					;32bit 레지스터 팝
	ret
DisplayMessage ENDP

;-----------------------------------------------------
TranslateBuffer PROC
;-----------------------------------------------------
	pushad				;32bit 레지스터 푸시
	mov	ecx,bufSize		;문자열의 갯수로 루프 횟수를 지정한다
	mov	keyindex,0		;사용자 정의 키 인덱스 시작
	mov	bufferindex,0		;버퍼 인덱스 시작
	
L1:
	mov	esi,keyindex		;esi에 키 인덱스 저장
	mov	al,userkey[esi]
	mov	tempKEY,al		;임시 키 저장공간에 해당 인덱스의 키 값 저장
	cmp	esi,userkeysize	;키 인덱스 값과 사용자 정의 키의 위치 비교
	je	initkey			;키 인덱스 초기화로 점프
	jne	continue			;키 인덱스 증가로 점프
	initkey:
	mov	keyindex,0		;키 인덱스 초기화
	jmp	goloop			;루프 계속한다
	continue:
	inc	keyindex			;키 인덱스값 증가시킨다
	goloop:
	
	mov	esi,bufferindex
	xor	buffer[esi],al	;buffer배열의 esi번째 문자를 KEY와 xor한다
	inc	bufferindex				;인덱스값 1증가
	loop	L1			;루프 반복

	popad				;32bit 레지스터 팝
	ret
TranslateBuffer ENDP
END main

풀이과정에서 line 82에서 cmp를 keyindex와 했기 때문에 프로그램 오류가 있었다.

cmp esi,userkeysize

를 통해서 keyindex가 사용자 정의 키의 배열 끝에 도달하지 못했다면 inc를 통해 계속 값을 올려줘야한다.

실행화면

Posted by 공돌이pooh
,