`
qdujunjie
  • 浏览: 108824 次
  • 性别: Icon_minigender_1
  • 来自: Mars
社区版块
存档分类
最新评论

汇编语言字符串加密代码分析(2)

 
阅读更多

 

来自于《Intel汇编语言程序设计》(第四版)第六章。

 

这个例子利用了XOR(异或)指令的一个特性(即对操作数两次异或之后操作效果抵消),对字符串进行加密。

 

书中代码:

 

 

TITLE Encryption Program     (Encrypt.asm)

 

INCLUDE Irvine32.inc

KEY = 239                                       ; any value between 1-255

BUFMAX = 128                                ; maximum buffer size

 

.data

sPrompt BYTE "Enter the plain text : ",0

sEncrypt BYTE "Cypher text :             ",0

sDecrypt BYTE "Decrypted :               ",0

buffer BYTE BUFMAX 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

;

; Asks the user to enter a string from the

; keyboard Saves the string and its length

; in variables.

; 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 length

        call Crlf

        popad

        ret

InputTheString ENDP

 

 

;------------------------------------------------------------------

DisplayMessage PROC

;

; Display 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

;

; Translate the string by exclusive-ORing each

; byte with the same integer .

; 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

 

 

 让我们来逐句分析这段程序的代码:

 

首先,程序包含了作者的一个inc文件,里面有一些常量的定义,随后定义了一个用来加密的数字,这里是239,和一个缓冲长度值,这里是128:

 

INCLUDE Irvine32.inc

KEY = 239                                       ; any value between 1-255

BUFMAX = 128                                ; maximum buffer size

 

随后,数据段如下:

 

.data

sPrompt BYTE "Enter the plain text : ",0

sEncrypt BYTE "Cypher text :             ",0

sDecrypt BYTE "Decrypted :               ",0

buffer BYTE BUFMAX dup(0)

bufsize DWORD ?

 

定义了三个字符串,用于程序中的显示,一个buffer数组,还有一个用来存储长度的bufsize变量

 

接下来的是主程序段,这里有一个main函数和三个子函数,分别是:

 

InputTheString

DisplayMessage

TranslateBuffer

 

让我们先看一下三个子函数。

 

首先是InputTheString ,这个函数用来提示用户输入值,并且将值保存到buffer中,看一下代码:

 

 

        pushad                                      ; 首先保存所有寄存器的值

        mov edx , OFFSET sPrompt        ; 将sPrompt的地址赋给edx(用于下面的显示)

        call WriteString                          ; 显示edx中的值

        mov ecx,BUFMAX                        ; 将字符串的数量赋给ecx,因为ecx将用于循环的计数器

        mov edx,OFFSET buffer              ; 将edx寄存器指向buffer数组的地址

        call ReadString                           ; 读取用户输入的字符串到buffer中

        mov bufsize , eax                       ; 将用户输入字符串的长度值(此时保存在eax寄存器中),赋值给bufsize

        call Crlf                                       ; 将光标输出到下一行的开始

        popad                                        ; 重新得到所有寄存器的值

        ret                                              ; EIP 跳回

 

整个过程很简单。

 

然后我们再来看DisplayMessage :

 

 

 

         pushad                                       ; 首先保存所有寄存器的值

         call WriteString                           ; 显示edx寄存器中的值,显然这需要在调用函数之前对edx赋值

         mov edx , OFFSET buffer            ; 将buffer 中保存的值赋值到edx中准备显示

         call WriteString                           ; 显示edx中的值

         call Crlf                                        ; 将光标输出到下一行的开始

         call Crlf                                        ; 将光标输出到下一行的开始

         popad                                         ; 重新得到所有寄存器的值

         ret                                               ; EIP 跳回

 

 

 

然后再来看一下 TranslateBuffer  :

 

          pushad                                       ; 首先保存所有寄存器的值

          mov ecx , bufsize                        ; 将长度赋值给ecx,用于循环计数

          mov esi , 0                                  ; esi作为数组的index值,从零开始

L1:

          xor buffer[esi] , KEY                    ; 使用key值对每一个字节进行异或操作

          inc esi                                         ; 将index值加1

          loop L1                                        ; 重复执行L1,此时ecx值自减1

          popad                                         ; 异或操作完成后,重新得到所有寄存器的值

          ret                                               ; EIP 跳回

 

此函数时比较核心的部分,用于执行异或操作。

 

最后让我们看一下main函数:

 

 

       call  InputTheString                    ; 得到用户的输入,放到buffer数组中

       call TranslateBuffer                     ; 将buffer数组中的每一个字节进行异或操作,即“加密”操作

       mov edx , OFFSET sEncrypt        ; 因为DisplayMessage需要用到edx值,所以为edx赋值

       call DisplayMessage                   ; 显示用户输入字符串的加密值

       call TranslateBuffer                     ; 对buffer数组进行第二次异或操作,即“解密”操作

       mov edx , OFFSET sDecrypt        ; 为edx赋值

       call DisplayMessage                   ; 显示解密后的字符串

 

       exit                                             ; 退出(此函数并不是MASM伪指令,而是作者库中的函数)

 

 

 以上便是最简单的汇编加密程序的代码分析。

0
0
分享到:
评论

相关推荐

    揭秘数据解密的关键技术 CHM

     2.2 汇编中的字符串——C语言中的字符串  …… 第3章 资源文件简介 第4章 揭秘文件数据基础——0和1 第5章 媒体数据格式解析 第6章 数据加密vs数据解密 第7章 神奇的数据压缩算法 第8章 分析打包数据存储结构...

    揭秘数据解密的关键技术

     第1章 走进数据解密 1.1 数据解密是什么 1.1.1 代码逆向工程和数据逆向工程 1.2 数据解密的方法 1.2.1 黑盒分析法 1.2.2 白盒分析法 1.2.3 黑盒分析法与白盒分析法的比较 1.3 万能的汇编语言 1.3.1 为什么选择汇编...

    Reversing:逆向工程揭密

    7.2.3 字符串过滤程序 256 7.2.4 整数溢出 256 7.2.5 类型转换错误 260 7.3 案例研究:IIS索引服务漏洞 262 7.3.1 CVariableSet:: 7.3.1 AddExtensionControlBlock 263 7.3.2 DecodeURLEscapes 267 7.4 结论 271 第8...

    JAVA上百实例源码以及开源项目源代码

     设定字符串为“张三,你好,我是李四”  产生张三的密钥对(keyPairZhang)  张三生成公钥(publicKeyZhang)并发送给李四,这里发送的是公钥的数组字节  通过网络或磁盘等方式,把公钥编码传送给李四,李四接收到...

    精易模块[源码] V5.15

    5、改善“汇编类->置入汇编代码”增添一个参数是否保留以前代码。感谢易友【@无名侠】反馈。 6、修正“文本_加密”返回文本传递给“文本_解密”后长度不正确BUG,改为返回字节集。 7、改善“外部编辑框_取密码框文本...

    delphi 开发经验技巧宝典源码

    0180 提取字符串中指定子字符串后的字符串 117 0181 替换指定的字符串 117 0182 在文本中删除指定的汉字或句子 118 0183 指定符号分割字符串 119 0184 如何使用随机密码和字符串 120 第6章 日期和时间 ...

    delphi 开发经验技巧宝典源码06

    0180 提取字符串中指定子字符串后的字符串 117 0181 替换指定的字符串 117 0182 在文本中删除指定的汉字或句子 118 0183 指定符号分割字符串 119 0184 如何使用随机密码和字符串 120 第6章 日期和时间 ...

    JAVA上百实例源码以及开源项目

     设定字符串为“张三,你好,我是李四”  产生张三的密钥对(keyPairZhang)  张三生成公钥(publicKeyZhang)并发送给李四,这里发送的是公钥的数组字节  通过网络或磁盘等方式,把公钥编码传送给李四,李四接收到...

    vc++ 应用源码包_6

    内含各种例子(vc下各种控件的使用方法、标题栏与菜单栏、工具栏与状态栏、图标与光标、程序窗口、程序控制、进程与线程、字符串、文件读写操作、文件与文件夹属性操作、文件与文件夹系统操作、系统控制操作、程序...

    vc++ 应用源码包_5

    内含各种例子(vc下各种控件的使用方法、标题栏与菜单栏、工具栏与状态栏、图标与光标、程序窗口、程序控制、进程与线程、字符串、文件读写操作、文件与文件夹属性操作、文件与文件夹系统操作、系统控制操作、程序...

    编程新手真言......

    4.2 C的数组,指针与字符串 84 4.3 C的输入与输出流 84 4.4 C的类型系统与表达式 85 4.5 二进制指令看循环 85 4.6 所谓指针:当指针用于设计居多时 86 4.7 指针成就的C语言 86 4.8 指针是语言的一种抽象机制 88 4.9 ...

    vc++ 开发实例源码包

    内含各种例子(vc下各种控件的使用方法、标题栏与菜单栏、工具栏与状态栏、图标与光标、程序窗口、程序控制、进程与线程、字符串、文件读写操作、文件与文件夹属性操作、文件与文件夹系统操作、系统控制操作、程序...

    java开源包8

    1. 完全透明的缓存支持,对业务代码零侵入 2. 支持使用Redis和Memcached作为后端缓存。3. 支持缓存数据分区规则的定义 4. 使用redis作缓存时,支持list类型的高级数据结构,更适合论坛帖子列表这种类型的数据 5. ...

    vc++ 应用源码包_1

    内含各种例子(vc下各种控件的使用方法、标题栏与菜单栏、工具栏与状态栏、图标与光标、程序窗口、程序控制、进程与线程、字符串、文件读写操作、文件与文件夹属性操作、文件与文件夹系统操作、系统控制操作、程序...

Global site tag (gtag.js) - Google Analytics