Major update (multi-label support, better encryption, masked labels by DoubleDutch):
Encryptor:
Code: Select all
;By Inf0Byt3, 10OCT07
;
;Based on code by Rings/Pdwyer/Franky/Wayne Diamond
;Mods/Fixes/Improvements by DoubleDutch/Thefool
;
;Free to use, credits appreciated
;It would be nice to improve it if you have time and if you want to share the knowledge
;
;Now with multi-label support ;)
;Don't forget to enable Inline ASM
Structure Block
StartOffset.l
EndOffset.l
Length.l
EndStructure
Structure CharArray
char.c[0]
EndStructure
Global NewList Blocks.Block()
Procedure BZ_CompareMemory(*Src, *Dst, Len)
MOV esi, *Src
MOV edi, *Dst
MOV eax, Len
MOV ecx, eax
AND eax, 3
SHR ecx, 2
XOR ebx, ebx
REPE CMPSD
!JNE .not_eq
MOV ecx, eax
XOR ebx, ebx
REPE CMPSB
!JNE .not_eq
ProcedureReturn 1
!.not_eq:
ProcedureReturn 0
EndProcedure
Procedure XorWithKey (sText.l, LenText.l, sKey.l, LenKey.l)
XOR ecx, ecx
MOV esi, sText
MOV edi, sKey
MOV edx, LenText
MOV ebp, LenKey
ADD ebp, esi
xornextbyte:
MOV al, [esi]
MOV bl, [edi]
XOR al, bl
MOV [esi], al
INC ecx
INC esi
INC edi
CMP esi, ebp
JGE l_xorcomplete
CMP ecx, edx
JGE l_xornextround
JMP l_xornextbyte
xornextround:
XOR ecx, ecx
SUB edi, edx
JMP l_xornextbyte
xorcomplete:
EndProcedure
Procedure BinSearch(*Object.CharArray, ObjectLength.l, StartOffset.l, *String.CharArray, StringLength.l)
Dim SkipLength.l(255)
For i = 0 To 255
SkipLength(i) = StringLength + 1
Next
For i = 0 To StringLength -1
SkipLength(*String\char[i]) = StringLength - i
Next
CurrentOffset.l = StartOffset
MaxOffset.l = ObjectLength - StringLength
While CurrentOffset <= MaxOffset
If BZ_CompareMemory(*Object + CurrentOffset, *String, StringLength) = 1
FoundPos = CurrentOffset + 1
Break
EndIf
CurrentOffset + SkipLength(*Object\char[CurrentOffset + StringLength])
Wend
ProcedureReturn FoundPos
EndProcedure
Procedure Callback(Message.s)
Debug Message
ProcedureReturn 1
EndProcedure
Procedure EncryptExecutablePieces(File.s,*Callback)
BlockStr.s = Chr($eb)+Chr($06)+Chr($eb)+Chr($fc)+Chr($eb)+Chr($fa)+Chr($eb)+Chr($f8)
BlockEnd.s = Chr($eb)+Chr($04)+Chr($eb)+Chr($04)+Chr($eb)+Chr($fc)+Chr($eb)+Chr($fc)
EXE_Block_Key.s = "this is the enc key"
If FileSize(File) = 0 Or FileSize(File) = -1
CallFunctionFast(*Callback,"No file or empty file...")
ProcedureReturn 0
EndIf
FLRH = OpenFile(#PB_Any,File)
If IsFile(FLRH)
CallFunctionFast(*Callback,"Opened file...")
;Read the file in memory
TotalLength = Lof(FLRH)
*MainMem = AllocateMemory(TotalLength)
ReadData(FLRH,*MainMem,TotalLength)
;Now search for the blocks that need encryption
CallFunctionFast(*Callback,"Searching for blocks...")
While Pos <= TotalLength
EStart = BinSearch(*MainMem,TotalLength,Pos,@BlockStr,Len(BlockStr))
EEnd = BinSearch(*MainMem,TotalLength,Pos,@BlockEnd,Len(BlockEnd))
If EStart > 0 And EEnd > 0
AddElement(Blocks())
Blocks()\StartOffset = EStart+Len(BlockStr)-1
Blocks()\EndOffset = EEnd-1
Blocks()\Length = Blocks()\EndOffset-Blocks()\StartOffset
Else
Break
EndIf
Pos + (EEnd-Pos)
Wend
;Read and encrypt the data
If CountList(Blocks()) > 0
CallFunctionFast(*Callback,Str(CountList(Blocks()))+" block(s) were found.")
ForEach Blocks()
CallFunctionFast(*Callback,"Block start at offset: "+Str(Blocks()\StartOffset))
CallFunctionFast(*Callback,"Block end at offset: "+Str(Blocks()\EndOffset))
CallFunctionFast(*Callback,"Block length: "+Str(Blocks()\Length))
*MemArea = AllocateMemory(Blocks()\Length)
FileSeek(FLRH,Blocks()\StartOffset)
ReadData(FLRH,*MemArea,Blocks()\Length)
XorWithKey (*MemArea, Blocks()\Length, @EXE_Block_Key, Len(EXE_Block_Key))
FileSeek(FLRH,Blocks()\StartOffset)
WriteData(FLRH,*MemArea,Blocks()\Length)
CallFunctionFast(*Callback,"Block patched...")
FreeMemory(*MemArea)
Next
CallFunctionFast(*Callback,"")
Else
CallFunctionFast(*Callback,"No blocks found...")
EndIf
CallFunctionFast(*Callback,"Closing file...")
CloseFile(FLRH)
CallFunctionFast(*Callback,"Ready...")
Else
ProcedureReturn -1
EndIf
EndProcedure
EncryptExecutablePieces("C:\Test.exe",@Callback())
Test executable
Code: Select all
;By Inf0Byt3, 10OCT07
;
;Based on code by Rings/Pdwyer/Franky/Wayne Diamond
;Mods/Fixes/Improvements by DoubleDutch/Thefool
;
;Free to use, credits appreciated
;It would be nice to improve it if you have time and if you want to share the knowledge
;
;Now with multi-label support ;)
;Don't forget to enable Inline ASM
Procedure XorWithKey (sText.l, LenText.l, sKey.l, LenKey.l)
XOR ecx, ecx
MOV esi, sText
MOV edi, sKey
MOV edx, LenText
MOV ebp, LenKey
ADD ebp, esi
xornextbyte:
MOV al, [esi]
MOV bl, [edi]
XOR al, bl
MOV [esi], al
INC ecx
INC esi
INC edi
CMP esi, ebp
JGE l_xorcomplete
CMP ecx, edx
JGE l_xornextround
JMP l_xornextbyte
xornextround:
XOR ecx, ecx
SUB edi, edx
JMP l_xornextbyte
xorcomplete:
EndProcedure
Procedure.l Scramble(StartAddress,Length)
EXE_Block_Key.s = "this is the enc key"
Mode = #PAGE_READWRITE
Result=VirtualProtect_(StartAddress,Length,Mode,@OrigMode)
XorWithKey (StartAddress,Length,@EXE_Block_Key,Len(EXE_Block_Key))
VirtualProtect_(StartAddress,Length,OrigMode,Mode)
ProcedureReturn 1
EndProcedure
;The code address
CStart = ?S1
CEnd = ?E1
CDiff = ?E1-?S1
Scramble(CStart,CDiff)
;Here's the protected code!
!_MarkBegin1 db $eb,$06,$eb,$fc,$eb,$fa,$eb,$f8
S1:
MessageRequester("","This code here is scrambled")
For t = 97 To 122
a$ + Chr(t)
Next
MessageRequester("","Result "+a$)
E1:
!_MarkEnd1 db $eb,$04,$eb,$04,$eb,$fc,$eb,$fc
;The protected code ends here
MessageRequester("","OUT MWAHAHAHAHAHAHAHAHAHAHA")
Enjoy!