原创xiaoyuer合天智汇

  1. 木马分析入门

大家好,我最近从Web安全开始学习二进制安全,分享一下自己学习过程的收获和心得体会。由于是入门的内容,所以对于二进制大佬来说这很简单,所以本文主要面向的对象主要是和我一样一直做Web安全,又想入门二进制安全的人。本次我学习的案例是木马和病毒常用的一个技术:确保只有一个病毒或者木马在系统中运行,即运行单一实例。对于病毒和木马而言,如果多次重复运行,会增加暴露的风险。所以要确保系统中只运行一个病毒或木马的进程。

  1. 正向编写C代码

要实现运行单一实例,一种常见且简单的方法是通过创建系统命名互斥对象实现的,这种方法主要是利用CreateMutex函数,通过该函数我们也可以查看是否已经有一个进程运行了。那么,如果通过CreateMutex函数得知是否已经有一个在运行的进程了呢?

下面简要介绍下CreateMutex函数,它的功能是创建或者打开一个已命名或者未命名的互斥对象。

关于它的返回值,如果函数成功,则返回值是新创建的互斥对象的句柄。如果函数失败,则返回值为NULL。要获得扩展的错误信息,请调用GetLastError。如果互斥锁是一个已命名的互斥锁,并且该对象在此函数调用之前就存在,则返回值是现有对象的句柄,GetLastError返回ERROR_ALREADY_EXISTS。

简单点来说,就是如果CreateMutex函数的返回值不是NULL,并且调用GetLastError函数后,返回值是ERROR_ALREADY_EXISTS,那么可以判定已经存在了一个在运行的进程。用C语言代码实现如下:

使用VC++6.0完成编译链接后生成可执行文件,双击运行,显示如下:

在不关闭上述进程的前提下,再次双击生成的可执行文件,显示如下:

可以看出当系统中运行第二个进程的时候,输出了Already Run!!!!说明程序已经成功地判断出重复运行了。

  1. 逆向分析

下面我们就对这个程序进行逆向分析,我们需要对主函数和子函数分别进行逆向分析,这次先分析主函数。

关于学习的方法,我的收获是在初学阶段,我们先分析自己写的代码,分析完之后再进行印证,慢慢地就可以脱离源码并尝试分析其他未公开源码的程序流程。

在学习过程中,十分重要的一点是:要分清主次。什么意思呢?

学习汇编语言和逆向,我们完全没有必要逐条指令去仔细阅读所有的代码,重要的是从整体上理解程序究竟做了哪些操作。汇编语言也是一种编程语言,平常大家也不会去一行一行地仔细阅读别人写的大量代码,除了必须要理解的重要部分花时间仔细读一读,剩下的部分基本都是一带而过,只要大体上理解程序在做什么事就好了。逆向工程也是一样,“重要的部分花时间仔细理解”“其余部分大概知道怎么回事就好”这两条原则同样适用。

那么哪些是重要的呢?在病毒木马分析中,其中一点比较重要的是分析call函数,只要将这个程序所调用的函数分析清楚了,那么就知道这个病毒木马在做什么了。与此同时要弄清楚它的逻辑结构,比如什么时候跳转到哪执行。

接下来我们首先对主函数进行分析:

  1. 主函数:

主函数的C语言代码如下图所示:

下面对其汇编代码进行分析:

以上代码完成所有的函数入栈操作,每个函数开始时都会有这样的操作,这里我们无需过分细究,如感兴趣,对这段代码详细的分析可参考《C++反汇编与逆向分析技术揭秘》p150,我也将其主要的内容贴出来了:

关于这段内容中补充介绍两个指令,其中,xor eax,eax直接会将eax的值设置为0,这是将寄存器设置为0最常见的方式,cmp指令是条件指令,详细内容如下图所示:

这段内容在这里暂时只需了解,无需深究,等需要的时候再去研究也不迟。

之后,到了需要认真理解的地方了,下一条的指令是

call    sub_401005

它的意思是调用子函数sub_401005,在这里其实对应的是我们编写的IsAlreadyRun函数。

