软件漏洞分析技巧分享

标签: 漏洞 系统安全 0day 软件漏洞 | 发表时间:2014-03-20 11:37 | 作者:腾讯安全中心
出处:http://www.freebuf.com

作者: riusksk【TSRC】

在日常分析软件漏洞时,经常需要耗费比较长的分析时间,少则几小时,多则数天,甚至更久。因此,经常总结一些分析技巧是非常有必要的,针对不同的漏洞类型采取不同的分析思路和技巧,可以有效地提高分析速度。对于一些被曝出来的热门0day,网上一般都会有分析文章,但一般都是“结论性分析”,也就是直接帖漏洞代码,指出哪里出错,而非“思路性分析”。如果你经常分析漏洞的话,会发现占用你分析时间的往往不是分析漏洞代码,而是定位漏洞代码。所以说,调试分析漏洞有时就是看下断点下得准不,再加上一些胡猜乱想来推测,最后才是分析漏洞代码了,如果熟悉汇编指令,这个就不是问题了。

下面是笔者就以往分析过的若干实例漏洞,总结出的一些小技巧。不过,技巧甚多,篇幅有限,此处仅列举一些比较个人常用的方法,也欢迎各位分享自己的一些分析技巧,大家共同学习探讨。

技巧一:快速定位JS代码调用的IE类成员函数

CVE-2011-0027 Microsoft Data Access组件整数溢出漏洞是Pwn2Own 2010黑客大赛中被用来攻破IE8浏览器的漏洞,其中关键的漏洞触发代码如下:

localxmlid1 = document.getElementById('xmlid1').recordset;    // 获取xml元素xmlid1的recordset,即数据库表的记录集
localxmlid1.CacheSize = 0x40000358;    // 设置能够被保存的记录条数,此值最终造成整数溢出

现在我们就介绍一种快速定位上述两行代码将对应调用的IE类成员函数,首先用IDA加载漏洞文件msado15.dll,并允许加载微软符号表,然后选中“Function name”一栏,按“Alt + T”快捷键弹出搜索框,输入搜索关键字“cachesize”:

通过按“Ctrl+T”可继续搜索下一个,最后找到两个相关函数:

CRecordset::put_CacheSize(long *)
CRocordset::get_CacheSize(long)

我们对CRecordset::put_CacheSize下断点验证下前面的猜测,用Windbg附加IE进程运行后打开poc.html,确实断在put_CacheSize,通过查看参数可以看到poc.html中设置的CacheSize值0×40000358,说明CRecordset::put_CacheSize确实是设置CacheSize值的函数:

0:005> g
Breakpoint 1 hit
eax=40000358 ebx=04bdcfd8 ecx=6e61d340 edx=00000000 esi=01fbf144 edi=00000000
eip=6e6ac957 esp=01fbeb58 ebp=01fbf040 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
msado15!CRecordset::put_CacheSize:
6e6ac957 8bff            mov     edi,edi
0:005> dd esp
01fbeb58  6e62f3ec 04bdcfd8 40000358 00000000
01fbeb68  01fbf074 04bdcfd8 11000011 00000000
01fbeb78  03570ae8 004ad070 00538a30 00000088
01fbeb88  00470000 00000002 03570760 01fbec84
01fbeb98  76fc3193 00470138 76fc316f 764736b8
01fbeba8  00000000 00470000 03570768 00518a78
01fbebb8  004767b8 004768e4 00559258 00476db8
01fbebc8  76f8d74d 0051d968 00472a98 01fbedc0

我们对CRecordset::put_CacheSize下断点验证下前面的猜测,用Windbg附加IE进程运行后打开poc.html,确实断在put_CacheSize,通过查看参数可以看到poc.html中设置的CacheSize值0×40000358,说明CRecordset::put_CacheSize确实是设置CacheSize值的函数:

技巧二:通过页堆快速定位堆漏洞代码

