sexta-feira, 20 de setembro de 2013

Entenda o Formato PE, o formato dos executáveis

Aprendi que a melhor forma de aprender é ensinando (né professor Pachecão?), que realmente é verdade, pois já apliquei essa técnica aprendendo química.

O assunto dessa vez será o formato de arquivos objetos e executáveis voltado para Windows 32bits (originado do Unix COFF) o PE (Portable Executable). Dando atenção ao fato que não sou nenhum expert no assunto, portanto pode haver inconsistência ou invalidez no texto redigito, portanto leia por conta e risco.

P: Gilson, porque seu interesse nesse assunto?
R: Eu sempre aprendi de acordo com a necessidade, nunca precisei saber do formato PE para executar minhas aplicações ou aplicar patchs aos softwares. Mas dessa vez, ao fazer um speed hack para um jogo procurei uma alternativa de sempre procurar os endereços das funções para substituir (como o jogo sofre constantes atualizações), assim teria uma dll estável e sem a necessidade de atualizá-la cada vez que o jogo passasse por um update.

Vamos lá.

Um arquivo PE é formado por blocos de códigos, abaixo mostrei os blocos, suas estruturas e tentarei descrever cada parte para um melhor entendimento.

O Windows tem seu system loader que é encarregado de pôr o arquivo na memória, verificar os blocos, resolver endereços, importar e exportar funções caso os tenha. HMODULE é o nome dado quando o arquivo vai pra memória nossos módulos.

Primeiro temos o DOS Header (IMAGE_DOS_HEADER) constituído de 64 bytes, segue a estrutura:

struct _IMAGE_DOS_HEADER {
    WORD e_magic;
    WORD e_cblp;
    WORD e_cp;
    WORD e_crlc;
    WORD e_cparhdr;
    WORD e_minalloc;
    WORD e_maxalloc;
    WORD e_ss;
    WORD e_sp;
    WORD e_csum;
    WORD e_ip;
    WORD e_cs;
    WORD e_lfarlc;
    WORD e_ovno;
    WORD e_res[4];
    WORD e_oemid;
    WORD e_oeminfo;
    WORD e_res2[10];
    DWORD e_lfanew;
};

e_magic – assinatura MZ (0x4D5A)
e_cblp – tamanho da última página
e_cp – total de página
e_crlc – itens de realocação
e_cparhdr – tamanho do cabeçalho
e_minalloc – tamanho mínimo de memória
e_maxalloc – tamanho máximo de memória
e_ss – valor inicial do registrador SS (Stack Segment)
e_sp – valor inicial do registrador SP (Stack Pointer)
e_csum – checksum do cabeçalho
e_ip – valor inicial do registrador IP (Instruction Pointer)
e_cs – valor inicial do registrador CS (Code Segment)
e_lfarlc – offset (distância) do fragmento stub
e_ovno – overlay
e_res[4] - bytes reservados
e_oemid – identificador OEM
e_oeminfo – informações OEM
e_res2[10] - bytes reservados
e_lfanew – offset do cabeçalho do arquivo PE

O e_lfarlc, esse fragmento é executado caso arquivo PE não possa ser executado. Consiste num número muito pequeno de bytes com instruções, assim ao carregar o arquivo na memória é verificado se é compatível com o sistema, caso não seja essa sessão é executada.

Continuando temos o bloco NT Header (IMAGE_NT_HEADERS) contendo File Header (IMAGE_FILE_HEADER) e Optional Header (IMAGE_OPTIONAL_HEADER).

struct _IMAGE_NT_HEADERS {
    DWORD Signature;
    IMAGE_FILE_HEADER FileHeader;
    IMAGE_OPTIONAL_HEADER32 OptionalHeader;
} IMAGE_NT_HEADERS;

Signature – Assinatura do cabeçalho PE
FileHeader – Estrutura IMAGE_FILE_HEADER
OptionalHeader – Estrutura IMAGE_OPTIONAL_HEADER32

struct _IMAGE_FILE_HEADER {
    WORD Machine;
    WORD NumberOfSections;
    DWORD TimeDateStamp;
    DWORD PointerToSymbolTable;
    DWORD NumberOfSymbols;
    WORD SizeOfOptionalHeader;
    WORD Characteristics;
} IMAGE_FILE_HEADER;

