微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Nasm:在 bmp 文件中隐藏 messagem

如何解决Nasm:在 bmp 文件中隐藏 messagem

我在汇编中制作了这个程序,它应该从终端接收一个文件 txt(msg 在哪里),一个文件 bmp 和文件 bmp 应该具有的名称文件等于原始文件,但带有隐藏的 msg) !

section .data
; -----
; Define standard constants.
LF equ 10 ; line Feed
NULL equ 0 ; end of string
TRUE equ 1
FALSE equ 0
EXIT_SUCCESS equ 0 ; success code
STDIN equ 0 ; standard input
STDOUT equ 1 ; standard output
STDERR equ 2 ; standard error
SYS_write equ 1; write
SYS_read equ 0 ; read
SYS_open equ 2 ; file open
SYS_close equ 3 ; file close
SYS_exit equ 60 ; terminate
SYS_creat equ 85 ; file open/create
SYS_time equ 201 ; get time
O_CREAT equ 0x40
O_Trunc equ 0x200
O_APPEND equ 0x400
O_RDONLY equ 000000q ; read only
O_WRONLY equ 000001q ; write only
S_IRUSR equ 00400q
S_IWUSR equ 00200q
S_IXUSR equ 00100q
; -----
; Variables/constants for main.
MSGBUFF_SIZE equ 256
IMGBUFF_SIZE equ 24000
NEWBUFF_SIZE equ 24000

newLine db LF,NULL
db LF,LF,NULL

msgDesc dq 1
imgDesc dq 1
newDesc dq 1


errMsgOpen db "Error opening the file.",NULL
errMsgRead db "Error reading from the file.",NULL

img_url db '-----------------',0
msg_url db '-----------------',0
new_img db '-----------------',0
nullstr     db '(null)',0

;offset db 1
;size db 1
; -------------------------------------------------------
section .bss
readMsgBuffer: resb MSGBUFF_SIZE
readImgBuffer: resb IMGBUFF_SIZE
readNewBuffer: resb NEWBUFF_SIZE



offset      resq 1
size        resq 1
; -------------------------------------------------------

section .text
global _start
_start:

mov rbp,rsp
mov rax,[rbp+8]    ; argc
cmp rax,4
jne fim

;read args
mov rax,[rbp+8*3]   ;argv[1]
mov rdi,msg_url     ;
call converte

mov rax,[rbp+8*4]   ;argv[2]
mov rdi,img_url     ;
call converte

mov rax,[rbp+8*5]   ;argv[3]
mov rdi,new_img     ;
call converte


;open file msg
openMsg:
mov rax,SYS_open     ; file open
mov rdi,msg_url      ; file name string
mov rsi,O_RDONLY     ; read only access
syscall               ; call the kernel
cmp rax,0           ; check for success
jl errorOnopen
mov qword [msgDesc],rax

;open file img
openImg:
mov rax,img_url      ; file name string
mov rsi,0           ; check for success
jl errorOnopen
mov qword [imgDesc],rax

;open file new image
openNewImg:
mov rax,new_img      ; file name string
mov rsi,O_APPEND     ; append
syscall               ; call the kernel
cmp rax,0           ; check for success
jl errorOnopen
mov qword [newDesc],rax


;read msg
mov rax,SYS_read
mov rdi,qword [msgDesc]
mov rsi,readMsgBuffer
mov rdx,MSGBUFF_SIZE
syscall
cmp rax,0
jl errorOnRead

;read img
mov rax,qword [imgDesc]
mov rsi,readImgBuffer
mov rdx,IMGBUFF_SIZE
syscall
cmp rax,0
jl errorOnRead


mov rsi,readImgBuffer
mov byte [rsi+rax],NULL
mov rdi,readImgBuffer

mov rsi,readMsgBuffer
mov byte [rsi+rax],NULL
mov r8,readMsgBuffer
call escrever


;close files
mov rax,SYS_close
mov rdi,qword [msgDesc]
syscall

mov rax,qword [imgDesc]
syscall

mov rax,qword [newDesc]
syscall




fim:
mov     rsp,rbp
pop     rbp

mov     rax,1
xor     rbx,rbx
int     0x80
ret


errorOnopen:
mov rdi,errMsgOpen
call printString
jmp fim

errorOnRead:
mov rdi,errMsgRead
call printString
jmp fim



escrever:
push rbp
mov rbp,rsp
push rbx

; first 10 bytes
mov rax,SYS_write  ; code for write()
mov rsi,rdi        ; addr of characters
mov rdi,newDesc    ; file descriptor
mov rdx,10
syscall             ; system call


mov rbx,0
add rbx,10


;eax = offset
offsetBit:
cmp rdx,4
je loop

mov r9b,byte[rbx]
add rax,r9
mov rcx,10
mul rcx
inc rdx
jmp offsetBit

mov r9,rax

mov rax,rbx        ; addr of characters
mov rdi,r9
syscall             ; system call


