16位汇编第九讲汇编指令以及逆向中的花指令

                                      16位汇编第九讲汇编指令以及逆向中的花指令

一丶LOOP指令(循环指令)

作用:

  循环指令利用cx计数器自动减1,方便实现计数循环的程序结构

例如:

mov cx,3   
loop1:    ;标号
        .....
    LOOP loop1;不断的循环标号,然后cx-- 直到变为零

每次循环过后,cx都会自减,直到cx == 0,不过现在的loop指令不常用了,因为局限性太大,比如loop只能自减,而不能自增,所以我们都用 JCC 指令,来模拟loop指令

二丶子程序指令(函数的概念基于子程序指令)

问题? 什么是子程序

  1.子程序是完成特定功能的一段程序

  2.当主程序(调用程序)需要执行这个功能的时候,采用call调用指令转移到改子程序的起始处执行

  3.当运行万子程序的功能的时候,采用 ret 返回指令回到主程序继续执行

如果懂C语言或者别的更高级的语言的请看

  这个其实就是函数,为了代码的重用性,可利用性研究出来的,否则汇编代码一多就会很乱,比如有效的管理代码

比如ret指令,其实就是平衡栈的,在C语言中变成了语法,为return了

1.最原始的Call

主程序调用子程序的流程示意图:

这里主要介绍call传参,以及使用ret

Call的原理是什么?

  首先先看一段汇编程序

jmp PROC_ADD           ;跳转到函数执行
d_One: jmp END_EXIT   ;跳转到程序结束位置,结束程序 PROC_ADD:             ;函数ADD方法   mov ax,1   mov bx,1   add ax,bx            ;ax和bx相加,结果保存到ax中,ax当做返回值返回   jmp d_ONE            ;跳转到  函数执行后的吓一吓一跳指令继续执行END_EXIT:             ;程序结束的代码不关注  mov ax,  4c00h int 21h

看到上面的代码发现了什么,是不是和我们上面的图很像

主程序 -> 子程序的add方法, 然后 -> 跳转回来,跳转到下一条指令继续指令

这个就是雏形了,但是你有没有想过,这个add只能实现1 + 1 了,根本就不通用,怎么办,而且如果调用多次怎么办,

一直加标号,一直调用吗,显然是不切实际的.

2.Call 带有参数的传递

上面发现了一个大缺陷,就是不能参数传递,这样就不行了,那么我们要想办法,可不可以在外面传入参数

看代码:

mov cx,1
mov dx,1
jmp PROC_ADD           ;跳转到函数执行
d_One: jmp END_EXIT   ;跳转到程序结束位置,结束程序 

PROC_ADD:             ;函数ADD方法
   mov ax,cx            ;改为cx  
   mov bx,dx            ;改为dx
   add ax,bx            ;ax和bx相加,结果保存到ax中,ax当做返回值返回
   jmp d_ONE            ;跳转到  函数执行后的吓一吓一跳指令继续执行

END_EXIT:             ;程序结束的代码不关注
  mov ax,
  4c00h int 21h    

我们发现,在外部寄存器更改了,就可以修改参数了,但是还有问题,寄存器一共才多少个,当我们参数有10个怎么办

比如CreateProcess API,它的参数就有10个以上,不用关心API是干啥的,可以看下参数.

正好10个,我们的寄存器都不够用了怎么办

3.更高级的Call带参数

  我们这个时候就会想到,寄存器已经不能满足我们的需求,这个时候,可以使用栈,我们可以使用栈来保存信息

出栈的时候栈平衡(就是使栈空间不被破坏)一下

mov cx,2
    push cx             ;压栈
    mov dx,1
    push dx        ;调用函数
    CALL PROC_ADD    
    mov dl,al
    mov ah,2h       ;执行显示al内容
    int 21h
    jmp END_EXIT
PROC_ADD:
    mov bp,sp
    mov ax,[bp +2]      ; 从栈中取出内容,注意为什么+2
    mov bx,[bp+ 4]
    add ax,bx
    ret

在这里应该注意到了,我们用Call调用的时候,为什么函数内部要+2

原因是当这个子程序执行完毕的时候,需要返回到主程序执行,所以主程序的下一条指令已经压栈了,所以+2位置,可以取得参数

最后调用ret平栈

当程序遇到ret的时候,做的事情

1. 首先修改IP的值,IP的值, =  (ss栈段寄存器) * 16 + (sp栈顶)的值,