页堆是windows 2000 引入的调试支持功能,简称DPH(Debug Page Heap),启用该机制后,堆管理器会在堆块后增加专门用于检测溢出的栅栏页,当数据溢出触及栅栏页便会立刻触发异常,此时往往就是触发漏洞的最及时的位置,它不仅适用于堆溢出,对于其它类型的堆漏洞也是适用的。
以CVE-2013-0077 微软DirectShow堆溢出漏洞为例,通过以下命令开启页堆(gflags):

gflags.exe –i player.exe +hpa


开启页堆hpa后,重新附加运行后,在复制数据到堆边界时断下:

(4b8.358): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=000000c3 ebx=003fac98 ecx=00000003 edx=000000f7 esi=001bbdd4 edi=003fb000
eip=7d0706d0 esp=02a5f650 ebp=02a5f658 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=0038  gs=0000             efl=00010202
quartz!ParseSequenceHeader+0x114:
7d0706d0 f3a5            rep movs dword ptr es:[edi],dword ptr [esi]

上面就是断在复制数据导致溢出的指令,通过分析其所在函数往往很容易定位漏洞代码。如果不开启页堆,直接以默认形式调试的话,你会发现是断在以下指令:

(4c8.6bc): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=41414141 ebx=003f0000 ecx=41414141 edx=03128e40 esi=03128e38 edi=00000012
eip=7c930efe esp=0465f998 ebp=0465fbb8 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010246
ntdll!RtlAllocateHeap+0x653:
7c930efe 8b39            mov     edi,dword ptr [ecx]  ds:0023:41414141=????????


这已经是堆溢出后导致的内存读取异常了,不再是触发漏洞时最原始的场景了。因此开启页堆后,会更方便你去定位漏洞代码。

技巧三:基于堆分配记录定位整数溢出漏洞代码

以CVE-2011-0027 Microsoft Data Access组件整数溢出漏洞为例,这个漏洞就是在Pwn2Own 2010黑客大赛中,荷兰黑客Peter Vreugdenhil利用它来攻破Win7上的IE8浏览器的。

下面是打开poc.html后的异常情况:

(7b8.278): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=0000036b ebx=0000035b ecx=00000000 edx=00000001 esi=088c8000 edi=00000000
eip=6887746f esp=044dee84 ebp=044dee88 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010202
mshtml!CImpIRowset::HRowNumber2HROWQuiet+0x23:
6887746f 8906            mov     dword ptr [esi],eax  ds:0023:088c8000=????????
0:005> !heap -p -a 088c8000
    address 088c8000 found in
    _DPH_HEAP_ROOT @ 8821000
    in busy allocation (  DPH_HEAP_BLOCK:         UserAddr         UserSize -         VirtAddr         VirtSize)
                                 88227ec:          88c7298             d64-          88c7000             2000
    72eb8e89 verifier!AVrfDebugPageHeapAllocate+0x00000229
    77034ea6 ntdll!RtlDebugAllocateHeap+0x00000030
    76ff7d96 ntdll!RtlpAllocateHeap+0x000000c4
    76fc34ca ntdll!RtlAllocateHeap+0x0000023a
    730d975d MSDART!MpHeapAlloc+0x00000029
    6e5406e7 msado15!CRecordGroup::AllocateHRowRange+0x00000085
    6e540650 msado15!CRecordset::PrepareForFetch+0x000000e2
    6e5d44ae msado15!CRecordset::MoveAbsolute+0x000003e3
    6e5680a5 msado15!CRecordset::_MoveFirst+0x0000007d
    6e5d7957 msado15!CRecordset::MoveFirst+0x00000221
    6e54fde6 msado15!CRecordset::Invoke+0x00001560
    71dcdb38 jscript!IDispatchInvoke2+0x000000f0
    71dcda8c jscript!IDispatchInvoke+0x0000006a
    71dcd9ff jscript!InvokeDispatch+0x000000a9
    71dcdb8a jscript!VAR::InvokeByName+0x00000093
    71dcd8c8 jscript!VAR::InvokeDispName+0x0000007d
    71dcd96f jscript!VAR::InvokeByDispID+0x000000ce
    71dce3e7 jscript!CScriptRuntime::Run+0x00002b80
    71dc5c9d jscript!ScrFncObj::CallWithFrameOnStack+0x000000ce
    71dc5bfb jscript!ScrFncObj::Call+0x0000008d
    71dc5e11 jscript!CSession::Execute+0x0000015f
    71dbf3ee jscript!NameTbl::InvokeDef+0x000001b5
    71dbea2e jscript!NameTbl::InvokeEx+0x0000012c
    71db96de jscript!NameTbl::Invoke+0x00000070
    685aaa7b mshtml!CWindow::ExecuteTimeoutScript+0x00000087
    685aab66 mshtml!CWindow::FireTimeOut+0x000000b6
    685d6af7 mshtml!CStackPtrAry<unsigned long,12>::GetStackSize+0x000000b6
    685d1e57 mshtml!GlobalWndProc+0x00000183
    770e86ef USER32!InternalCallWinProc+0x00000023
    770e8876 USER32!UserCallWinProcCheckWow+0x0000014b
    770e89b5 USER32!DispatchMessageWorker+0x0000035e
    770e8e9c USER32!DispatchMessageW+0x0000000f

