Hvordan Lage en antivirusmotor

Sende

Bruker Rating4.54(13 stemmer)

Innledning

når jeg roaming rundt techies-forumene, ser jeg ofte noen mennesker (og mange ikke veldig erfarne) som spør om «Hvordan lager jeg et antivirus», noen ganger med ikke veldig tilpassede språk (bat, PHP, …) og har en feil ide om hva et antivirus er, og hvordan det skal bygges.

jeg har også sett mange «Antivirusprogrammer» laget av kiddies, med svært få still-at-school folk og ca 4 timer per dag med koding på flere uker. Jeg forteller ikke at barn ikke er dyktige, men jeg forteller at å bygge en antivirusmotor trenger enten mange dyktige mennesker med heltidsjobb pluss mye tid til å frigjøre en anstendig programvare eller mye penger til å betale dem 🙂 (i tilfelle de ikke er frivillige).

så, jeg vil dekke her retningslinjene for en grunnleggende antivirus koding, For Windows Og I C / C++. Man kan finne her pekerne til å designe en antivirusmotor, eller bare lære hvordan de fleste er bygget.

Beskyttelse

For en god beskyttelse må Et Antivirusprogram ha minst en driver for å kunne kjøre kode i kjernen og generelt ha tilgang til Kernel Apier. Fra Og Med Vista forsto Microsoft At Antivirusindustrien trengte nøkler for å komme inn i kjernen og aktivere filtre på strategiske steder, for eksempel filsystem, register og nettverk. Ikke bli bedøvet hvis det å bygge et antivirus for pre-Vista-systemer kan være en reell smerte, fordi den ikke var laget for dette.

  • Men På Pre-Vista-systemer brukte Antivirusselskaper å bruke rootkit-lignende funksjoner for å beskytte dørene (selv Om Det ikke ble anbefalt I Det Hele Tatt Av Microsoft) og kunne beskytte systemet ditt. De brukte det vi kaller «Kroker» (API omveier for filtrering formål).
  • På Vista + ga Microsoft Apier for å sette inn vår lave nivådriver mellom userland-anrop og Kernel Apier. På den måten er det enkelt å registrere et antivirusprodukt i kjernen. Mer, det slags registreringsbasert system tillater oss å sende vår systemsikkerhet i lag, hvor flere produkter med ulike mål kan samle seg. Dette var ikke tilfelle for kroker, da implementeringen var helt produktavhengig.

NOTAT: Jeg vil ikke dekke løsninger med kroker for Pre-Vista systemer, fordi det er lett å finne på internett, og fordi det ville trenge et helt kapittel for å forklare hvordan å koble, hvor du skal koble og så… Men du må vite det er den samme ideen Enn kjernen Apier, bortsett fra at Du må implementere selv Hva Microsoft gitt På Vista+ systemer.

for å lære om kodingsdrivere, kan du sjekke at nyttige lenker:
http://msdn.microsoft.com/en-us/library/windows/hardware/gg490655.aspx
http://www.codeproject.com/Articles/9504/Driver-Development-Part-1-Introduction-to-Drivers

å lære om kroker, du kan sjekke at grunnleggende eksempel:
http://www.unknowncheats.me/forum/c-and-c/59147-writing-drivers-perform-kernel-level-ssdt-hooking.html

Process

det første du må beskytte brukeren fra, er lanseringen av ondsinnede prosesser. Dette er det grunnleggende. Antivirus bør registrere En PsSetCreateProcessNotifyRoutineEx tilbakeringing. Ved å gjøre dette, på hver prosessopprettelse, og før hovedtråden begynner å løpe (og forårsake skadelige ting), blir antivirus tilbakeringing varslet og mottar all nødvendig informasjon.

den mottar prosessnavnet, filobjektet, PID og så videre. Som prosessen venter, kan sjåføren fortelle sin tjeneste for å analysere prosessens minne for noe skadelig. Det det grunnla noe, sjåføren vil bare sette CreationStatus TIL FALSE og retur.