2.(sp栈顶) = (sp栈顶) + 2

需要注意的是,ret只会把最后压入的返回地址返回,但是参数还没有平栈,只能在调用完毕之后,在返回地址出的下一条指令自己平栈

4.Call的详细调用

mov cx,1
push cx
mov bx,2
push bx
CALL PROC_ADD

PROC_ADD:
    ......
    ret

ret的作用,就是从栈栈中取出返回地址,然后赋值给IP继续执行吓一条指令

但是注意,这里并没有平栈,我们必须在外面自己平栈

比如,我们我们入栈两个参数,比如  add sp,4   让sp平栈

四丶花指令

 请看下面的汇编代码

我们发现jmp的地方下面申请了一个字节,但是在汇编的时候,这1个字节和mov的机器码在一起了

因而产生的汇编代码就出错了,花指令混淆就是这样,这段代码还是可以正常执行的

对抗手法

1.如果是动态的调试,那么花指令是没用的(动态调试就是一步一步走)为什么,因为为了保证汇编代码不出错

每走一次代码都会重新反汇编

2.花指令主要对抗的是静态调试,因为病毒是不能运行的,只能看二进制和汇编,这个时候怎么办

我们发现了,他要jmp, jmp 1个字节,这个时候可以写个工具去弄,把jmp变为NOP(就是告诉CPU不执行)

现在我们在WINHEX中找到,然后改为 90机器码(代表NOP)

修改的时候,先看下反汇编 找到01的地方,改为90则NOP掉了,那么正确的反汇编就出现了

然后发现花指令去除了,这个就是最简单的花指令,当然这个可以通过寻找jmp的跳转的字节数,把里面的内容依次修改为NOP,所以就有了花指令去除工具

注意,这里是最简单的花指令,还有更复杂的,道高一尺魔高一丈,所以没有完整的花指令去除工具,到最后,可能你需要自己去分析,自己去修改了.

 学习资料链接: http://pan.baidu.com/s/1slHi4vN 密码:hvjp

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Java帮帮-微信公众号-技术文章全总结

JavaWeb10-request&response你不得不学(1)

? request&response 一.request和response的介绍 1. request和response的作用执行流程 Web服务器收到客户端...

86340
来自专栏数据之美

shell 学习笔记(17)

声明:转载需署名出处,严禁用于商业用途! 1601.关于rsync相同文件后 du 大小不一样的问题: 不一样大小很正常,因为文件系统的block...

32480
来自专栏微信公众号:Java团长

各大公司Java后端开发面试题总结

ThreadLocal(线程变量副本) Synchronized实现内存共享,ThreadLocal为每个线程维护一个本地变量。 采用空间换时间,它用于线程间的...

16510
来自专栏互联网开发者交流社区

jsp 内置对象(五)

13750
来自专栏微信公众号:Java团长

Java网络爬虫基础知识

Java 网络爬虫具有很好的扩展性可伸缩性,其是目前搜索引擎开发的重要组成部分。例如,著名的网络爬虫工具 Nutch 便是采用 Java 开发,该工具以 Apa...

20020
来自专栏北京马哥教育

Python如何防止sql注入

豌豆贴心提醒,本文阅读时间10分钟 前言 web漏洞之首莫过于sql了,不管使用哪种语言进行web后端开发,只要使用了关系型数据库,可能都会遇到sql注入攻...

63660
来自专栏深度学习之tensorflow实战篇

R语言的数据导入与导出(write.table,CAT)

福尔·摩斯曾说过:“数据,数据,没有数据的推理是罪恶!”不过比起有意思的统计分析,数据的导入与导出显得十分的无趣,但是不得不说统计分析的数据导入与导出是个让人沮...

97470
来自专栏落影的专栏

静态库与动态库的思考

前言 在上文《编译与链接过程的思考》评论中暴走大牙提到了静态库和动态库依赖的问题,还在群里提了几个测试样例和测试工程。 大致介绍下测试工程和如何进行测试: ...

40860
来自专栏杂烩

mongodb拾遗

9210
来自专栏MasiMaro 的技术博文

VC++ 崩溃处理以及打印调用堆栈

一般当程序发生异常时,用户代码停止执行,并将CPU的控制权转交给操作系统,操作系统接到控制权后,将当前线程的环境保存到结构体CONTEXT中,然后查找针对此异常...

52440

扫码关注云+社区

领取腾讯云代金券