• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

加壳原理与简单实现加壳(delphi源码)

原作者: [db:作者] 来自: [db:来源] 收藏 邀请
{*****************************************************************
AddShell()源自于前一段时间有写的addsection()新增区段代码,
在增加区段代码的基础上,追加了
1.修改启动入口点位置
2.增加一段壳头xor $50的代码function AttachStart-function AttachEnd
这一段代码是先填充,再被修改成合适原EXE的壳头
3.修改原启动代码入口点所在区段的段属性可写并进行xor $50运算加密


不支持addshell()处理已经过addshell的exe
*****************************************************************}  
  
unit Unit1;    
  
interface  
  
uses    
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,    
  Dialogs, StdCtrls;    
  
type    
  TForm1 = class(TForm)    
    Button1: TButton;    
    Edit1: TEdit;    
    Button2: TButton;    
    Button3: TButton;    
    procedure Button1Click(Sender: TObject);    
    procedure Button3Click(Sender: TObject);    
    procedure Button2Click(Sender: TObject);    
  private  
    { Private declarations }    
  public  
    { Public declarations }    
  end;    
  
var  
  Form1             : TForm1;    
  
implementation    
  
{$R *.dfm}    
function AttachStart: dword; stdcall;   //我们定义的待填充数据    
asm    
       pushfd    
       pushad    
       mov eax,$12345678      //将会被自动计算并修改为加密初始地址    
       mov ebx,$1234          //将会被自动计算并修改为加密大小    
       mov ecx,0    
       @AA:    
       xor byte ptr[eax],$50  
       inc eax    
       inc ecx    
       cmp ecx,ebx    
       jbe @aa    
       popad    
       popfd    
       push $12345678        //将会被自动计算并修改为原OEP    
       ret    
end;    
  
function AttachEnd: dword; stdcall;    
begin    
end;    
  
{-------------------------增加区块并实现简易加壳--------------------------------}    
procedure AddShell(lFileName: string; lBackup: boolean); //打开exe文件,是否备份    
var  
  hFile             : THandle;          //文件句柄    
  ImageDosHeader    : IMAGE_DOS_HEADER; //DOS部首    
  ImageNtHeaders    : IMAGE_NT_HEADERS; //映象头    
  ImageSectionHeader: IMAGE_SECTION_HEADER; //块表    
  lPointerToRawData : dword;            //指向文件中的偏移    
  lVirtualAddress   : dword;            //指向内存中的偏移    
  i                 : integer;          //循环变量    
  BytesRead, ByteSWrite: Cardinal;      //读写用参数    
  AttachSize        : dword;            //附加段大小    
  AttachData, ChangeData: integer;      //附加段填充数据    
  OEP               : integer;          //使用过程中用到的EP    
  lpBuffer          : array[0..1024 * 400] of byte; {待加密数据存储缓冲区}    
  nNumberOfBytesToRead, lpNumberOfBytesRead: dword; //加密时用到的一些数据    
  StartEN, SizeEN, StartCr: dword;      //加密用的开始物理地址和大小    