根据上面异常的信息,可以知道程序是在向地址为0x88c7298,大小0xd64的堆块写入数据时造成堆溢出了。再根据!heap命令中返回的栈回溯信息可以知道,被溢出的堆块是在CRecordset::MoveFirst函数中调用MpHeapAlloc函数分配的,调用该分配函数的上层函数是CRecordGroup::AllocateHRowRange,对此函数下断,跟进后:  

Breakpoint 0 hit
eax=00000001 ebx=40000358 ecx=76fc316f edx=096f2d34 esi=09759d70 edi=40000358eip=69da06be esp=0446eeec ebp=0446eef8 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
msado15!CRecordGroup::AllocateHRowRange+0x5e:
69da06be 85ff            test    edi,edi0:005> p
eax=00000001 ebx=40000358 ecx=76fc316f edx=096f2d34 esi=09759d70 edi=40000358
eip=69da06c0 esp=0446eeec ebp=0446eef8 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
msado15!CRecordGroup::AllocateHRowRange+0x60:
69da06c0 0f8e34380200    jle     msado15!CRecordGroup::AllocateHRowRange+0x62 (69dc3efa) [br=0]
0:005> p
eax=00000001 ebx=40000358 ecx=76fc316f edx=096f2d34 esi=09759d70 edi=40000358
eip=69da06c6 esp=0446eeec ebp=0446eef8 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
msado15!CRecordGroup::AllocateHRowRange+0x64:
69da06c6 8bc7            mov     eax,edi	// eax = edi = 0x40000358,即CacheSize0:005> p
eax=40000358 ebx=40000358 ecx=76fc316f edx=096f2d34 esi=09759d70 edi=40000358
eip=69da06c8 esp=0446eeec ebp=0446eef8 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
msado15!CRecordGroup::AllocateHRowRange+0x66:
69da06c8 8b3dfc10d969    mov     edi,dword ptr [msado15!_imp__MpHeapAlloc (69d910fc)] ds:0023:69d910fc={MSDART!MpHeapAlloc (72de9730)}
0:005> p
eax=40000358 ebx=40000358 ecx=76fc316f edx=096f2d34 esi=09759d70 edi=72de9730
eip=69da06ce esp=0446eeec ebp=0446eef8 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
msado15!CRecordGroup::AllocateHRowRange+0x6c:
69da06ce 89460c          mov     dword ptr [esi+0Ch],eax ds:0023:09759d7c=00000000
0:005> p
eax=40000358 ebx=40000358 ecx=76fc316f edx=096f2d34 esi=09759d70 edi=72de9730
eip=69da06d1 esp=0446eeec ebp=0446eef8 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
msado15!CRecordGroup::AllocateHRowRange+0x6f:
69da06d1 8b0d10f0e569    mov     ecx,dword ptr [msado15!g_hHeapHandle (69e5f010)] ds:0023:69e5f010=096f0000
0:005> p
eax=40000358 ebx=40000358 ecx=096f0000 edx=096f2d34 esi=09759d70 edi=72de9730
eip=69da06d7 esp=0446eeec ebp=0446eef8 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
msado15!CRecordGroup::AllocateHRowRange+0x75:
69da06d7 8d048504000000  lea     eax,[eax*4+4]	// 分配的堆块大小= 0x40000358*4+4 = 0xd64,这里eax的最大值是0xFFFFFFFF,经eax*4+4后变成0x100000D64 > 0xFFFFFFFF造成整数溢出,结果溢出后等于0xD64。如果我们把CacheSize设置成0x3FFFFFFF,那么后面分配的堆块就是0了。0:005> p
eax=00000d64 ebx=40000358 ecx=096f0000 edx=096f2d34 esi=09759d70 edi=72de9730
eip=69da06de esp=0446eeec ebp=0446eef8 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
msado15!CRecordGroup::AllocateHRowRange+0x7c:
69da06de 50              push    eax	// 堆块大小=0xd640:005> p
eax=00000d64 ebx=40000358 ecx=096f0000 edx=096f2d34 esi=09759d70 edi=72de9730
eip=69da06df esp=0446eee8 ebp=0446eef8 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
msado15!CRecordGroup::AllocateHRowRange+0x7d:
69da06df 680000a000      push    0A00000h
0:005> p
eax=00000d64 ebx=40000358 ecx=096f0000 edx=096f2d34 esi=09759d70 edi=72de9730
eip=69da06e4 esp=0446eee4 ebp=0446eef8 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
msado15!CRecordGroup::AllocateHRowRange+0x82:
69da06e4 51              push    ecx
0:005> p
eax=00000d64 ebx=40000358 ecx=096f0000 edx=096f2d34 esi=09759d70 edi=72de9730
eip=69da06e5 esp=0446eee0 ebp=0446eef8 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
msado15!CRecordGroup::AllocateHRowRange+0x83:
69da06e5 ffd7            call    edi {MSDART!MpHeapAlloc (72de9730)}