Machine – Tipo de plataforma prevista pra rodar o executável
NumberOfSections – Número de seções apos o cabeçalho
TimeDateStamp – Data e hora de criação do arquivo
PointerToSymbolTable – Ponteiro para tabela de símbolos
NumberOfSymbols – Número de símbolos
SizeOfOptionalHeader – Tamanho do cabeçalho opcional
Characteristics – Características (Flags) do arquivo.

struct _IMAGE_OPTIONAL_HEADER {
    WORD Magic;
    BYTE MajorLinkerVersion;
    BYTE MinorLinkerVersion;
    DWORD SizeOfCode;
    DWORD SizeOfInitializedData;
    DWORD SizeOfUninitializedData;
    DWORD AddressOfEntryPoint;
    DWORD BaseOfCode;
    DWORD BaseOfData;
    DWORD ImageBase;
    DWORD SectionAlignment;
    DWORD FileAlignment;
    WORD MajorOperatingSystemVersion;
    WORD MinorOperatingSystemVersion;
    WORD MajorImageVersion;
    WORD MinorImageVersion;
    WORD MajorSubsystemVersion;
    WORD MinorSubsystemVersion;
    DWORD Win32VersionValue;
    DWORD SizeOfImage;
    DWORD SizeOfHeaders;
    DWORD CheckSum;
    WORD Subsystem;
    WORD DllCharacteristics;
    DWORD SizeOfStackReserve;
    DWORD SizeOfStackCommit;
    DWORD SizeOfHeapReserve;
    DWORD SizeOfHeapCommit;
    DWORD LoaderFlags;
    DWORD NumberOfRvaAndSizes;
    IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
} IMAGE_OPTIONAL_HEADER32;

Magic – Especifica o tipo de arquivo (0x010B executável, 0x0107 imagem rom)
MajorLinkerVersion – versão maior do linker
MinorLinkerVersion – versão menor do linker
SizeOfCode – tamanho do código executável
SizeOfInitializedData – tamanho do bloco de dados de inicialização (Data Segment)
SizeOfUninitializedData – tamanho do bloco de dados não inicializados (BSS Segment)
AddressOfEntryPoint – endereço do ponto de inicialização (RVA)
BaseOfCode – base de código
BaseOfData – base de dados
ImageBase – endereço de mapeamento (preferencial)
SectionAlignment – alinhamento da seção na memória RAM
FileAlignment – alinhamento da seção do arquivo em disco
MajorOperatingSystemVersion – versão maior esperada do sistema operacional
MinorOperatingSystemVersion – versão mínima esperada do sistema operacional
MajorImageVersion – versão máxima do arquivo
MinorImageVersion – versão mínima do arquivo
MajorSubsystemVersion – versão máxima do subsistema esperado
MinorSubsystemVersion – versão mínima do subsistema esperado
Win32VersionValue – versão do win32
SizeOfImage – tamanho da imagem somando os cabeçalhos e seções
SizeOfHeaders – tamanho dos cabeçalhos
CheckSum – checksum do arquivo
Subsystem – subsistema requerido
DllCharacteristics – Características (Flags) das DLLs
SizeOfStackReserve – tamanho reservado do da pilha stack
SizeOfStackCommit – tamanho inicial da pilha salva
SizeOfHeapReserve – tamanho reservado aos heaps
SizeOfHeapCommit – tamanho inicial do heap salvo
LoaderFlags – Parâmetros (Flags) para o carregador do sistema
NumberOfRvaAndSizes – Número e tamanho de RVA
DataDirectory – Diretório de dados constituído de uma matriz de 16 índices (com localização RVA e tamanho de cada peça de informação)

Seguindo temos a estrutura de cada índice do DataDirectory

struct _IMAGE_DATA_DIRECTORY {
    DWORD VirtualAddress;
    DWORD Size;
} IMAGE_DATA_DIRECTORY;

VirtualAddress – endereço da seção
Size – tamanho da seção

Começando do índice 0 temos as seguintes estruturas em DataDirectory:

enum E_DIRECTORY_ENTRY {
    IMAGE_DIRECTORY_ENTRY_EXPORT,
    IMAGE_DIRECTORY_ENTRY_IMPORT,
    IMAGE_DIRECTORY_ENTRY_RESOURCE,
    IMAGE_DIRECTORY_ENTRY_EXCEPTION,
    IMAGE_DIRECTORY_ENTRY_SECURITY,
    IMAGE_DIRECTORY_ENTRY_BASERELOC,
    IMAGE_DIRECTORY_ENTRY_DEBUG,
    IMAGE_DIRECTORY_ENTRY_COPYRIGHT, // IMAGE_DIRECTORY_ENTRY_ARCHITECTURE
    IMAGE_DIRECTORY_ENTRY_GLOBALPTR,
    IMAGE_DIRECTORY_ENTRY_TLS,
    IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG,
    IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT,
    IMAGE_DIRECTORY_ENTRY_IAT,
    IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT,
    IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTION,
}; 