NTSTATUS PsSetCreateProcessNotifyRoutineEx( _In_ PCREATE_PROCESS_NOTIFY_ROUTINE_EX NotifyRoutine, _In_ BOOLEAN Remove);
VOID CreateProcessNotifyEx( _Inout_ PEPROCESS Process, _In_ HANDLE ProcessId, _In_opt_ PPS_CREATE_NOTIFY_INFO CreateInfo);
typedef struct _PS_CREATE_NOTIFY_INFO { SIZE_T Size; union { ULONG Flags; struct { ULONG FileOpenNameAvailable :1; ULONG Reserved :31; }; }; HANDLE ParentProcessId; CLIENT_ID CreatingThreadId; struct _FILE_OBJECT *FileObject; PCUNICODE_STRING ImageFileName; PCUNICODE_STRING CommandLine; NTSTATUS CreationStatus;} PS_CREATE_NOTIFY_INFO, *PPS_CREATE_NOTIFY_INFO;

Tråder

i samme ide enn for prosesser, kan tråder være en måte for ondsinnede ting å forårsake skader. For eksempel kan man injisere noen kode i en legitim prosess, og starte en ekstern tråd på den koden i prosessens kontekst (lett å følge? 🙂 ). Den veien, en legit prosess kan gjøre skadelige ting.

Vi kan filtrere nye tråder med PsSetCreateThreadNotifyRoutine tilbakeringing. Hver gang en tråd er opprettet, blir antivirusprogrammet varslet MED TID og PID. Dermed er det i stand til å se på trådens startadressekode, analysere den og enten stoppe tråden eller gjenoppta den.

NTSTATUS PsSetCreateThreadNotifyRoutine( _In_ PCREATE_THREAD_NOTIFY_ROUTINE NotifyRoutine);
VOID(*PCREATE_THREAD_NOTIFY_ROUTINE) ( IN HANDLE ProcessId, IN HANDLE ThreadId, IN BOOLEAN Create );

Bilder

den tredje dynamiske trusselen handler om bilder som kan lastes inn i minnet. Et bilde er EN PE-fil, enten EN EXE, EN DLL eller SYS fil. For å bli varslet om lastet bilder, bare registrere PsSetLoadImageNotifyRoutine. At tilbakeringing tillater oss å bli varslet når bildet er lastet inn i virtuelt minne, selv det er aldri utført. Vi kan da oppdage når en prosess forsøker å laste EN DLL, å laste en driver eller å brenne en ny prosess.

tilbakeringingen får informasjon om hele bildebanen (nyttig for statisk analyse), og jo viktigere Etter min mening, Bildebaseadressen (for minneanalyse). Hvis bildet er skadelig antivirus kan bruke små triks for å unngå utførelsen, som parsing in-memory bildet og gå til entrypoint, deretter ringe forsamlingen opcode » ret » for å oppheve det.

