Lab 6-3
问题
1.比较在main函数于实验6-2的mian函数的调用。从main中调用的新的函数是什么?
解答: 我们也是先跟着书走一遍
先静态分析(基本都是静态分析)
可以清楚的看到,这个函数有创建文件夹(目录)的能力,还有删除一个文件,复制一个文件的能力
和Lab 6-2
一样,也有打开一个URL
的并从里面读取文件的能力
然后我还会发先,这个函数有打开一个注册表和设置值的能力
然后我们查看一下字符串有那些比较有意思
会发现这里一个键值,是设置开机启动的,还有一个C盘下的目录和一个可执行程序的位置
然后我们来看看IDA
中的汇编代码
代码的的结构和上一个分析的函数差不多
都是先调用一个sub_401000
判断一下本地的连接是否可以用,然后调用了一个sub_401040
获得一个命令,之后开始判断函数的返回值,最后做出不同的选择
但是在从网址上的网页获得命令之后,这里又多调用了一个函数sub_401130
,我们这里就集中在这里分析这个函数
2.这个新的函数使用的参数是什么?
解答:如下
这里从[ebp+argv]
中获得一个输入参数,然后将[edx]
的地址赋值给eax
(现在eax
相当于一个指针),然后将这个指针压入栈中
书中是说,这个
argv
相当于argv[0]
,也就是当前运行程序的名字
当然,在C语言中,argv
的开始地址,其实也是argv[0]
的地址,因为argv[0]
是argv[]
的第一个元素
然后还压入了一个var_8
的参数
我们从这里可以看出,var_8
在这里被设置成sub_401040
的返回值al
所以这里压栈的var_8
其实就是从恶意网址上获得的命令
3.这个函数包含的主要代码结构是什么?
解答: 这个结构,我们进去看看就知道了
根据书中的说法
arg_0
是IDA
自动标注的最后被压栈的参数
那么这个arg_0
也就是var_8
,从网页上获得的命令
最后经过这么一串的变化,ecx
其实就变成了指向了arg_0
这个值的指针
然后后面执行了
sub ecx, 61h
61h
其实就是a
的ASCII码标识,如果ecx
这时的值是a
,最后ecx
就变成0
了
然后将ecx
的值和4
比较,ja
是无符号大于跳转
如果ecx的值大于4
,就跳转到这里
然后push
一个值,这个值的值是
然后之后调用了sub_401271
,其实sub_401271
的作用就是printf
我们在Lab6-1
中详细分析了这个汇编为什么是prinf
,如果跟着大部队一路走来的同学应该不会忘记
所以,如果大于4
,则跳到这里输出Error 3.2: Not a valid command provided
于是我们可以推理就是这个函数要求ecx
要小于等于4
如果小于4
了,则来这里执行
会发现这里将减了a
之后的值移动到了edx
中,然后开始一个无条件跳转jmp
来跳转到特定的跳转表上
然后我们可以双击这个跳转表,来看更多的信息
对比书中的图片我们可以发现一个问题,就是
我的IDA
显示loc_40116C
的地址是.text:004011F2
,而不是像书中那样的004011F6
我们还可以发现,跳转表结束的地方,就是.text:00401206
,和.text:004011F2
相差了不少的地址空缺
根据4
个字节一个地址的做法,我们可以类推地址
.text:004011F2 off_4011F2 dd offset loc_40115A
.text:004011F6 dd offset loc_40116C
.text:004011FA dd offset loc_40117F
.text:004011FE dd offset loc_40118C
.text:00401102 dd offset loc_4011D4
.text:00401206 align 10
于是这个跳转地址就明朗多了
如果获得的参数是a
,跳转loc_40115A
如果是b
,跳转loc_40116c
如果是c
,跳转loc_40117F
如果是d
,跳转loc_40118C
如果是e
,跳转loc_4011D4
所以这个函数的代码结构就是一个switch
4.这个函数能够做什么?
解答: 借助上面的分析,我们可以看看,如果获得的参数是a
的时候这个函数做写什么
是a
的话,就创建一个目录在C:\\Temp
如果是b
的话会做什么
这里调用了CopyFileA
函数,这个函数我们来查一下
函数第一个入参是lpExistingFileName
,也就是我们最后push进去那个参数,上上图已经标注出来了,然后第二个入参是lpNewFileName
也就是我们第一个push的参数C:\\Temp\\cc.exe
,然后现在我们主要要弄清的就是这个lpExistingFileName
是什么东西
书上很笼统的说了一下,这个是
argv[0]
但是这个结论是如何得出的呢?
我们可以双击lpExistingFileName
,会跳到这个地方
lpExistingFileName
在栈中的位置是在arg_0
的下方(这里我们设栈底在下,且计算机架构里面说栈底是高地址,栈顶是低地址),由此我们判断lpExistingFileName
是函数调用之前倒数第二次push进栈的参数(先进后出,前面我们已经说了arg_0
是IDA
标注的最后一个push进栈的参数,所以其实现在的arg_0
就在这个栈的栈顶,lpExistingFileName
是栈的栈底)
然后我们退出这个函数回到main
函数
第一个push进栈的是eax
,而这里的eax
是指向argv[0]
或者argv
的指针,于是lpExistingFileName
其实指的就是这个程序本身的名字,第二个push进栈的是获得的参数abcde
,也就是arg_0
所以这个汇编的意思就是把这个程序本身复制到C:\\Temp\cc.exe
中
然后我们看c
会看什么
c
就简单多了,offset Data
指的是
直接删除这个文件
然后看看d
的
d
就是先打开注册表Software\Microsoft\Windows\CurrentVesion\Run
,然后把值C:\\Temp\\cc.exe
写进去开机启动
然后看看e
是干什么的
e
就是调用了Sleep
函数,然后休眠了186A0h
毫秒,也就是
100
秒
5.在这个恶意代码中有什么本地特征?
解答: 会在本地创建一个C:\\Temp
文件夹和创建一个C:\\Temp\\cc.exe
文件,然后会在注册表中Software\Microsoft\Windows\CurrentVersion\Run
中添加一个值C:\Temp\cc.exe
6.这个恶意代码的目的是什么?
解答: 设置开机运行这个可执行程序
本文完