begin    
  
  //定义附加段填充数据    
  AttachData := 0;    
  
  //打开文件    
  hFile := CreateFile(PChar(lFileName), GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);    
  
  //校验    
  if hFile = INVALID_HANDLE_VALUE then    
  begin    
    ShowMessage(\'打开文件失败\');    
    exit;    
  end;    
  
  //确认备份    
  if lBackup then CopyFile(PChar(lFileName), PChar(lFileName + \'.bak\'), False);    
  try    
  
    //读取DOS部首到ImageDosHeader    
    ReadFile(hFile, ImageDosHeader, SizeOf(ImageDosHeader), BytesRead, nil);    
  
    //校验    
    if ImageDosHeader.e_magic <> IMAGE_DOS_SIGNATURE then    
    begin    
      ShowMessage(\'不是有效的PE文件!\');    
      exit;    
    end;    
  
    //指向映象头    
    SetFilePointer(hFile, ImageDosHeader._lfanew, nil, FILE_BEGIN);    
  
    //读取映向头到ImageNtHeaders    
    ReadFile(hFile, ImageNtHeaders, SizeOf(ImageNtHeaders), BytesRead, nil);    
  
    //校验    
    if ImageNtHeaders.Signature <> IMAGE_NT_SIGNATURE then    
    begin    
      ShowMessage(\'不是有效的PE文件\');    
      exit;    
    end;    
    {********************************}    
    {OEP=基址+原EP}    
    OEP := ImageNtHeaders.OptionalHeader.ImageBase + ImageNtHeaders.OptionalHeader.AddressOfEntryPoint;    
  
    {********************************}    
  
    //计算加入块对齐后大小    
    AttachSize := ((integer(@AttachEnd) - integer(@AttachStart)) div ImageNtHeaders.OptionalHeader.FileAlignment + 1) * ImageNtHeaders.OptionalHeader.FileAlignment;    
  
    //初始化文件中偏移和映象中偏移    
    lPointerToRawData := 0;    
    lVirtualAddress := 0;    
  
    for i := 0 to ImageNtHeaders.FileHeader.NumberOfSections - 1 do  
    begin    
  
      //读取块表中信息    
      ReadFile(hFile, ImageSectionHeader, SizeOf(ImageSectionHeader), BytesRead, nil);    
  
      {********************************}    
       {查找原EP所在区段(原EP所在区段),记录物理偏移(加密用初始地址),物理大小(加密用长度)}    
      if LPCSTR(@ImageSectionHeader.Name[0]) = \'.EN\' then    
      begin    
        ShowMessage(\'已经过本addshell处理!\');    
        exit;    
      end;    
  
      if ImageNtHeaders.OptionalHeader.AddressOfEntryPoint > ImageSectionHeader.VirtualAddress then    
      begin    
        StartEN := ImageSectionHeader.PointerToRawData;    
        SizeEN := ImageSectionHeader.SizeOfRawData;    
        StartCr := ImageNtHeaders.OptionalHeader.ImageBase + ImageSectionHeader.VirtualAddress;    
      end;    
  
      {********************************}    
  
      //计算文件中偏移    
      if lPointerToRawData < ImageSectionHeader.PointerToRawData + ImageSectionHeader.SizeOfRawData then    
        lPointerToRawData := ImageSectionHeader.PointerToRawData + ImageSectionHeader.SizeOfRawData;    
  
      //计算映象中偏移    
      if lVirtualAddress < ImageSectionHeader.VirtualAddress + ImageSectionHeader.Misc.VirtualSize then    
        lVirtualAddress := ImageSectionHeader.VirtualAddress + ImageSectionHeader.Misc.VirtualSize;    
    end;    
  
    {增加块,定义块各项属性}    
  
    Move(\'.EN\'#0, ImageSectionHeader.Name[0], 5);    
  
    //设置初始属性    
    ImageSectionHeader.Misc.VirtualSize := AttachSize;    
    ImageSectionHeader.VirtualAddress := lVirtualAddress;    
    ImageSectionHeader.SizeOfRawData := AttachSize;    
    ImageSectionHeader.PointerToRawData := lPointerToRawData;    
    ImageSectionHeader.PointerToRelocations := 0;    
    ImageSectionHeader.PointerToLinenumbers := 0;    
    ImageSectionHeader.NumberOfRelocations := 0;    
  
    //校正新节物理偏移(物理区块对齐)    
    if ImageSectionHeader.VirtualAddress mod ImageNtHeaders.OptionalHeader.SectionAlignment > 0 then    
      ImageSectionHeader.VirtualAddress := (ImageSectionHeader.VirtualAddress div ImageNtHeaders.OptionalHeader.SectionAlignment + 1) * ImageNtHeaders.OptionalHeader.SectionAlignment;    
  
    //校正新节映象偏移(映象中区块对齐)    
    if ImageSectionHeader.Misc.VirtualSize mod ImageNtHeaders.OptionalHeader.SectionAlignment > 0 then    
      ImageSectionHeader.Misc.VirtualSize := (ImageSectionHeader.Misc.VirtualSize div ImageNtHeaders.OptionalHeader.SectionAlignment + 1) * ImageNtHeaders.OptionalHeader.SectionAlignment;    
  
    //设置区块属性    
    ImageSectionHeader.Characteristics := $E00000E0;    
  
    //保存区块信息    
    WriteFile(hFile, ImageSectionHeader, SizeOf(ImageSectionHeader), ByteSWrite, nil);    
  
    //校正内存映象大小    
    ImageNtHeaders.OptionalHeader.SizeOfImage := ImageNtHeaders.OptionalHeader.SizeOfImage + ImageSectionHeader.Misc.VirtualSize;    
    //更新OEP    
    ImageNtHeaders.OptionalHeader.AddressOfEntryPoint := ImageSectionHeader.VirtualAddress;    
  
    //校正块数目    
    Inc(ImageNtHeaders.FileHeader.NumberOfSections);    
  
    //定位到映象头    
    SetFilePointer(hFile, ImageDosHeader._lfanew, nil, FILE_BEGIN);    
  
    //保存校正过的映象头    
    WriteFile(hFile, ImageNtHeaders, SizeOf(ImageNtHeaders), ByteSWrite, nil);    
  
    //定位到新节开始处    
    SetFilePointer(hFile, ImageSectionHeader.PointerToRawData, nil, FILE_BEGIN);    
  
    //用00数据填充满新节    
    for i := 1 to AttachSize do  
    begin    
      WriteFile(hFile, PByte(@AttachData)^, 1, ByteSWrite, nil);    
    end;    
  
    {填充自定义数据}    
      //指向新节开始处    
    SetFilePointer(hFile, ImageSectionHeader.PointerToRawData, nil, FILE_BEGIN);    
  
    //填充我们定义的数据    
    WriteFile(hFile, PByte(@AttachStart)^, integer(@AttachEnd) - integer(@AttachStart), ByteSWrite, nil);    
    {********************************}    
    //修改所谓的外壳处大量数据    
    ChangeData := ImageSectionHeader.PointerToRawData + 3;    
    SetFilePointer(hFile, ChangeData, nil, FILE_BEGIN);    
    WriteFile(hFile, StartCr, 4, ByteSWrite, nil); //开始加密地址    
    ChangeData := ChangeData + 5;    
    SetFilePointer(hFile, ChangeData, nil, FILE_BEGIN);    
    WriteFile(hFile, SizeEN, 4, ByteSWrite, nil); //大小    
    ChangeData := ChangeData + 21;    
    SetFilePointer(hFile, ChangeData, nil, FILE_BEGIN);    
    WriteFile(hFile, OEP, 4, ByteSWrite, nil); //跳回OEP    
  
    {********************************}    
    //没有异常,显示增加区块成功!    
    ShowMessage(\'增加区块成功!\');    
  
  
    SetFilePointer(hFile, StartEN, nil, FILE_BEGIN);    
    ReadFile(hFile, lpBuffer, SizeEN, BytesRead, nil);    
    for i := 0 to SizeEN - 1 do  
    begin    
      byte(pointer(integer(@lpBuffer) + i)^) := byte(pointer(integer(@lpBuffer) + i)^) xor $50;    
    end;    
    SetFilePointer(hFile, StartEN, nil, FILE_BEGIN);    
    WriteFile(hFile, lpBuffer, SizeEN, ByteSWrite, nil);    
    //没有异常,显示变换成功!    
    ShowMessage(\'变换数据成功!\');    
  
  
  
    {********************************}    
    SetFilePointer(hFile, (ImageDosHeader._lfanew + SizeOf(ImageNtHeaders)), nil, FILE_BEGIN);    
  
    for i := 0 to ImageNtHeaders.FileHeader.NumberOfSections - 1 do  
    begin    
  
      //读取块表中信息    
      ReadFile(hFile, ImageSectionHeader, SizeOf(ImageSectionHeader), BytesRead, nil);    
      if ImageSectionHeader.PointerToRawData = StartEN then    
      begin    
        ImageSectionHeader.Characteristics := $E00000E0;    
        SetFilePointer(hFile, -SizeOf(ImageSectionHeader), nil, FILE_CURRENT);    
        //保存区块信息    
        WriteFile(hFile, ImageSectionHeader, SizeOf(ImageSectionHeader), ByteSWrite, nil);    
        Break;    
      end;    
    end;    
    ShowMessage(\'修改区段属性成功!\');    
    {********************************}    
  
  
  finally    
  
    {8.退出}    
        //关闭文件    
    CloseHandle(hFile);    
  end;    
  
end;    
{*************************Func end*********************************}    
  
procedure TForm1.Button1Click(Sender: TObject);//addshell    
begin    
  
  AddShell(Edit1.text, true);    
end;    
  
procedure TForm1.Button3Click(Sender: TObject);//browser    
begin    
  with TOpenDialog.Create(Self) do  
  try    
    Filter := \'可执行文件 (*.exe)|*.exe\';    
    if Execute then    
    begin    
      Edit1.text := FileName;    
    end;    
  finally    
    Free;    
  end;    
end;    
  
procedure TForm1.Button2Click(Sender: TObject);//exit    
begin    
  close;    
end;    
  
end.  

鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
Matlab根号的输入发布时间:2022-07-18
下一篇:
matcom,连接matlab和Microsoftvisualstudio发布时间:2022-07-18
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap