从反汇编看恶意程序的C语言结构(一)

简介: 从反汇编看恶意程序的C语言结构

本文利用IDA分析4个简单的恶意程序,旨在基本掌握这4个恶意程序的C语言逻辑结构,同时这4个程序功能逐渐递增,循序渐进。笔者也是初学者,有些不足之处在所难免,请师傅们斧正

前言

本文利用IDA分析4个简单的恶意程序,旨在基本掌握这4个恶意程序的C语言逻辑结构,同时这4个程序功能逐渐递增,循序渐进。笔者也是初学者,有些不足之处在所难免,请师傅们斧正

详细分析

首先静态分析该exe文件,看下导入函数,其中一个调用了 WININET.dll中的 InternetGetConnectedState 函数,这个跟其他调用 kernel32.dll 中的函数相比,显得有些特殊。

查阅文档可知,这是一个 判断本地网络连接状态的函数,连接成功返回1,连接失败返回0

互联网连接状态功能 (wininet.h) - win32 应用程序|微软文档 (microsoft.com)

BOOL InternetGetConnectedState(
  [out] LPDWORD lpdwFlags,
  [in]  DWORD   dwReserved
);

找到了main 函数,就从这里开始分析

main函数位于401040,调用了401000处的函数

跳过去看看

上面一大堆没用的是编译器生成的,不要陷入其中

看到该区段的权限是 可读/可执行,并且调用了 InternetGetConnectedState 函数

不看流程图的话大概也可以看出这是一个 if 语句的汇编代码,cmp [ebp+var_4] ,0 ,根据结果跳转到不同的分支

View->Graphs->Flow chart可以查看流程图,相比较于空格的 流程图,更简洁明了

这里使用cmp指令对保存了返回结果的eax寄存器与0比较,然后使用 jz 指令控制执行流。上面我们提到,当 建立网络连接时,InternetGetConnectedState函数返回1,否则返回0. 如果结果是1,0标志位(ZF)会被清除,jz跳转到1所在的false分支,否则跳转到true分支

下面分析这个位于 40105f处的子过程

其实这里是printf 函数,但是我们并没有看到一些printf函数的特征,这就需要去找一些其他的特征来证明这里是printf函数

在调用这个函数之前,都向栈中push了 一串 格式化字符串,并且结尾是\n 换行符,因此可以推出这里调用的函数就是 printf

上面都是是根据静态分析得出的结论,真正的结果还是要实践检验一下,确实与我们分析的结果一样

总结

这个恶意代码的主要功能就是检查是否存在 Internet连接,存在输出1,否则输出0。

详细分析

首先还是看到这个pe文件的导入表

InternetOpenUrl: 通过FTP或 HTTP URL打开一个原始资源。如果连接成功建立,则返回一个有效的句柄,如果连接失败,则返回 NULL
internetclosehandle :关闭句柄,成功关闭返回 true,否则返回false
InternetReadFile: 从InternetOpenA打开的句柄读取数据
InternetGetConnectedState: 验证网络连接状态
InternetOpenA: 设置用户代理,即HTTP的 user-agent 头

看到其中的一些字符串,在结合上面调用的 api函数,不难猜出,要访问的url地址

接着来分析 main 函数

401000 处这里就不说了,和前面一样

但是401000 这里还调用的 40117f,跳过去看看

这个结构很像前面分析的 printf函数,那我们再往前看一看。

果然,在push入栈中也有一串格式化的字符串,基本可以确定40117f 处的函数是 printf函数

同时,main 函数中还调用了另一个401040函数

这里包含了所有 前面发现的 WinINet api的调用。首先调用了InternetOpen ,以初始化对WinINet的使用。在这之前,将 Internet Explorer 7.5push 入栈,当作 User-Agent 头部,接着调用 InternetOpenUrl ,打开该静态网页

可以看到,调用完 InternetOpenUrl后,返回值被赋值给了hFIle,并接着与0比较,如果等于0会返回,否则跳转到40109D,hFile被传递给InternetReadFIle函数。

