flat assembler
Message board for the users of flat assembler.

Index > Windows > Fasm as simple one-section PE encryptor

Author
Thread Post new topic Reply to topic
Grom PE



Joined: 13 Mar 2008
Posts: 114
Location: i@grompe.org.ru
Grom PE
Fasm is really powerful, isn't it? =)
See comments.

Code:
; Simple PE encryptor
; v0.50
; for flat assembler by Grom PE
;
; What it does
; ============
; Finds a section that contains code, and if there's enough
; space and it doesn't contain any directories, makes it
; writeable, expands, encrypts with xor, inserts decrypting
; code in the end of section, and updates entry point.
;
; It won't process DLL or any other relocateable image!
; Other than that, there's few checks made, so
;             USE AT YOUR OWN RISK.
;
; Usage
; =====
; Create crypto.bat file with following text:
;   @echo off
;   call fasm fasmcrypto.asm %2 -dsubject='%1'
; Now you can encrypt your executables by writing:
;   crypto myprog.exe myprog_encrypted.exe

format binary as 'exe'
use32

encrypt_constant = 71h

; === Useful macros ===

macro getword offs*, variable*
{
  local there
  virtual
    there = $
    file subject:offs, 2
    load variable word from there
  end virtual  
}

macro getdword offs*, variable*
{
  local there
  virtual
    there = $
    file subject:offs, 4
    load variable dword from there
  end virtual  
}

macro patchfile name
{
  virtual
    @@:
    file name
    p_filesize = $ - @b
  end virtual
  p_start = ($-$$)
  p_pointer = 0
  p_filename equ name
}

macro patchat address
{
  p_pointer = p_pointer - p_start + ($-$$)
  p_toadd = address - ($-$$)

  if address >= 0
    if p_toadd >= 0
      if p_pointer + p_toadd <= p_filesize
        file p_filename: p_pointer, p_toadd
      else
        p_addpart = 0
        if p_pointer < p_filesize
          p_addpart = p_filesize - p_pointer
          file p_filename: p_pointer, p_addpart
        end if
        rb p_toadd - p_addpart
      end if
    else
      "Error: can't move backwards."
    end if
  else
    "Error: invalid address, must be >= 0."
  end if

  p_start = ($-$$)
  p_pointer = p_pointer + p_toadd
}

macro patchend
{
  p_pointer = p_pointer - p_start + ($-$$)
  p_toadd = p_filesize - ($-$$)

  if p_toadd >= 0
    if p_pointer + p_toadd <= p_filesize
      file p_filename: p_pointer, p_toadd
    else
      p_addpart = 0
      if p_pointer < p_filesize
        p_addpart = p_filesize - p_pointer
        file p_filename: p_pointer, p_addpart
      end if
      db p_toadd - p_addpart dup 0
    end if
  end if
}

; === Loading and calculating ===

getword 0, mz_header

if mz_header <> 'MZ'
  "Error: Not valid MZ file."
end if

getdword 3Ch, pe_offset
getdword pe_offset, pe_signature

if pe_signature <> 'PE'
  "Error: Not valid PE file."
end if

getword pe_offset + 6, number_of_sections
getword pe_offset + 14h, size_of_optional_header
getdword pe_offset + 28h, entry_point

repeat number_of_sections
  section_offset = pe_offset + 18h + size_of_optional_header + (%-1)*28h
  getdword section_offset + 8  , section_virtual_size
  getdword section_offset + 0Ch, section_rva
  if section_virtual_size + section_rva > entry_point
    break
  end if
end repeat

getdword pe_offset + 74h, number_of_directories

repeat number_of_directories
  getdword pe_offset + 78h + (%-1)*8, directory_rva
  if directory_rva <> 0
    if % = 6
      "Error: Won't process relocatable image."
    end if
    if section_virtual_size + section_rva > directory_rva
      "Error: Directories in code section are not supported."
    end if
  end if
end repeat