Agora temos o bloco de código _IMAGE_SECTION_HEADER onde a quantidade é definida em _IMAGE_FILE_HEADER.NumberOfSections

typedef struct _IMAGE_SECTION_HEADER {
    BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; // IMAGE_SIZEOF_SHORT_NAME 8
    union {
        DWORD PhysicalAddress;
        DWORD VirtualSize;
    } Misc;
    DWORD VirtualAddress;
    DWORD SizeOfRawData;
    DWORD PointerToRawData;
    DWORD PointerToRelocations;
    DWORD PointerToLinenumbers;
    WORD NumberOfRelocations;
    WORD NumberOfLinenumbers;
    DWORD Characteristics;
} IMAGE_SECTION_HEADER,*PIMAGE_SECTION_HEADER;

Name – Nome da seção tendo no máximo 8 caracteres
Misc.PhysicalAddress, Misc.VirtualSize – dividem o mesmo valor, sendo o endereço físico ou o tamanho virtual.
VirtualAddress – endereço virtual
SizeOfRawData – tamanho
PointerToRawData – ponteiro do inicio do arquivo até os dados da seção
PointerToRelocations – ponteiro para remanejamento para arquivos objetos
PointerToLinenumbers – ponteiro para o número de linhas para arquivos objetos
NumberOfRelocations – número de remanejamentos para arquivos objetos
NumberOfLinenumbers – quantidade de números de linhas para arquivos objetos;
Characteristics – características que descrevem como a memória da seção deve ser trata

Estrutura dos DataDirectory começando pelo IMAGE_DIRECTORY_ENTRY_EXPORT

struct _IMAGE_EXPORT_DIRECTORY {
    DWORD Characteristics;
    DWORD TimeDateStamp;
    WORD MajorVersion;
    WORD MinorVersion;
    DWORD Name;
    DWORD Base;
    DWORD NumberOfFunctions;
    DWORD NumberOfNames;
    DWORD AddressOfFunctions;
    DWORD AddressOfNames;
    DWORD AddressOfNameOrdinals;
} IMAGE_EXPORT_DIRECTORY,*PIMAGE_EXPORT_DIRECTORY;

Characteristics – Características de exportação. Atualmente não são usadas
TimeDateStamp – Data/hora em que as exportações foram criadas
MajorVersion – número de versão maior das exportações, não utilizado e setado como 0
MinorVersion – número de versão menor das exportações, não utilizado e setado como 0
Name – endereço relativo para o nome associado as exportações.
Base – valor ordinal inicial a ser utilizado para exportação do executável.
NumberOfFunctions – número de funções na tabela de exportação
NumberOfNames – número de nomes na tabela de exportação, esse valor vai ser sempre menor ou igual ao NumberOfFunctions
AddressOfFunctions – endereço relativo da tabela de exportação em uma matriz, cada índice diferente de 0 corresponde a um símbolo exportado.
AddressOfNames – endereço relativo da tabela de exportação nomes em uma matriz, cada índice corresponde a um símbolo exportado pelo nome.
AddressOfNameOrdinals - endereço relativo da tabela ordinal de exportação. Essa tabela é um conjunto de palavras.

Estrutura IMAGE_IMPORT_DESCRIPTOR

typedef struct _IMAGE_IMPORT_DESCRIPTOR {
    _ANONYMOUS_UNION union {
        DWORD Characteristics;
        PIMAGE_THUNK_DATA OriginalFirstThunk;
    } DUMMYUNIONNAME;
    DWORD TimeDateStamp;
    DWORD ForwarderChain;
    DWORD Name;
    PIMAGE_THUNK_DATA FirstThunk;
} IMAGE_IMPORT_DESCRIPTOR,*PIMAGE_IMPORT_DESCRIPTOR;