mov r12,0          ;count byte pixel,to jump the 4ºbit
mov r13,0          ;size file
mov rdi,readImgBuffer  ;have position of content

loop:
cmp byte [r8],NULL     ;not done
je done
inc r13                 ;count one byte

mov rdx,0              ;count bit character msg

caracter:
mov sil,byte[r8]       ;read one byte of the pixel
cmp rdx,8              ;end of last bit
je loop
cmp r12,4              ;4º byte pixel
jne continue
mov r12,0              ;reset byte pixel

continue:
mov al,byte[rdi]       ;have byte of pixel
mov cl,10
shr al,1
mul cl
shl sil,1
adc al,0
mov byte[rdi],al       ;modify last bit
inc rdx                 ;change bit of character
inc r8                  ;change byte of pixel
jmp caracter

done:
mov rdi,readImgBuffer
add rdi,r9               ; offset position

mov rax,newDesc    ; file descriptor newImage
mov rdx,r13
syscall

pop rbx
pop rbp
ret

global printString
printString:
push rbp
mov rbp,rsp
push rbx
; Count characters in string.
mov rbx,rdi
mov rdx,0

strCountLoop:
cmp byte [rbx],NULL
je strCountDone
inc rdx
inc rbx
jmp strCountLoop

strCountDone:
cmp rdx,0
je prtDone
; Call OS to output string.
mov rax,SYS_write ; code for write()
mov rsi,rdi ; addr of characters
mov rdi,STDOUT ; file descriptor
; count set above
syscall ; system call
; String printed,return to calling routine.

prtDone:
pop rbx
pop rbp
ret


converte:
push rbx
push rcx
push rdx

mov rbx,10
xor rcx,rcx
.J1:
xor rdx,rdx
div rbx
push dx
add cl,1
or eax,eax
jnz .J1
mov rbx,rcx
.J2:
pop ax
or al,00110000b            ; to ASCII
mov [rdi],al               ; Store AL to [EDI] (EDI is a pointer to a buffer)
add rdi,1                  ; = inc edi
loop .J2                    ; until there are no digits left
mov byte [rdi],0           ; ASCIIZ terminator (0)
mov rax,rbx                ; Restore Count of digits

pop rdx
pop rcx
pop rbx
ret

我是这样运行的:

$ nasm -F dwarf -f elf64 hiddeMsg.asm
$ ld -o HideMsg hiddeMsg.o
$ ./HiddeMsg msg.txt img.bmp img_mod.bmp

并且我期望“生成一个名称为 img_mod.bmp 的图像等于原始图像(又名 img.bmp)但隐藏 msg.txt 中的 msg...但是当我编译并运行它时显示任何错误但也不做任何事情,我不知道为什么?

文件 msg 有文本:«one text message»

原图: img.bmp

解决方法

您的程序再次提前终止,因为第一次检查没有正确比较 argc
当您的程序启动时 (HiddeMsg msg.txt img.bmp img_mod.bmp),堆栈包含以下内容:

at RSP+32  argv3  pointer to 'img_mod.bmp'
at RSP+24  argv2  pointer to 'img.bmp'
at RSP+16  argv1  pointer to 'msg.txt'
at RSP+8   argv0  pointer to the program name
at RSP     argc   4

检查参数的数量:

mov rbp,rsp
mov rax,[rbp]       ; argc
cmp rax,4
jne fim

其他参数是指向文件名的指针。将这些指针转换为它们的十进制表示形式并没有用,就像您的程序调用 converte 所做的那样。只需将指针存储在本地以备后用:

mov rax,[rbp+8*2]   ; argv[1]
mov [msg_url],rax

mov rax,[rbp+8*3]   ; argv[2]
mov [img_url],[rbp+8*4]   ; argv[3]
mov [new_img],rax

打开消息文件变成

  mov rsi,O_RDONLY
  mov rdi,[msg_url]
  mov rax,SYS_open
  syscall
  test rax,rax
  js errorOnOpen
  mov [msgDesc],rax

您在从消息文件和位图文件读取的部分中进行了混搭,出于某种原因,您将读取的这两个内容都以零结尾。
您将消息的零放在与用于位图的相同偏移量处!此操作将破坏位图的 1 个字节!
继续阅读并归零,以便使用正确的 RAX

mov edx,MSGBUFF_SIZE
mov rsi,readMsgBuffer
mov rdi,[msgDesc]
mov rax,SYS_read
syscall                 ; -> RAX
test rax,rax
js errorOnRead
mov rsi,readMsgBuffer
mov byte [rsi+rax],NULL

fim:
mov     rsp,rbp
pop     rbp

mov     rax,1
xor     rbx,rbx
int     0x80
ret

不要像这样终止 64 位程序。使用正确的SYS_exit syscall

fim:
  xor edi,edi
  mov eax,SYS_exit
  syscall

有这么多错误你最好不要过分强调escrever的内容。首先练习打开和关闭文件,并从消息文件中打印消息。更简单的事情。只有在效果良好时才继续前进......

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。