该漏洞主要是由于对CacheSize整数值未作有效判断,导致经CacheSize*4+4造成整数溢出,当以CacheSize*4+4结果作为分配堆块的大小时,由于分配过小堆块就会造成堆溢出。

技巧四:基于条件记录断点的漏洞分析技巧

以CVE-2012-0774 Adobe Reader TrueType字体整数溢出漏洞为例,该漏洞主要是在解析TTF字体中的虚拟指令导致的溢出,为了确定导致溢出的是哪条虚拟指令,就可以通过设置条件记录断点来实现。

打开poc触发崩溃后,通过栈回溯定位漏洞函数,此处标记为VulFunction,它就是用于索引虚拟指令处理函数的。

通过快捷键Shift + F4对VulFunction下条件记录断点,记录每次调用VulFunction时对应的虚拟指令索引号

设置好后重新加载AcroRd32.exe运行(不要关闭调试器否则前面设置的断点可能失效),打开poc.pdf运行后查看日志窗口:

导致漏洞的虚拟指令索引号为0×26,通过苹果官方提供的指令集 https://developer.apple.com/fonts/ttrefman/RM05/Chap5.html,可以查到字节码0×26对应的虚拟指令为MINDEX,正是该条指令导致的溢出。

技巧五:基于JS日志的漏洞分析技巧

有时在调试IE漏洞时,我们需要样本中的JS代码的执行先后情况,通过添加一些数学函数,比如math.atan2、math.asin等,还可以使用其它函数,然后通过对jscript!Js::Math::Atan(或者其它函数)下断点来输出log,以方便分析者观察执行情况。比如poc中有如下js,其中的math.atan2是我们添加的:

Math.atan2(0xbabe, "[*] Creating object button...");
    var obj = document.createElement("button");

    Math.atan2(0xbabe, "[*] Assigning data to title...");
    obj.title = data.substring(0,0x40000-0x58); 

    Math.atan2(0xbabe, "[*] Let's AppendChild");
    div_container.appendChild(obj);

通过设置以下断点:

