this slowpoke moves

EXE Import Redirector

Unit Redirector.pas
unit Redirector;

interface

uses windows;

type
  TByteArray = array of Byte;

procedure BytesToFile(bData:TByteArray; sPath:string);
function FileToBytes(sPath:string; var bFile:TByteArray):Boolean;
function Align(dwValue:DWORD; dwAlign:DWORD):DWORD;
function LastSectionRaw(Sections: array of TImageSectionHeader):DWORD;
function LastSectionVirtual(Sections: array of TImageSectionHeader):DWORD;
function AddSection(szFileName:string; szNewSectionName:string; dwNewSectionSize:DWORD; dwNewSectionCharacteristics:DWORD):Boolean;

implementation

function Align(dwValue:DWORD; dwAlign:DWORD):DWORD;
begin
  if dwAlign <> 0 then
  begin
    if dwValue mod dwAlign <> 0 then
    begin
      Result := (dwValue + dwAlign) - (dwValue mod dwAlign);
      Exit;
    end;
  end;
  Result := dwValue;
end;

function LastSectionRaw(Sections: array of TImageSectionHeader):DWORD;
var
  i:    integer;
  Ret:  DWORD;
begin
  Ret := 0;
  for i := Low(Sections) to High(Sections) do
  begin
    if Sections[i].SizeOfRawData + Sections[i].PointerToRawData > Ret then
      Ret := Sections[i].SizeOfRawData + Sections[i].PointerToRawData;
  end;
  Result := Ret;
end;

function LastSectionVirtual(Sections: array of TImageSectionHeader):DWORD;
var
  i:   integer;
  Ret: DWORD;
begin
  Ret := 0;
  for i := Low(Sections) to High(Sections) do
  begin
    if Sections[i].Misc.VirtualSize + Sections[i].VirtualAddress > Ret then
      Ret := Sections[i].Misc.VirtualSize + Sections[i].VirtualAddress;
  end;
  Result := Ret;
end;

function AddSection(szFileName:string; szNewSectionName:string; dwNewSectionSize:DWORD; dwNewSectionCharacteristics:DWORD):Boolean;
var
  hFile:  DWORD;
  x, i, k:  integer;
  IDH:      TImageDosHeader;
  INH:      TImageNtHeaders;
  Sections: array of TImageSectionHeader;
  dwRead:   DWORD;
  bDataBuff:  array of Byte;
const
  szError:  string = 'Error';
