装配中的Adobe Type 1加密算法

时间:2017-05-24 15:45:53

标签: algorithm file assembly encryption tasm

我正在尝试使用adobe type 1字体加密算法加密文本文件。但是,我不知道如何在汇编语言中正确实现该算法。如果可以,请帮助我。

这是adobe type 1字体加密算法:

 unsigned short int r;
 unsigned short int c1 =52845;
 unsigned short int c2 = 22719;


unsigned char eencrypt(char plain) unsigned char plain;
   {    unsigned char cipher; 

     cipher = (plain ^ (r >> 8));  
     r = (cipher + r) * c1 + c2;    
 return cipher; 
 } 

这是我的代码:

.model tiny
.data


filename db "file.txt", 0
bufferSize = 512
filehandle dw ?
buffer db bufferSize dup (0)

 r dw 0
c1 dw 52845
c2 dw 22719
cipher dw ?

message1 db 'Cannot open file. $' 
message2 db 'Cannot read file. $' 
message3 db 'Cannot close file. $' 



 .code
org 100h

 start:

call open
call read
call close
call Exit 

;procedures

 open:
  mov ah,3DH
  mov al,0
  mov dx, offset filename
  int 21h
  jc openErr
  mov filehandle, ax
  ret

   read:                        ;reads file
  mov ah, 3Fh
  mov bx, filehandle
  mov cx, bufferSize
  mov dx, offset buffer
  int 21h
  cmp ax,0
  jc readErr


;displays content of file
 call clear
 mov ah, 9
 mov dx, offset buffer
 int 21h
 ret 

close:
 mov ah, 3Eh
 mov bx, filehandle
int 21h
jc closeErr
ret

 encrypt:
; need loop to loop through each char, don't know how to do that 
        mov ax, [r]
        shr ax, 8          
        mov bl, [buffer]
        xor bh,bh    
        xor bx, ax       
        mov cipher, bx      
        mov dx, cipher     
        add dx, [r]       ;get error: extra characters on line
        imul dx, c1 
        add dx, c2 
        mov [r], dx     



 ;decrypt:

 clear: ;clears the screen

      mov ax,003h
      int 10h
      ret 
  Exit: 
  mov ax, 4C00h
  int 21h


newline:  ;prints a newline                           
        mov ah, 2                    
        mov dl, 0DH
        int 21h            
        mov dl, 0AH                 
        int 21h         
        ret

   ;error messages 

  openErr :
     call newline
    lea  DX,message1    ;set up pointer to error message
    mov  AH,9          ;display string function
    int  21H           ;DOS call
    stc               ;set error flag
    ret

 readErr :
    call newline
     lea  DX,message2    ;set up pointer to error message
     mov  AH,9          ;display string function
    int  21H           ;DOS call
    stc               ;set error flag
    ret

closeErr :
  call newline
  lea  DX,message3    ;set up pointer to error message
  mov  AH,9          ;display string function
  int  21H           ;DOS call
  stc               ;set error flag
  ret

结束开始

1 个答案:

答案 0 :(得分:0)

 ;encrypt:
; need loop to loop through each char, don't know how to do that 
;mov ax, r
;shr ax, 8           r>>8
;mov bl, buffer      bl = buffer

buffer是符号地址,而不是缓冲区中的值。使用mov bl,[buffer]从内存中读取值。如果你想循环遍历整个缓冲区内容,将该地址放入某个寄存器,si通常更有利于保持指向数据源的指针(因为它在lods指令中是硬编码的,并且“s “可能被视为”来源“)。如果你是C ++编译器,你不关心,你选择任何备用寄存器,而不考虑它的名字。

;xor bx, ax          bx = buffer ^(r>>8)

bh未设置,可能是任何内容,破坏了您的计算。在从缓冲区加载xor bx,bx之前执行bl,或者仅xor bh,bh清除bh(在现代x86上稍微慢一点,因为它必须合并bh + bl进入bx),或者在上一步中使用movzx bx,byte ptr [buffer]将char值零扩展为字值。

;mov cipher, bx      cipher = buffer^(r>>8)

标签cipher是在db ?之前定义的,但是在这里你要将两个字节写入内存,因此它也会覆盖message1字符串的第一个字节。我强烈建议每次写入内存时使用[],即使TASM / MASM允许这种语法,但我发现很难阅读(看到[cipher]会让我的大脑自动思考“记忆访问“即使快速浏览一下来源。”

;mov cx, c1

c1c2可以是EQU,因此它们会直接编译为代码中的中间值。

;add cx, c2

那不是,C加密的作用(乘法优先于加法)。

;mov dx, cipher

您再次将cipher视为单词,这是有道理的,但它与db ?相反(因此db需要修复,而不是此处的代码)。

;add dx, r
;imul dx, cx     

我会再次在[]周围使用r括号,而乘法/加法顺序当然是错误的。

尝试不错,但是不要犹豫,取消注释那段代码,预先设置一些调试值的寄存器,然后直接跳转到它,在调试器中打开二进制文件,然后单步执行以验证它像你想要的那样工作。您可能很快就会找到我上面写的所有内容。

然后将其转换为循环(使用任何ASM书籍/教程以及有关使用数组/字符串的一些示例,学习使用指针,那么它应该不难完成)。