.386 .model flat, stdcall option casemap :none include windows.inc include user32.inc include kernel32.inc include comdlg32.inc includelib user32.lib includelib kernel32.lib includelib comdlg32.lib DlgProc PROTO :DWORD,:DWORD,:DWORD,:DWORD Validate PROTO :DWORD AddSection PROTO :DWORD .data strFilter db "Executable Files (*.exe, *.dll)",0, "*.exe;*.dll",0,"All Files",0,"*.*",0,0 OpenError db "Unable to open target file",0 Invalid db "This is not a valid PE file!!",0 Success db "New section added successfully",0 NoSpace db "No space for new Section Header",0 Backup db ".bak",0 ;*********VALUES REQUIRED TO CONSTRUCT NEW SECTION************* NewSecName dd "WEN." NewSecSize dd 100h NewSecChar dd 0E0000060h KeepBkup db TRUE .data? ofn OPENFILENAME <> hInstance HINSTANCE ? TargetName db 512 dup(?) hTarget dd ? hMapping dd ? pMapping dd ? pPEHeader dd ? Buffer db 512 dup (?) .const IDD_MAIN equ 1001 IDC_TARGET equ 1003 IDC_BROWSE equ 1004 IDC_GO equ 1005 IDC_EXIT equ 1006 ARIcon equ 2001 .code start: invoke GetModuleHandle, NULL mov hInstance, eax invoke DialogBoxParam,hInstance,IDD_MAIN,0,addr DlgProc,0 invoke ExitProcess, eax DlgProc proc hWin:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD mov eax,uMsg .if eax==WM_INITDIALOG invoke LoadIcon,hInstance,2001 invoke SendMessage,hWin,WM_SETICON,1,eax .elseif eax==WM_COMMAND mov eax,wParam .if eax==IDC_BROWSE mov ofn.lStructSize,SIZEOF ofn mov ofn.lpstrFilter,offset strFilter mov ofn.lpstrFile,offset TargetName mov ofn.nMaxFile,512 mov ofn.Flags,OFN_FILEMUSTEXIST+OFN_PATHMUSTEXIST+\ OFN_LONGNAMES+OFN_EXPLORER+OFN_HIDEREADONLY invoke GetOpenFileName,addr ofn .if eax==TRUE invoke SetDlgItemText,hWin,IDC_TARGET,addr TargetName invoke RtlZeroMemory,addr TargetName,512 .endif .elseif eax==IDC_GO invoke GetDlgItemText,hWin,IDC_TARGET,addr TargetName,512 invoke lstrlen,addr TargetName .if eax!=0 invoke Validate,addr TargetName .if eax==1 invoke AddSection,addr TargetName .if eax==1 invoke MessageBox,hWin,addr Success,0,0 .elseif eax==-1 invoke MessageBox,hWin,addr NoSpace,0,0 .endif .elseif eax==-1 invoke MessageBox,hWin,addr Invalid,0,0 .endif .endif .elseif eax==IDC_EXIT invoke SendMessage,hWin,WM_CLOSE,0,0 .endif .elseif eax==WM_CLOSE invoke EndDialog,hWin,0 .endif xor eax,eax ret DlgProc endp Validate proc FileName:DWORD ;************************************************************************************** ; TAKES POINTER TO TARGET NAME, RETURNS 1 IF VALID, -1 IF NOT, 0 IF UNABLE TO OPEN FILE ;************************************************************************************** LOCAL ReturnValue:DWORD invoke CreateFile,FileName,GENERIC_READ,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0 .if eax!=INVALID_HANDLE_VALUE mov hTarget,eax invoke CreateFileMapping,eax,0,PAGE_READONLY,0,0,0 mov hMapping,eax invoke MapViewOfFile,eax,FILE_MAP_READ,0,0,0 mov pMapping,eax .if [eax.IMAGE_DOS_HEADER.e_magic]==IMAGE_DOS_SIGNATURE add eax,[eax.IMAGE_DOS_HEADER.e_lfanew] .if [eax.IMAGE_NT_HEADERS.Signature]==IMAGE_NT_SIGNATURE mov ReturnValue,1 jmp @EXIT .endif .else mov ReturnValue,-1 jmp @EXIT .endif @EXIT: invoke UnmapViewOfFile,pMapping invoke CloseHandle,hMapping invoke CloseHandle,hTarget mov eax,ReturnValue ret .else invoke MessageBox,0,addr OpenError,0,0 xor eax,eax Ret .endif Validate EndP AddSection proc FileName:DWORD ;********************************************************************************************* ; TAKES POINTER TO TARGET NAME, RETURNS 1 IF SUCCESS, -1 IF NO SPACE, 0 IF UNABLE TO OPEN FILE ;********************************************************************************************* LOCAL ReturnValue:DWORD ;*******MAKE BACKUP*************************************************** invoke lstrcpy,addr Buffer,FileName invoke lstrcat,addr Buffer,addr Backup invoke CopyFile,FileName,addr Buffer,TRUE ;*******OPEN FILE MAP IN AND INCREASE SIZE**************************** invoke CreateFile,FileName,GENERIC_READ+GENERIC_WRITE,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0 .if eax!=INVALID_HANDLE_VALUE mov hTarget,eax invoke GetFileSize,eax,0 add eax,NewSecSize invoke CreateFileMapping,hTarget,0,PAGE_READWRITE,0,eax,0 mov hMapping,eax invoke MapViewOfFile,eax,FILE_MAP_ALL_ACCESS,0,0,0 mov pMapping,eax ;******CHECK ENOUGH ROOM FOR NEW ISH IN SECTION TABLE****************** add eax,[eax.IMAGE_DOS_HEADER.e_lfanew] ;pointer to PE header in eax mov pPEHeader,eax movzx esi,[eax.IMAGE_NT_HEADERS.FileHeader.NumberOfSections];no of sections in ecx inc esi ;add 1 imul esi,esi,40 ;calc size of all ISHs add esi,0F8h ;add above to offset of sec table from PE header mov ebx,pMapping add esi,[ebx.IMAGE_DOS_HEADER.e_lfanew] ;add above to offset of PE header from beginning of file .if esi<[eax.IMAGE_NT_HEADERS.OptionalHeader.SizeOfHeaders] ;cmp offset of end of new ISH to offset of first section ;*******IF SO FILL NEW ISH********************************************** add esi,ebx ;make above offset into a pointer by adding base address sub esi,40 mov edi,esi ;pointer to start of new ISH in edi sub esi,40 ;pointer to start of last ISH in esi mov eax,NewSecName mov dword ptr [edi.IMAGE_SECTION_HEADER.Name1],eax ;write in Name1 mov eax,NewSecSize mov [edi.IMAGE_SECTION_HEADER.Misc.VirtualSize],eax ;write in virtual size xor edx,edx ;align raw size of new sec mov ebx,pPEHeader mov ecx,[ebx.IMAGE_NT_HEADERS.OptionalHeader.FileAlignment] div ecx ;divides file alignment by raw size, quotient into eax, remainder into edx .if edx!=0 ;if no remainder, ie already aligned then multiply back up inc eax ;if there is remainder, ie not aligned, then .endif ;add 1 to quotient and multiply back up (rounds up to alignment value) mul ecx mov [edi.IMAGE_SECTION_HEADER.SizeOfRawData],eax ;write in raw size mov eax,[esi.IMAGE_SECTION_HEADER.VirtualAddress] ;get RVA of last section add eax,[esi.IMAGE_SECTION_HEADER.Misc.VirtualSize] ;add virt size of last sec to get RVA of new sec xor edx,edx ;align RVA of new sec mov ecx,[ebx.IMAGE_NT_HEADERS.OptionalHeader.SectionAlignment] div ecx .if edx!=0 inc eax .endif mul ecx mov [edi.IMAGE_SECTION_HEADER.VirtualAddress],eax ;write in RVA of new sec mov eax,[esi.IMAGE_SECTION_HEADER.PointerToRawData] ;get raw offset of last sec add eax,[esi.IMAGE_SECTION_HEADER.SizeOfRawData] ;add raw size xor edx,edx ;align raw offset mov ecx,[ebx.IMAGE_NT_HEADERS.OptionalHeader.FileAlignment] div ecx .if edx!=0 inc eax .endif mul ecx mov [edi.IMAGE_SECTION_HEADER.PointerToRawData],eax ;write in raw offset of new sec mov edx,NewSecChar mov [edi.IMAGE_SECTION_HEADER.Characteristics],edx ;write in new sec characteristics ;*******UPDATE PE HEADER*********************************************** mov eax,[edi.IMAGE_SECTION_HEADER.Misc.VirtualSize] ;get new sec virt size xor edx,edx ;align to section alignment mov ecx,[ebx.IMAGE_NT_HEADERS.OptionalHeader.SectionAlignment] div ecx .if edx!=0 inc eax .endif mul ecx add eax,[edi.IMAGE_SECTION_HEADER.VirtualAddress] ;add RVA where new section begins in memory mov [ebx.IMAGE_NT_HEADERS.OptionalHeader.SizeOfImage],eax ;write new size of image inc [ebx.IMAGE_NT_HEADERS.FileHeader.NumberOfSections];add 1 to no of sections mov ReturnValue,1 jmp @EXIT .else ;*******IF NO SPACE THEN RESTORE FROM BACKUP AND DELETE BACKUP********** invoke UnmapViewOfFile,pMapping invoke CloseHandle,hMapping invoke CloseHandle,hTarget invoke DeleteFile,FileName invoke CopyFile,addr Buffer,FileName,FALSE invoke DeleteFile,addr Buffer mov ReturnValue,-1 jmp @EXIT .endif @EXIT: ;*******DECIDE WHETHER TO KEEP BACKUP AFTER SUCCESS********************* invoke UnmapViewOfFile,pMapping invoke CloseHandle,hMapping invoke CloseHandle,hTarget .if KeepBkup==FALSE invoke DeleteFile,addr Buffer .endif mov eax,ReturnValue ret .else invoke MessageBox,0,addr OpenError,0,0 xor eax,eax Ret .endif Ret AddSection EndP end start