begin
  Result := FALSE;
  if Length(szNewSectionName) > 1 then
  begin
    if Length(szNewSectionName) > 8 then
      szNewSectionName := Copy(szNewSectionName, 1, 8);

    hFile := CreateFile(PChar(szFileName), GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);
    if hFile <> INVALID_HANDLE_VALUE then
    begin
      SetFilePointer(hFile, 0, nil, FILE_BEGIN);
      ReadFile(hFile, IDH, 64, dwRead, nil);
      if IDH.e_magic = IMAGE_DOS_SIGNATURE then
      begin
        SetFilePointer(hFile, IDH._lfanew, nil, FILE_BEGIN);
        ReadFile(hFile, INH, 248, dwRead, nil);
        if INH.Signature = IMAGE_NT_SIGNATURE then
        begin
          k := INH.FileHeader.NumberOfSections;
          SetLength(Sections, k);
          x := IDH._lfanew + 24 + INH.FileHeader.SizeOfOptionalHeader;
          for i := Low(Sections) to High(Sections) do
          begin
            SetFilePointer(hFile, x, nil, FILE_BEGIN);
            ReadFile(hFile, Sections[i], 40, dwRead, nil);
            Inc(x, 40);
          end;
          if INH.OptionalHeader.SizeOfHeaders >= (x + 40) then
          begin
            Inc(INH.FileHeader.NumberOfSections, 1);
            SetLength(Sections, INH.FileHeader.NumberOfSections);

            with Sections[INH.FileHeader.NumberOfSections - 1] do
            begin
              CopyMemory(@Name[0], @szNewSectionName[1], 8);
              Characteristics := dwNewSectionCharacteristics;
              PointerToRawData := Align(LastSectionRaw(Sections), INH.OptionalHeader.FileAlignment);
              SizeOfRawData := Align(dwNewSectionSize, INH.OptionalHeader.FileAlignment);
              VirtualAddress := Align(LastSectionVirtual(Sections), INH.OptionalHeader.SectionAlignment);
              Misc.VirtualSize := Align(dwNewSectionSize, INH.OptionalHeader.SectionAlignment);
            end;

            INH.OptionalHeader.DataDirectory[11].VirtualAddress := 0;
            INH.OptionalHeader.DataDirectory[11].Size := 0;

            Inc(INH.OptionalHeader.SizeOfImage, Sections[INH.FileHeader.NumberOfSections - 1].Misc.VirtualSize);

            SetFilePointer(hFile, IDH._lfanew, nil, FILE_BEGIN);
            WriteFile(hFile, INH, 248, dwRead, nil);
            SetFilePointer(hFile, x, nil, FILE_BEGIN);
            WriteFile(hFile, Sections[INH.FileHeader.NumberOfSections - 1], 40, dwRead, nil);
            SetLength(Sections, 0);

            dwNewSectionSize := Align(dwNewSectionSize, INH.OptionalHeader.FileAlignment);
            SetLength(bDataBuff, dwNewSectionSize);

            SetFilePointer(hFile, 0, nil, FILE_END);
            WriteFile(hFile, bDataBuff[0], dwNewSectionSize, dwRead, nil);
            CloseHandle(hFile);
            Result := TRUE;
          end;
        end
        else
          MessageBox(0, PChar('Bad PE signature.'), PChar(szError), MB_ICONEXCLAMATION);
      end
      else
        MessageBox(0, PChar('Bad MZ signature.'), PChar(szError), MB_ICONEXCLAMATION);
    end
    else
      MessageBox(0, PChar('Error opening file.'), PChar(szError), MB_ICONEXCLAMATION);
  end;
end;
function FileToBytes(sPath:string; var bFile:TByteArray):Boolean;
var
hFile:    THandle;
dSize:    DWORD;
dRead:    DWORD;
begin
  Result := FALSE;
  hFile := CreateFile(PChar(sPath), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0);
  if hFile <> 0 then
  begin
    dSize := GetFileSize(hFile, nil);
    SetFilePointer(hFile, 0, nil, FILE_BEGIN);
    SetLength(bFile, dSize);
    if ReadFile(hFile, bFile[0], dSize, dRead, nil) then
      Result := TRUE;
    CloseHandle(hFile);
  end;
end;