OriginalFirstThunk – esse campo é mal nomeado, ele contém um endereço relativo da tabela de nomes de importação. Isto é uma matriz de IMAGE_THUNK_DATA. Esse campo é 0 para indicar o final da matriz.
TimeDateStamp - recebe o valor 0 caso o executável não esteja vinculado a DLL importada. Quando tem a ligação é definido a data/hora quando a ligação ocorreu.
ForwarderChain – este é o índice da primeira API encaminhada. Definido como -1 se não tiver encaminhadores.
Name – endereço relativo para o nome da dll importada.
FirstThunk - endereço relativo a tabela de endereço de importação. É uma matriz de estruturas IMAGE_THUNK_DATA.

Estrutura IMAGE_THUNK_DATA

typedef struct _IMAGE_THUNK_DATA {
    union {
        LPBYTE ForwarderString;
        PDWORD Function;
        DWORD Ordinal;
        PIMAGE_IMPORT_BY_NAME AddressOfData;
    } u1;
} IMAGE_THUNK_DATA, *PIMAGE_THUNK_DATA;

u1.ForwarderString – endereço relativo para um texto transitário
u1.Function – endereço da função importada
u1.Ordinal – valor ordinal da função importada
u1.AddressOfData – endereço relativo para um IMAGE_IMPORT_BY_NAME com o nome da função importada

Estrutura IMAGE_IMPORT_BY_NAME

typedef struct _IMAGE_IMPORT_BY_NAME {
    WORD Hint;
    BYTE Name[1];
} IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME;

Hint – Dica para o carregador com o ordinal
Name – Nome da função importada

Estrutura IMAGE_RESOURCE_DIRECTORY

typedef struct _IMAGE_RESOURCE_DIRECTORY {
    DWORD Characteristics;
    DWORD TimeDateStamp;
    WORD MajorVersion;
    WORD MinorVersion;
    WORD NumberOfNamedEntries;
    WORD NumberOfIdEntries;
} IMAGE_RESOURCE_DIRECTORY,*PIMAGE_RESOURCE_DIRECTORY;

Characteristics – Não usado
TimeDateStamp – Não usado
MajorVersion – Não usado
MinorVersion – Não usado
NumberOfNamedEntries – Número de entradas com nome
NumberOfIdEntries – Número de entrada com id

Estrutura IMAGE_DEBUG_DIRECTORY

typedef struct _IMAGE_DEBUG_DIRECTORY {
    DWORD Characteristics;
    DWORD TimeDateStamp;
    WORD MajorVersion;
    WORD MinorVersion;
    DWORD Type;
    DWORD SizeOfData;
    DWORD AddressOfRawData;
    DWORD PointerToRawData;
} IMAGE_DEBUG_DIRECTORY,*PIMAGE_DEBUG_DIRECTORY;

Characteristics – Não usado e setado como 0
TimeDateStamp – Data/hora desta informação de depuração
MajorVersion - A versão maior desta informação de depuração. Não usado
MinorVersion – a versão mínima desta informação de depuração. Não usado.
Type - O tipo de informação de depuração. Os tipos são IMAGE_DEBUG_TYPE_COFF, IMAGE_DEBUG_TYPE_CODEVIEW, MAGE_DEBUG_TYPE_FPO, IMAGE_DEBUG_TYPE_MISC, IMAGE_DEBUG_TYPE_OMAP_TO_SRC, IMAGE_DEBUG_TYPE_OMAP_FROM_SRC, IMAGE_DEBUG_TYPE_BORLAND
SizeOfData - O tamanho dos dados de depuração neste arquivo. Não inclui o tamanho dos arquivos de depuração externo como .PDBs
AddressOfRawData – endereço relativo dos dados de depuração, quando mapeado na memória. Setado como 0 caso não seja mapeado.
PointerToRawData – Ponteiro para o dado de depuração. Não é endereço relativo.

Estrutura _IMAGE_TLS_DIRECTORY, IMAGE_TLS_DIRECTORY32

typedef struct _IMAGE_TLS_DIRECTORY32 {
    DWORD StartAddressOfRawData;
    DWORD EndAddressOfRawData;
    DWORD AddressOfIndex;
    DWORD AddressOfCallBacks;
    DWORD SizeOfZeroFill;
    DWORD Characteristics;
} IMAGE_TLS_DIRECTORY32,*PIMAGE_TLS_DIRECTORY32;