需要补充的是在函数调用时,如果有参数需要传递,需要在call指令之前,使用push先将参数从后往前入栈。这里因为无任何参数传递,所以在调用之前,无需使用push指令将参数入栈。后面还会详细介绍是如何从后往前入栈的,这里需要先记住这个知识点。

还有一个要记住的是在函数调用完成后,VC中,会使用eax寄存器来保存函数的返回值。

接下来的一条指令是

test    eax, eax

关于test指令,只需记住若eax为0,则zf标志位会设置为1,此时eax中的值是上一条指令的返回值,若对test指令感兴趣可参考如下解释:

接下来的指令是

jz      short loc_4010E0

jz是跳转指令,即jump zero,即当零标志位ZF=1的时候跳转到 loc_4010E0这个位置执行,此时也就是上一个指令test eax,eax得到的操作使得ZF=1,也就是eax=0,由于eax保存的是子函数的返回值,所以我们得知子函数的返回值为0。由我们编写的C语言代码可知,此时对应的是IsAlreadyRun函数返回结果为false,和我们的分析相对应。

跳转到该位置后:

可以看到的call _printf 指令,这将会调用printf输出函数。由于printf需要传递参数,所以在call _printf之前,需要先执行push的操作。我们将鼠标放在aNotAlreadyRun上可以看到对应的字符串与loc_4010E0:后的备注信息"NOT Already Run!"一样,如下图所示:

所以得出结论,若子函数sub_401005的返回值为0时,跳转到loc_4010E0位置,将会输出"NOT Already Run!"。与我们编写的C语言代码相符合。

那么,若子函数sub_401005的返回值为1时,会怎么样呢?

此时,会走到左边的执行框内,不会跳转到右边。同理,这里将会输出"NOT Already Run!"字符串。

执行完成后,左右两边的内容都会到loc_4010ED这个位置继续执行:

这段内容看到有call ds:Sleep指令,此处是调用了Sleep函数,对应的是我们C代码中的Sleep(10000):

由于要传递参数,所以需要先将参数入栈,即push操作,可以看到在call ds:Sleep指令之前,有push 186A0h 指令,将鼠标放置在186A0h上,右键可观察对应的十进制:

刚好也是100000,所以和我们编写的C代码也刚好符合。

之后,使用pop和call __chkesp等指令,完成出栈、检查栈平衡等函数返回工作。

目前,关于主函数的分析已经完成,下次我们一起进一步对子函数进行详细的分析。

参考书籍:

《Windows黑客编程技术详解》甘迪文著--北京:人民邮电出版社,2018年12月。

《C++反汇编与逆向分析技术揭秘》钱松林,赵海旭著--北京:机械工业出版社,2011年9月。

《恶意代码分析实战》 (美)Michael Sikorski / Andrew Honig 著,诸葛建伟,姜辉,张光凯译 -- 北京:电子工业出版社,2014年4月,原书名: Practical Malware Analysis: The Hands-On Guide to Dissecting Malicious Software。

《汇编语言》王爽 著--2版,北京:清华大学出版社,2008年4月。

声明:笔者初衷用于分享与普及网络知识,若读者因此作出任何危害网络安全行为后果自负,与合天智汇及原作者无关!

