首页
社区
课程
招聘
[原创] 隐藏进程中的模块绕过IceSword的检测
发表于: 2008-6-19 17:59 51057

[原创] 隐藏进程中的模块绕过IceSword的检测

2008-6-19 17:59
51057

【文章标题】: 隐藏进程中的模块绕过IceSword的检测
【文章作者】: 小伟的小伟[0GiNr](看雪ID:xPLK)
【作者主页】: http://www.0GiNr.com    http://hi.baidu.com/zoo%5F  
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
       最近对隐藏DLL来了点兴趣,首先是断了PEB里面的双向链,过了大部分程序。然后呢把MZ标志改掉了过了暴力搜索(感谢aegisys)。
  接下来就是对抗IceSword使用的NtQueryVirtualMemory的方法了。
  我去WRK里面看了下NtQueryVirtualMemory的源码,找到了这里。
  以下是调试笔记。
  
  lkd> dt_EPROCESS 0x81583B60
  nt!_EPROCESS
     +0x000 Pcb              : _KPROCESS
  ;.............
     +0x11c VadRoot          : 0x816afb68
  ;.............
  lkd> dt_MMVAD 0x816afb68 ;看到了吧。。。二叉树。。。。。。。。。。。
  nt!_MMVAD
     +0x000 StartingVpn      : 0x30
     +0x004 EndingVpn        : 0x12f
     +0x008 Parent           : (null)
     +0x00c LeftChild        : 0x813d7748 _MMVAD
     +0x010 RightChild       : 0x816b21d8 _MMVAD  ;选择右节点来遍历
     +0x014 u                : __unnamed
     +0x018 ControlArea      : 0x0a050004 _CONTROL_AREA
     +0x01c FirstPrototypePte : 0x6d665346 _MMPTE
     +0x020 LastContiguousPte : 0x00000001 _MMPTE
     +0x024 u2               : __unnamed
  lkd> dt_MMVAD 0x816b21d8
  nt!_MMVAD
     +0x000 StartingVpn      : 0x400
     +0x004 EndingVpn        : 0x410
     +0x008 Parent           : 0x816afb68 _MMVAD
     +0x00c LeftChild        : 0x81672bb0 _MMVAD
     +0x010 RightChild       : 0x817b58d8 _MMVAD  ;再来一次
     +0x014 u                : __unnamed
     +0x018 ControlArea      : 0x8144a2f8 _CONTROL_AREA   ;这里是进程映像的地方。
     +0x01c FirstPrototypePte : 0xe24faaa0 _MMPTE
     +0x020 LastContiguousPte : 0xfffffffc _MMPTE
     +0x024 u2               : __unnamed
  lkd> dt_MMVAD 0x817b58d8
  nt!_MMVAD
     +0x000 StartingVpn      : 0x7c920
     +0x004 EndingVpn        : 0x7c9b3
     +0x008 Parent           : 0x816b21d8 _MMVAD
     +0x00c LeftChild        : 0x81731348 _MMVAD
     +0x010 RightChild       : 0x81629b70 _MMVAD
     +0x014 u                : __unnamed
     +0x018 ControlArea      : 0x81f05138 _CONTROL_AREA   ;从这里进去。。
     +0x01c FirstPrototypePte : 0xe1377040 _MMPTE
     +0x020 LastContiguousPte : 0xfffffffc _MMPTE
     +0x024 u2               : __unnamed
  lkd> dt_CONTROL_AREA 0x81f05138
  nt!_CONTROL_AREA
     +0x000 Segment          : 0xe1377008 _SEGMENT
     +0x004 DereferenceList  : _LIST_ENTRY [ 0x0 - 0x0 ]
     +0x00c NumberOfSectionReferences : 1
     +0x010 NumberOfPfnReferences : 0x6d
     +0x014 NumberOfMappedViews : 0x19
     +0x018 NumberOfSubsections : 5
     +0x01a FlushInProgressCount : 0
     +0x01c NumberOfUserReferences : 0x1a
     +0x020 u                : __unnamed
     +0x024 FilePointer      : 0x81e9d938 _FILE_OBJECT  ;这里可以得到模块信息
     +0x028 WaitingForDeletion : (null)
     +0x02c ModifiedWriteCount : 0
     +0x02e NumberOfSystemCacheViews : 0
  lkd> dt_FILE_OBJECT 0x81e9d938 ;到这里ntdll.dll已经出来了。。。。
  nt!_FILE_OBJECT
     +0x000 Type             : 5
     +0x002 Size             : 112
     +0x004 DeviceObject     : 0x81dce7b8 _DEVICE_OBJECT
     +0x008 Vpb              : 0x81e9f8e0 _VPB
     +0x00c FsContext        : 0xe13939e0
     +0x010 FsContext2       : 0xe1393b38
     +0x014 SectionObjectPointer : 0x81e9338c _SECTION_OBJECT_POINTERS
     +0x018 PrivateCacheMap  : (null)
     +0x01c FinalStatus      : 0
     +0x020 RelatedFileObject : (null)
     +0x024 LockOperation    : 0 ''
     +0x025 DeletePending    : 0 ''
     +0x026 ReadAccess       : 0x1 ''
     +0x027 WriteAccess      : 0 ''
     +0x028 DeleteAccess     : 0 ''
     +0x029 SharedRead       : 0x1 ''
     +0x02a SharedWrite      : 0 ''
     +0x02b SharedDelete     : 0 ''
     +0x02c Flags            : 0x44040
     +0x030 FileName         : _UNICODE_STRING "\WINDOWS\system32\ntdll.dll"
     +0x038 CurrentByteOffset : _LARGE_INTEGER 0x0
     +0x040 Waiters          : 0
     +0x044 Busy             : 0
     +0x048 LastLock         : (null)
     +0x04c Lock             : _KEVENT
     +0x05c Event            : _KEVENT
     +0x06c CompletionContext : (null)
  lkd> dt_FILE_OBJECT 0x81c08350 ;再往后是kernel32.dll
  nt!_FILE_OBJECT
  ;......................
     +0x030 FileName         : _UNICODE_STRING "\WINDOWS\system32\kernel32.dll"
  ;......................
   
  
  这里是源码,包含了大量硬编码,要编译的话自己搜索一下就可以。
  Code:
  
  
  //////////////////////////////////////
  //在Ring0下通过遍历VAD获取进程内的模块(WinXP SP2)
  //By 小伟的小伟[0GiNr](看雪ID:xPLK)
  //http://www.0GiNr.com
  //http://hi.baidu.com/zoo%5F
  /////////////////////////////////////
  VOID ShowModules()
  {
      ULONG VAD;
      PEPROCESS TargetProcess;
      ////////////////////////////////////////
      PsLookupProcessByProcessId( (HANDLE)Pid,TargetProcess);
      if(!TargetProcess)
       {
          dprintf("[EnumModules] Error on Get EProcess By Pid.");
          return;
       }
      VAD = *(ULONG *)((ULONG)TargetProcess + Vad);
      //+0x11c VadRoot : Ptr32 Void
      dprintf("[EnumModules] EPROCESS : 0x%X , VAD : 0x%X",TargetProcess,VAD);
      PreOrderTraverse(VAD);  //遍历二叉树。。。
      dprintf("[EnumModules] Modules count : %d",nCount);
      //start.
  }
  
  VOID PreOrderTraverse(ULONG mmVad)
  {
      if ( MmIsAddressValid( (ULONG *)mmVad ) )
       {
          ShowPath(mmVad);//读取地址
          PreOrderTraverse( *(ULONG *)(mmVad + LeftChild) );
          PreOrderTraverse( *(ULONG *)(mmVad + RightChild) );
       }
  }
  
  VOID ShowPath(ULONG mmVad)
  {
      PUNICODE_STRING pPath;
      ULONG ca;//_CONTROL_AREA
      ULONG fp;//_FILE_OBJECT
      ca = *(ULONG *)(mmVad + ControlArea);
      if( !MmIsAddressValid( (ULONG *)ca ) )
       {
          //dprintf("[EnumModules] ControlArea is not available : 0x%X",ca);
          return;
       }
      fp = *(ULONG *)(ca + FilePointer);
      if( !MmIsAddressValid( (ULONG *)fp ) )
       {
          //dprintf("[EnumModules] FileObject is not available : 0x%X",fp);
          return;
       }
      pPath = (PUNICODE_STRING)(fp + FileName);
      dprintf("[EnumModules] The file name is %S",pPath->Buffer);
      //dprintf("[EnumModules] The MMVAD is 0x%X",mmVad);
      //dprintf("\n");
      nCount++;//计数
  }
  
  
  这样和用NtQueryVirtualMemory扫描出来的结果一样(MemorySectionName),可以在DebugView里看到。输出是这样的。
  [EnumModules] The file name is \Project\VisualC++\HideModule\Release\HideModule.exe
  [EnumModules] The file name is \WINDOWS\system32\ntdll.dll
  [EnumModules] The file name is \WINDOWS\system32\kernel32.dll
  [EnumModules] The file name is \WINDOWS\system32\advapi32.dll
  [EnumModules] The file name is \WINDOWS\system32\rpcrt4.dll
  [EnumModules] The file name is \WINDOWS\system32\gdi32.dll
  [EnumModules] The file name is \WINDOWS\system32\user32.dll
  [EnumModules] The file name is \WINDOWS\system32\imm32.dll
  [EnumModules] The file name is \WINDOWS\system32\msvcrt.dll
  [EnumModules] The file name is \WINDOWS\system32\apphelp.dll
  [EnumModules] The file name is \WINDOWS\system32\version.dll
  [EnumModules] The file name is \WINDOWS\system32\lpk.dll
  [EnumModules] The file name is \WINDOWS\system32\usp10.dll
  [EnumModules] The file name is \WINDOWS\system32\unicode.nls
  [EnumModules] The file name is \WINDOWS\system32\sortkey.nls
  [EnumModules] The file name is \WINDOWS\system32\ctype.nls
  [EnumModules] The file name is \WINDOWS\system32\sorttbls.nls
  [EnumModules] The file name is \WINDOWS\system32\locale.nls
  
  
  所以要隐藏呢,就简单了,当然遍历二叉树找到需要隐藏的DLL的时候,我们可以做手脚。
  当初测试抹掉FileObject会不稳定,运行某些程序会蓝屏。
  
  感谢炉子提示,抹掉_FILE_OBJECT里面的路径就可以了。
  代码如下:
  ////////
  RtlZeroMemory(pPath->Buffer,pPath->Length);
  pPath->Length = 0;
  pPath->MaximumLength = 0;
  ///////
  
  
  效果图如下,我隐藏的是ntdll.dll,IceSword是最新版:
  
  比较有意思的是,隐藏掉了之后,再所有进程中都不会显示该模块(ntdll.dll)。
  经过测试,对新创建的进程同样有效,新进程中也没有ntdll.dll的痕迹(IceSword)。
  抹了这点地方,应该还是有办法检测出来的。
  大家发挥创造力吧。

  再次感谢几位朋友的帮忙:
  aegisys: http://hi.baidu.com/aegisys
  Sysnap :http://hi.baidu.com/sysnap
  炉子 :http://hi.baidu.com/breakinglove_
  FlowerCode: http://hi.baidu.com/flowercode
  
  本人菜鸟,文中难免有所缺漏,敬请各位看官指出不足之处。。

  注:sysnap大牛已经检测出来了,得到了一个基址,十分不错,我把bin放出来,有兴趣的可以玩一下,完整src就不放了,主要是怕流氓啊~。
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!

                                                       2008年06月19日 18:02:30


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

上传的附件:
收藏
免费 7
支持
分享
最新回复 (46)
雪    币: 133
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
这么好的文章。顶
2008-6-19 18:06
0
雪    币: 581
活跃值: (149)
能力值: ( LV12,RANK:600 )
在线值:
发帖
回帖
粉丝
3
呵呵...顶个....俺在想还有没其他方法检测DLL.........?????
2008-6-19 18:22
0
雪    币: 564
活跃值: (42)
能力值: ( LV12,RANK:230 )
在线值:
发帖
回帖
粉丝
4
[QUOTE=xPLK;469024]【文章标题】: 隐藏进程中的模块绕过IceSword的检测
【文章作者】: 小伟的小伟[0GiNr](看雪ID:xPLK)
【作者主页】: http://www.0GiNr.com    http://hi.baidu.com/zoo%5F  
【作者声明】: 只是感兴趣,没有其他目的。失误之...[/QUOTE]
顶,,,不错。。。
2008-6-19 18:57
0
雪    币: 375
活跃值: (12)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
5
谢谢斑竹了。。
2008-6-19 20:54
0
雪    币: 220
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
稳定?没崩溃只是因为内核还没访问这个fileobject吧?
说实话不如自己分配内存,ring3就行还稳定
2008-6-19 21:15
0
雪    币: 381
活跃值: (140)
能力值: ( LV13,RANK:330 )
在线值:
发帖
回帖
粉丝
7
了解一下
2008-6-19 21:16
0
雪    币: 375
活跃值: (12)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
8
ntdll~ 你说呢~?
2008-6-19 21:27
0
雪    币: 220
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
ntdll的页基本不可能被交换出去,要是自己的dll页在内存不足时就可能交换掉,待要读回时不知会怎样.
2008-6-19 21:44
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
支持小伟.....
2008-6-19 21:53
0
雪    币: 375
活跃值: (12)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
11
考虑得十分周到。
但我测试了一个Hook的dll到目前为止没出现问题。
你自己动手一下~
看看能不能让这种方法出错。。

谢谢啊~
2008-6-19 22:16
0
雪    币: 220
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
这样啊,看来比较稳定?只要绝大部分时候不出错就有价值了
2008-6-19 22:22
0
雪    币: 375
活跃值: (12)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
13
不行,要精益求精的。。。
所以,麻烦你了。
2008-6-19 22:26
0
雪    币: 321
活跃值: (271)
能力值: ( LV13,RANK:1050 )
在线值:
发帖
回帖
粉丝
14
呵呵,支持下
2008-6-20 12:54
0
雪    币: 224
活跃值: (147)
能力值: ( LV9,RANK:970 )
在线值:
发帖
回帖
粉丝
15



我只会PS
上传的附件:
2008-6-20 14:22
0
雪    币: 375
活跃值: (12)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
16
十五楼的没有看说明~~
哈哈。。

而且
我还不会PS呢。。

0GiNr从来不骗人!

请你注意!

ReadMe.txt

里面说得很清楚了,读一下OK?

如果认为有问题,自己编译吧。
2008-6-20 17:16
0
雪    币: 202
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
我是菜鸟,怎么我在Win2003下的_EPROCESS是这样,VadRoot的地址差好远,而且对应的_MM_AVL_TABLE结构也不同:

0:000> dt _EPROCESS
ntdll!_EPROCESS
   +0x000 Pcb              : _KPROCESS
   +0x078 ProcessLock      : _EX_PUSH_LOCK
   +0x080 CreateTime       : _LARGE_INTEGER
   +0x088 ExitTime         : _LARGE_INTEGER
   +0x090 RundownProtect   : _EX_RUNDOWN_REF
   +0x094 UniqueProcessId  : Ptr32 Void
   +0x098 ActiveProcessLinks : _LIST_ENTRY
   +0x0a0 QuotaUsage       : [3] Uint4B
   +0x0ac QuotaPeak        : [3] Uint4B
   +0x0b8 CommitCharge     : Uint4B
   +0x0bc PeakVirtualSize  : Uint4B
   +0x0c0 VirtualSize      : Uint4B
   +0x0c4 SessionProcessLinks : _LIST_ENTRY
   +0x0cc DebugPort        : Ptr32 Void
   +0x0d0 ExceptionPort    : Ptr32 Void
   +0x0d4 ObjectTable      : Ptr32 _HANDLE_TABLE
   +0x0d8 Token            : _EX_FAST_REF
   +0x0dc WorkingSetPage   : Uint4B
   +0x0e0 AddressCreationLock : _KGUARDED_MUTEX
   +0x100 HyperSpaceLock   : Uint4B
   +0x104 ForkInProgress   : Ptr32 _ETHREAD
   +0x108 HardwareTrigger  : Uint4B
   +0x10c PhysicalVadRoot  : Ptr32 _MM_AVL_TABLE
   +0x110 CloneRoot        : Ptr32 Void
   +0x114 NumberOfPrivatePages : Uint4B
   +0x118 NumberOfLockedPages : Uint4B
   +0x11c Win32Process     : Ptr32 Void
   +0x120 Job              : Ptr32 _EJOB
   +0x124 SectionObject    : Ptr32 Void
   +0x128 SectionBaseAddress : Ptr32 Void
   +0x12c QuotaBlock       : Ptr32 _EPROCESS_QUOTA_BLOCK
   +0x130 WorkingSetWatch  : Ptr32 _PAGEFAULT_HISTORY
   +0x134 Win32WindowStation : Ptr32 Void
   +0x138 InheritedFromUniqueProcessId : Ptr32 Void
   +0x13c LdtInformation   : Ptr32 Void
   +0x140 VadFreeHint      : Ptr32 Void
   +0x144 VdmObjects       : Ptr32 Void
   +0x148 DeviceMap        : Ptr32 Void
   +0x14c Spare0           : [3] Ptr32 Void
   +0x158 PageDirectoryPte : _HARDWARE_PTE_X86
   +0x158 Filler           : Uint8B
   +0x160 Session          : Ptr32 Void
   +0x164 ImageFileName    : [16] UChar
   +0x174 JobLinks         : _LIST_ENTRY
   +0x17c LockedPagesList  : Ptr32 Void
   +0x180 ThreadListHead   : _LIST_ENTRY
   +0x188 SecurityPort     : Ptr32 Void
   +0x18c PaeTop           : Ptr32 Void
   +0x190 ActiveThreads    : Uint4B
   +0x194 GrantedAccess    : Uint4B
   +0x198 DefaultHardErrorProcessing : Uint4B
   +0x19c LastThreadExitStatus : Int4B
   +0x1a0 Peb              : Ptr32 _PEB
   +0x1a4 PrefetchTrace    : _EX_FAST_REF
   +0x1a8 ReadOperationCount : _LARGE_INTEGER
   +0x1b0 WriteOperationCount : _LARGE_INTEGER
   +0x1b8 OtherOperationCount : _LARGE_INTEGER
   +0x1c0 ReadTransferCount : _LARGE_INTEGER
   +0x1c8 WriteTransferCount : _LARGE_INTEGER
   +0x1d0 OtherTransferCount : _LARGE_INTEGER
   +0x1d8 CommitChargeLimit : Uint4B
   +0x1dc CommitChargePeak : Uint4B
   +0x1e0 AweInfo          : Ptr32 Void
   +0x1e4 SeAuditProcessCreationInfo : _SE_AUDIT_PROCESS_CREATION_INFO
   +0x1e8 Vm               : _MMSUPPORT
   +0x230 MmProcessLinks   : _LIST_ENTRY
   +0x238 ModifiedPageCount : Uint4B
   +0x23c JobStatus        : Uint4B
   +0x240 Flags            : Uint4B
   +0x240 CreateReported   : Pos 0, 1 Bit
   +0x240 NoDebugInherit   : Pos 1, 1 Bit
   +0x240 ProcessExiting   : Pos 2, 1 Bit
   +0x240 ProcessDelete    : Pos 3, 1 Bit
   +0x240 Wow64SplitPages  : Pos 4, 1 Bit
   +0x240 VmDeleted        : Pos 5, 1 Bit
   +0x240 OutswapEnabled   : Pos 6, 1 Bit
   +0x240 Outswapped       : Pos 7, 1 Bit
   +0x240 ForkFailed       : Pos 8, 1 Bit
   +0x240 Wow64VaSpace4Gb  : Pos 9, 1 Bit
   +0x240 AddressSpaceInitialized : Pos 10, 2 Bits
   +0x240 SetTimerResolution : Pos 12, 1 Bit
   +0x240 BreakOnTermination : Pos 13, 1 Bit
   +0x240 SessionCreationUnderway : Pos 14, 1 Bit
   +0x240 WriteWatch       : Pos 15, 1 Bit
   +0x240 ProcessInSession : Pos 16, 1 Bit
   +0x240 OverrideAddressSpace : Pos 17, 1 Bit
   +0x240 HasAddressSpace  : Pos 18, 1 Bit
   +0x240 LaunchPrefetched : Pos 19, 1 Bit
   +0x240 InjectInpageErrors : Pos 20, 1 Bit
   +0x240 VmTopDown        : Pos 21, 1 Bit
   +0x240 ImageNotifyDone  : Pos 22, 1 Bit
   +0x240 PdeUpdateNeeded  : Pos 23, 1 Bit
   +0x240 VdmAllowed       : Pos 24, 1 Bit
   +0x240 SmapAllowed      : Pos 25, 1 Bit
   +0x240 CreateFailed     : Pos 26, 1 Bit
   +0x240 DefaultIoPriority : Pos 27, 3 Bits
   +0x240 Spare1           : Pos 30, 1 Bit
   +0x240 Spare2           : Pos 31, 1 Bit
   +0x244 ExitStatus       : Int4B
   +0x248 NextPageColor    : Uint2B
   +0x24a SubSystemMinorVersion : UChar
   +0x24b SubSystemMajorVersion : UChar
   +0x24a SubSystemVersion : Uint2B
   +0x24c PriorityClass    : UChar
   +0x250 VadRoot          : _MM_AVL_TABLE
   +0x270 Cookie           : Uint4B