StartAddressOfRawData – endereço inicial de um intervalo de memória usado para iniciar novos segmentos TLS na memória
EndAddressOfRawData – endereço final do intervalo na memória usada para inciar novos segmentos TLS na memória.
AddressOfIndex – endereço do índice que localiza o segmento de dados local. Quando um executável é trazido pra memória e uma seção .tls está presente, o carregador aloca um controlador TLS via TlsAlloc. Isto armazena o endereço fornecido nesse campo.
AddressOfCallBacks - endereço de uma matriz de ponteiros funções PIMAGE_TLS_CALLBACK. Quando um thread é criado ou destruído, cada função na lista é chamada. O final da lista é indicado por um ponteiro nulo. Em executáveis normais em visual c++ essa lista é vazia
SizeOfZeroFill - tamanho em bytes dos dados de inicialização, além dos dados iniciados serem delimitados pelos campos StartAddressOfRawData e EndAddressOfRawData. Todos os dados de threads iniciados depois desse intervalo é iniciado em 0.
Characteristics – Reservado, definido como 0

Estrutura IMAGE_DELAY_IMPORT_DESCRIPTOR

typedef struct _IMAGE_DELAY_IMPORT_DESCRIPTOR {
    DWORD grAttrs;
    DWORD szName;
    DWORD phmod;
    DWORD pIAT;
    DWORD pINT;
    DWORD pBoundIAT;
    DWORD pUnloadIAT;
    DWORD dwTimeStamp;
} IMAGE_DELAY_IMPORT_DESCRIPTOR, *LPIMAGE_DELAY_IMPORT_DESCRIPTOR;

grAttrs - Os atributos para essa estrutura. Atualmente, a única bandeira é definida dlattrRva (1) indicando que os campos de endereço na estrutura deve ser tratado como endereços relativos, em vez de endereços virtuais.
szName – endereço relativo com o nome da dll importada. esse valor é passado para o LoadLibrary
phmod – endereço relativo para uma localização na memória para um HMODULE. Quando a dll é trazida para a memória ela é armazenada a partir do HMODULE.
pIAT – endereço relativo para a tabela de endereços de importação para essa dll. Este é o mesmo formato de um IAT regular
pINT – endereço relativo para o nome da tabela de importação para essa dll. Este é o mesmo formato como um INT regular
pBoundIAT – endereço relativo do limite IAT opcional. um endereço relativo a uma cópia encadeada de uma tabela de endereços de importação para essa dll. Este é o mesmo formato de um IAT regular. Atualmente, está cópia do IAT não é realmente ligado, mas esse recurso pode ser adicionado em futuras versões do programa BIND.
pUnloadIAT – endereço relativo de uma cópia opcional o IAT original. Um endereço relativo para uma cópia não ligada de uma tabela de endereços de importação para essa DLL. Este é o mesmo formato de um IAT regular. Atualmente é definido como 0
dwTimeStamp – Data/hora que a dll foi importada. Normalmente definido como 0.

Referências
PE Format (PDF) 373kb
An In-Depth Look into the Win32 Portable Executable File Format Part 1 - http://msdn.microsoft.com/en-us/magazine/bb985996.aspx
An In-Depth Look into the Win32 Portable Executable File Format Part 2 - http://msdn.microsoft.com/en-us/magazine/cc301808.aspx
http://msdn.microsoft.com/en-us/magazine/ms809762.aspx

domingo, 25 de agosto de 2013

Aplicativo android com horários de ônibus

Ha muito tempo tive em mente em desenvolver um aplicativo para android com os horários dos ônibus da minha cidade (Resende/RJ), finalmente coloquei o projeto em prática e ai está o resultado. Pretendo atualiza-lo com novos recursos e opções. Espero que gostem, avaliem e deêm sugestões/críticas/elogios pelo formulário do meu site.

Você pode baixar o aplicativo para o seu android clicando aqui.



Futuras atualizações serão postada aqui.

Att, Gilson Fabiano.

sexta-feira, 12 de julho de 2013

Carregando uma dll apartir da memória

Quando se trata de fazer hack's ou vírus o quanto mais stealth for seu código melhor, certo? Exato!

Ao desenvolver um hack para um jogo, vi a necessidade do código ser mais oculto possível. Nisso comecei a codificar e bolar algumas coisas e nisso pensei: porque não carregar meu código apartir da memória?.

Até ai tudo bem, fiz um código que carregava o código da dll na memória do jogo e executava o DllEntry. A primeira vista eu sorri alegremente até ver meu código dar um "access violation", fiquei triste (eu confesso). Depurando um pouco meu código vi que ele não resolvia as referências das funções e nem alocava de modo correto os setores da dll (nessa hora fiquei mais triste ainda).