getdword section_offset + 10h, section_physical_size
getdword section_offset + 14h, section_physical_offset
getdword section_offset + 24h, section_attributes

if section_physical_size - section_virtual_size < our_code_end - our_code
  "Error: No free space to add code."
end if

getdword pe_offset + 34h, image_base

new_entry_point = section_virtual_size + section_rva

; === Writing modified file ===

patchfile subject

patchat pe_offset + 28h
  dd new_entry_point

patchat section_offset + 8h
  dd section_virtual_size + our_code_end - our_code

patchat section_offset + 24h
  dd section_attributes or 80000000h

patchat section_physical_offset

  startcrypt:
    file subject:section_physical_offset, section_virtual_size

    repeat section_virtual_size
      load a byte from startcrypt + %-1
      store byte a xor encrypt_constant at startcrypt + %-1
    end repeat

patchat section_physical_offset + section_virtual_size

  our_code:
    mov ecx, section_virtual_size
  decrypt:
    xor byte [image_base + section_rva + ecx - 1], encrypt_constant
    loop decrypt
    jmp entry_point - section_rva + section_physical_offset
  our_code_end:

patchend
    


Tell me what you think.
Post 14 Jul 2008, 22:31
View user's profile Send private message Visit poster's website Reply with quote
comrade



Joined: 16 Jun 2003
Posts: 1137
Location: Russian Federation
comrade
Good job, really elaborate. Clever use of the command-line definitions to alter the compilation process.

This is somewhat similar to this.
See http://comrade.ownz.com/docs/fasm.html#selfencrypt.
Also see http://board.flatassembler.net/topic.php?t=2126.
Though everything there is used to encrypt the executable itself. Yours encrypts any executable.
Post 15 Jul 2008, 04:41
View user's profile Send private message Visit poster's website AIM Address Yahoo Messenger MSN Messenger ICQ Number Reply with quote
bitRAKE



Joined: 21 Jul 2003
Posts: 2937
Location: vpcmipstrm
bitRAKE
Grom PE, you have a folder in my FASM/Forum directory - these kinds of demonstrations are invaluable. Very Happy

_________________
¯\(°_o)/¯ unlicense.org
Post 15 Jul 2008, 06:07
View user's profile Send private message Visit poster's website Reply with quote
Grom PE



Joined: 13 Mar 2008
Posts: 114
Location: i@grompe.org.ru
Grom PE
comrade, thanks for the interesting links!
Your obfuscating macros are amazing.
Yes, I used xor encrypting macros for programs written in fasm, but thought it wasn't so spectacular.

bitRAKE, nice to know =)
Post 15 Jul 2008, 06:36
View user's profile Send private message Visit poster's website Reply with quote
Grom PE



Joined: 13 Mar 2008
Posts: 114
Location: i@grompe.org.ru
Grom PE
Updated for the version with removed -d support.
Code:
; Simple PE encryptor
; v0.51
; for flat assembler by Grom PE
;
; What it does
; ============
; Finds a section that contains code, and if there's enough
; space and it doesn't contain any directories, makes it
; writeable, expands, encrypts with xor, inserts decrypting
; code in the end of section, and updates entry point.
;
; It won't process DLL or any other relocateable image!
; Other than that, there's few checks made, so
;             USE AT YOUR OWN RISK.
;
; Usage
; =====
; Create crypto.bat file with following text:
;   @echo off
;   set crypttempinc=%temp%\crypt_temp.inc
;   echo define subject '%1'> %crypttempinc%
;   call fasm fasmcrypto.asm %1.cry
;   del %crypttempinc%
; Now you can encrypt your executables by writing:
;   crypto myprog.exe
; It will create myprog.cry on success.
;
; If you find bugs or have anything to say,
; you can contact me from my site:
;   http://grompe.org.ru/
;
; Regards, Grom PE

format binary as 'exe'
use32

include '%crypttempinc%'

encrypt_constant = 71h

; === Useful macros ===

macro getword offs*, variable*
{
  local there
  virtual
    there = $
    file subject:offs, 2
    load variable word from there
  end virtual  
}

