<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
<channel>
<title><![CDATA[中国龙派信息安全团队]]></title>
<link>http://www.chinahacker.net/</link>
<description><![CDATA[自由　技术　学习]]></description>
<language>zh-cn</language>
<copyright><![CDATA[Copyright 2005 PBlog3 v2.8]]></copyright>
<webMaster><![CDATA[freeshell2002@yahoo.com(中国龙派)]]></webMaster>
<generator>PBlog2 v2.4</generator> 
<image>
	<title>中国龙派信息安全团队</title>
	<url>http://www.chinahacker.net/images/logos.gif</url>
	<link>http://www.chinahacker.net/</link>
	<description>中国龙派信息安全团队</description>
</image>

			<item>
			<link>http://www.chinahacker.net/article.asp?id=109</link>
			<title><![CDATA[防CC攻击的ASP代码]]></title>
			<author>freeshell2002@yahoo.com(gaby)</author>
			<category><![CDATA[网文网摘]]></category>
			<pubDate>Thu,22 Jul 2010 08:28:38 +0800</pubDate>
			<guid>http://www.chinahacker.net/default.asp?id=109</guid>
		<description><![CDATA[较为全面的asp防CC代码<br/><br/>&lt;%<br/>Dim CC_Info(4),strInfo,strTemp<br/>If Session(&#34;CC_Info&#34;) = &#34;&#34; Then<br/>CC_Info(0) = &#34;cclog.txt&#34; &#39;日志文件名<br/>CC_Info(1) = Request.ServerVariables(&#34;HTTP_X_FORWARDED_FOR&#34;)<br/>CC_Info(2) = Request.ServerVariables(&#34;REMOTE_ADDR&#34;)<br/>CC_Info(3) = 10 &#39;N秒内禁止刷新当前页面<br/>CC_Info(4) = &#34;badip.txt&#34; &#39;IP黑名单文件名<br/>Session(&#34;CC_Info&#34;) = CC_Info(0) &amp;&#34;|&#34;&amp; CC_Info(1) &amp;&#34;|&#34;&amp; CC_Info(2) &amp;&#34;|&#34;&amp; CC_Info(3) &amp;&#34;|&#34;&amp; CC_Info(4)<br/>Else<br/>strInfo = Split(Session(&#34;CC_Info&#34;),&#34;|&#34;)<br/>CC_Info(0) = strInfo(0)<br/>CC_Info(1) = strInfo(1)<br/>CC_Info(2) = strInfo(2)<br/>CC_Info(3) = strInfo(3)<br/>CC_Info(4) = strInfo(4)<br/>End If<br/><br/>Const chkRefresh = 1 &#39;0关闭防刷新<br/>Const chkProxy = 1 &#39;0关闭代理验证<br/>Const chkBadIP = 1 &#39;0关闭IP黑名单<br/><br/>If Session(&#34;BadIP&#34;) = &#34;&#34; Then<br/>strInfo = ReadFile(CC_Info(4))<br/>If strInfo = &#34;&#34; Then strInfo = &#34;chinavb.net&#34;<br/>Session(&#34;BadIP&#34;) = strInfo<br/>Else<br/>strInfo = Session(&#34;BadIP&#34;)<br/>End If<br/><br/>&#39;/*第一层判断，N秒内禁止刷新*/<br/>If chkRefresh = 1 Then<br/>If Session(&#34;RefreshTime&#34;)=&#34;&#34; Then<br/>&nbsp;&nbsp; Session(&#34;RefreshTime&#34;)=Now()<br/>Else<br/>&nbsp;&nbsp; If DateDiff(&#34;s&#34;, Session(&#34;RefreshTime&#34;), Now()) &lt; CInt(CC_Info(3)) Then<br/>&nbsp;&nbsp;&nbsp;&nbsp;Response.Write(&#34;系统繁忙，请稍候再试！错误代码001&#34;)<br/>&nbsp;&nbsp;&nbsp;&nbsp;Response.End()<br/>&nbsp;&nbsp; Else<br/>&nbsp;&nbsp;&nbsp;&nbsp;Session(&#34;RefreshTime&#34;)=Now()<br/>&nbsp;&nbsp; End If<br/>End If<br/>End If<br/><br/>&#39;/*第二层判断，代理禁止查看*/<br/>If chkProxy = 1 Then<br/>If CC_Info(1) &lt;&gt; &#34;&#34; Then<br/>&nbsp;&nbsp; If InStr(strInfo,CC_Info(1)) = 0 Then<br/>&nbsp;&nbsp;&nbsp;&nbsp;strTemp = CC_Info(1) &amp; vbCrLf<br/>&nbsp;&nbsp;&nbsp;&nbsp;If InStr(strInfo,CC_Info(2)) = 0 Then<br/>&nbsp;&nbsp;&nbsp;&nbsp; strTemp = strTemp &amp; &#34;[&#34; &amp; CC_Info(2) &amp; &#34;]&#34; &amp; vbCrLf<br/>&nbsp;&nbsp;&nbsp;&nbsp;End If<br/>&nbsp;&nbsp;&nbsp;&nbsp;SaveLog CC_Info(4),strTemp<br/>&nbsp;&nbsp;&nbsp;&nbsp;strInfo = strInfo &amp; strTemp<br/>&nbsp;&nbsp;&nbsp;&nbsp;Session(&#34;BadIP&#34;) = strInfo<br/>&nbsp;&nbsp; End If<br/>&nbsp;&nbsp; &#39;记录CC攻击日志<br/>&nbsp;&nbsp; SaveLog CC_Info(0),CC_Info(1) &amp; &#34;[&#34;&amp; CC_Info(2) &amp; &#34;]&#34; &amp; Now() &amp;vbCrLf<br/>&nbsp;&nbsp; Response.Write(&#34;系统繁忙，请稍候再试！错误代码002&#34;)<br/>&nbsp;&nbsp; Response.End()<br/>End If<br/>End If<br/><br/>&#39;/*第三层判断，IP黑名单禁止查看*/<br/>If chkBadIP = 1 Then<br/>If InStr(strInfo,CC_Info(2))&gt;0 Then<br/>&nbsp;&nbsp; Response.Write(&#34;系统繁忙，请稍候再试！错误代码003&#34;)<br/>&nbsp;&nbsp; Response.End()<br/>End If<br/>End If<br/><br/>&#39;ForReading=1,ForWriting=2,ForAppending=8<br/>Function SaveLog(filename, filecontent)<br/>On Error Resume Next<br/>&nbsp;&nbsp;&nbsp;&nbsp;Dim fso, thisfile<br/>&nbsp;&nbsp;&nbsp;&nbsp;filename = Server.MapPath(filename)<br/>&nbsp;&nbsp;&nbsp;&nbsp;Set fso = Cr&#101;ateObject(&#34;Scripting.FileSystemObject&#34;)<br/>If Err &lt;&gt; 0 Then<br/>&nbsp;&nbsp; Response.Write(&#34;写入文件&#34;&amp;filename&amp;&#34;失败，可能您的系统不支持FSO！&#34;)<br/>&nbsp;&nbsp; Response.End()<br/>End If<br/>&nbsp;&nbsp;&nbsp;&nbsp;Set thisfile = fso.OpenTextFile(filename, 8, True)<br/>&nbsp;&nbsp;&nbsp;&nbsp;thisfile.write (filecontent)<br/>&nbsp;&nbsp;&nbsp;&nbsp;thisfile.Close<br/>&nbsp;&nbsp;&nbsp;&nbsp;Set fso = Nothing<br/>End Function<br/><br/>Function ReadFile(filename)<br/>On Error Resume Next<br/>Dim fso, thisfile<br/>Set fso = Cr&#101;ateObject(&#34;Scripting.FileSystemObject&#34;)<br/>If Err &lt;&gt; 0 Then<br/>&nbsp;&nbsp; Response.Write(&#34;读取文件&#34;&amp;filename&amp;&#34;失败，可能您的系统不支持FSO！&#34;)<br/>&nbsp;&nbsp; Response.End()<br/>End If<br/>Set thisfile = fso.OpenTextFile(Server.MapPath(filename), 1, True)<br/>ReadFile = thisfile.ReadAll<br/>thisfile.Close<br/>Set thisfile = Nothing<br/>Set fso = Nothing<br/>End Function<br/>%&gt;<br/>]]></description>
		</item>
		
			<item>
			<link>http://www.chinahacker.net/article.asp?id=108</link>
			<title><![CDATA[利用VB编写dll注入其他进程的源代码]]></title>
			<author>freeshell2002@yahoo.com(gaby)</author>
			<category><![CDATA[网文网摘]]></category>
			<pubDate>Fri,19 Mar 2010 13:59:31 +0800</pubDate>
			<guid>http://www.chinahacker.net/default.asp?id=108</guid>
		<description><![CDATA[本文没什么特别的技术含量，高手免阅。 <br/><br/>本文是此帖的具体实现…………<a href="http://www.rekersoft.cn/article.asp?id=4" target="_blank" rel="external">http://www.rekersoft.cn/article.asp?id=4</a><br/><br/>前些日子为了隐藏KillIM（见<a href="http://www.rekersoft.cn/article.asp?id=8" target="_blank" rel="external">http://www.rekersoft.cn/article.asp?id=8</a>）于是上网找了些注入dll的资料，另外在一个u盘里面意外发现了以前备份的一些代码（原来的电脑被偷了 ），其中就包含了dll注入，呵呵，可以省点事了，把精力集中在vb编译标准dll上。以前其实有个csdn上牛人写的vb插件，可以用标准exe工程生成dll，而不是网上流行的activex dll工程加连接参数生成标准dll（那样其实不是标准的，本质还是activex dll，比如不能用来做hook）。可惜csdn改版以后，原来的下载页面都没了，也就再也找不到了。<br/><br/>此帖主要讲一下dll的注入与卸载（叫反注入貌似不太恰当，反正就是那个意思），以及如何编写一个注入用dll。因为在网上好多讲注入的帖子中的dll都讲得很简单，简单的show一个msgbox。问题是注入之后，dllmain执行一次就返回了，接着要怎么继续让dll做事情很多菜鸟（包括我）都不知道。所以就研究了下,贴在这里。<br/><br/>第一部分讲的是注入程序：<br/><br/>dll注入的核心就是用Cr&#101;ateRemoteThread函数在目标进程中创建一个线程（如果你不知道线程是什么?just google it），该线程只有一个作用，就是LoadLibraryA我们的dll，而LoadLibraryA又会调用dll的DllMain函数并发送DLL_PROCESS_ATTACH参数告诉dll你被加载了。此时我们的dll就成为了目标进程的一部分，于是乎，你该干吗就可以干吗去了。<br/><br/>ok，来说说代码吧。下面是api申明，放在模块当中。<br/> <br/><br/> 程序代码<br/><br/>Option Explicit<br/>&#39;dll注入程序<br/>&#39;api申明模块<br/>&#39;<br/>&#39;蓝色炫影&nbsp;&nbsp;制作<br/>&#39;www.rekersoft.cn<br/>&#39;<br/>&#39;最后更新 2008/05/06<br/>&#39;您可以自由用于非商业用途。<br/>&#39;请保留此行版权信息，谢谢。<br/><br/>Public Const PROCESS_VM_READ = &amp;H10<br/>Public Const TH32CS_SNAPPROCESS = &amp;H2<br/>Public Const MEM_COMMIT = 4096<br/>Public Const MEM_DECOMMIT = &amp;H4000<br/>Public Const PAGE_READWRITE = 4<br/>Public Const PROCESS_Cr&#101;ate_THREAD = (&amp;H2)<br/>Public Const PROCESS_VM_OPERATION = (&amp;H8)<br/>Public Const PROCESS_VM_WRITE = (&amp;H20)<br/>Public Const PROCESS_ALL_ACCESS = &amp;H1F0FFF<br/>Public Const INFINITE = &amp;HFFFF&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;&nbsp;&nbsp;Infinite timeout<br/><br/>Public Declare Function VirtualAllocEx Lib &#34;kernel32&#34; (ByVal hProcess As Long, _<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ByVal lpAddress As Long, ByVal dwSize As Long, ByVal flAllocationType As Long, _<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ByVal flProtect As Long) As Long<br/>Public Declare Function VirtualFreeEx Lib &#34;kernel32&#34; (ByVal hProcess As Long, _<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ByVal lpAddress As Long, ByVal dwSize As Long, _<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ByVal dwFreeType As Long) As Long<br/>&#39;这两个api的作用是在目标进程中分配一段空白内存供程序使用。在vb的api浏览器中是找不到的。<br/><br/>Public Declare Function GetProcAddress Lib &#34;kernel32&#34; (ByVal hModule As Long, _<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ByVal lpProcName As String) As Long<br/>Public Declare Function GetModuleHandle Lib &#34;kernel32&#34; Alias &#34;GetModuleHandleA&#34; _<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(ByVal lpModuleName As String) As Long<br/>&#39;得到函数地址与dll模块地址<br/><br/>Public Declare Function Cr&#101;ateToolhelp32Snapshot Lib &#34;kernel32&#34; _<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(ByVal dwFlags As Long, ByVal th32ProcessID As Long) As Long<br/>Public Declare Function Process32First Lib &#34;kernel32&#34; (ByVal hSnapshot As Long, _<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lppe As PROCESSENTRY32) As Long<br/>Public Declare Function Process32Next Lib &#34;kernel32&#34; (ByVal hSapshot As Long, _<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lppe As PROCESSENTRY32) As Long<br/>&#39;这三个api用来遍历进程<br/><br/>Public Declare Function OpenProcess Lib &#34;kernel32&#34; _<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, _<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ByVal dwProcessId As Long) As Long<br/>Public Declare Function CloseHandle Lib &#34;kernel32&#34; (ByVal hObject As Long) As Long<br/>&#39;打开与关闭进程句柄<br/><br/>Public Declare Function WriteProcessMemory Lib &#34;kernel32&#34; _<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(ByVal hProcess As Long, ByVal lpBaseAddress As Long, lpBuffer As Any, _<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long<br/>&#39;这里注意lpBaseAddress的传送方式是byval，和api浏览器中的声明是不一样的。 _<br/>byval是传值，默认是byref是传址，也就是传递的是参数在内存中的地址<br/>Public Declare Function Cr&#101;ateRemoteThread Lib &#34;kernel32&#34; _<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(ByVal hProcess As Long, ByVal lpThreadAttributes As Long, _<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ByVal dwStackSize As Long, ByVal lpStartAddress As Long, _<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ByVal lpParameter As Long, ByVal dwCreationFlags As Long, _<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lpThreadId As Long) As Long<br/>&#39;这里也是一样，几个参数的传递方式与api浏览器中的声明不一样<br/>Public Declare Function WaitForSingleObject Lib &#34;kernel32&#34; _<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long<br/>Public Declare Function GetExitCodeThread Lib &#34;kernel32&#34; _<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(ByVal hThread As Long, lpExitCode As Long) As Long<br/>&#39;这两个函数程序当中没用到。在窗体代码中有注释。<br/><br/>Public Type PROCESSENTRY32<br/>&nbsp;&nbsp;&nbsp;&nbsp;dwSize&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;As Long<br/>&nbsp;&nbsp;&nbsp;&nbsp;cntUseage&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; As Long<br/>&nbsp;&nbsp;&nbsp;&nbsp;th32ProcessID&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; As Long<br/>&nbsp;&nbsp;&nbsp;&nbsp;th32DefaultHeapID&nbsp;&nbsp; As Long<br/>&nbsp;&nbsp;&nbsp;&nbsp;th32ModuleID&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;As Long<br/>&nbsp;&nbsp;&nbsp;&nbsp;cntThreads&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;As Long<br/>&nbsp;&nbsp;&nbsp;&nbsp;th32ParentProcessID As Long<br/>&nbsp;&nbsp;&nbsp;&nbsp;pcPriClassBase&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;As Long<br/>&nbsp;&nbsp;&nbsp;&nbsp;swFlags&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; As Long<br/>&nbsp;&nbsp;&nbsp;&nbsp;szExeFile&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; As String * 1024<br/>End Type<br/> <br/><br/><br/>接着在窗体中画一个Text1用来输入准备注入的dll名，外加2个Button，Command1是注入，Command2是卸载。<br/>窗体代码：<br/><br/> <br/><br/> 程序代码<br/><br/>Option Explicit<br/>&#39;dll注入程序<br/>&#39;主窗体代码<br/>&#39;<br/>&#39;蓝色炫影&nbsp;&nbsp;制作<br/>&#39;www.rekersoft.cn<br/>&#39;<br/>&#39;最后更新 2008/05/06<br/>&#39;您可以自由用于非商业用途。<br/>&#39;请保留此行版权信息，谢谢。<br/><br/>Public Sub Inject()<br/>&#39;注入子程序<br/><br/>Dim MySnapHandle&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;As Long&nbsp;&nbsp; &#39;存放进程快照句柄<br/>Dim ProcessInfo&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; As PROCESSENTRY32<br/>Dim MyRemoteProcessId&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; As Long&nbsp;&nbsp; &#39;目标进程pid<br/>Dim MyDllFileName&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; As String &#39;dll文件路径<br/>Dim MyDllFileLength&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; As Long&nbsp;&nbsp; &#39;dll文件名长度<br/>Dim MyDllFileBuffer&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; As Long&nbsp;&nbsp; &#39;写入dll文件名的内存地址<br/>Dim MyAddr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;As Long&nbsp;&nbsp; &#39;执行远程线程代码的起始地址。这里等于LoadLibraryA的地址<br/>Dim MyReturn&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;As Long<br/><br/>MySnapHandle = Cr&#101;ateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)<br/>ProcessInfo.dwSize = Len(ProcessInfo)<br/>&#39;建立进程快照<br/><br/>If Process32First(MySnapHandle, ProcessInfo) &lt;&gt; 0 Then<br/>&#39;开始遍历进程<br/>Do<br/>&nbsp;&nbsp;&nbsp;&nbsp;If InStr(ProcessInfo.szExeFile, &#34;explorer.exe&#34;) &gt; 0 Then<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;遍历进程,查找explorer.exe<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MyDllFileName = App.Path &amp; &#34;\&#34; &amp; IIf(LCase(Right(Text1, 4)) = &#34;.dll&#34;, Text1, Text1.Text &amp; &#34;.dll&#34;)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;dll文件路径<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MyDllFileLength = LenB(StrConv(MyDllFileName, vbFromUnicode)) + 1<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;这里把dll文件名从Unicode转换成Ansi，否则英文字母是2个字节。 _<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 顺便说一下，学过C的应该知道字符串要以/0标志结尾，所以dll文件名长度要加上1个字节存放Chr(0)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MyRemoteProcessId = OpenProcess(PROCESS_ALL_ACCESS, False, ProcessInfo.th32ProcessID)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;得到进程的句柄<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;If MyRemoteProcessId = 0 Then MsgBox &#34;OpenProcess Error&#34;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MyDllFileBuffer = VirtualAllocEx(MyRemoteProcessId, 0, MyDllFileLength, MEM_COMMIT, PAGE_READWRITE)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;在目标进程中申请分配一块空白内存区域。内存的起始地址保存在MyDllFileBuffer中。 _<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这块内存区域我们用来存放dll文件路径，并作为参数传递给LoadLibraryA。<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;If MyDllFileBuffer = 0 Then MsgBox &#34;VirtualAllocEx Error&#34;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MyReturn = WriteProcessMemory(MyRemoteProcessId, MyDllFileBuffer, ByVal (MyDllFileName), MyDllFileLength, 0)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;在分配出来的内存区域中写入dll路径径。注意第二个参数传递的是MyDllFileBuffer的内容， _<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 而不是MyDllFileBuffer的内存地址。<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;If MyReturn = 0 Then MsgBox &#34;WriteProcessMemory Error&#34;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MyAddr = GetProcAddress(GetModuleHandle(&#34;Kernel32&#34;), &#34;LoadLibraryA&#34;)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;得到LoadLibraryA函数的起始地址。他的参数就是我们刚才写入的dll路径。但是LoadLibraryA本身是不知道参数在哪里的。 _<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 接下来我们就用Cr&#101;ateRemoteThread函数告诉他参数放在哪里了。<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;If MyAddr = 0 Then MsgBox &#34;GetProcAddress Error&#34;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MyResult = Cr&#101;ateRemoteThread(MyRemoteProcessId, 0, 0, MyAddr, MyDllFileBuffer, 0, 0)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;好了,现在用Cr&#101;ateRemoteThread在目标进程创建一个线程，线程起始地址指向LoadLibraryA， _<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 参数就是MyDllFileBuffer中保存的dll路径。<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;If MyResult = 0 Then MsgBox &#34;error Cr&#101;ateRemoteThread&#34;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;接下来你可以使用WaitForSingleObject等待线程执行完毕。 _<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 并用GetExitCodeThread得到线程的退出代码，用来判断时候正确执行了dll中的代码。<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CloseHandle MyResult<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CloseHandle MyRemoteProcessId<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;扫地工作<br/>&nbsp;&nbsp;&nbsp;&nbsp;End If<br/>Loop While Process32Next(MySnapHandle, ProcessInfo) &lt;&gt; 0<br/>End If<br/><br/>CloseHandle MySnapHandle<br/>End Sub<br/><br/>Private Sub Command1_Click() &#39;点击注入按钮<br/>Inject &#39;执行注入<br/>End Sub<br/><br/>接下来我们讲怎么把注入进去的dll卸载掉，其实与注入基本上是一样的，只不过用到的API要换一下。<br/>我们先在目标进程当中执行GetModuleHandleA，得到我们dll的句柄，然后再远程执行FreeLibrary，把我们的dll卸载。<br/>那么这里有个问题，如何得到GetModuleHandleA的返回值呢？<br/>那就要用到WaitForSingleObject，这个函数的作用是等待远程线程执行完毕，之后我们只要调用GetExitCodeThread得到远程线程的退出码就行了。因为远程线程是调用GetModuleHandleA，所以退出码就是GetModuleHandleA的返回值。<br/><br/>代码如下：<br/><br/> <br/><br/> 程序代码<br/><br/>Private Sub Enject()<br/><br/>Dim MySnapHandle As Long<br/>Dim ProcessInfo As PROCESSENTRY32<br/>Dim MyRemoteProcessId As Long<br/>Dim MyDllFileLength As Long<br/>Dim MyDllFileBuffer As Long<br/>Dim MyReturn As Long<br/>Dim MyAddr As Long<br/>Dim MyResult As Long<br/>Dim MyDllFileName As String<br/>Dim dwHandle As Long<br/><br/>MySnapHandle = Cr&#101;ateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)<br/>ProcessInfo.dwSize = Len(ProcessInfo)<br/><br/><br/>If Process32First(MySnapHandle, ProcessInfo) &lt;&gt; 0 Then<br/>Do<br/>&nbsp;&nbsp;&nbsp;&nbsp;If InStr(ProcessInfo.szExeFile, &#34;explorer.exe&#34;) &gt; 0 Then<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MyRemoteProcessId = OpenProcess(PROCESS_ALL_ACCESS, False, ProcessInfo.th32ProcessID)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;If MyRemoteProcessId = 0 Then MsgBox &#34;error OpenProcess&#34;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MyStartAddr = GetProcAddress(GetModuleHandle(&#34;Kernel32&#34;), &#34;GetModuleHandleA&#34;)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;与注入一样,只不过这里换成了GetModuleHandleA. _<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 原理就是先在目标进程执行GetModuleHandleA得到我们的dll的地址，然后再用FreeLibrary卸载掉我们的dll。<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;If MyStartAddr = 0 Then MsgBox &#34;error GetProcAddress&#34;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MyDllFileName = IIf(LCase(Right(Text1, 4)) = &#34;.dll&#34;, Text1, Text1.Text &amp; &#34;.dll&#34;)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MyDllFileLength = LenB(StrConv(MyDllFileName, vbFromUnicode)) + 1<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MyDllFileBuffer = VirtualAllocEx(MyRemoteProcessId, 0, MyDllFileLength, MEM_COMMIT, PAGE_READWRITE)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;If MyDllFileBuffer = 0 Then MsgBox &#34;error VirtualAllocEx&#34;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MyReturn = WriteProcessMemory(MyRemoteProcessId, MyDllFileBuffer, ByVal (MyDllFileName), MyDllFileLength, temp)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;If MyReturn = 0 Then MsgBox &#34;error WriteProcessMemory&#34;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MyResult = Cr&#101;ateRemoteThread(MyRemoteProcessId, 0, 0, MyAddr, MyDllFileBuffer, 0, temp)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;都与注入一样。执行到这里就得到了<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WaitForSingleObject MyResult, INFINITE &#39;等待远程线程执行完毕。<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GetExitCodeThread MyResult, dwHandle &#39;这里可以得到远程线程的返回值，也就是GetModuleHandleA返回的我们的dll的句柄。<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;VirtualFreeEx MyRemoteProcessId, MyDllFileBuffer, MyDllFileLength, MEM_DECOMMIT<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;释放掉我们申请的内存段<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CloseHandle MyResult<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MyAddr = GetProcAddress(GetModuleHandle(&#34;Kernel32&#34;), &#34;FreeLibrary&#34;)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;If MyAddr = 0 Then MsgBox &#34;error FreeLibrary&#34;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MyResult = Cr&#101;ateRemoteThread(MyRemoteProcessId, 0, 0, MyAddr, dwHandle, 0, temp)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;这次不需要再用WriteProcessMemory写入FreeLibrary的参数了， _<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 因为我们的dll的句柄刚才已经保存在dwHandle里面了。<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;If MyResult = 0 Then MsgBox &#34;error Cr&#101;ateRemoteThread&#34;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CloseHandle MyResult<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CloseHandle MyRemoteProcessId<br/>&nbsp;&nbsp;&nbsp;&nbsp;End If<br/>Loop While Process32Next(MySnapHandle, ProcessInfo) &lt;&gt; 0<br/>End If<br/><br/><br/>CloseHandle MySnapHandle<br/><br/>End Sub<br/> <br/><br/>我们再加上几个按钮的动作，整个注入程序就完成了<br/> <br/><br/> 程序代码<br/><br/>Private Sub Command1_Click()<br/>Inject<br/>End Sub<br/><br/>Private Sub Command2_Click()<br/>Enject<br/>End Sub<br/><br/>Private Sub Form_Load()<br/>Text1 = GetSetting(App.Title, &#34;dllname&#34;, &#34;dllname&#34;)<br/>End Sub<br/><br/>Private Sub Form_Unload(Cancel As Integer)<br/>SaveSetting App.Title, &#34;dllname&#34;, &#34;dllname&#34;, Text1<br/>End Sub<br/><br/>Private Sub Text1_GotFocus()<br/>Text1.SelStart = 0<br/>Text1.SelLength = Len(Text1.Text)<br/>End Sub<br/> <br/><br/><br/>在text1里面输入想要注入的dll文件名，然后点Command1就行了。<br/><br/>明天讲注入的dll怎么写……<br/><br/>实在对不起，最近太忙了，没什么时间更新blog。<br/><br/>今天讲一下dll怎么写。<br/><br/>需要装一个vb插件：vbAdvance<br/>利用它可以让生成dll文件。<br/><br/>具体用法我就不讲了，很简单。我主要讲一下代码。<br/>由于是利用loadlibrary来注入，所以只会执行dllmain函数，然后返回<br/>因为dll不是exe，没有自己的消息循环，执行完了dllmain函数就返回了，所以我们要想个办法让他一直可以发挥作用。其实很简单，就是SetTimer和KillTimer。<br/>新建一个工程，类型选择vbAdvance提供的dll模板<br/> <br/><br/> 程序代码<br/><br/>Option Explicit<br/>Private Declare Function SetTimer Lib &#34;user32&#34; (ByVal hwnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As Long) As Long<br/>Private Declare Function KillTimer Lib &#34;user32&#34; (ByVal hwnd As Long, ByVal nIDEvent As Long) As Long<br/>Private Declare Function MessageBox Lib &#34;user32&#34; Alias &#34;MessageBoxA&#34; (ByVal hwnd As Long, ByVal lpText As String, ByVal lpCaption As String, ByVal wType As Long) As Long<br/><br/>Private Const DLL_PROCESS_ATTACH&nbsp;&nbsp;&nbsp;&nbsp;As Long = 1<br/>Private Const DLL_THREAD_ATTACH&nbsp;&nbsp;&nbsp;&nbsp; As Long = 2<br/>Private Const DLL_PROCESS_DETACH&nbsp;&nbsp;&nbsp;&nbsp;As Long = 0<br/>Private Const DLL_THREAD_DETACH&nbsp;&nbsp;&nbsp;&nbsp; As Long = 3<br/><br/>&#39;这个是Dll主函数，加载/卸载dll时会调用<br/>Public Function DllMain(ByVal hinstDLL As Long, ByVal fdwReason As Long, ByVal lpvReserved As Long) As Long<br/>Sel&#101;ct Case fdwReason<br/>&nbsp;&nbsp;&nbsp;&nbsp;Case DLL_PROCESS_ATTACH &#39;dll加载<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;RuntimeInitialize hinstDLL &#39;vbAdvance提供的初始化函数，用来初始化vb运行库。我这里没有用，这样我们就不能使用vb的函数了，都要自己实现。<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;getHandle<br/>&nbsp;&nbsp;&nbsp;&nbsp;Case DLL_PROCESS_DETACH &#39;dll卸载<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;KillTimer Handle, 1 &#39;杀掉timer<br/>End Sel&#101;ct<br/>DllMain = 1 &#39;返回true。<br/>End Function<br/><br/>Private Sub getHandle()<br/>&nbsp;&nbsp;&nbsp;&nbsp;Handle = FindWindow(&#34;Progman&#34;, &#34;Program Manager&#34;) &#39;用来得到explorer.exe的句柄，当然，你也可以用GetCurrentProcess，因为此时dll已经是explorer.exe进程的一部分了<br/>&nbsp;&nbsp;&nbsp;&nbsp;SetTimer Handle, 1, 5000, AddressOf timer1_Timer &#39;SetTimer第一个参数是进程句柄，我们把explorer句柄传进去，第二个是timer的编号，用来区分timer的。第三个是时间间隔。第四个参数是一个回调函数。我们用AddressOf操作符把timer1_Timer函数的地址传进去。这样到了我们设定的时间间隔，系统就会自动调用timer_timer<br/>End Sub<br/><br/>Public Sub timer_Timer()<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#39;这里就可以做你想做的事情了。<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#39;这个例子当中，此过程每5秒执行一次。<br/>end Sub<br/> <br/><br/><br/>另外我们可以改写默认的窗口函数，接收消息。这样我们可以利用我们的程序向被注入的进程发送消息来控制dll。<br/><br/>dll注入到此就结束了。<br/>这篇文章有点凑数了，还望海涵。<br/><br/>]]></description>
		</item>
		
			<item>
			<link>http://www.chinahacker.net/article.asp?id=107</link>
			<title><![CDATA[最简单的VB动态调用外部函数源代码（vb使用函数指针）VB use function pointer]]></title>
			<author>freeshell2002@yahoo.com(gaby)</author>
			<category><![CDATA[网文网摘]]></category>
			<pubDate>Fri,19 Mar 2010 13:56:07 +0800</pubDate>
			<guid>http://www.chinahacker.net/default.asp?id=107</guid>
		<description><![CDATA[此篇博文为<br/><a href="http://www.vbgood.com/viewthread.php?tid=69444" target="_blank" rel="external">http://www.vbgood.com/viewthread.php?tid=69444</a>&amp;extra=page%3D1<br/>的源代码<br/><br/><br/>实现思路:<br/>我是个懒人，我的目标就是干最少的活，完成最多的事情。<br/>当我看到网上那么多帖子中讨论的方法都很麻烦时，我觉得应该有更简单的办法。<br/>调用api(或者其他函数指针)其实就是call过去，我的第一反应是：<br/>建一个空的function。<br/>得到api的入口，然后复制代码，覆盖掉我的function。<br/>执行我的function就等于执行了api。<br/><br/>但仔细一想不行，很多api会jmp +xxx，这样的话，我不能保证把jmp到的代码都复制下来<br/>如果自己检测jmp，会变得很麻烦。<br/><br/>那么如果复制代码不行，那我不复制行不行？<br/>接下来很容易就想到了，为什么不改写我的function，让他直接跳转到api呢？<br/>好像可以耶~call不行，因为会有压栈动作，我这个汇编盲这点还是知道的。<br/>那么就jmp吧……最近看api hook看得太多了，经典的5个字节。<br/>jmp的好处多多，没有任何多余动作，参数完整保留到jmp目的地。<br/><br/>问题又来了，怎么才可以知道我的function在哪里呢？<br/>容易，经常用到回调函数的朋友一定知道Addressof操作符吧，它的作用就是返回函数的入口。<br/>但是vb里面是不能直接使用a=Addressof b的，必须在函数中调用。那么我们就走个弯路：<br/>a=Clng(&#34;&amp;H&#34; &amp; Hex(Addressof b))<br/>把Addressof b当作参数传给Hex函数就可以了，得到16进制，然后再用Clng转换成10进制。<br/>这样就得到了b函数的地址了。<br/>那么接下来就容易了，只要在a地址处写入5个字节就行了，具体哪五个字节其实我也不知道，<br/>我随便找了个程序，od载入一下，找了个jmp看一下16进制代码，明白了，原来是E9啊。<br/>后面4个字节容易，算一下就行了。它=目标地址-E9的地址-5。<br/><br/>好了，问题基本解决。那么参数呢？走一步算一步吧，实验对象经典的MessageBoxA<br/>4个参数。那么我就新建一个模块，输入2行代码：<br/>Public Function myFunc(ByVal a As Long = 0, ByVal b As Long = 0, ByVal c As Long = 0, ByVal d As Long = 0) As Long<br/>End Function<br/>再来个主窗口：<br/>text1=Clng(&#34;&amp;H&#34; &amp; Hex(Addressof myFunc))<br/>再来个按钮：<br/>call myFunc(0,0,0,0)<br/><br/>编译，od载入，ctrl+g到text1里显示的地址，哈哈<br/>xor eax,eax<br/>ret<br/>nop<br/>还真简单，od里at MessageBoxA，然后记下MessageBoxA的地址，<br/>返回myFunc地址，把原来的代码修改成jmp MessageBoxA-myFuc -5。<br/>回到程序里点按钮，哈哈，msgbox出现了。<br/><br/>接下来就容易了，先测试下传参数怎么样。<br/>call myFunc(me.hwnd, strptr(&#34;123&#34;),strptr(&#34;456&#34;),0)<br/>因为myFunc的原型4个参数都是byval的long,而MessageBoxA的2、3个参数是字符串指针，<br/>所以我就用strptr得到字符串的地址，然后传过去，就不会有问题了。<br/>执行一下，果然没错。<br/><br/>再来看看多个参数怎么办。我想到了Optional,这样就可以不用管参数个数了。<br/>因为如果有2个必选参数，4个Optional参数，那么你传2个参数进去，后面的4个参数因为不存在就不会压栈，<br/>如果api有3、4、5、6个参数，我只要按参数个数传就可以了，少于myFunc的参数会自动省略掉。这是我觉得最巧妙的地方,所以不会有参数数量问题<br/><br/>试验一下吧：<br/>改成<br/>Public Function myFunc(Optional ByVal a As Long = 0, Optional ByVal b As Long = 0, Optional ByVal c As Long = 0, _<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Optional ByVal d As Long = 0, Optional ByVal e As Long = 0, Optional ByVal f As Long = 0) As Long<br/><br/>End Function<br/>其他不变。。。执行一下看看，omg，成功了，哈~<br/>写上10个参数，应该可以应付任何api了吧？<br/><br/>哈哈，那么到这里原理大家都明白了吧？<br/>至于如何写入那5个字节的jmp就随意了，CopyMemory和WriteProcessMemory都可以<br/>我的程序用的是WriteProcessMemory，用起来顺手。<br/>剩下的大家就看源代码吧~实现的核心代码其实就8行<br/><img src="http://www.chinahacker.net/images/download.gif" alt="下载文件" style="margin:0px 2px -4px 0px"/> <a href="http://www.chinahacker.net/attachments/month_1003/8201031913564.rar" target="_blank">点击下载此文件</a><br/>]]></description>
		</item>
		
			<item>
			<link>http://www.chinahacker.net/article.asp?id=106</link>
			<title><![CDATA[一些Ring3下结束进程的方法.Ring3 terminate-process method]]></title>
			<author>freeshell2002@yahoo.com(gaby)</author>
			<category><![CDATA[网文网摘]]></category>
			<pubDate>Fri,19 Mar 2010 13:46:34 +0800</pubDate>
			<guid>http://www.chinahacker.net/default.asp?id=106</guid>
		<description><![CDATA[OpenProcess-&gt;TerminateProcess 这个很常用<br/><br/>OpenProcess-&gt;Cr&#101;ateRemoteThread-&gt;ExitProcess 这个比较麻烦<br/><br/>下面的大多数是用ntdll.dll中的函数了。。用来结束一些顽固进程<br/><br/>Thread32First/Thread32Next-&gt;OpenThread-&gt;TerminateThread<br/><br/>DebugActiveProcess<br/><br/>ZwOpenProcess-&gt;ZwTerminateProcess<br/><br/>ZwOpenProcess(PID+1/+2/+3)-&gt;ZwTerminateProcess<br/><br/>ZwOpenProcess-&gt;ZwProtectVirtualMemory-&gt;ZwWriteVirtualMemory<br/><br/>ZwQueryInformationProcess-&gt;ZwOpenThread-&gt;ZwTerminateThread<br/><br/>ZwQuerySystemInformation-&gt;ZwOpenProcess-&gt;ZwDuplicateHandle-&gt;ZwQueryInformationProcess-&gt;ZwTerminateProcess<br/><br/>ZwQuerySystemInformation-&gt;ZwOpenProcess-&gt;ZwDuplicateHandle-&gt;ZwQueryInformationThread-&gt;ZwTerminateThread<br/><br/>ZwQuerySystemInformation-&gt;ZwOpenProcess-&gt;ZwDuplicateHandle-&gt;ZwQueryInformationProcess-&gt;DbgUiDebugActiveProcess<br/><br/>3种经典方法：<br/><br/>PostMessage(WM_CLOSE)<br/><br/>PostMessage(WM_QUIT)<br/><br/>PostMessage(NC_DESTORY)<br/>]]></description>
		</item>
		
			<item>
			<link>http://www.chinahacker.net/article.asp?id=105</link>
			<title><![CDATA[教你自制最便宜的时光机]]></title>
			<author>freeshell2002@yahoo.com(gaby)</author>
			<category><![CDATA[网文网摘]]></category>
			<pubDate>Fri,19 Mar 2010 13:42:53 +0800</pubDate>
			<guid>http://www.chinahacker.net/default.asp?id=105</guid>
		<description><![CDATA[1、准备一张厚厚的，防水的，质量好的纸，至少要100克的，但表面不能太光滑，防止墨迹脱落。<br/><br/>2、在纸上用郑重的语气写上，给我的第N代子孙，我是你的祖先XXX，出生在XXXX年，我留下这张纸的时间是XXX年XX月XX日.........................<br/><br/>3、按照以上的基调，写完这封信，明确提出要你的子孙坐时光机回来看你。<br/><br/>4、最后别忘了说一句，“如果你们那个年代还没发明时光机，请继续封存这封信给你的子孙”<br/><br/>5、用一个绝对可靠的保险箱把这封信存起来，当然，要非常小心，保证几百上千年后你的子孙必然会看到。<br/><br/>6、如果一切顺利，几分钟之内你就可以看到你的子孙坐着时光机，轰然而来。。。 否则即可证明未来不会有时光机<br/><br/><br/>成功的朋友请在这留言。]]></description>
		</item>
		
			<item>
			<link>http://www.chinahacker.net/article.asp?id=104</link>
			<title><![CDATA[一道很黄很暴力的智力题]]></title>
			<author>freeshell2002@yahoo.com(gaby)</author>
			<category><![CDATA[网文网摘]]></category>
			<pubDate>Fri,19 Mar 2010 12:54:21 +0800</pubDate>
			<guid>http://www.chinahacker.net/default.asp?id=104</guid>
		<description><![CDATA[有这样一道智力题，感觉很有有意思，在这里写一下，呵呵。<br/><br/>两个男的两个女的都有性病。现在只有两个套套，问怎么才能让两个男的分别和两个女的搞（就是说总共要搞4次）而不交叉感染。任两个人之间有间接的XX都算要感染。套套可以重复用（就是说可以不射）。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;为了让大家理解题意，这里再说明一下传统的方法为什么是错的。如果让两个男的各套各的套，依次搞两个女的，那么两个女的就要交叉感染，因为同一个套套接触过两个女的。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;答案在下面，白的。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;让第一个男的同时戴两个套套（这样很爽的:-) ），把第一个女的干了，然后把外面那层套套取出来给第二个男的戴上，让第二个男的也把第一个女的搞了；第一个男的接着（用他里面那个套套）把剩下的那个MM做了，然后把套套取下来给第二个男的套在外面（第二个男的就套了两个套了），让第二个男的搞第二个女的。<br/>]]></description>
		</item>
		
			<item>
			<link>http://www.chinahacker.net/article.asp?id=102</link>
			<title><![CDATA[Freeiris-老杨语录]]></title>
			<author>freeshell2002@yahoo.com(gaby)</author>
			<category><![CDATA[网文网摘]]></category>
			<pubDate>Wed,10 Feb 2010 18:49:13 +0800</pubDate>
			<guid>http://www.chinahacker.net/default.asp?id=102</guid>
		<description><![CDATA[人生最重要的不是所在的位置，而是所朝的方向。同样是个B，你一路向北能变成NB，撞破南墙不回头，就只能当个SB。]]></description>
		</item>
		
			<item>
			<link>http://www.chinahacker.net/article.asp?id=101</link>
			<title><![CDATA[squid 2.7 通过域名反向代理多个服务器配置成功[转]]]></title>
			<author>freeshell2002@yahoo.com(gaby)</author>
			<category><![CDATA[网文网摘]]></category>
			<pubDate>Tue,02 Feb 2010 12:23:38 +0800</pubDate>
			<guid>http://www.chinahacker.net/default.asp?id=101</guid>
		<description><![CDATA[visible_hostname squid1.abc.com<br/><br/>#设定squid的主机名,如无此项squid将无法启动<br/><br/>http_port 80 accel vhost vport<br/><br/>#设定squid为accel加速模式,vhost必须要加.否则将无法将主机头转发至后端服务器,访问时就会出现无法找到主机头的错误<br/><br/>cache_peer 192.168.1.88 parent 80 0 no-query o&#114;iginserver name=contentchina<br/><br/>cache_peer 192.168.1.88 parent 80 0 no-query o&#114;iginserver name=bbs<br/><br/>cache_peer 192.168.1.1 parent 80 0 no-query o&#114;iginserver name=ihompy<br/><br/>#定义不同的父节点,将节点设为no-query以及originserver说明这些节点是实际服务器<br/><br/>cache_peer_domain contentchina aaa.abc.com<br/><br/>cache_peer_domain bbs bbb.abc.com<br/><br/>cache_peer_domain ihompy ccc.abc.com<br/><br/>#设定不同域名转发到不同的cache_peer上,如果没有这项.不同域名的域名可能被分发到同一台服务器上.<br/><br/>acl all src 0.0.0.0/0.0.0.0<br/><br/>no_cache deny all<br/><br/>http_access allow all<br/><br/>#允许所有客户端访问<br/><br/>cache_log /var/log/squid/cache.log<br/><br/>#记录日志<br/><br/>#***********ACL存取控制*************<br/><br/>#acl QueryString url_regex .php?<br/><br/>#***********缓冲存取控制*************<br/><br/>#no_cache deny QueryString<br/><br/>#不对符合QueryString的ACL内容进行缓冲<br/><br/>#***********性能优化配置*************<br/><br/>maximum_object_size 320010 KB<br/><br/>#大于此容量的对象将不会被保存在磁盘上,默认大小是4M,如果squid服务器用于缓冲flash等大型文件,建议将此值变大.否则过大的文件在下次重启后将需要重新获取<br/><br/>maximum_object_size_in_memory 100 KB<br/><br/>#最大位于内存中的对象的大小,默认大小是8K,如果服务器内存很大.可以适当提高此值的大小,建议根据网站的80%图片的大小来定.或者根据WEB服务器实际存取文件中最常访问的文件大小来定制<br/><br/>#***********其他可选配置*************<br/><br/>#dns_nameservers 10.0.0.1 192.172.0.4<br/><br/>#配置DNS服务器地址.获取后端时将从此dns获取IP地址<br/><br/>#cache_mgr ggg_g@tom.com<br/><br/>#在错误日志中出现的webmaster地址.]]></description>
		</item>
		
			<item>
			<link>http://www.chinahacker.net/article.asp?id=100</link>
			<title><![CDATA[双刀客转(转)]]></title>
			<author>freeshell2002@yahoo.com(gaby)</author>
			<category><![CDATA[经典语录]]></category>
			<pubDate>Fri,29 Jan 2010 22:32:38 +0800</pubDate>
			<guid>http://www.chinahacker.net/default.asp?id=100</guid>
		<description><![CDATA[内裤双刀客,八桂人士也，生卒年不详。貌奇异，体雄健，性侠勇，常手持两把大刀，重四五十斤许，人谓之奇。常游历于粤桂一带，独行君子之德，义不苟合当世，其言必信，其行必果，已诺必诚，不爱其躯，赴士之厄困，诚有古时荆轲壮士侠客之遗风。<br/>己丑年，客过闽粤，不冠不袜，以山寨安踏运动衣裹身，身携除亥双刀，一物无所持，与人罕言语。时闽粤一带无良商人、资本家颇多，且与官府勾结，结为朋党，设厂役贫，豪暴侵凌孤弱，恣欲自快。<br/>初，客受役于某厂谋生计。其厂主多行克扣，横征暴敛，厂内尘土飞扬，几不识人面。某日，客感胸口闷热，偶有咳嗽，未几，疾益重，日咳血斗升。遂前往就医，有良医扁鹊曰，君有疾在心肺间，或曰尘肺，不治命将休矣。客大惊，问其故。医者曰：“君是否谋事于血汗工厂也？”客答然也。医者曰：“此为获疾之故耳。若要痊愈而归，请付医疗费一万余也。”客愤然曰：“某效颜回，一箪食，一瓢饮，在陋巷，何此多金焉，此天亡我也。”医者曰：“君勿忧，有工伤保险可也。”遂授秘技。<br/>客自以为得计，前往劳动局索金。某官曰，不可，请往疾控所诊疗再来。客遂往疾控所，所内人曰，不可，需劳动保险者得焉。客复往劳动局。如此三番，客不胜其力，疾益重矣，日咳血三升。然苦心人，天不负，某日终得劳动局证明。疾控所检查完曰，此非尘肺也，乃风寒感冒，请回家自愈之。一语鄂然。客不服，遂去医院要求开胸验肺，苦劝不止。验之果尘肺也。客以此向某厂索赔。厂主支吾以对，告之曰，请走司法程序也。去法院，某法官曰，此案不予受理，请先予以劳动裁决。遂再遣回劳动局。<br/>交困之际，适某商家促销，客购三鹿奶粉若干饮用。未几，下腹不适。再前往就医，扁鹊摇头叹息曰，难兮，有石大如斗在君之肾也，若非君天生神力，早命丧黄泉。<br/>是夜，客回住所，遥闻泣声不绝，疾往视之，见数工友相掩面而泣，问之，答焉，今工厂爆炸事故，梁柱皆塌，众工友十之二三陷其内，恐不复还矣；所幸逃回者，手脚皆断；然厂主欲瞒其事故，不许就医，以打手围困，故此痛哭耳。<br/>客闻之，皆瞋目，发尽上指冠，怒曰：“匹夫欺我甚矣！吾尝十步杀一人，千里不留行，何受此辱，待我手刃仇敌，为之报仇，纵死侠骨香，不惭世上英。”<br/>次日，客饱食轻装，着短裤风衣，血脉賁张，持除亥双刀，独行于猎猎寒风中。至工厂前，大呼挥刀，厂主蜷缩于办公室，众小蜜芳颜失色，作鸟兽散，惟其双股战战，屎尿齐出。<br/>顷之，若干警力四面蜂拥而至，客大呼驰下，警皆披靡，望风而走。是时，某警追客，客嗔目而叱之，警心惊胆寒，枪棒坠地，辟易数里。客含笑独行，警复围之。客曰：“吾自幼游历至今，抚双刀，一扬眉，身经无数战，所当者破，所击者服，未尝败北，然今受困于此，天亡我也。”遂点烟长叹----<br/>我自横刀向天笑，<br/>去留肝胆两昆仑。<br/>人生自古谁无死，<br/>留取丹心照汗青。<br/>当是时，草木为之动容，天地为之含悲，闻者无不流涕。<br/>悲哉，哀哉，痛哉！昔荆轲刺秦于殿上，感恩也；韩信受辱于胯下，志远也；岳飞刺字于背间，尽忠也；今内裤双刀客擒于井市，时局也。<br/>自此以后，内裤双刀客绝矣。吾深感其义，遂作文已志之。己丑年冬岁。<br/><br/><img src="http://www.chinahacker.net/attachments/month_1001/z201012922322.jpg" border="0" alt=""/><br/><br/><img src="http://www.chinahacker.net/attachments/month_1001/42010129223214.jpg" border="0" alt=""/><br/><img src="http://www.chinahacker.net/attachments/month_1001/12010129223225.jpg" border="0" alt=""/><br/><img src="http://www.chinahacker.net/attachments/month_1001/d2010129223234.jpg" border="0" alt=""/><br/>]]></description>
		</item>
		
			<item>
			<link>http://www.chinahacker.net/article.asp?id=99</link>
			<title><![CDATA[squid.conf 详细解释]]></title>
			<author>freeshell2002@yahoo.com(gaby)</author>
			<category><![CDATA[网文网摘]]></category>
			<pubDate>Wed,20 Jan 2010 07:41:14 +0800</pubDate>
			<guid>http://www.chinahacker.net/default.asp?id=99</guid>
		<description><![CDATA[squid.conf -- 初级篇<br/>在这个初级篇中,只是要提醒几个设定重点,只要把这个设定好了,你就可以启动<br/>squid了.当然这只是squid的一部分而已,要做最佳化那就有得努力了.<br/>先写在前面,若在各选项中,若某一设定行前面有 &#34; # &#34;,那代表这是默认值.也就<br/>是说除非uncomment及更动内容, 否则squid在启动时会以此来默认值来准.<br/>1. 浏览器连接proxy时,所使用的port.<br/>#http_port 3128<br/>http_port 8080<br/>2. sibling连接本proxy时,所使用的port.<br/>#icp_port 3130<br/>icp_port 3130<br/>3. 设定local_domain &amp; local_ip:目的在于欲联机的server若在此范围内的,就不透<br/>过sibling或parent.(请配合stoplist使用,可减少硬盘使用空间)<br/># local_domain my.domain<br/>local_domain ym.edu.tw<br/>#local_ip IP/netmask<br/>local_ip 140.129.51.0/255.255.255.0<br/>local_ip 140.129.52.0/255.255.248.0<br/>local_ip 140.129.64.0/255.255.240.0<br/>local_ip 140.129.80.0/255.255.255.0<br/>4. 设定squid可利用多少内存来cache 数据在mem中.如果是新手,我会建议将此值<br/>设为通常是物理内存的1/3.<br/>如现在我有64MB RAM,我就设为20M.这个只是用来cache data, squid为了要正常<br/>运作,通常会在多吃些内存,以我现在的/cache中有600MB,squid大概吃了31M,<br/>所以请将此值设为物理内存的1/3,否则可能会使得squid可能会因为要不到多的<br/>内存而一直挂点,然后又重新启动,甚至当机.<br/>#cache_mem 8<br/>cache_mem 20<br/>5. /usr/local/squid/cache可以有多大,也就是指可以在硬盘中存放多少MB的东西.<br/>在此,我把它改为1024MB,也就是1GB.<br/>#cache_swap 100<br/>cache_swap 1024<br/>6. 这个log 档通常没用,可以不要它.请在目录位置改为none.<br/>#cache_store_log /usr/local/squid/logs/store.log<br/>cache_store_log none<br/>7. 资料保存多久.在此为一笔已在cache中的资料,若一个礼拜内没人再来access,<br/>则这笔资料会被清掉<br/>#reference_age 1 year<br/>reference_age 7 days<br/>8. 当squid挂点后,要mail给squid.<br/>#cache_mgr webmaster<br/>cache_mgr squid<br/>9. 若由root来启动squid,那要变成谁的身分来执行.<br/># UID GID<br/>#cache_effective_user nobody nogroup<br/>cache_effective_user squid squid<br/>10. Stoplist:<br/>1) hierarchy_stoplist<br/>如果在URL中出现以下的字样,则本机proxy不会向parent o&#114; sibling做查询,<br/>而是直接处理.(默认值为cgi-bin 及 ? ;在下面的例子,多加了个cgi)<br/>#hierarchy_stoplist cgi-bin ?<br/>hierarchy_stoplist cgi-bin ? cgi<br/>2) cache_stoplist<br/>用途在于,如果在URL中含有以下的字符,则不将它留在cache中,而是立即清掉.<br/>除了可以滤掉一些不想存在硬盘中的垃圾外,我们还是也可以利用这个以确保<br/>我们所在网域的其它主机档案不会留在proxy server中.<br/>(在下面的例子中,我将阳明大学的domain及可能的IP address列为stoploist)<br/>#cache_stoplist cgi-bin ?<br/>cache_stoplist cgi-bin ? cgi<br/>cache_stoplist ym.edu.tw<br/>cache_stoplist 140.129.51 140.129.6 140.129.7 140.129.80<br/>==================================================================<br/>squid.conf -- Cache Hierarchies<br/>==================================================================<br/>说文解字: hierarchy :阶级的意思!!<br/>Cache hierarchies也就是说把proxy server搞出一个阶级制度.怎么说呢??<br/>Parent<br/>/ |<br/>/ |<br/>sibling -- machine A<br/>| |<br/>| |<br/>Browser Browser<br/>以上是个简图,这只是阶级构造中的一小部分而已,可以由它再去组成广大的网状图.<br/>1) 当machine A 收到 browser的要求时,它会检视自己的cache中是否有browser所<br/>要的档案,如果有且是&#34;质量优良&#34;的,则machine A会直接把这个档案送回给browser.<br/>若在machine A的cache中没有这个档或这个档已经过期,那它会送出含有URL的UDP<br/>封包给它的silbling &amp; parent.<br/>2) 当machine A的sibling收到这个封包后,它也会去检视它自己有无这个档,若有则<br/>向machine A回说: &#34;我有!你过来抓吧!!&#34; 若没有,他就会说: &#34; Sorry, I can&#39;t<br/>help you!&#34;<br/>3) 同样的,parent到目前为止所做的事跟sibling一模一样.<br/>4) 若所要的档案有人响应该说,&#34;我有!&#34; 那machine A会在收到通知后,立刻去那里抓档.<br/>但如果在一定的时间内(默认值是2 sec),没人回说&#34;我有!&#34;,那machine A这时怎么办<br/>呢??? Machine A它会去找出刚刚是哪一个parent最早回&#34;我没有&#34;,于是就请它帮忙<br/>抓档回来.<br/>5) 看到没,我开始点出parent跟sibling的不一样了.parent的意思就是,你在亲朋好友间<br/>得不到协助,那你跟我说,我就去帮抓档.于是parent开始重复machine A做过的事,<br/>check silbing &amp; parent有没有资料,有就抓回来给machine A,没有的话,看是要自己<br/>去抓或者是再透过parent.<br/>6) 看了第五点,你应该就会知道在阶层中设太多的层,或多层间上下相互query,其实说不<br/>定不会省下频宽,反而可能会加重主机及网络的负担.所以正确地设定parent &amp;<br/>sibling很重要,不要一拿到全部proxy server列表就全部都设上去.这是很危险的.<br/>&gt;--------------------------------------------------------------------------&lt;<br/>#cache_host hostname type 3128 3130<br/>cache_host 140.111.1.52 parent 3128 3130 [default][no-query]<br/>cache_host proxy.ee.ntu.edu.tw sibling 3128 3130 [proxy-only]<br/>cache_host proxy.ncu.edu.tw sibling 3128 3130<br/>cache_host proxy.csie.ncu.edu.tw sibling 8080 3130<br/>cache_host proxyftp.csie.ncu.edu.tw sibling 3128 3130<br/>cache_host 140.111.1.2 sibling 3128 3130<br/>这是一般设定方法.在parent的后面可以接一些参数,详请请见squid.conf说明,不过会用<br/>到的机会不多.而sibling后面可以接proxy-only,这代表东西取回来后,不存下来,这样<br/>可以省下硬盘空间.但除非你的硬盘太少或者是与对方网络够快,否则没有必要这样设.<br/>cache_host_domain 140.111.1.52 !.tw !hinet.net<br/>cache_host_domain 140.129.56.251 .tw<br/>这是是用来规范那些domain的数据要跟谁问,或者不跟谁问.<br/>像cache_host_domain 140.111.1.52 !.tw !hinet.net代表只要是.tw o&#114; hinet.net结<br/>尾的,就不向140.111.1.52这台主机查询.<br/>==================================================================<br/>squid.conf -- Access controls<br/>==================================================================<br/>Access control,顾名思义,就是要控制联机.这里的学问也不小,我先就几个比较重要的<br/>来解释,其余的部分希望有人可以帮忙补充,或者过几天我再post.<br/>我个人&#34;私自&#34;把这个部分拆成两个部分,一个是&#34;定义群组&#34;,另一则为 &#34;access rule&#34;.(<br/>名字自己取的).<br/>1) 定义群组:<br/>在squid.conf中,已经有几个预先建立的群组.我们先来看看.<br/>#acl aclname acltype string/file<br/>------------------------------------------------<br/>acl manager proto cache_object<br/>acl localhost src 127.0.0.1/255.255.255.255<br/>acl all src 0.0.0.0/0.0.0.0<br/>acl SSL_ports port 443 563<br/>acl Dangerous_ports port 7 9 19<br/>acl CONNECT method CONNECT<br/>----------------------------------------------------<br/>常用的是只有前三个.后三者,请不要移除!<br/>在定rule时,以acl 关键词起始.第二栏就自己取个好记的名字,第三栏<br/>是你要定义的东西是什么的项目.第四栏就是就依第三栏而变,如果第三<br/>栏是port的话,就在此打port;如果是src的话,就打ip/netmask.<br/>以我的设定档为例,我就多加了五个定义项目.<br/>acl hint src 140.129.51.0/255.255.255.0<br/>acl school src 140.129.52.0/255.255.252.0<br/>acl dorm src 140.129.56.0/255.255.248.0<br/>acl teaching src 140.129.64.0/255.255.240.0<br/>acl dialup src 140.129.80.0/255.255.255.0<br/>2) Access rule:<br/>以下为预设rule:<br/>-------------------------------------------------------------------------<br/># Only allow access to the cache manager functions from the local host.<br/>http_access deny manager !localhost<br/>http_access deny CONNECT !SSL_ports<br/>http_access deny Dangerous_ports<br/># Allow everything else<br/>http_access allow all<br/># Reply to all ICP queries we receive<br/>icp_access allow all<br/>--------------------------------------------------------------------------<br/>这些rules的比对,是从上而下的,先对的,先赢!!举个例子来说,你想挡掉所有的http<br/>access,要怎么写呢???<br/>(A) http_access allow all<br/>http_access deny all<br/>(B) http_access deny all<br/>http_access allow all<br/>答案是(B),因为若设为A,那所有联机在第一个rule时都被允许通过了,哪轮到第二个<br/>rule来对呢!<br/>这个东西都常被拿来用的地方是,你的proxy server开放给谁做http_access,如只有校<br/>内.像我们这个烂学校,拿台IDE HD的计算机叫我架proxy,我只好忍痛把icp_access全部<br/>拿掉.以下是我的部分设定档.<br/># Allow everything else<br/>#http_access allow all<br/>http_access deny all !hint !school !dorm !dialup !teaching<br/>#hint, school,dorm,dialup.teaching,已经在第一点中就定义了,别忘了!!<br/># Reply to all ICP queries we receive<br/>icp_access deny all<br/>固定的是 DS、OS &amp; NO, <br/>L1 &amp; L2 指的是第一层、第二层目录，则是未知数<br/>DS 指的是 disk space, OS 指的是平均每个档案的大小<br/>而 NO 指的是一个目录内的档案数量.<br/>写成 L1*L2*OS*NO=DS 会比较容易懂一点...<br/>最好是留多一点，这样临时如果加大 space 的话才不需要再额外调整目录的数量.<br/>------------------------------------------------------------------------------<br/>Proxy 与 Proxy 它们之间的check是有一个叫 ICP (Internet caching Protocol)<br/>的协议 如果 hit 那就以 http 的协议传到另一台 Proxy Server<br/>如果 miss 它会传回 miss 的讯息<br/><br/>squid.conf设定<br/><br/>squid.conf设定档一样是以「#」为批注，有些设定前面有「#」，代表是默认值。也就是说除非去掉「#」并更动内容，否则squid会以默认值来启动。由于squid.conf的设定不少，且squid.conf对每个设定都有批注，以下只针对重要的设定来作说明，而没有提到的，通常使用默认值即可。关于squid.conf的设定范例，您可参考<a href="http://www.twnic.net/proxy/squid.conf" target="_blank" rel="external">http://www.twnic.net/proxy/squid.conf</a>，再配合以下讲解，修改从光盘中复制的squid.conf设定档，改成适合自己Proxy Server的设定档。 <br/>#http_port 3128 <br/>#icp_port 3130 <br/>icp protocol是用来询问Proxy Server有没有它需要的数据，http protocol则是 用来取回所需的Cache资料。两者分别需要一个埠号，与其它机器沟通。建议采默认值即可，除非有特别需求，才去更改。 <br/>Cache_host cache.tmtc.edu.tw sibling 3128 3130 proxy-only <br/>语法：cache_host hostname type http_port icp_port option <br/>type：最常用的当然是parent或sibling <br/>option：此选项常用到的是proxy-only、no-query、default、round-robin <br/>等等。 <br/>proxy-only选项说明： <br/>Cache_host cache.tmtc.edu.tw sibling 3128 3130 proxy-only <br/>以上的范例是设定cache.tmtc.edu.tw当我们的Proxy Server而cache.tmtc.edu.tw的http_port为3128 icp_port为3130。proxy-only表示从cache.tmtc.edu.tw Cache来的数据，不在自己的Proxy中储存起来。除非自己Proxy Server的Cache硬盘空间很小，或者与此Proxy Server的网络连接速度很快(例如在同个局域网络中)，否则通常不用proxy-only这个选项。 <br/>default选项说明： <br/>cache_host proxy.ntu.edu.tw parent 3128 3130 default <br/>用在parent上，继续丢出ICP Request，重复Proxy Server之间的Cache查询动作。 <br/>round-robin选项说明： <br/>cache_host cacheA parent 3128 3130 round-robin no-query <br/>cache_host cacheB parent 3128 3130 round-robin no-query <br/>如有多个Parent Proxy Server则可使用这个选项，与选项作用相似，但是 会对Parent Proxy Server轮流送出需求。例如：这次找A Parent Proxy，下次找B Parent Proxy。 <br/>no-query选项说明： <br/>不送ICP查询出去，直接由http protocol取回数据。我们常将no-query配合上default、round-robin来使用。通常只有一个Parent Proxy Server的设定为default no-query，而多个Parent Proxy Server则使用round-robin no-query。 <br/>cache_host_domain proxy.ntu.edu.tw !.ntu.edu.tw <br/>语法：Cache_host_domain cache [!]domain <br/>说明：Proxy Server通常不去Cache自己Domain里的数据，所以底下的设定意义为：我们的Proxy Server接到Client端的需求，而这个需求不是ntu.edu.tw Domain(台大)的资料时，才会送ICP query过去。因为即使送ICP过去询问也是白费功夫。 <br/>cache_host_domain cache.jwindow.net .jp <br/>设定说明：由于cache.jwindow.net有丰富的日本网页资料。所以我们也当然可以设定，只要有「.jp」Domain的数据需求，就往cache.jwindow.net送request。 <br/>cache_host proxy.ntu.edu.tw parent 3128 3130 default <br/>cache_host_domain proxy.ntu.edu.tw !.ntu.edu.tw <br/>neighbor_type_domain proxy.ntu.edu.tw sibling .com <br/>语法：neighbor_type_domain cache parent|sibling domain.. <br/>说明：可用来改变一些parent或sibling的规则，例如以下设定proxy.ntu.edu.tw为我们的parent，可替我们抓取除了.com之外的数据。就是设定了neighbor_type_domain，造成当需要www.ibm.com的资料时，只能靠自己去取回，因为此时proxy.ntu.edu.tw只能为sibling。 <br/><br/>acl acl 名称 src ip-address/netmask 说明 : 使用src这种ACL类型，后面必须为Client端的IP-Address范围 / 网络屏蔽(或为 CIDR格式)。请注意，「src」乃是 针对Client端的IP Address来分类，但对主机名 称无效。所以如果想针对Client端的Domain Name来分类，则要使用 「srcdomain」。 <br/>举例: <br/>acl 1ocal src l27.0.0.1/32 140.131.41.0/255.255.255.0 <br/>→将127.0.0.l这个loop back lP与一个140.131.41.O的Class C IP器，归为local群组。 <br/>acl mydomain srcdomain tmtc.edu.tw <br/><br/>→设定所有以tmtc.edu.tw结尾的机器，皆属于my domain的ACL群组。 <br/>说明：我们也可以设定拒绝无reverse domain name的机器(即 <br/>查Domain Name。登入不完全)，将这些机器归为一类，以 <br/>便稍后作「进一步处理」。设定方法如下: <br/><br/>acl nodns srcdomain none <br/>ad my_url url_regex ^<a href="http://www.tmtc.edu.tw/" target="_blank" rel="external">http://www.tmtc.edu.tw/</a> <br/><br/>→设定只要发出<a href="http://www.tmtc.edu.tw" target="_blank" rel="external">http://www.tmtc.edu.tw</a>需求的Client，就属于名myu_url的ACL群组。 <br/>说明： 底下的设定为系统预设定义的ACL，大抵上无须更动。 <br/><br/>acl all src O.0.0.0/0.0.0.0 <br/><br/>→将所有的IP Address分类归属为 all。 <br/><br/>acl manager proto cache_object <br/>acl SSL_ports port 443 563 <br/>acl Dangerous_ports port 7 9 19 <br/>acl CONNECT method CONNECT <br/><br/>· 针对自己所定义的ACL群组，进行权限设定: <br/>http_access deny CONNECT ISSL_ports <br/>→这个设定为刚才定义的CONNECT群组与「非」SSL_ports群组，都不能进行 <br/>http_access 。请注意惊叹号「!」，代表「除了…之外的设定值，有些状况就很 <br/>适合使用「!」，所以要能够灵活运用。 <br/>http_access deny Dangerous_ports <br/>http_access deny nodns <br/>→拒绝nodns群组进行http_access，即reverse domain name登入不全的机器，无法使用 <br/>我们的Proxy，进行http的object存取。 <br/>http_access allow my＿url <br/>http_access allow local <br/>http_access allow mydomain <br/>http_access deny all <br/><br/>☆注意： <br/><br/>ACL的权限设定有First match的特性，也就是说只要联机的Client端，符合第一个 <br/>权 限 设定，就跳开并依据遵守最先符合的权限设定。 <br/><br/>针对以上First match的特性，兹举以下设定，让读者了解： <br/>http_access deny all <br/>http_access allow local <br/>如此一来所有的http_access均会被拒绝，并不会只允许「local」的ACL群组，进行 <br/>http access <br/>说明：当您把多项所定义的ACL群组写在同一行的http_access <br/>设定时，要特别小心。因为同一行的http_access设定, ，会作AND逻辑 运 <br/>算，所以底下的范例将无效。 <br/><br/>acl ME src lO.0.0.l <br/>acl YOU src lO.0.0.2 <br/>http_access allow ME YOU <br/><br/>因为没有一个IP可以同时符合ME这个ACL与YOU这个ACL，所以分开写就没 <br/>问题啦!如下: <br/>http_access allow ME <br/>http_access allow YOU <br/>因此底下的http_access设定，最好分成两行。 <br/>http_access allow local mydomain <br/><br/>icp_access allow local <br/>icp_access allow mydomain <br/>icp_access deny all <br/><br/>说明：底下的icp_access权限设定与http_access相同，一样要注意「Firstmatch」，与 <br/>设定值是否写在同一列是否冲突等问题。不同的是icp_access用来设定，是 <br/>否要响应别人的ICP询问。 <br/>miss_access allow mydomain <br/>miss_access deny !mydomain <br/>说明：还记得要当别人的Parent，必须负起帮它取回，它所需要的数据，所以这负 <br/>担比较重。因此可以利用「miss_access」的权限设定，而不接受别人来乱认 <br/>「父母」(Parent)，顶多当他的邻居(Neighbor)或姊妺(sibling)，加减帮一些 <br/>忙，以免造成系统负荷过重，严重影响原系统功能。底下设定只有属于 <br/>mydomain的ACL群组才可以认我当「父母」，获得chlid_parent关系承认并受 <br/>到「扶养」。 <br/>cache_host_acl proxy.ntu.edu.tw !twdn !twip <br/>语法：cache_host_acl cache-host [!]aclname <br/>说明：这个设定有点像&#39;cache_host_domain，但是因为使用ACL因此更具弹性假如有 <br/>任何 「非」台湾的URL的存取需求，我们只把这些需求送往指定位于台湾 <br/>内的 Proxy Server，而都不急着送出台湾外去查询，以免浪费频宽。如要达 <br/>到此设定的目的，便可藉由cache_host_acl来做到，举例说明如下: <br/><br/>1﹒先用 ACL 定义出哪些是台湾的URL的需求 ，如果用domain来 设定，则acl类 <br/>型 须用「dstdomain」;如果要设定IP部份则 使用「dst」。特别注意，厎下 <br/>「twdn」与「dst」这两个 ACL，要各自写成一行。笔者因为排版的关系无法 <br/>写成一行。 <br/><br/>acl twdn dstdomain tw twnic.net hinet.net acer.net <br/>wownet.net seeder.net silkera.net neto.net timenet.net tw.aunef.net <br/>acl twip dst 140.96.0.0/11 140.128.0.0/12 140.92.0.0 139.175.0.0/16 139.223.0.0/16 163.12.0.0/14 163.16.0.0/14 168.95.0.0/16 192.72.0.0/16 192.83.160.0/19 192.83.192.0/22 192.192.0.0/16 202.39.0.0/16 202.132.128.0/17 202.145.224.0/19 203.64.0.0/12 210.64.0.0/13 <br/>2. 开始设定cache_host_acl指定Proxy Server： <br/>设定范例如下，意思是说如果有任何「非」台湾地区URL的需求(包括Domain <br/>Server形式或IP形式)，就转往proxy.ntu.edu.tw寻求协助。您可以多找几个Cache资 <br/>料丰富又邻近的Proxy Server，依样画葫芦。 <br/><br/><br/>· 接下来设定一些管理方面的参数 <br/>cache_mgr squid@proxy.tmtc.edu.tw <br/>→设定Proxy Server管理者的E-mail，方便他人联系。 <br/>语法 : cache_effective_user UserID GroupID <br/>说明：假如是由root启动squid，那么一些squid相关的Process的拥有者、拥有群组 <br/>，便是Cache_effeCtive_user所设定的。为了方便起见(但并非最好)，们将设 <br/>定改为Proxy管理者的UserID与GroupID: <br/>cache_effective_user squid squid <br/>visible＿hostname proxy.tmte.edu.tw <br/>→当别人使用您的Proxy Server而出现错误讯息时，将显示所设定的visible_hostname <br/>说明 : 厎下的设定是向sd.cache.nlanr.net注册，宣告我们也使用Squid Proxy Server <br/>。假 如您 不想对外宣告，那么就把「cache_announce 24」给mark起来。 <br/>cache_announce 24 <br/>announce_to sd.cache.nlanr.net:3131 <br/>dns_testname ns.tmtc.edutw ns2.tmtc.edu.tw dnS.ntu.edu.tw <br/>→将一些较近的DNS(Domain Name Server)设定进去，越快可以得到DNS查询响应的 <br/>位置较前面。 <br/>说明 : 假如一天下来，log记录文件很大，或想要细分log檔，那就把logfile_rotate设大 <br/>一 点，请自行视情况调整。以 cache.log档来说:设定「logfile_rotate l」，会 <br/>把 旧的 log更名为cache.log.O储存，而新的log则存在cache.log。 <br/>logfile_rotate l <br/><br/>append_domain tmtc.edu.tw <br/>→替换成您的Domain Zone即可。 <br/>还有一些没捉到的部份使用默认值即可，另外有些设定将还会有机会再捉 <br/>到。现在已经把Squid.conf的设定大抵完成，可先暂告一段，继续进行安装 <br/>Squid Proxy Server。 <br/>]]></description>
		</item>
		
</channel>
</rss>