bu jscript!JsAtan2 ".printf \"%mu\", poi(poi(poi(esp+14)+8)+8);.echo;g"

运行后在windbg上的输出窗口就会看到:

[*] Creating object button...
[*] Assigning data to title...
[*] Let&#039;s AppendChild

技巧六:通过虚拟机快照来固定堆地址

最早听到这个方法,是instruder在QQ群里面提到的。由于在分析漏洞时,尤其是堆漏洞时,每个重新加载运行时,分配的堆地址都是固定,无论是分析还是写文档,都不太利用于我们分析和描述。因此我们可以先将程序调试已经完成堆分配的某个地址,然后将其保存为虚拟机快照,等我们需要再重新开始调试时,可通过恢复先前保存的快照来重新调试,那么此时的堆地址跟之前分析的地址都是固定的。

技巧七:监控堆分配释放动作来分析UAF、double free漏洞

以之前分配libpng某个double free漏洞的分析为例,主要是通过对释放函数free进行监控并输出记录来分析的。程序崩溃时的栈回溯如下:

重新用windbg加载,通过监控堆块的释放过程,可以发现它在对其中某堆块进行了双重释放,先下断:

bu 3440D279 ".if(1){.echo EnterVulnFunc;gc}"
bu 6e264b6c ".if(1){.echo Free heap block; dd esp l4;gc}"

输出结果:

EnterVulnFunc
Free heap block
0011bc5c  3441e2a2 138f0020 3b906313 10027b64
Free heap block
0011bc5c  3441dc6c 138f0020 3b906313 10027b64
(1508.e84): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=138f0018 ebx=138f0020 ecx=6e287a7e edx=10028a70 esi=008a0000 edi=00000000
eip=77691f88 esp=0011bbe8 ebp=0011bbf8 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010246
ntdll!RtlFreeHeap+0x3a:
77691f88 80780705        cmp     byte ptr [eax+7],5         ds:0023:138f001f=??

可以看到它对同一个堆块进行多次释放。在IE漏洞分析中最常见的还是UAF,如果想快速定造成UAF的IE对象,就需要对对象的分配的释放进行释放,这个可通过调试器脚本来实现,或者像之前h4ckmp同学基于Windbg接口写的EXE工具,可以快速分析出导致UAF漏洞的对象,如下图所示。

技巧八:基于污点追踪的分析方法

污点追踪理论挺好的,但成品往往不容乐观。污点追踪犹如“七伤拳”一般,“先伤己,再伤人”,开发污点追踪工具,不仅费时费力,而且开发完成后,运行比较大的工具往往需要运行很长时间,比如IE、Adobe等软件,有时甚至需要整整一天的时间,这种一般是在调试分析不方便的时候才使用的,主要针对文件格式漏洞。另外,你也可利用pin等动态插桩框架开发出动态分析工具,针对特定函数挂钩,比如堆分配与释放函数,也可以用它来实现快速分析。

相关 [软件 漏洞 分析] 推荐:

软件漏洞分析技巧分享

- - FreeBuf.COM
作者: riusksk【TSRC】. 在日常分析软件漏洞时,经常需要耗费比较长的分析时间,少则几小时,多则数天,甚至更久. 因此,经常总结一些分析技巧是非常有必要的,针对不同的漏洞类型采取不同的分析思路和技巧,可以有效地提高分析速度. 对于一些被曝出来的热门0day,网上一般都会有分析文章,但一般都是“结论性分析”,也就是直接帖漏洞代码,指出哪里出错,而非“思路性分析”.

pentesterlab xss漏洞分析

- - JavaScript - Web前端 - ITeye博客
pentesterlab简介. pentesterlab官方定义自己是一个简单又十分有效学习渗透测试的演练平台. pentesterlab环境搭建. 官方提供了一个基于debian6的镜像,官网下载镜像,使用vmware建立一个虚拟机,启动即可. ps:官方文档建议做一个host绑定,方便后面使用.

Jailbreakme 3 PDF 越狱漏洞分析