macro getdword offs*, variable*
{
  local there
  virtual
    there = $
    file subject:offs, 4
    load variable dword from there
  end virtual  
}

macro patchfile name
{
  virtual
    @@:
    file name
    p_filesize = $ - @b
  end virtual
  p_start = ($-$$)
  p_pointer = 0
  p_filename equ name
}

macro patchat address
{
  p_pointer = p_pointer - p_start + ($-$$)
  p_toadd = address - ($-$$)

  if address >= 0
    if p_toadd >= 0
      if p_pointer + p_toadd <= p_filesize
        file p_filename: p_pointer, p_toadd
      else
        p_addpart = 0
        if p_pointer < p_filesize
          p_addpart = p_filesize - p_pointer
          file p_filename: p_pointer, p_addpart
        end if
        rb p_toadd - p_addpart
      end if
    else
      "Error: can't move backwards."
    end if
  else
    "Error: invalid address, must be >= 0."
  end if

  p_start = ($-$$)
  p_pointer = p_pointer + p_toadd
}

macro patchend
{
  p_pointer = p_pointer - p_start + ($-$$)
  p_toadd = p_filesize - ($-$$)

  if p_toadd >= 0
    if p_pointer + p_toadd <= p_filesize
      file p_filename: p_pointer, p_toadd
    else
      p_addpart = 0
      if p_pointer < p_filesize
        p_addpart = p_filesize - p_pointer
        file p_filename: p_pointer, p_addpart
      end if
      db p_toadd - p_addpart dup 0
    end if
  end if
}

; === Loading and calculating ===

getword 0, mz_header

if mz_header <> 'MZ'
  "Error: Not valid MZ file."
end if

getdword 3Ch, pe_offset
getdword pe_offset, pe_signature

if pe_signature <> 'PE'
  "Error: Not valid PE file."
end if

getword pe_offset + 6, number_of_sections
getword pe_offset + 14h, size_of_optional_header
getdword pe_offset + 28h, entry_point

repeat number_of_sections
  section_offset = pe_offset + 18h + size_of_optional_header + (%-1)*28h
  getdword section_offset + 8  , section_virtual_size
  getdword section_offset + 0Ch, section_rva
  if section_virtual_size + section_rva > entry_point
    break
  end if
end repeat

getdword pe_offset + 74h, number_of_directories

repeat number_of_directories
  getdword pe_offset + 78h + (%-1)*8, directory_rva
  if directory_rva <> 0
    if % = 6
      "Error: Won't process relocatable image."
    end if
    if section_virtual_size + section_rva > directory_rva
      "Error: Directories in code section are not supported."
    end if
  end if
end repeat


getdword section_offset + 10h, section_physical_size
getdword section_offset + 14h, section_physical_offset
getdword section_offset + 24h, section_attributes

if section_physical_size - section_virtual_size < our_code_end - our_code
  "Error: No free space to add code."
end if

getdword pe_offset + 34h, image_base

new_entry_point = section_virtual_size + section_rva

; === Writing modified file ===

patchfile subject

patchat pe_offset + 28h
  dd new_entry_point

patchat section_offset + 8h
  dd section_virtual_size + our_code_end - our_code

patchat section_offset + 24h
  dd section_attributes or 80000000h

patchat section_physical_offset

  startcrypt:
    file subject:section_physical_offset, section_virtual_size

    repeat section_virtual_size
      load a byte from startcrypt + %-1
      store byte a xor encrypt_constant at startcrypt + %-1
    end repeat

patchat section_physical_offset + section_virtual_size

  our_code:
    mov ecx, section_virtual_size
  decrypt:
    xor byte [image_base + section_rva + ecx - 1], encrypt_constant
    loop decrypt
    jmp entry_point - section_rva + section_physical_offset
  our_code_end:

patchend    
Post 13 Sep 2009, 16:43
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2020, Tomasz Grysztar. Also on YouTube, Twitter.

Website powered by rwasa.