木马编程入门_逆向入门分析实战(一)相关推荐

  1. python 量化分析 入门_量化入门-小白到菜鸟的学习路线

    小白到菜鸟的入门学习路线,不要盲目以为多看策略就能学会,要注意学习方法. 本文的主要目的 很多新人面对多如牛毛的策略不知从何下手,在很多较难的帖子下面留言一些最基础的问题.小白不知道该先学什么,后学什 ...

  2. 计算机科学与python编程导论_计算机科学入门和使用Python编程

    你将学到什么 A Notion of computation The Python programming language Some simple algorithms Testing and de ...

  3. python编程程序设计_程序设计入门—Python

    知识单元一:程序设计语言基础 第1周:程序设计的基础知识 教学内容:计算的基本概念,计算机程序设计语言的历史,Python语言的发展简史及语言的特点,程序设计语言的基本语法 教学要求:了解冯诺依曼计算 ...

  4. java编程启蒙_程序设计入门—Java语言

    第一周:做点计算 1.1 第一个程序 如何下载.安装Eclipse和JRE,并且简单介绍一下这个软件的几个主要部分:如何在Eclipse中编辑.编译和运行程序:详解第一个程序:程序框架.输出.出错怎么 ...

  5. python编程设计_程序设计入门—Python

    知识单元一:程序设计语言基础 第1周:程序设计的基础知识 教学内容:计算的基本概念,计算机程序设计语言的历史,Python语言的发展简史及语言的特点,程序设计语言的基本语法 教学要求:了解冯诺依曼计算 ...

  6. git入门_绝对入门的Git

    git入门 by Shahzan 由Shahzan 绝对入门的Git (Git for Absolute Beginners) If you're new to the programming wor ...

  7. 爬虫python入门_如何入门Python爬虫?爬虫原理及过程详解

    "入门"是良好的动机,但是可能作用缓慢.如果你手里或者脑子里有一个项目,那么实践起来你会被目标驱动,而不会像学习模块一样慢慢学习. 另外如果说知识体系里的每一个知识点是图里的点,依 ...

  8. 1 数列分块入门_线性代数入门——利用分块矩阵简化矩阵乘法运算

    系列简介:这个系列文章讲解线性代数的基础内容,注重学习方法的培养.线性代数课程的一个重要特点(也是难点)是概念众多,而且各概念间有着千丝万缕的联系,对于初学者不易理解的问题我们会不惜笔墨加以解释.在内 ...

  9. 1 数列分块入门_线性代数入门——关于分块矩阵的典型证明题与综合题

    系列简介:这个系列文章讲解线性代数的基础内容,注重学习方法的培养.线性代数课程的一个重要特点(也是难点)是概念众多,而且各概念间有着千丝万缕的联系,对于初学者不易理解的问题我们会不惜笔墨加以解释.在内 ...

最新文章

  1. setFilters使用方法
  2. PMP-【第11章 项目风险管理】-2021-2-16(220页-251页)
  3. 开始→运行→输入的命令集锦(转载)
  4. 用键盘全局钩子[Hook]监视多进程键盘操作
  5. Expression Blend实例中文教程(4) - 布局控件快速入门Canvas
  6. Docker container与宿主进程相互隔离的实现原理
  7. 程序员求职面试丨面试必备之终极指导篇,掌握这些,面试不再困难!
  8. 超好用的自带火焰图的 Java 性能分析工具 Async-profiler 了解一下
  9. 一步步学习SPD2010--第四章节--创建和修改网页(9)--附上母版页
  10. mysql性能优化 洪斌_洪斌 - MySQL性能诊断与实践
  11. 第八篇:ZTree操作总结
  12. PS CS4抽出滤镜抠图小技巧
  13. 墨刀原型设计工具学习体会——临摹网易云音乐App
  14. 云计算:程序员重回个人英雄时代
  15. 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...
  16. python实现马科维茨模型的资本市场线_资产配置理论的基础之马科维茨模型
  17. 按键精灵脚本-windows桌面自动化操作
  18. Error starting daemon: error initializing graphdriver: driver not supported
  19. 如何使用Excel完成网站上的数据爬取
  20. autojs怎么暂停脚本_三国群英传8脚本已暂停名片点赞autojs

热门文章

  1. matlab通过数据进行曲线拟合 导出公式
  2. 嵌入式软件工程师—成长笔记#01
  3. 阿里内部资料,10W字总结JAVA面试题-Git篇
  4. 4.1 数据结构——串
  5. H5下载安装app(ios端和android)
  6. oro什么意思_oro
  7. Surround360 Render目录下RENDER文档——中文翻译
  8. Rockland 艾美捷丨TrueBlot链霉亲和素磁珠
  9. 线性插值、抛物插值、Lagrange插值 | Lagrange拉格朗日插值法(一)
  10. MTU问题导致大数据包出不去。