讓偵測工具把殼識別為VC++7.0的原始碼

看雪資料發表於2004-05-08

看了LiNSoN兄"讓偵測工具把殼識別為VC++",還不錯,可惜是手動的...

於是我順手寫了程式自動完成這一工作,經實驗現在可以把不帶CRC32的殼成功
偽裝,如果殼帶有CRC32就不行了
現帖出原始碼,與大家共享,有興趣的可以加以改進
程式不復雜,我就直接帖出來了

{
  Author: xIkUg
  Email: xikug@163.com
  HOMEPAGE: http://www.xp-program.com
  Description: 把PE程式偽裝為VC7.0編譯的
}
unit uMain;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Label1: TLabel;
    edFName: TEdit;
    Button1: TButton;
    Label2: TLabel;
    edOEP: TEdit;
    Button2: TButton;
    Button3: TButton;
    Button4: TButton;
    Button5: TButton;
    OpenDialog1: TOpenDialog;
    procedure Button5Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
  private
    { Private declarations }
    FImageBase: DWORD;
    
  public
    { Public declarations }
  end;

  THEAD = array [0..63] of byte;

var
  Form1: TForm1;

const
  MYSECTION = 'xIkUg';
  
  JMPOFF = 43;
  
  //這個是HEAD.asm中的程式碼的機器碼
  OEPCODE: THEAD = ($55, $8B, $EC, $6A, $FF, $68, $2A, $2C, $0A, $00, $68, $38,
                    $90, $0D, $00, $64, $A1, $00, $00, $00, $00, $50, $64, $89,
                    $25, $00, $00, $00, $00, $58, $64, $A3, $00, $00, $00, $00,
                    $58, $58, $58, $58, $8B, $E8, $B8, $00, $10, $40, $00, $FF,
                    $E0, $90, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
                    $00, $00, $00, $00);

procedure AddSection(FName: string);      //新加一個Section,並把OEPCode寫進去

implementation

{$R *.dfm}

procedure TForm1.Button5Click(Sender: TObject);
begin
  Close;
end;

procedure TForm1.Button4Click(Sender: TObject);
begin
  MessageBox(Handle, 'Author: xIkUg' + #10#13 +
    'Email: xikug@163.com' + #10#13 +
    'HOMEPAGE: http://www.xp-program.com',
    'About', MB_OK);
end;

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

procedure TForm1.Button2Click(Sender: TObject);
var
  DOSHEADER: IMAGE_DOS_HEADER;
  PEHEADER: IMAGE_NT_HEADERS;
  fs: TFileStream;

begin
  fs := TFileStream.Create(edFName.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;
    edOEP.Text := IntToHex(PEHEADER.OptionalHeader.AddressOfEntryPoint, 8);
  finally
    fs.Free;
  end;
end;

procedure AddSection(FName: string);
var
  DOSHEADER: IMAGE_DOS_HEADER;
  PEHEADER: IMAGE_NT_HEADERS;
  SectionHeader: IMAGE_SECTION_HEADER;
  MySectionHeader: IMAGE_SECTION_HEADER;
  fs: TFileStream;

  AddressOfEntryPoint: DWORD;
  
begin
  fs := TFileStream.Create(FName, fmOpenReadWrite +
    fmShareDenyWrite);
  try
    fs.Seek(0, soFromBeginning);
    fs.Read(DOSHEADER, sizeof(DOSHEADER));
    
    fs.Seek(DOSHEADER._lfanew, soFromBeginning);
    fs.Read(PEHEADER, sizeOf(PEHEADER));

    fs.Seek(sizeOf(SectionHeader) *
      (PEHEADER.FileHeader.NumberOfSections - 1), soFromCurrent);

    fs.Read(SectionHeader, sizeof(IMAGE_SECTION_HEADER));

    MySectionHeader.Name[0] := ord('x');
    MySectionHeader.Name[1] := ord('I');
    MySectionHeader.Name[2] := ord('k');
    MySectionHeader.Name[3] := ord('U');
    MySectionHeader.Name[4] := ord('g');
    MySectionHeader.Name[5] := 0;
    MySectionHeader.Name[6] := 0;
    MySectionHeader.Name[7] := 0;

    MySectionHeader.VirtualAddress := PEHEADER.OptionalHeader.SizeOfImage;
    MySectionHeader.Misc.VirtualSize := $200;
    MySectionHeader.SizeOfRawData := (MySectionHeader.VirtualAddress div
      PEHEADER.OptionalHeader.FileAlignment + 1) * PEHEADER.OptionalHeader.FileAlignment -
      PEHEADER.OptionalHeader.SizeOfImage;
    MySectionHeader.PointerToRawData :=
      SectionHeader.SizeOfRawData+SectionHeader.PointerToRawData;
    MySectionHeader.Characteristics := $e0000020;

    Inc(PEHEADER.FileHeader.NumberOfSections);
    fs.Write(MySectionHeader, sizeOf(MySectionHeader));

    fs.Seek(DOSHEADER._lfanew, soFromBeginning);

    AddressOfEntryPoint := PEHEADER.OptionalHeader.AddressOfEntryPoint;

    PEHEADER.OptionalHeader.AddressOfEntryPoint :=
      MySectionHeader.VirtualAddress;

    PEHEADER.OptionalHeader.MajorLinkerVersion := 7;
    PEHEADER.OptionalHeader.MinorLinkerVersion := 0;
    AddressOfEntryPoint := AddressOfEntryPoint +
      PEHEADER.OptionalHeader.ImageBase;

    asm
      PUSHAD
      LEA eax, OEPCODE
      ADD eax, JMPOFF
      MOV edx, AddressOfEntryPoint

      MOV DWORD ptr [eax], edx
      POPAD
    end;

    PEHEADER.OptionalHeader.SizeOfImage :=
      PEHEADER.OptionalHeader.SizeOfImage + MySectionHeader.Misc.VirtualSize;
      
    fs.Write(PEHEADER, sizeof(PEHEADER));


    fs.Seek(fs.Size, soFromBeginning);
    fs.Write(OEPCODE, MySectionHeader.Misc.VirtualSize)
  finally
    fs.Free;
  end;
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
  //偽裝
  if trim(edFName.Text) = '' then
  begin
    MessageDlg('請先選擇一個可執行檔案', mtError, [mbOK], 0);
    Exit;
  end;

  //這段其實是不需要的,我懶得刪了,看看也不錯
  if trim(edOEP.Text) = '' then
  begin
    MessageDlg('請先獲取程式入口點', mtError, [mbOK], 0);
    Exit;
  end;

  AddSection(edFName.Text);             //偽裝
  MessageDlg('偽裝成功!', mtInformation, [mbOK], 0); 
end;

end.

相關文章