0:000> dt _MM_AVL_TABLE
ntdll!_MM_AVL_TABLE
   +0x000 BalancedRoot     : _MMADDRESS_NODE
   +0x014 DepthOfTree      : Pos 0, 5 Bits
   +0x014 Unused           : Pos 5, 3 Bits
   +0x014 NumberGenericTableElements : Pos 8, 24 Bits
   +0x018 NodeHint         : Ptr32 Void
   +0x01c NodeFreeHint     : Ptr32 Void
2008-6-21 17:25
0
雪    币: 375
活跃值: (12)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
18
是有点意外~
我没有Win2003

找人帮你测试一下。。
2008-6-21 18:03
0
雪    币: 354
活跃值: (10)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
19
只抹MZ?
太容易检测了。。。
2008-6-21 18:12
0
雪    币: 375
活跃值: (12)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
20
欢迎放Bin与代码~

目前有两种方法检测出来了~

2008-6-21 23:06
0
雪    币: 451
活跃值: (78)
能力值: ( LV12,RANK:470 )
在线值:
发帖
回帖
粉丝
21
支持下

暴力内存搜索
2008-6-23 08:43
0
雪    币: 375
活跃值: (12)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
22
目前的3中方法都是暴力搜索内存的。。。哈哈。。。
2008-6-23 12:31
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
不实用,。。。lj
2008-6-23 13:47
0
雪    币: 218
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
支持下
~!
2008-6-24 00:18
0
雪    币: 220
活跃值: (28)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
是AVL--平衡二叉树
从普通的搜索二叉树到平衡二叉树,这是一个性能的改进
2008-8-4 21:06
0
游客
登录 | 注册 方可回帖
返回
//