作者:k0shl 转载请注明出处
我的报告中,代码部分一般都是从Windbg和IDA中拷贝下来的,因为一次调试过程可能会重启windbg很多次,有很多重要的逻辑过程,所以我没有用截图的方法,但实际上,截图后的效果和我拷贝的代码片段是一样的,但有些小伙伴向我反应,可能有些地方不太清楚,我又不能在代码中给重要代码标记红色,因此我这里特别对常用的一些场景进行说明。
通过场景中包含的重要元素,可以和我的文字解释进行对照,大家可能就会很明白了,尤其是对于刚刚接触和想入门的小伙伴。
在我的分析中,每一个重要的逻辑代码片段,都会搭配对应的文字解释,整个下来就是一个漏洞分析的过程。以下的解释,都是从报告里筛选出来代码片段中的片段,解释这些代码片段分别代表什么,这样才能和文字对照。
Windows部分:
Windbg:
0:010> g
这个标记是windbg的命令标记,在“>”后面的是我输入的指令,常用的比如有dd,kb,p,g等等,关于windbg指令,网上有很多的描述,这里就不详解了,在报告中如果有不明白的可以直接搜到,都是常用的指令。
eax=00000000 ebx=00104a54 ecx=41414141 edx=00000461 esi=77c2fce0 edi=0000c350
eip=41414141 esp=000ffd34 ebp=00104674 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010202
这一部分是寄存器的值,eax,ebx代表寄存器名称,后面的值代表寄存器此时的值。关于每个寄存器的功能,也是都可以在网上搜到的,比较重要的有eip,esp,ebp等等。
ASX2MP3Converter+0x1f3b5:
0041f3b5 81c42c890000 add esp,892Ch
这一部分是当前执行到的位置的代码,ASX...代表目前执行到的函数及偏移,在dll中有可能展现形式是 ntdll!xxxxx+0nh 这种形势,+ 后面的一般是偏移,但这个函数的值不可信,在没有符号表的情况下不准确。
需要通过下面0041f3b5 这个值是现在执行到的地址,在没有ASLR的情况下,可以直接在IDA pro中定位到,如果存在ASLR,需要算一下偏移。
后面81c4...是当前汇编代码对应的机器码,后面的add esp...是汇编指令。
那么组合起来就是我在Windbg中经常展现的代码片段。
接下来展现一些其他常用的,比如
>kb
000ffd30 41414141 41414141 41414141 41414141 0x41414141
001046bc 77d18bd9 00000001 00000000 00000000 0x41414141
001046d0 73dc840e 001047c8 77d4048f 77d18830 USER32!GetWindowThreadProcessId+0x159
001046e4 77d1882a 77d2a013 00000000 77d3e577 MFC42!Ordinal1569+0x1e
001046e8 77d2a013 00000000 77d3e577 000d02cc USER32!GetDC+0x163
这个是通过kb命令回溯对战调用的情况,实际上这个就是对应栈的调用,分为三部分,第一行0010xxx...是一部分,77d1.. -> 0000..是第二部分,最后是第三部分,我们通常会关注第二部分的第一个值,是调用的地址,比如77d18bd9一列,还有第三部分,是调用函数的名称。
还有
0:000> dd esp
000ffd2c 00104674 00446380 00000001 00000000
000ffd3c 009a0054 00104a54 00000000 00000000
000ffd4c 00000000 00000000 00000000 00000000
这个是展示堆栈中的值,dd后面可以是esp这样的寄存器名称,也可以是一个地址,比如dd 1234abcd。
IDA pro部分:
IDA pro在分析过程中通常是静态分析的角色,因此我在报告中,一般伪代码,和一些静态汇编代码,是通过IDA展示的。
比如:
.text:0041C957 push offset aRb ; "rb"
.text:0041C95C push ebp ; Filename
.text:0041C95D call ds:fopen
最前面的.text是代码段,一般都是代码段,少数加壳或者数据段都会不太一样,比如.UPX,比如.data等等,后面0041...是地址,在之前动态分析提到的地址,这里通过jmp to address的方法可以定位到这里面的地址,后面就是汇编指令了,分号后面是一些注释。
还有
for ( j = &v14; v10; ++j )
{
sub_10006FD0(v10, *(_DWORD *)(a1 + 1156));
v10 = j[1];
}
v12 = Dest;
for ( k = &Dest; v12; ++k )
{
sub_10006FD0(v12, *(_DWORD *)(a1 + 1156));
v12 = k[1];
}
这个是通过IDA pro的F5插件得到的伪代码,类似于C代码,就不详细解释了。
我的漏洞分析中还包含linux的漏洞分析,主要通过gdb调试,这里gdb我用了peda插件,能够很清晰的展现出堆栈调用的情况,这里也列举一些常见的命令
gdb-peda$ run -r crash
$ 后面的是gdb命令,网上也有很多相关的命令了,多数都是常用命令,可以去查看。
gdb-peda$ bt
#0 0x8001e612 in ?? ()
#1 0x8001e7da in ?? ()
#2 0x80013677 in ?? ()
#3 0x8001ab11 in ?? ()
#4 0x80013f65 in ?? ()
#5 0xb7dc6a18 in ?? () from /usr/lib/i386-linux-gnu/libpcap.so.0.8
#6 0xb7db79c3 in pcap_loop () from /usr/lib/i386-linux-gnu/libpcap.so.0.8
#7 0x80012621 in main ()
bt命令常用来回溯堆栈调用,很清晰,前面的0x是地址,后面in ??在有源码或者函数的情况下会显示对应函数,如果有from通常是外部调用。
最后是peda的内容。
[----------------------------------registers-----------------------------------]
EAX: 0x5
EBX: 0x800f2d18 --> 0xf2c10
ECX: 0xbfffdfaf --> 0x30303000 ('')
EDX: 0xbfffdfc9 ("......")
ESI: 0x107bd
EDI: 0x801c1085 --> 0xff000000
EBP: 0x0
ESP: 0xbfffdf5c --> 0x801c2148 --> 0xb7fffa8c --> 0xb7daa604 --> 0xb7fff930 --> 0x80000000 (--> ...)
EIP: 0x8001e612 (movzx edi,BYTE PTR [edi+esi*2+0x1])
EFLAGS: 0x210296 (carry PARITY ADJUST zero SIGN trap INTERRUPT direction overflow)
这个是寄存器的内容,eax代表寄存器的名称,后面的是值,以及这个值的变化情况。
[-------------------------------------code-------------------------------------]
0x8001e607: mov DWORD PTR [esp+0xc],edx
0x8001e60b: sub esp,0x4
0x8001e60e: movzx ebp,BYTE PTR [edi+esi*2]
=> 0x8001e612: movzx edi,BYTE PTR [edi+esi*2+0x1]
0x8001e617: mov eax,ebp
0x8001e619: mov edx,edi
0x8001e61b: mov BYTE PTR [esp+0x16],al
0x8001e61f: mov BYTE PTR [esp+0x17],dl
这个是对应的会变代码,以及上下文,=>表示当前汇编的位置。
[------------------------------------stack-------------------------------------]
0000| 0xbfffdf5c --> 0x801c2148 --> 0xb7fffa8c --> 0xb7daa604 --> 0xb7fff930 --> 0x80000000 (--> ...)
0004| 0xbfffdf60 --> 0xbfffe020 --> 0xb7daa604 --> 0xb7fff930 --> 0x80000000 --> 0x464c457f
0008| 0xbfffdf64 --> 0x5
0012| 0xbfffdf68 --> 0xbfffdfaa (" 0000")
0016| 0xbfffdf6c --> 0xbfffdfc9 ("......")
0020| 0xbfffdf70 --> 0xb058
0024| 0xbfffdf74 --> 0xbfffdf96 (" 0000 0000 0000 0000 0000")
0028| 0xbfffdf78 --> 0x7ffffff9
这个是栈中的值。
这就是一些常用的场景,如果还有问题可以联系我,我的QQ是2223944275