邪恶八进制信息安全团队技术讨论组's Archiver

sudami 2008-1-12 10:45

[原创]SDTrestore Version 0.2 学习注释存档

文章作者:sudami [[email]xiao_rui_119@163.com[/email]]

信息来源:邪恶八进制信息安全团队([url]www.eviloctal.com[/url])

[color=#008000]/********************************************************************************************
* Name  : SDTrestore Version 0.2
* Author : Coded by Chew Keong TAN
* Learner: sudami [[email]xiao_rui_119@163.com[/email]]
* Time  : 08/01/12
*
* Comment:
*
* 适用 XP 和 WIN2K
* SDT恢复是一个古老的技术了,这些天复习以前的知识,发现东西都忘了.正好找到了这份源码.
* 于是开始边注释边复习起来. 现在终于又把RING3下恢复SSDT的东西温习了一下,感觉很充实.
* 偶很菜,一开始看代码的时候,不知道如何下手,因为原作者的代码风格很乱,看得糊涂.于是偶
* 按照M$ 的代码风格重新注释了一遍,方便以后温习. 如果你还木有看过这份源码的话,在偶注释
* 的基础上应该会理解的更快些了.
*
* 搜索了下坛子,发现没有关于这份源码的相关细节.于是偶来补充下.
* 存档的主要目的是方便以后学习这些知识的同学更快的找到资源,少走弯路. 老鸟飘过~
*
* Description:
*
* 在RING3获得\device\physicalmemory 的读写权限(前提必须是Administrator). 从磁盘读取
* ntoskrnl.exe,对齐后映射进内存(这需要我们自己来做),在其EAT中得到KeServiceDescriptorTable
* 相对于ntoskrnl.exe的偏移.把系统高端加载的ntoskrnl.exe 的SSDT地址映射到进程的虚拟地址空间里
* 推算出ServiseTable的地址后,把其所有内容映射到进程的虚拟地址空间里. 得到了ServiseTable的地址
* 但它里面的函数是否被HOOK过,并不知道.所以需要参照我们自己映射的ntoskrnl.exe中的ServiseTable
* 里函数的偏移来作比较.不相同,则被HOOK了,然后恢复之.
*
* btw: 90210 的那个搜索SSDT的方法好像不行.得到的地址不正确.而且导致系统直接重启
*
*********************************************************************************************/[/color]

注释风格类似如下:

[quote]
[color=#0000D0]BOOL[/color]
LoadPE (
[color=#0000D0]char[/color] *exePtr,
MZHeader *inMZ,
PE_Header *inPE,
PE_ExtHeader *inpeXH,
SectionHeader *inSecHdr,
[color=#0000D0]LPVOID[/color] ptrLoc
)

[color=#008000]/*++

学习者: sudami [[email]xiao_rui_119@163.com[/email]]
时间 : 08/01/11

功能:
加载从磁盘读取的文件到内存,需要自己对齐

      <PE加载到内存对齐后的示意图>
   所有文件头   节   节  ...   节N
   ------------------------------------------------
  |aa...aa######| a...a##| a...a###| ... | a...a##|
   ------------------------------------------------
注: a 表示实际数据; # 表示空隙,是内存中对齐后留出的空隙

参数:
exePtr - PE文件在磁盘中时起始的地址.还没有经过对齐.所以需要把它映射到内存

modulePos - [IN] 将磁盘上的文件读出来后,映射到进程的虚拟地址空间中,对齐后得到其起始地址.

outMZ - [OUT] 保存MZ头 IMAGE_DOS_HEADER

outPE - [OUT] 保存PE头 IMAGE_FILE_HEADER

outpeXH - [OUT] 保存扩展PE头 IMAGE_OPTIONAL_HEADER

outSecHdr - [OUT] 2级指针,保存Section头 IMAGE_SECTION_HEADER

ptrLoc - 根据内存中PE的大小调用HeapAlloc而分配的一块空闲内存区域.

返回: TRUE

--*/[/color]
{
  [color=#0000D0]char[/color] *outPtr = ([color=#0000D0]char[/color] *)ptrLoc;

  [color=#008000]// 把所有文件头的数据全部拷贝到ptrLoc指向的地址处[/color]
  [color=#008000]// 然后地址按照PE在内存中的对齐方式往后挪[/color]
  memcpy (outPtr, exePtr, inpeXH->sizeOfHeaders);
  outPtr += GetAlignedSize (inpeXH->sizeOfHeaders, inpeXH->sectionAlignment);

  [color=#008000]// 拷贝所有的节数据到新的地址处. 复制的时候要知道每个节在文件中的实际大小.而不是在内存在对齐后的大小[/color]
  [color=#0000D0]for[/color] ([color=#0000D0]int[/color] i = 0; i < inPE->numSections; i++) {

    [color=#0000D0]if[/color] (inSecHdr[i].sizeOfRawData > 0) { [color=#008000]// sizeOfRawData 是节对齐后的长度[/color]
      [color=#0000D0]ULONG[/color] toRead = inSecHdr[i].sizeOfRawData;

      [color=#0000D0]if[/color] (toRead > inSecHdr[i].virtualSize) {
        toRead = inSecHdr[i].virtualSize;
      }

      [color=#008000]// 拷贝没个节的实际数据,然后把指针挪到每个节在内存中对齐后的位置处[/color]
      memcpy (outPtr, exePtr + inSecHdr[i].pointerToRawData, toRead);

      outPtr += GetAlignedSize (inSecHdr[i].virtualSize, inpeXH->sectionAlignment);
    }
  }

  [color=#0000D0]return[/color] [color=#0000D0]true[/color];
}
[/quote]

希望偶们这样的菜鸟能一起共同成长~[s:267]

ayarei 2008-1-12 13:09

[s:267] 认真学习的好孩子
真是很久没有看过代码了

54sking 2008-1-12 13:35

ring3下还可以试试用ZwSystemDebugControl恢复SSDT

sudami 2008-1-12 15:21

嗯,有这样一份代码。也帖出来吧。存档。
---------------------------------------------------------
汗,发完帖发现这份代码被删了。如果哪位牛牛还能在硬盘里找到,麻烦一起帖出来。方便大家学习~
懒得google了~[s:265]

takdick 2008-1-13 15:19

好東西,可惜我不懂VC,有Delphi的代碼嗎?

uncledo 2008-2-28 02:31

补充二楼:
[url=https://www.xfocus.net/bbs/index.php?act=ST&f=3&t=65188]https://www.xfocus.net/bbs/index.php?act=ST&f=3&t=65188[/url]
源代码及执行文件(37K)[url=http://topmint.googlepages.com/ssdt2.zip]http://topmint.googlepages.com/ssdt2.zip[/url]

向sudami学习,同样是学生,差距呀!:sweat: 还请楼主以后有机会帮帮我呦

页: [1]
© 1999-2008 EvilOctal Security Team