NTSTATUS PsSetLoadImageNotifyRoutine( _In_ PLOAD_IMAGE_NOTIFY_ROUTINE NotifyRoutine);
VOID (*PLOAD_IMAGE_NOTIFY_ROUTINE)( __in_opt PUNICODE_STRING FullImageName, __in HANDLE ProcessId, __in PIMAGE_INFO ImageInfo );
typedef struct _IMAGE_INFO { union { ULONG Properties; struct { ULONG ImageAddressingMode : 8; //code addressing mode ULONG SystemModeImage : 1; //system mode image ULONG ImageMappedToAllPids : 1; //mapped in all processes ULONG Reserved : 22; }; }; PVOID ImageBase; ULONG ImageSelector; ULONG ImageSize; ULONG ImageSectionNumber;} IMAGE_INFO, *PIMAGE_INFO;

Filsystem

Når hver dynamisk ting er sikret, bør et antivirusprogram kunne varsle brukeren om skadelige ting på fly, ikke bare når de skal starte. Et antivirusprogram skal kunne skanne filer når brukeren åpner en mappe, et arkiv eller når det lastes ned på disken. Mer, et antivirusprogram skal kunne beskytte seg selv ved å forby noe program for å slette filene.

måten å gjøre alt dette på, er å installere en driver i filsystemet, og mer spesifikt et minifilter av et eldre filter (gammel måte). Her snakker vi om minifilter.

et minifilter er en bestemt type driver som kan registrere tilbakeringinger på Hver Lese / Skrive-operasjon som gjøres på filsystemet (irp-hovedfunksjoner). En IRP (Interrupt Request Paquet) er et objekt som brukes til å beskrive En Lese / Skrive-operasjon på disken, som overføres sammen med driverstakken. Minifilteret vil ganske enkelt settes inn i den stakken, og motta DEN IRP for å bestemme hva du skal gjøre med den (tillat/avslå operasjon).

for et lite eksempel på minifilter, vennligst sjekk den nyttige lenken eller den. Microsofts retningslinjer finnes her.

DU finner også 2 eksempler PÅ wdk-dokumentasjonen her og her.

en grunnleggende minifilter tilbakeringing ser slik ut. Det er 2 typer tilbakeringing, pre drift Og etter operasjonen, som er i stand til å filtrere før av etter spørringen. Her er en preoperation pseudokode:

FLT_PREOP_CALLBACK_STATUS PreOperationCallback (__inout PFLT_CALLBACK_DATA Data, __in PCFLT_RELATED_OBJECTS FltObjects, __deref_out_opt PVOID *CompletionContext){ ... if ( all_good ) { return FLT_PREOP_SUCCESS_NO_CALLBACK; } else { // Access denied Data->IoStatus.Information = 0; Data->IoStatus.Status = STATUS_ACCESS_DENIED; return FLT_PREOP_COMPLETE; } }

Register

registeret er et av de mest kritiske stedene å beskytte. Det er mange mange måter for en malware å holde vedvarende hånd på systemet ved å registrere en enkelt (eller få) nøkler / verdier i registret. De mest kjente stedene Er Kjøre nøkler Og Tjenester. Dette er også stedet der antivirusprogrammet kan bli beseiret (sammen med filsystemet), ved å bare fjerne driver/tjenestenøkler, slik at den ikke lenger starter på nytt ved systemstart.

dette er ikke en reell nødvendighet for et antivirus for å beskytte omstart steder, de fleste av dem ikke. Men de må vokte sine installere registernøkler, for å unngå å bli beseiret lett av malwares. Dette kan gjøres ved å registrere CmRegisterCallback.

tilbakeringingen gir nok informasjon til å få hele nøkkelnavnet, typen tilgang (Opprett, Endre Navn, Slett, … ) og oppringerens PID. På den måten er det enkelt å gi tilgang eller ikke til samtalen, ved å angi Statusfeltet For tilbakeringing Etter Operasjonen.

NTSTATUS CmRegisterCallbackEx(_In_ PEX_CALLBACK_FUNCTION Function,_In_ PCUNICODE_STRING Altitude,_In_ PVOID Driver,_In_opt_ PVOID Context,_Out_ PLARGE_INTEGER Cookie,_Reserved_ PVOID Reserved);
EX_CALLBACK_FUNCTION RegistryCallback;NTSTATUS RegistryCallback( _In_ PVOID CallbackContext, _In_opt_ PVOID Argument1, _In_opt_ PVOID Argument2){ ... }Argument1 = typedef enum _REG_NOTIFY_CLASS { RegNtDeleteKey, RegNtPreDeleteKey = RegNtDeleteKey,...Argument2 = typedef struct _REG_POST_OPERATION_INFORMATION { PVOID Object; NTSTATUS Status; PVOID PreInformation; NTSTATUS ReturnStatus; PVOID CallContext; PVOID ObjectContext; PVOID Reserved;} REG_POST_OPERATION_INFORMATION, *PREG_POST_OPERATION_INFORMATION;

Nettverk (Brannmur)

for å beskytte dørene til hele internett-trafikken som kan være stor på visse systemer (servere, store båndbreddebrukere) uten å bli bremset av kontekstbyttet som foregår i userland, anbefales det ikke å installere en brannmur som ikke har noen underliggende driver, bortsett fra noen nettleserfiltre som kan være nok for http-trafikk, men det vil ikke beskytte mot skadelig kommunikasjon inn/ut.

for å få riktig implementering av brannmur, bør man kode EN NDIS, TDI eller en annen metode for lavt NIVÅ IP-filtreringsdriver. NDIS / TDI er litt vanskelig å gjøre, og vil kreve mye kunnskap (mer enn andre filtre etter min mening).

uansett, Her Er noen tips for å starte koding av en slik driver, microsofts retningslinjer og gammel codeproject-opplæring (men fortsatt god å lese), et eksempel PÅ NDIS-brannmur og et eksempel PÅ tdi-brannmur. Her er også en god skriving om NDIS firewall bypass trick, og en liten forklaring om nettverksdriverstakken,

Userland protection

userland protection er ikke en nødvendighet, men kan være en ekstra modul mot Trojanske Bankfolk, og mer spesifikt mot prosessspioner. De injiseres vanligvis i hver prosess, av flere grunner.

Først kan de (på forespørsel) drepe prosessen hvis den er identifisert som skadelig programvare (dette bør ikke skje, fordi AVs skal stoppe det før det starter). Det er alltid lettere å stoppe en prosess når du er i sin sammenheng.

For Det Andre er de i Stand til å beskytte kritisk prosess, som nettlesere, mot å hekte malwares i stand til å omvei OG filtrere API-anrop for å samle passord, bankinformasjon og omdirigere internettflyt til malware-servere. De bare se FOR IAT modifikasjon, for skjøting, og kan også sette kroker seg å unngå LoadLibray av en malware DLL, og dermed forby visse metoder for kode injeksjon.

en enkel måte å injisere en protector DLL i alle prosesser er å bruke appinitdll registernøkkelen for å registrere protector DLL. DET vil laste DLL inn i hver prosess startet på systemet, så snart De kobler User32.dll bilde(de fleste av dem gjør).

Analysemotor

analysemotoren er en av de viktigste delene,den er ansvarlig for å analysere fil / minneprøver som kommer fra driverne. Hvis må være rask (selv med en stor database), og skal kunne håndtere de fleste filtyper (Selvutpakkede kjørbare filer, Arkiver-RAR, ZIP, Pakkede filer – UPX, … ) :

  • Unpacker: den modulen må kunne oppdage og pakke ut de fleste kjente packers(UPX, Armadillo, ASPack,…)
  • Signaturmotor: databasen til et antivirusprogram inneholder millioner av signaturer, og motoren skal kunne raskt søke etter dem i en prøve. Dermed bør en meget kraftig algoritme være en del av den. Eksempler : AhoCorasick, RabinKarp, streng matchende algoritmer.
  • Sandkasse : den modulen er ikke nødvendig, Men vil være et pluss å kunne kjøre prøver i et begrenset minne, uten effekt på systemet. Det kan bidra til å pakke ut prøver pakket med ukjente pakkere, og hjelpe heuristisk motor (se etter) for å oppdage API-kall som kan anses som mistenkelig eller skadelig. Noen gode sandkasser her.
  • Heuristisk motor: som sagt ovenfor søker den heuristiske motoren ikke etter signaturer, men ser heller etter mistenkelig oppførsel (dvs. eksempel som åpner en connexion på nettstedet hxxp: / / malware_besite. com). Det kan gjøres ved statisk analyse, eller gjennom en sandkasse.

Signatursyntaks

signatursyntaksen er «ordboken» for språket signaturmotoren forstår. Det er en måte å formalisere hva som er mønsteret å finne, hvordan du søker det og hvor du skal søke det inn i prøven. Syntaksen må være enkel nok for forskerne å forstå, kraftig nok til å håndtere hver brukstilfelle, og lett å analysere for bedre motorprestasjoner.

VirusTotal har utviklet en god syntaks og motor (Yara prosjekt), som er åpen kildekode. Det burde være en god peker for å lage din egen syntaks, eller bare bruke den. Her er også et godt innlegg blogg om hvordan lage signaturer for antivirus.

eksempel på signatur:

rule silent_banker : banker{ meta: description = "This is just an example" thread_level = 3 in_the_wild = true strings: $a = {6A 40 68 00 30 00 00 6A 14 8D 91} $b = {8D 4D B0 2B C1 83 C0 27 99 6A 4E 59 F7 F9} $c = "UVODFRYSIHLNWPEJXQZAKCBGMT" condition: $a or $b or $c}

Selvbeskyttelse

selvbeskyttelsen er svært viktig for et antivirusprogram, for å unngå å bli beseiret av en skadelig programvare og fortsette å beskytte brukeren. Dette er grunnen til at et antivirusprogram skal kunne beskytte sin egen installasjon og holde utholdenhet ved omstart.

det er flere steder å beskytte: Filer, Registernøkler, Prosesser / Tråder, Minne.

  • Filbeskyttelse er implementert i minifilteret, med spesielle regler for filene til antivirusprogrammet (ingen tilgang i sletting, omdøping, flytting, skriving).
  • Registerbeskyttelse gjøres til registerfilteret, med tilgang nektet for registernøkler til driveren og tjenesten.
  • drivertrådene er beskyttet, fordi det er ganske umulig å laste ut kjernemodulen uten å krasje systemet
  • for å kunne beskytte tjenesten, som er en userland-prosess, 2 løsninger:
  1. det enkleste ville være å legge til regler for feil i service manager, og sett hver feilregel til «restart service». På den måten, når tjenesten ikke stoppes av service manager, starter den på nytt. Selvfølgelig bør tjenesten ikke kunne godta kommandoer før systemet ikke starter på nytt (eller stopper).
491838-428-487-263x300
  1. Den andre metoden, som er mer generisk, ville være å sette tilbakeringinger på prosesshåndtak Med ObRegisterCallbacks.

ved å sette ObjectType Til PsProcessType og Operasjonen TIL OB_OPERATION_HANDLE_CREATE, får Du en tilbakeringing Før og Etter operasjonen, og du kan returnere ACCESS_DENIED til ReturnStatus hvis prosesshåndtaket spørres Har Gitt Tilgang som har prosessavslutningsrettigheter (eller prosessskrivingsrettigheter, eller noe som kan føre til krasj/drep), og selvfølgelig hvis prosessen er en antivirusprogrammet må beskytte (for eksempel tjenesten).

selvfølgelig må man også beskytte Duplikathåndtak og psthreadtype for å unngå termineringsmetode som krever å ta tak i et håndtak på prosessen eller en tråd. Her er et lite eksempel på bruk av den tilbakeringingen.

NTSTATUS ObRegisterCallbacks( _In_ POB_CALLBACK_REGISTRATION CallBackRegistration, _Out_ PVOID *RegistrationHandle);

typedef struct _OB_CALLBACK_REGISTRATION { USHORT Version; USHORT OperationRegistrationCount; UNICODE_STRING Altitude; PVOID RegistrationContext; OB_OPERATION_REGISTRATION *OperationRegistration;} OB_CALLBACK_REGISTRATION, *POB_CALLBACK_REGISTRATION;
typedef struct _OB_OPERATION_REGISTRATION { POBJECT_TYPE *ObjectType; OB_OPERATION Operations; POB_PRE_OPERATION_CALLBACK PreOperation; POB_POST_OPERATION_CALLBACK PostOperation;} OB_OPERATION_REGISTRATION, *POB_OPERATION_REGISTRATION;
VOID ObjectPostCallback( _In_ PVOID RegistrationContext, _In_ POB_POST_OPERATION_INFORMATION OperationInformation);
typedef struct _OB_POST_OPERATION_INFORMATION { OB_OPERATION Operation; union { ULONG Flags; struct { ULONG KernelHandle :1; ULONG Reserved :31; }; }; PVOID Object; POBJECT_TYPE ObjectType; PVOID CallContext; NTSTATUS ReturnStatus; POB_POST_OPERATION_PARAMETERS Parameters;} OB_POST_OPERATION_INFORMATION, *POB_POST_OPERATION_INFORMATION;
typedef union _OB_POST_OPERATION_PARAMETERS { OB_POST_CREATE_HANDLE_INFORMATION CreateHandleInformation; OB_POST_DUPLICATE_HANDLE_INFORMATION DuplicateHandleInformation;} OB_POST_OPERATION_PARAMETERS, *POB_POST_OPERATION_PARAMETERS;
typedef struct _OB_POST_CREATE_HANDLE_INFORMATION { ACCESS_MASK GrantedAccess;} OB_POST_CREATE_HANDLE_INFORMATION, *POB_POST_CREATE_HANDLE_INFORMATION;

GUI (Graphical User Interface)

Dette er den synlige delen av isfjellet. Etter min mening, en (kanskje den) viktigste delen hvis du vil selge produktet ditt. Brukere elsker det som er vakkert, enkelt å bruke, intuitivt. Selv om det ikke er 100% effektivt. GUI må være sexy.

GUI er bare et tomt skall, det gjør bare grafiske behandlinger, og sender / mottar kommandoer til kjernen (tjenesten). Det viser også fremdriftslinjer, hva som blir analysert, gir konfigurasjon, Og Så… Her er Avast UI. Sexy, ikke sant? 🙂

avast

Arkitektur

den globale arkitekturen kan være noe som ser slik ut:

  1. GUI: ingen administrative rettigheter, SVAK
  2. Vakt DLL(er) : nettleser beskyttelse, MEDIUM
  3. Tjeneste : Admin rettigheter. Fungerer SOM en gateway til kjernekode og ta beslutninger sammen med noen database, STRONG
  4. Driver ( er): Kernel filters, STRONG

GUI trenger ingen administrative rettigheter, det tar bare brukerhandlinger og overfører dem til tjenesten. Den viser også produktstatus. Ingenting mer, dette er ikke målet. HVIS GUI er drept, er dette ikke et problem da tjenesten skal kunne starte den på nytt.

guard DLLs (hvis noen), blir massivt injisert i alle prosesser, og bør kunne se ETTER iat kroker og/eller ondsinnede tråder. De bør være ganske vanskelig å losse eller beseire. De er ikke kritiske, men viktige.

tjenesten er kjernen i produktet. Det bør være unkillable, eller i det minste skal kunne starte på nytt på drep. Tjenesten er ansvarlig for kommunikasjon mellom alle modulene i produktet, den sender kommandoer til drivere, tar kommandoer fra brukeren og spør databasen for prøveanalyse. Dette er hjernen.

kjernedriverne er også kritiske. De er tentakler som samler informasjon om alt som skjer pa systemet, og overforer dem til tjenesten for beslutning. De kan også nekte tilgang til bevoktede steder, basert på tjenestens beslutning.

Konklusjon

Å Lage en sterk, pålitelig og stabil antivirusmotor er en komplisert oppgave, som trenger eksperimenterte mennesker med en veldig sterk kunnskap i windows kernel programmering, windows – programmering, GUI design, programvarearkitektur, malware analyse, …

Bygge stabile drivere er også en komplisert oppgave, fordi et lite sandkorn kan krasje hele systemet. Det krever testing, testing og mye testing. Når motoren din er ferdig og fungerer, trenger du bare å ansette forskere for å analysere malwares Og legge til signaturer Til databasen 🙂 Hva venter Du På? Kom igjen! 😀

Lenker

  • http://www.symantec.com/connect/articles/building-anti-virus-engine

Leave a Reply

Din e-postadresse vil ikke bli publisert.