InternetReadFile 函数用于从InternetOpenUrlA打开的网页中读取内容。在调用完后,会和0比较,如果为0,该函数会关闭句柄并终止,否则会跳转到 4010E5,逐步比较 buffer 数组 与每个字符的值,

这里有注释会好很多

这时候就可以猜测存在 http 交互

因此大概就可以确定,如果 buffer 的前 4个字节与

接着分析 main 函数,

看到在 401173 处 ,调用了 sleep 函数,传递的参数为 0xEA60h,即60000ms,1min

总结

该恶意样本检查是否有可用的网络连接,如果不存在,终止运行,否则返回 true,使用代理去下载其中包含的一个网址中的内容,这个网址包含注释,并且将printf解析后的字符串 “success: Parsed command is %c”到屏幕,输出成功的话,会sleep一分钟。这种方式是通过注释来隐藏指令,使得恶意代码看起来像是访问正常网页。



相关文章
|
2月前
|
存储 自然语言处理 编译器
【C语言】编译与链接:深入理解程序构建过程
【C语言】编译与链接:深入理解程序构建过程
|
2月前
|
网络协议 编译器 Linux
【C语言】结构体内存对齐:热门面试话题
【C语言】结构体内存对齐:热门面试话题
108 0
|
27天前
|
存储 缓存 算法
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
53 5
|
27天前
|
C语言
C语言编程中,错误处理至关重要,能提升程序的健壮性和可靠性
C语言编程中,错误处理至关重要,能提升程序的健壮性和可靠性。本文探讨了C语言中的错误类型(如语法错误、运行时错误)、基本处理方法(如返回值、全局变量、自定义异常处理)、常见策略(如检查返回值、设置标志位、记录错误信息)及错误处理函数(如perror、strerror)。强调了不忽略错误、保持处理一致性及避免过度处理的重要性,并通过文件操作和网络编程实例展示了错误处理的应用。
59 4
|
26天前
|
并行计算 算法 测试技术
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面,旨在通过综合策略提升程序性能,满足实际需求。
57 1
|
27天前
|
网络协议 物联网 数据处理
C语言在网络通信程序实现中的应用,介绍了网络通信的基本概念、C语言的特点及其在网络通信中的优势
本文探讨了C语言在网络通信程序实现中的应用,介绍了网络通信的基本概念、C语言的特点及其在网络通信中的优势。文章详细讲解了使用C语言实现网络通信程序的基本步骤,包括TCP和UDP通信程序的实现,并讨论了关键技术、优化方法及未来发展趋势,旨在帮助读者掌握C语言在网络通信中的应用技巧。
38 2
|
27天前
|
程序员 C语言
C语言中的指针既强大又具挑战性,它像一把钥匙,开启程序世界的隐秘之门
C语言中的指针既强大又具挑战性,它像一把钥匙,开启程序世界的隐秘之门。本文深入探讨了指针的基本概念、声明方式、动态内存分配、函数参数传递、指针运算及与数组和函数的关系,强调了正确使用指针的重要性,并鼓励读者通过实践掌握这一关键技能。
37 1
|
1月前
|
存储 搜索推荐 算法
【数据结构】树型结构详解 + 堆的实现(c语言)(附源码)
本文介绍了树和二叉树的基本概念及结构,重点讲解了堆这一重要的数据结构。堆是一种特殊的完全二叉树,常用于实现优先队列和高效的排序算法(如堆排序)。文章详细描述了堆的性质、存储方式及其实现方法,包括插入、删除和取堆顶数据等操作的具体实现。通过这些内容,读者可以全面了解堆的原理和应用。
89 16
|
2月前
|
编译器 C语言 Python
C语言结构
C语言结构
21 0
|
2月前
|
存储 文件存储 C语言
深入C语言:文件操作实现局外影响程序
深入C语言:文件操作实现局外影响程序