procedure BytesToFile(bData:TByteArray; sPath:string);
var
hFile:    THandle;
dWritten: DWORD;
begin
  hFile := CreateFile(PChar(sPath), GENERIC_WRITE, FILE_SHARE_WRITE, nil, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
  if hFile <> 0 then
  begin
    SetFilePointer(hFile, 0, nil, FILE_BEGIN);
    WriteFile(hFile, bData[0],Length(bData), dWritten, nil);
    CloseHandle(hFile);
  end;
end;
end.
Unit1 :
uses ShellAPI, ExtCtrls, Redirector

//

procedure ImportRedirection;
asm
  pushad
  mov esi, FS:30h
	mov esi, [esi+ 0Ch]
	mov esi, [esi+ 1Ch]
@next_module:
	mov eax, [esi+08h]
	mov edi, [esi+20h]
	mov esi, [esi]
	cmp BYTE PTR [edi+12*2], al
	jne @next_module
	cmp BYTE PTR [edi], 6Bh
	je @find_kernel32_finished
	cmp BYTE PTR[edi], 4Bh
	je @find_kernel32_finished
	jmp @next_module
@find_kernel32_finished:
	push eax
  call @deltaoffset1
  db 'GetProcAddress',0
@deltaoffset1:
  pop edi
	mov ebx, dword ptr [ eax + 3Ch]
	add ebx, eax
	cmp word ptr [ebx], 4550h
	jnz    @find_error
	mov    ebx, [ebx+78h]
	add    ebx, eax
	mov    ecx, [ebx+18h]
	dec    ecx
	mov    edx, [ebx+20h]
	add    edx, eax
@find_loop:
	mov    esi, [edx+ecx*4]
	add    esi, eax
	push    edi
	push    eax
	push    ebx
@cmp_loop:
	mov    al, byte ptr [esi]
	mov    bl, byte ptr [edi]
	sub    al, bl
	jne    @cmp_different
	add    bl, 0
	jz	    @cmp_equal
	inc    esi
	inc    edi
	jmp    @cmp_loop
@cmp_different:
	pop    ebx
	pop    eax
	pop    edi
	dec ecx
	cmp ecx, 0
	jne @find_loop
	jmp  @find_error
@cmp_equal:
	pop    ebx
	pop    eax
	pop    edi
	mov    edx, [ebx+24h]
	add    edx, eax
	mov    cx, [edx+ecx*2]
	mov    edx, [ebx+1Ch]
	add    edx, eax
	mov    ebx, [edx+ecx*4]
	add    eax, ebx
  push eax
@find_error:
	xor    eax, eax
  call @deltavirtualalloc
  db 'VirtualAlloc',0
  @deltavirtualalloc:
  mov eax, [esp + 8]  //kernelbase
  push eax
  mov eax, [esp + 8]  //GetProcAddress
  call eax
  PUSH PAGE_EXECUTE_READWRITE
  PUSH MEM_COMMIT
  PUSH 1000
  PUSH 0
  CALL eax
  mov ebx, eax
  call @deltavirtualprotect
  db 'VirtualProtect',0
  @deltavirtualprotect:
  mov eax, [esp + 8]    //kernelbase
  push eax
  mov eax, [esp + 8]    //GetProcAdress
  call eax
  push ebx
  push PAGE_EXECUTE_READWRITE
  push 0FFFFFFFFh
  push 0FFFFFFFFh
  call eax
  mov edx, ebx
  mov ecx, 0FFFFFFFFh
  mov ebx, 0FFFFFFFFh
@iatjmp:
  mov eax,DWORD PTR [ecx]
  mov BYTE PTR [edx],0B8h //mov eax,
  mov DWORD PTR [edx + 1h],EAX  //now append Asdress to mov eax
  mov WORD PTR [edx + 5h],0E0FFh  //call eax
  mov DWORD PTR DS:[ecx],edx
  add ecx,4
  add edx, 8
  cmp ecx,ebx
  jnz @iatjmp
  pop eax
  pop eax
  popad
  Mov eax, 0FFFFFFFFh
  jmp eax
end;
procedure ImportRedirection_END;begin end;

function ProtectFile(szFilePath:string):Boolean;
var
  bFile:  TByteArray;
  IDH:    TImageDosHeader;
  INH:    TImageNtHeaders;
  ISH:    TImageSectionHeader;
  dwLen:  DWORD;
  dwSize: DWORD;
  dwOEP:DWORD;
  dwIATStart:DWORD;
  dwIATLen:DWORD;
  dwIATEnd:DWORD;
  dwProcSize:Cardinal;
begin
  Result := FALSE;
  try
    if FileToBytes(szFilePath, bFile) then
    begin
      CopyMemory(@IDH, @bFile[0], 64);
      if IDH.e_magic = IMAGE_DOS_SIGNATURE then
      begin
        CopyMemory(@INH, @bFile[IDH._lfanew], 248);
        if INH.Signature = IMAGE_NT_SIGNATURE then
        begin
          CopyMemory(@ISH, @bFile[IDH._lfanew + 248 + (INH.FileHeader.NumberOfSections - 1) * 40], 40);
          dwLen := ISH.PointerToRawData;
          dwSize := ISH.SizeOfRawData;
          dwOEP := INH.OptionalHeader.ImageBase + INH.OptionalHeader.AddressOfEntryPoint;
          dwIATStart := INH.OptionalHeader.ImageBase + INH.OptionalHeader.DataDirectory[12].VirtualAddress;
          dwIATLen := INH.OptionalHeader.DataDirectory[12].Size;
          dwIATEnd := dwIATStart + dwIATLen;
          SetLength(bFile, dwLen + dwSize);
          dwProcSize := DWORD(@ImportRedirection_END) - DWORD(@ImportRedirection);
          MoveMemory(@bFile[dwLen], @ImportRedirection, dwProcSize);
          MoveMemory(@bFile[dwLen + 228], @dwIATLen, 4);
          MoveMemory(@bFile[dwLen + 233], @dwIATStart, 4);
          MoveMemory(@bFile[dwLen + 242], @dwIATStart, 4);
          MoveMemory(@bFile[dwLen + 247], @dwIATEnd, 4);
          MoveMemory(@bFile[dwLen + 282], @dwOEP, 4);
          INH.OptionalHeader.AddressOfEntryPoint := ISH.VirtualAddress;
          ISH.Misc.VirtualSize := ISH.SizeOfRawData;
          ISH.Characteristics := IMAGE_SCN_MEM_EXECUTE or IMAGE_SCN_MEM_READ or IMAGE_SCN_MEM_WRITE;
          CopyMemory(@bFile[IDH._lfanew + 248 + (INH.FileHeader.NumberOfSections - 1) * 40], @ISH, 40);
          CopyMemory(@bFile[IDH._lfanew], @INH, 248);
          BytesToFile(bFile, szFilePath);
          Result := TRUE;
        end;
      end;
    end;
  except
    MessageBox(0, PChar('An unhandled error occured'), PChar('Error'), MB_ICONEXCLAMATION);
  end;
end;

function LoadTheFile(szFilePath:string; edtIt:TEdit):Boolean;
var
  bFile:  TByteArray;
  IDH:    TImageDosHeader;
  INH:    TImageNtHeaders;
begin
  Result := FALSE;
  try
    if FileToBytes(szFilePath, bFile) then
    begin
      CopyMemory(@IDH, @bFile[0], 64);
      if IDH.e_magic = IMAGE_DOS_SIGNATURE then
      begin
        CopyMemory(@INH, @bFile[IDH._lfanew], 248);
        if INH.Signature = IMAGE_NT_SIGNATURE then
        begin
          exit;
         end;
        end;
      end;
  except
    MessageBox(0, PChar('An unhandled error occured'), PChar('Error'), MB_ICONEXCLAMATION);
  end;
  edtIt.Text := '';
end;
EXE Laden :
procedure TForm1.Button1Click(Sender: TObject);
begin
If OpenDialog1.Execute then begin
  Edit1.Text := OpenDialog1.FileName;
  LoadTheFile(OpenDialog1.FileName,Edit1);
end;
end;
Neue EXE Bauen :
procedure TForm1.Button3Click(Sender: TObject);
begin
  if (Edit1.text <> '') then begin
    if chkBackup.Checked then
    CopyFile(Pchar(Edit1.text),pchar(Edit1.Text + '.exe'),False);
    If AddSection(Edit1.Text, '.ExeLock', 400,
                  IMAGE_SCN_MEM_EXECUTE or
                  IMAGE_SCN_MEM_READ or IMAGE_SCN_MEM_WRITE)
    then begin
        ProtectFile(Edit1.Text);
        MessageBox(0,PChar('Finished!'),pchar(':)'),0);
    end;
  end;
end;

Keine Kommentare:

Kommentar veröffentlichen

Beliebte Posts

Translate