- f41c0n - cnBeta.COM
Jailbreakme 3 PDF 越狱使用Apple iOS操作系统中处理Postscript Type(又称Adobe Type 1)字体的一个缓冲区溢出漏洞,漏洞存在于t1_decoder_parse_charstrings() 函数,该函数用于解码Type 1字体文件中编码过的CharStrings字段.

漏洞分析:Struts2 S2-020在Tomcat 8下的命令执行分析

- - Seay's blog 网络安全博客
Struts S2-020这个通告已经公布有一段时间了. 目前大家都知道这个漏洞可以造成DOS、文件下载等危害,相信各大厂商也已经采取了相应的安全措施. 今天是和大家分享一下对这个漏洞的一点研究,包括如何在Tomcat 8下导致RCE,目的是抛砖引玉,有不足之处欢迎大家指出. 这个漏洞分析的一个难点在于:通过ognl的class.xx这种方式来遍历属性时,得到的是实际运行环境中的动态class,因此仅作静态分析是很困难的.

恶意软件分析环境 cuckoo+malwasm

- - 开源中国社区最新新闻
分析恶意软件malicious ware有很多方法. 请容我不自量力推荐两个开放源代码的免费系统 Cuckoo和 MalWasm. 这是一个虚拟化环境下的恶意软件分析系统. 基于虚拟化进行程序分析有很多优点:. 整机内存可以dump出来,并且可以随时做snapshot;. 无论杀毒软件如何吹嘘它们的启发式分析引擎,但是xss的故事已经证明区区XOR加密就可以将他们全部bypass.

开源网站分析软件Piwik的数据库表结构

- sun - 标点符
Piwik是一套基于Php+MySQL技术构建,能够与Google Analytics相媲美的开源网站访问统计系统,前身是phpMyVisites. Piwik可以给你详细的统计信息,比如网页浏览人数, 访问最多的页面, 搜索引擎关键词等等,并且采用了大量的AJAX/Flash技术,使得在操作上更加便易.

科学绘图与数据分析软件:SigmaPlot绿色版

- alex - 精品绿色便携软件
Systat SigmaPlot是一款专业的科学绘图软件,可用于绘制准确、高质量的图形和曲线,支持一百多种2D、3D科学图形. 2D图表如散点图、线性图、面积图、极坐标图、柱状图表、水平图表、盒状图、饼图、等高线图;3D图形如散点图、线性图、网眼图、柱状图等. SigmaPlot还具有强大的数据统计分析功能:从简单描述统计到复杂回归分析、从基本假设检验到复杂的重复测量方差分析.

OriginLab OriginPro绿色版:专业绘图与数据分析软件

- vicky - 精品绿色便携软件
OriginLab公司研发的专业制图和数据分析软件Origin,是公认的简单易学、操作灵活、功能强大的科学绘图与数据分析软件. OriginLab OriginPro既可以满足一般用户的制图需求,也可以满足高级用户数据分析、函数拟合的需求. Origin软件适合研究人员、工程师和科学人员使用;Origin 8全新版本已经显著地简化了汇入数据、创建图形以及为图形应用各种格式所需的步骤.

科学绘图与数据分析软件:SigmaPlot绿色版

- Iamlongly - FeedzShare
来自: 精品绿色便携软件 - FeedzShare  . 发布时间:2011年07月24日,  已有 2 人推荐. Systat SigmaPlot是一款专业的科学绘图软件,可用于绘制准确、高质量的图形和曲线,支持一百多种2D、3D科学图形. 2D图表如散点图、线性图、面积图、极坐标图、柱状图表、水平图表、盒状图、饼图、等高线图;3D图形如散点图、线性图、网眼图、柱状图等.

开源网站分析软件Piwik的数据库表结构

- Michael - IT技术博客大学习
标签:  Piwik  表结构.     Piwik是一套基于Php+MySQL技术构建,能够与Google Analytics相媲美的开源网站访问统计系统,前身是phpMyVisites. Piwik可以给你详细的统计信息,比如网页浏览人数, 访问最多的页面, 搜索引擎关键词等等,并且采用了大量的AJAX/Flash技术,使得在操作上更加便易.