I'm conscient it's not beautifull/optimised code, so any constructive comments are welcome !
It works with almost all EXE file (excluding .NET).
It does not work with some other files example : ollydbg.exe I still don't know why.
PS : Resetting the boundimport DATA DIRECTORY structure does not blow anything since it's optional.
The added section does NOTHING, it just jump on the OEP !
Next step is to crypt the fisrt section of the target exe. (for the sake of a test)
Sorry, comments are in french, easyer for me to read, I believe it's not to hard to understand anyway
The target EXE MUST be C:\CALC.EXE (for the sake of an example)
format PE GUI 4.0
entry start
include "c:\fasm\include\win32a.inc"
include "c:\fasm\include\PE.inc"
include "c:\fasm\include\API\KERNEL32.INC"
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;MAPPING DU FICHIER EN MEMOIRE;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
start:
;on ouvre un handle sur le fichier
push NULL
push FILE_ATTRIBUTE_NORMAL
push OPEN_EXISTING
push NULL
push NULL
push GENERIC_READ or GENERIC_WRITE
push szFilename
call [CreateFile]
mov [hFile], eax
;on recupere la taille du fichier
push NULL
push [hFile]
call [GetFileSize]
;On ajoute la taille du code a injecter dans l'exe
add eax, NEWSECTION_SIZE
;On aligne que si on aligne la taille des rawDATA et c'est pas obligatoire visiblement ...
;mov ecx, 200h
;call alignoffset
mov [filesize], eax
;on crée un map du fichier ouvert en mémoire
push mapName
push [filesize]
push NULL
push PAGE_READWRITE
push NULL
push [hFile]
call [CreateFileMapping]
mov [hMap],eax
;mapping fu fichier
push [filesize]
push NULL
push NULL
push FILE_MAP_WRITE
push [hMap]
call [MapViewOfFile]
mov [mapLocation],eax
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;FIN MAPPING DU FICHIER EN MEMOIRE;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;RECUPERATION DES INFOS PE NECESSAIRES;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;On pointe sur le DOS STUB des headers
mov esi, [mapLocation]
;Check validité PE
is_pe:
cmp word[esi], "MZ"
jne exitprocess
add esi, [esi + 3Ch] ;on pointe sur e_lfanew du stub PE des headers
cmp word[esi], "PE"
jne exitprocess
;On pointe sur IMAGE_FILE_HEADER
get_peinfo:
add esi, 4h ;add du magic PE
mov dword[PEOffset], esi ;on backup la position du debut de IMAGE_FILE_HEADER
virtual at esi
ifh IMAGE_FILE_HEADER
end virtual
;on backup la taille de IMAGE_OPTIONAL_HEADER32 ainsi que le nb de section
push [ifh.SizeOfOptionalHeader]
pop [sizeofoptionalheader]
push [ifh.NumberOfSections]
pop [numberofsections]
;on incremente le nb de section dans le PE
inc [ifh.NumberOfSections]
;On pointe sur les IMAGE_OPTIONAL_HEADER32
add esi,14h ; sizeof.IMAGE_FILE_HEADER
virtual at esi
ioh IMAGE_OPTIONAL_HEADER32
end virtual
;On backup l'OEP, l'imageBase, l'alignement des sections et la taille de l'image
push [ioh.AddressOfEntryPoint]
pop [oep]
push [ioh.ImageBase]
pop [imagebase]
push [ioh.SectionAlignment]
pop [sectionalignment]
push [ioh.SizeOfImage]
pop [sizeofimage]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;FIN RECUPERATION DES INFOS PE NECESSAIRES;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;RESET BOUNDIMPORT DIRECTORY;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;On est dans la structure directory pointant sur les BOUNDSIMPORTS
mov dword[esi + 0B8h] , 0 ;reset premier membre
mov dword[esi + 0BCh] , 0 ;reset deuxieme membre
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;FIN RESET BOUNDIMPORT DIRECTORY;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;GO SUR LA FIN DES SECTION HEADERS;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;on est au debut des section headers
add si, word[sizeofoptionalheader]
virtual at esi
ish IMAGE_SECTION_HEADER
end virtual
xor eax, eax
mov ax, 28h
imul ax, [numberofsections] ;numberofsections * taille des headers
add esi, eax ;fin des sections headers
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;FIN GO SUR LA FIN DES SECTION HEADERS;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;CREATION HEADER NOUVELLE SECTION;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;on pointe sur les headers a ajouter
mov edi, _sh
xchg edi, esi
;edi = le fichier mapper à la fin des headers
;esi = le header a ajouter
;RVA on aligne sans ça on a jamais d'exe valide
mov eax, [edi-5*8+8D] ; VA derniere section
add eax, [edi-5*8+12D] ;+VS derniere section
mov ecx, [sectionalignment]
call alignoffset
mov dword[va], eax
;SIZEOFRAWDATA on aligne pas au file align si on aligne pas la taille de l'exe dans le map
mov eax, NEWSECTION_SIZE
;mov ecx, 200h
;call alignoffset ;visiblement optionnel si on aligne pas la taille du fichier lors du map
mov dword[rs], eax
;VIRTUALSIZE
mov eax, NEWSECTION_SIZE
mov dword[vs], eax
;RAWOFFSET si j'ajoute l'align ça plante !
mov eax, [edi-5*8+20D] ; RO derniere section
add eax, [edi-5*8+16D] ;+RS derniere section
mov dword[ro], eax
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;FIN CREATION HEADER NOUVELLE SECTION;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;MOD TAILLE IMAGE + EP;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pushad
mov esi, dword[PEOffset]
add esi,14h ;sizeof IMAGE_FILE_HEADER
virtual at esi
ioh1 IMAGE_OPTIONAL_HEADER32
end virtual
;mod oep
mov ecx, [va]
mov [ioh.AddressOfEntryPoint],ecx
;mod sizeOfImage
xor ecx, ecx
mov ecx, [va]
add ecx, [vs]
mov [ioh1.SizeOfImage], ecx
popad
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;FIN MOD TAILLE IMAGE + EP;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;ECRITURE NEW SECTION HEADERS;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;on ecrit le nouveau section header, et si on a pas la place ??
mov ecx,28h
rep movsb
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;FIN ECRITURE NEW SECTION HEADERS;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;on backup l'OEP + IMAGEBASE pour re-jumper dessus apres l'exec du code de notre nouvelle section
mov edi, dword[oep]
add edi, dword[imagebase]
mov dword[foep], edi
;et si data EOF ??
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;ECRITURE NOUVELLE SECTION AT EOF;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mov edi, [ro] ;fin code derniere section
add edi, [mapLocation] ;on ajoute le handle du map
mov esi, newsection ;src
xor ecx, ecx
mov ecx, NEWSECTION_SIZE ;taille dans ecx
cld ;reset flag direction
rep movsb ;ecriture
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;FIN ECRITURE NOUVELLE SECTION AT EOF;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;on sort en refermant tout les handles
exitprocess:
push NULL
push mapLocation
call [FlushViewOfFile]
push [mapLocation]
call [UnmapViewOfFile]
push [hMap]
call [CloseHandle]
push [hFile]
call [CloseHandle]
push NULL
call [ExitProcess]
;fonction alignement fichier
alignoffset:
xor edx, edx
div ecx
inc eax
mul ecx
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;DECLARATIONS;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;structure new section
_sh:
szName db ".daphnee"
vs dd 0h
va dd 0h
rs dd 0h
ro dd 0h
reserved dd 0h, 0h, 0h
flags dd 0A0000020h
numberofsections dw ?
oep dd ?
imagebase dd ?
sectionalignment dd ?
sizeofimage dd ?
sizeofoptionalheader dw ?
PEOffset dd ?
hFile dd ?
hMap dd ?
mapLocation dd ?
szFilename db 'C:\CALC.EXE',0
mapName db "mapHandleName", 0
filesize dd ?
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;FIN DECLARATIONS;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;code a injecter dans l'exe
newsection:
call .hwndDelta
.hwndDelta:
pop ebp
sub ebp, .hwndDelta
;jmp sur l'EOP
jmp [ebp + foep]
;declaration
foep dd ?
NEWSECTION_SIZE = $ - newsection ;taille du code
data import
library kernel32, "kernel32.dll"
end data