Com todo o ocorrido resolvi apelar, fui no google e achei exatamente o que eu queria, um cara chamado Joachim Bauch desenvolveu um código (git) e um tutorial (link em inglês) explicando como fazê-lo (Foi tiro e queda).

Única coisa foi que tive que portar as minhas necessidades, já que se trata de uma dll injetável, essa dll injetável que carregava a outra dll, já que o código carrega a dll no processo atual (se é que vocês entenderam a embolação).

O código abaixo ilustra como é fácil carregar a dll apartir da dll injetada.

void InjectDll()
{
    FILE *fp;
    DWORD dwSize;
    unsigned char *data;
    HMEMORYMODULE handle;

    fp = fopen(DLLFILE, "rb"); // DLLFILE = minha dll

    fseek(fp, 0, SEEK_END);
    dwSize = ftell(fp);
    fseek(fp, 0, SEEK_SET);

    data = (unsigned char*)malloc( dwSize );
    fread(data, dwSize, 1, fp);

    handle = MemoryLoadLibrary(data);
    if (handle == NULL)
    {
        // não foi possível carregar a dll
    }
    else
    {
        // dll carregada e DllEntry executado.
    }
}
extern "C" DLL_EXPORT BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
    switch (fdwReason)
    {
        case DLL_PROCESS_ATTACH:
            InjectDll();
            return FALSE; // assim esse dll e descarregada automáticamente.
    }
    return TRUE;
}

Reparem no return FALSE; assim a dll é descarregada automáticamente, não deixando rastros :P. Do contrário a dll iria ficar lá.

Então meus pequenos, boa sorte nas suas brincadeiras e códigos.

Att, Gilson Fabiano

segunda-feira, 24 de junho de 2013

Engenharia reversa, o prazer em desmontar as coisas

Desde pequeno tenho o gosto de desmontar as coisas, eu não tive muitos brinquedos e os poucos que tinha eu desmontava todos. Meu pai devia pensar que eu destroçava os brinquedos, mas eu procurava ver o funcionamento das coisas por dentro e ainda continuo e claro meus brinquedos mudaram.

Quando ganhei meu primeiro computador passei os 3 primeiros meses sem ver a luz do dia literalmente – Era um Positivo com míseros 128mb de RAM mas que rodava o counter-strike – com a falta de instrução, resolvi procurar por mim mesmo com os recursos disponíveis.

Nesses 3 primeiros meses mexi no windows xp de cabo a rabo, como eu não tinha acesso à internet naquela época, lembro que achei o utilitário msconfig olhando arquivo por arquivo na pasta system32. Bons tempos aquele.

Enfim, voltando ao assunto de desmontar, ver como tudo funciona é prazeroso, olhar as coisas se encaixando e funcionando é uma sensação que não consigo explicar. Mas o mal de desmontar as coisas é montar novamente e deixar tudo funcionando como antes – já estraguei muito carrinho assim.

Com o computador não foi diferente, mas é claro que eu não ia violar a garantia abrindo o danado, parti logo para ver como tudo funcionava, abri muitas dlls, muitos exes no bloco de notas e só via coisa estranha, como eu não entendi nada daquilo eu só ficava boiando.


Aprendendo programação, fui entendendo aos poucos como era brilhante e complexo o funcionamento do computador, pelo menos pra mim, me fascinava. Hoje com o conhecimento que tenho vejo que falta muito a aprender.

Mas o que tem a ver desmontar carrinhos e desmontar softwares?

A ideologia é a mesma e o prazer também, mas sem perdas de peças como ocorre no hardware. Com o software quando não dá certo basta reiniciar.

Lembro do primeiro software que violei, era um que mostrava as senhas do antigo MSN, o software era pago e precisava de uma licença pra mostrar a senha por completo. Lembro que fiquei todo bobo com aquilo, e quem não ficaria?

Hoje em dia quebro alguns softwares que utilizo, como o conversor de dvd e um servidor dlna.

É errado? Pode ser que sim. Mas tudo que é errado é mais legal. ;)


Então se você é pai e leu isso, quando ver seu filho desmontando um carrinho, ajude-o e mostre como aquilo funciona, pois seu pequeno garoto pode virar um grande profissional em engenharia reversa. E o mercado paga muito bem para esses profissionais.

