NASM - The Netwide Assembler
NASM Forum => Programming with NASM => Topic started by: Johnksilver on July 24, 2013, 06:34:33 PM
-
Hi there, how can I change this code below to a NASM code? My key to encrypt is k = 326 and I want to user type a number of lenght = 7. So I want encrypt this number with XOR property and then I want to show the encrypted number (cipher text), after I want to decrypt and show the decrypted number and see if the algorithm is correct.
KEY = 326 ; any value between 1-255
BUFMAX = 128 ; maximum buffer size
section .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 ?
.code
main PROC
call InputTheString ; input the plain text
call TranslateBuffer ; encrypt the buffer
mov edx,OFFSET sEncrypt ; display encrypted message
call DisplayMessage
call TranslateBuffer ; decrypt the buffer
mov edx,OFFSET sDecrypt ; display decrypted message
call DisplayMessage
exit
main ENDP
;-----------------------------------------------------
InputTheString PROC
;
; Prompts user for a plaintext string. Saves the string
; and its length.
; Receives: nothing
; Returns: nothing
;-----------------------------------------------------
pushad
mov edx,OFFSET sPrompt ; display a prompt
call WriteString
mov ecx,BUFMAX ; maximum character count
mov edx,OFFSET buffer ; point to the buffer
call ReadString ; input the string
mov bufSize,eax ; save the length
call Crlf
popad
ret
InputTheString ENDP
;-----------------------------------------------------
DisplayMessage PROC
;
; Displays the encrypted or decrypted message.
; Receives: EDX points to the message
; Returns: nothing
;-----------------------------------------------------
pushad
call WriteString
mov edx,OFFSET buffer ; display the buffer
call WriteString
call Crlf
call Crlf
popad
ret
DisplayMessage ENDP
;-----------------------------------------------------
TranslateBuffer PROC
;
; Translates the string by exclusive-ORing each
; byte with the encryption key byte.
; Receives: nothing
; Returns: nothing
;-----------------------------------------------------
pushad
mov ecx,bufSize ; loop counter
mov esi,0 ; index 0 in buffer
L1:
xor buffer[esi],KEY ; translate a byte
inc esi ; point to next byte
loop L1
popad
ret
TranslateBuffer ENDP
END main
-
I edited your message to put "code tags" around your code - just the word "code" in square brackets at the beginning of your code, and "/code" in square brackets at the end. Hope I didn't screw anything up.
We can, and probably will, show you how to translate your code to Nasm syntax. However, there are some "issues" to be worked out first. The worst one is probably that your proposed key exceeds a byte. As the comment says, "between 1 and 255". What do you actually want to do here?
The other issue is that you use some apparently external functions - "WriteString" and "ReadString". These look like they might be Kip Irvine's stuff, but it could be anything. Do you have this library (irvine32.lib or whatever)? Do you wish to link against it ("should" work, but I'm not certain) or do you want to include "WriteString" and "ReadString" in your Nasm code? There is an apparent "exit" macro that will have to be dealt with, too.
Outside of that, it's mostly a case of deleting the "Masm cruft", but there are some things that will have to be changed as well. I used to do a lot of this, and I think I mostly remember how it goes. But merely translating it to Nasm syntax is unlikely to give you working code.
What do you really want to do here? (especially with the key?) Why do you want to use Nasm for what is apparently Masm code?
Best,
Frank
-
I want the key to be 326, that comment was from the before this existing code. But this key could be any number, it's just the key to encryption.
I want to include the WriteString and ReadString to the Nasm code.
I want a Nasm code to implement the XOR property applied to encryption and decryption. I found this Masm code and I want to translate it for Nasm.
-
326 isn't going to fit in a byte, regardless of what you want. You could, I suppose, xor your plain text with a word, two bytes at a time. I guess it would work.
Including "WriteFile" and "ReadFile" in Nasm would require knowing what OS. Windows, I suppose?
Best,
Frank
-
Windows Seven x86. Let me try to be more clear, I need to do this:
Logic XOR operation has an interesting property. If an integer X is XORed with Y and the result Z is XORed with Y again, the result produced is X:
Z = X xor Y (Z xor Y) = X
This “reversible” property of XOR provides an easy way to perform data encryption: a plain text message can be transformed into an unintelligible string called cipher text by XORing each of its characters with a character called a key. The cipher text can be stored or transmitted to a remote location and not able to be read by unauthorized persons who do not have the key. The intended viewer uses the key to decrypt the cipher text and produce the original plain text.
Write an assembly language program in NASM to do the following:
1. Ask user to enter an account number (7 digits in length),
2. encrypt the account number with the key= 326,
3. print the encrypted string, cipher text, on the screen,
4. decrypt the encrypted string with the same key
5. print the decrypted string on the screen to verify the algorithm correctness.
Can you help me??
-
Hi John,
Here's my attempt. I'm clueless in Windows, so that part's probably wrong. I could have made a mistake in the "translate to Nasm" part too. It assembles without complaint - that doesn't mean it runs correctly!
global main
; these "true names" may be wrong
; try 'em without the underscore and/or without @n
; if your linker can't find 'em
; may depend on linker
%define ExitProcess _ExitProcess@4
%define GetStdHandle _GetStdHandle@4
%define WriteFile _WriteFile@20
%define ReadFile _ReadFile@20
extern ExitProcess
extern GetStdHandle
extern WriteFile
extern ReadFile
; comment does not match code!
KEY equ 326 ; any value between 1-255
BUFMAX equ 128 ; maximum buffer size
section .data
sPrompt db "Enter the plain text: ",0
sEncrypt db "Cipher text: ",0
sDecrypt db "Decrypted: ",0
; should probably be local to routine
newline db 13, 10, 0
section .bss
buffer resb BUFMAX+1
bufSize resd 1
; maybe should be local to routines
; but we want 'em persistant
hstdin resd 1
hstdout resd 1
; should probably be local to routines
byteswritten resd 1
bytesread resd 1
section .text
main:
call InputTheString ; input the plain text
call TranslateBuffer ; encrypt the buffer
mov edx, sEncrypt ; display encrypted message
call DisplayMessage
call TranslateBuffer ; decrypt the buffer
mov edx, sDecrypt ; display decrypted message
call DisplayMessage
push 0
call ExitProcess
;-----------------------------------------------------
InputTheString:
;
; Prompts user for a plaintext string. Saves the string
; and its length.
; Receives: nothing
; Returns: nothing
;-----------------------------------------------------
pushad
mov edx, sPrompt ; display a prompt
call WriteString
mov ecx, BUFMAX ; maximum character count
mov edx, buffer ; point to the buffer
call ReadString ; input the string
mov [bufSize], eax ; save the length
call Crlf
popad
ret
;-----------------------------------------------------
DisplayMessage:
;
; Displays the encrypted or decrypted message.
; Receives: EDX points to the message
; Returns: nothing
;-----------------------------------------------------
pushad
call WriteString
mov edx, buffer ; display the buffer
call WriteString
call Crlf
call Crlf
popad
ret
;-----------------------------------------------------
TranslateBuffer:
;
; Translates the string by exclusive-ORing each
; byte with the encryption key byte.
; Receives: nothing
; Returns: nothing
;-----------------------------------------------------
pushad
mov ecx, [bufSize] ; loop counter
mov esi,0 ; index 0 in buffer
L1:
; this is shonky - should be byte!
xor word [buffer + esi],KEY ; translate a byte
inc esi ; point to next byte
loop L1
popad
ret
;------------------------
;-------------------------
WriteString:
; expects: buffer in edx, zero-terminated
; returns: bytes written in eax
add dword [hstdout], 0
jnz .gothandle
push -11
call GetStdHandle
mov [hstdout], eax
.gothandle:
push 0 ; character size? ascii=0 unicode=1
push byteswritten
xor eax, eax
.getlen:
cmp byte [edx + eax], 0
jz .gotlen
inc eax
jmp .getlen
.gotlen:
push eax
push edx
push dword [hstdout]
call WriteFile
; check error?
mov eax, [byteswritten]
ret
;-----------------------------
;-------------------------
ReadString:
; expects: buffer in edx, ecx = max
; returns: bytes written in eax
add dword [hstdin], 0
jnz .gothandle
push -10
call GetStdHandle
mov [hstdin], eax
.gothandle:
push 0 ; character size? ascii=0 unicode=1
push bytesread
push ecx
push edx
push dword [hstdout]
call ReadFile
; check error?
mov eax, [bytesread]
; does Readfile return input zero-terminated?
; zero-terminate it to be sure
; pray ReadFile doesn't trash edx!
mov byte [edx + eax + 1], 0
ret
;-----------------------------
;----------------------------
Crlf:
push edx
mov edx, newline
call WriteString
pop edx
ret
;--------------------------
Since you mention in a PM that you have Linux available, I'll probably do a Linux version that I can actually test. Patience, Grasshopper! :)
Best,
Frank
-
Hehehehe, thank you. I hope that everything goes right in the version for linux. Meanwhile I will analyze this version. Thank you for your help, I really appreciate it.
-
I tried to run the .obj but I got the following error: in function main nasm error undefined reference to WinMain@16.
Did you have any success with linux code?
Thanks in advance!
-
Yeah, seems to work. I take it that using a key larger than a byte was your instructor's idea?
; nasm -f elf32 myfile.asm
; ld -o myfile myfile.o -melf_i386
global _start
; comment does not match code!
KEY equ 326 ; any value between 1-255
BUFMAX equ 128 ; maximum buffer size
section .data
sPrompt db "Enter the plain text: ",0
sEncrypt db "Cipher text: ",0
sDecrypt db "Decrypted: ",0
; should probably be local to routine
newline db 10, 0
section .bss
buffer resb BUFMAX+1
bufSize resd 1
section .text
_start:
call InputTheString ; input the plain text
call TranslateBuffer ; encrypt the buffer
mov edx, sEncrypt ; display encrypted message
call DisplayMessage
call TranslateBuffer ; decrypt the buffer
mov edx, sDecrypt ; display decrypted message
call DisplayMessage
mov eax, 1
xor ebx, ebx
int 80h
;-----------------------------------------------------
InputTheString:
;
; Prompts user for a plaintext string. Saves the string
; and its length.
; Receives: nothing
; Returns: nothing
;-----------------------------------------------------
pushad
mov edx, sPrompt ; display a prompt
call WriteString
mov ecx, BUFMAX ; maximum character count
mov edx, buffer ; point to the buffer
call ReadString ; input the string
mov [bufSize], eax ; save the length
call Crlf
popad
ret
;-----------------------------------------------------
DisplayMessage:
;
; Displays the encrypted or decrypted message.
; Receives: EDX points to the message
; Returns: nothing
;-----------------------------------------------------
pushad
call WriteString
mov edx, buffer ; display the buffer
call WriteString
call Crlf
call Crlf
popad
ret
;-----------------------------------------------------
TranslateBuffer:
;
; Translates the string by exclusive-ORing each
; byte with the encryption key byte.
; Receives: nothing
; Returns: nothing
;-----------------------------------------------------
pushad
mov ecx, [bufSize] ; loop counter
mov esi,0 ; index 0 in buffer
L1:
; this is shonky - should be byte!
xor word [buffer + esi],KEY ; translate a byte
inc esi ; point to next byte
loop L1
popad
ret
;------------------------
;-------------------------
WriteString:
; expects: buffer in edx, zero-terminated
; returns: bytes written in eax
mov ecx, edx
xor edx, edx
.getlen:
cmp byte [ecx + edx], 0
jz .gotlen
inc edx
jmp .getlen
.gotlen:
mov ebx, 1
mov eax, 4
int 80h
ret
;-----------------------------
;-------------------------
ReadString:
; expects: buffer in edx, ecx = max
; returns: bytes written in eax
xchg ecx, edx
mov ebx, 1
mov eax, 3
int 80h
mov byte [ecx + eax + 1], 0
ret
;-----------------------------
;----------------------------
Crlf:
push edx
mov edx, newline
call WriteString
pop edx
ret
;--------------------------
-
Yes, thats right. Very thanks. I will just try to make the win code works. I don't know how to thank you.
-
Many people helped me when I was first learning this stuff (and still do!). I'm just trying to "pass it on". If you want to "thank" me, do the same when you get the opportunity! 'Til then, you're welcome!
The "undefined reference to WinMain@16" sounds like you need to tell the linker that the entrypoint is "main". "-e main" for ld, probably "/entry main" or "/entrypoint main" for other linkers? You might try:
%define main WinMain@16
Do it before "global main"! The error message, as you've posted it, seems not to have an underscore on it. The other "true names" may not want an underscore either. Read the error messages (if any) carefully - there's information in 'em!
I should have mentioned that the Windows version is intended to be assembled with "-f win32". "-f obj" would need slightly different source code (it "will" do 32-bit code, but isn't very good at it, IMO).
If you need help with linking (and perhaps the correct "true names"), mention what linker you're using, and what command line you gave it, along with any error messages. Like assemblers, linkers are all different.
I can only hope that my "ReadString" and "WriteString" functions are correct... "close" probably won't work! I hope someone more familiar with Windows will take a look at that.
As Betov (author of RosAsm) used to say, "Courage!"
Best,
Frank