Para terem uma idéia existe um filme chamado "O Pagamento (Paycheck)", o ator principal é uma especialista em engenharia reversa onde ele cria uma máquina que prever o futuro.

Att, Gilson Fabiano

segunda-feira, 11 de março de 2013

Sublime Text 2/3 Build 2126-3019 + Patch

Sublime Text 3

Lançado apenas para membros registrados (até o momento), tras novos recursos e melhorias que podem ser conferidas no site oficial. O build atual é 3019 que pode ser baixado aqui (windows x86).

Sublime Text 2

O nosso querido Sublime Text 2 se graduou saindo do Beta. Seu Build atual é 2217 (versão 2.0.1).
Você pode baixar a nova versão do Sublime Text 2 por aqui.

Patch

O patch agora é multi versão desde o build 2126 até o atual 3019, mas apenas suportando versões do windows para arquitetura x86 (32 bits).
Acesse aqui e baixe o patch!

Em caso de dúvidas entre em contato por aqui.

Att, Gilson Fabiano

domingo, 3 de março de 2013

C++, Barra de progresso nos botões da barra de tarefas no Windows 7.

Deixar o character "afk" as vezes fica um tanto complicado, ainda mais quando PK'lowlevel ta sem nada pra fazer. Como o cliente não dá a opção de mostrar na barra de tarefa a vida do personagem, resolvi implementar.
No começo foi trabalhosso devido ao pacote do compilador não ter incluso os headers necessários e por eu não ter usado o CoInitialize() corretamente. Depois de muitas horas, tentativas e pesquisas descobri que não estava iniciando a biblioteca COM (por isso o EAX ficava com o cara de tacho). Mas graças ao todo poderoso oráculo (vulgo google) tudo se encaixou.

Vamos dá uma olhada num exemplo e ver como implementar esse estilo em uma janela do bloco de notas aberta.

#include <windows.h>
#include <shobjidl.h>

const GUID my_IID_ITaskbarList3 =
{ 0xea1afb91, 0x9e28, 0x4b86, { 0x90, 0xe9, 0x9e, 0x9f, 0x8a, 0x5e, 0xef, 0xaf } };

const GUID my_CLSID_TaskbarList =
{ 0x56fdf344, 0xfd6d, 0x11d0, { 0x95, 0x8a, 0x00, 0x60, 0x97, 0xc9, 0xa0, 0x90 } };

ITaskbarList3* ptbl = NULL;

int main()
{
    // inicia a biblioteca
    CoInitialize(NULL);
    // cria a instancia para a interface ITaskbarList3
    CoCreateInstance(my_CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, my_IID_ITaskbarList3, (LPVOID*)&ptbl);
    // procura por uma janela do bloco de notas
    HWND hWindow = FindWindow("Notepad", NULL);
    ptbl->SetProgressState(hWindow, TBPF_ERROR);
    ptbl->SetProgressValue(hWindow, 40, 100);
    return 0;
}


Recomendo o link onde o autor faz uma introdução de COM e explica o que é e como usar (texto em inglês).


Att, Gilson Fabiano.

quinta-feira, 14 de fevereiro de 2013

C++, Chamando endereços como se fossem funções

Quando se usa uma dll injetável ou algum outro código, saber o endereço da função não é o suficiente - as vezes. Para evitar de códigos em asm massivos em seu código fonte podemos criar um tipo da função ou simplesmente usar uma sintaxe.

Sintaxe


type-return ([modifier] *[variable])([type , [type , [type , ...]]])

Veja


void (*variavel)(int, int, char); // declara a variavel
variavel = (void(*)(int, int, char))0x00FF00FF; // atribui o valor do seu endereço a ser chamado
variavel(10, 20, 6);

ou

( (void(*)(int, int, char)) 0x00FF00FF ) (10, 20, 6);

Código de exemplo


void function1(int x, int y, char z)
{
    printf("Function1 - X: %d, Y: %d, Z: %d\n", x, y, z);
}
int function2(int x, int y, char z)
{
    printf("Function2 - X: %d, Y: %d, Z: %d\n", x, y, z);
    return (x + y + z);
}
int main()
{
    void(*f1)(int, int, char);
    int (*f2)(int, int, char);

    f1 = &function1;
    f2 = &function2;

    f1(1,2,3);
    int result = f2(4,5,6);

    printf("Result: %d", result);

    return 0;
}


Att, Gilson Fabiano