tag:blogger.com,1999:blog-10363250974617708422024-02-07T18:10:00.127-03:00Gilson Fabiano - BlogUnknownnoreply@blogger.comBlogger28125tag:blogger.com,1999:blog-1036325097461770842.post-79794103400883312742013-09-20T00:12:00.001-03:002013-09-20T00:12:43.449-03:00Entenda o Formato PE, o formato dos executáveisAprendi que a melhor forma de aprender é ensinando (né <a href="http://www.palestrasmotivacionais10.com.br/">professor Pachecão</a>?), que realmente é verdade, pois já apliquei essa técnica aprendendo química.<br />
<br />
O assunto dessa vez será o formato de arquivos objetos e executáveis voltado para Windows 32bits (originado do <a href="http://en.wikipedia.org/wiki/COFF">Unix COFF</a>) o PE (Portable Executable). <b>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.</b><br />
<br />
<b>P: Gilson, porque seu interesse nesse assunto?</b><br />
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.<br />
<br />
<b>Vamos lá.</b><br />
<br />
Um arquivo PE é formado por blocos de códigos, abaixo mostrei os blocos, suas estruturas e tentarei descrever cada parte para um melhor entendimento.<br />
<br />
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.<br />
<br />
Primeiro temos o <b id="IMAGE_DOS_HEADER">DOS Header</b> (IMAGE_DOS_HEADER) constituído de 64 bytes, segue a estrutura:<br />
<br />
<pre>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;
};</pre><br />
e_magic – assinatura MZ (0x4D5A)<br />
e_cblp – tamanho da última página<br />
e_cp – total de página<br />
e_crlc – itens de realocação<br />
e_cparhdr – tamanho do cabeçalho<br />
e_minalloc – tamanho mínimo de memória<br />
e_maxalloc – tamanho máximo de memória<br />
e_ss – valor inicial do registrador SS (Stack Segment)<br />
e_sp – valor inicial do registrador SP (Stack Pointer)<br />
e_csum – checksum do cabeçalho<br />
e_ip – valor inicial do registrador IP (Instruction Pointer)<br />
e_cs – valor inicial do registrador CS (Code Segment)<br />
e_lfarlc – offset (distância) do fragmento stub<br />
e_ovno – overlay<br />
e_res[4] - bytes reservados<br />
e_oemid – identificador OEM<br />
e_oeminfo – informações OEM<br />
e_res2[10] - bytes reservados<br />
e_lfanew – offset do cabeçalho do arquivo PE<br />
<br />
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.<br />
<br />
Continuando temos o bloco <b>NT Header</b> (IMAGE_NT_HEADERS) contendo <b>File Header</b> (<a href="#IMAGE_FILE_HEADER">IMAGE_FILE_HEADER</a>) e <b>Optional Header</b> (<a href="#IMAGE_OPTIONAL_HEADER32">IMAGE_OPTIONAL_HEADER</a>).<br />
<br />
<pre id="IMAGE_NT_HEADERS">struct _IMAGE_NT_HEADERS {
DWORD Signature;
<a href="#IMAGE_FILE_HEADER">IMAGE_FILE_HEADER</a> FileHeader;
<a href="#IMAGE_OPTIONAL_HEADER32">IMAGE_OPTIONAL_HEADER32</a> OptionalHeader;
} IMAGE_NT_HEADERS;</pre><br />
Signature – Assinatura do cabeçalho PE<br />
FileHeader – Estrutura IMAGE_FILE_HEADER<br />
OptionalHeader – Estrutura IMAGE_OPTIONAL_HEADER32<br />
<br />
<pre id="IMAGE_FILE_HEADER">struct _IMAGE_FILE_HEADER {
WORD Machine;
WORD NumberOfSections;
DWORD TimeDateStamp;
DWORD PointerToSymbolTable;
DWORD NumberOfSymbols;
WORD SizeOfOptionalHeader;
WORD Characteristics;
} IMAGE_FILE_HEADER;</pre><br />
Machine – Tipo de plataforma prevista pra rodar o executável<br />
NumberOfSections – Número de seções apos o cabeçalho<br />
TimeDateStamp – Data e hora de criação do arquivo<br />
PointerToSymbolTable – Ponteiro para tabela de símbolos<br />
NumberOfSymbols – Número de símbolos<br />
SizeOfOptionalHeader – Tamanho do cabeçalho opcional<br />
Characteristics – Características (Flags) do arquivo.<br />
<br />
<pre id="IMAGE_OPTIONAL_HEADER32">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;
<a href="#IMAGE_DATA_DIRECTORY">IMAGE_DATA_DIRECTORY</a> DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
} IMAGE_OPTIONAL_HEADER32;</pre><br />
Magic – Especifica o tipo de arquivo (0x010B executável, 0x0107 imagem rom)<br />
MajorLinkerVersion – versão maior do linker<br />
MinorLinkerVersion – versão menor do linker<br />
SizeOfCode – tamanho do código executável<br />
SizeOfInitializedData – tamanho do bloco de dados de inicialização (Data Segment)<br />
SizeOfUninitializedData – tamanho do bloco de dados não inicializados (BSS Segment)<br />
AddressOfEntryPoint – endereço do ponto de inicialização (RVA)<br />
BaseOfCode – base de código<br />
BaseOfData – base de dados<br />
ImageBase – endereço de mapeamento (preferencial)<br />
SectionAlignment – alinhamento da seção na memória RAM<br />
FileAlignment – alinhamento da seção do arquivo em disco<br />
MajorOperatingSystemVersion – versão maior esperada do sistema operacional<br />
MinorOperatingSystemVersion – versão mínima esperada do sistema operacional<br />
MajorImageVersion – versão máxima do arquivo<br />
MinorImageVersion – versão mínima do arquivo<br />
MajorSubsystemVersion – versão máxima do subsistema esperado<br />
MinorSubsystemVersion – versão mínima do subsistema esperado<br />
Win32VersionValue – versão do win32<br />
SizeOfImage – tamanho da imagem somando os cabeçalhos e seções<br />
SizeOfHeaders – tamanho dos cabeçalhos<br />
CheckSum – checksum do arquivo<br />
Subsystem – subsistema requerido<br />
DllCharacteristics – Características (Flags) das DLLs<br />
SizeOfStackReserve – tamanho reservado do da pilha stack<br />
SizeOfStackCommit – tamanho inicial da pilha salva<br />
SizeOfHeapReserve – tamanho reservado aos heaps<br />
SizeOfHeapCommit – tamanho inicial do heap salvo<br />
LoaderFlags – Parâmetros (Flags) para o carregador do sistema<br />
NumberOfRvaAndSizes – Número e tamanho de RVA<br />
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)<br />
<br />
Seguindo temos a estrutura de cada índice do DataDirectory<br />
<br />
<pre id="IMAGE_DATA_DIRECTORY">struct _IMAGE_DATA_DIRECTORY {
DWORD VirtualAddress;
DWORD Size;
} IMAGE_DATA_DIRECTORY;</pre><br />
VirtualAddress – endereço da seção<br />
Size – tamanho da seção<br />
<br />
Começando do índice 0 temos as seguintes estruturas em DataDirectory:<br />
<br />
<pre>enum E_DIRECTORY_ENTRY {
<a href="#IMAGE_EXPORT_DIRECTORY">IMAGE_DIRECTORY_ENTRY_EXPORT</a>,
<a href="#IMAGE_IMPORT_DESCRIPTOR">IMAGE_DIRECTORY_ENTRY_IMPORT</a>,
<a href="#IMAGE_RESOURCE_DIRECTORY">IMAGE_DIRECTORY_ENTRY_RESOURCE</a>,
IMAGE_DIRECTORY_ENTRY_EXCEPTION,
IMAGE_DIRECTORY_ENTRY_SECURITY,
IMAGE_DIRECTORY_ENTRY_BASERELOC,
<a href="#IMAGE_DEBUG_DIRECTORY">IMAGE_DIRECTORY_ENTRY_DEBUG</a>,
IMAGE_DIRECTORY_ENTRY_COPYRIGHT, // IMAGE_DIRECTORY_ENTRY_ARCHITECTURE
IMAGE_DIRECTORY_ENTRY_GLOBALPTR,
<a href="#IMAGE_TLS_DIRECTORY32">IMAGE_DIRECTORY_ENTRY_TLS</a>,
IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG,
IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT,
IMAGE_DIRECTORY_ENTRY_IAT,
<a href="#IMAGE_DELAY_IMPORT_DESCRIPTOR">IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT</a>,
IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTION,
}; </pre><br />
Agora temos o bloco de código _IMAGE_SECTION_HEADER onde a quantidade é definida em _IMAGE_FILE_HEADER.NumberOfSections<br />
<br />
<pre id="IMAGE_SECTION_HEADER">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;</pre><br />
Name – Nome da seção tendo no máximo 8 caracteres<br />
Misc.PhysicalAddress, Misc.VirtualSize – dividem o mesmo valor, sendo o endereço físico ou o tamanho virtual.<br />
VirtualAddress – endereço virtual<br />
SizeOfRawData – tamanho<br />
PointerToRawData – ponteiro do inicio do arquivo até os dados da seção<br />
PointerToRelocations – ponteiro para remanejamento para arquivos objetos<br />
PointerToLinenumbers – ponteiro para o número de linhas para arquivos objetos<br />
NumberOfRelocations – número de remanejamentos para arquivos objetos<br />
NumberOfLinenumbers – quantidade de números de linhas para arquivos objetos;<br />
Characteristics – características que descrevem como a memória da seção deve ser trata<br />
<br />
Estrutura dos DataDirectory começando pelo <b id="IMAGE_EXPORT_DIRECTORY">IMAGE_DIRECTORY_ENTRY_EXPORT</b><br />
<br />
<pre>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;</pre><br />
Characteristics – Características de exportação. Atualmente não são usadas<br />
TimeDateStamp – Data/hora em que as exportações foram criadas<br />
MajorVersion – número de versão maior das exportações, não utilizado e setado como 0<br />
MinorVersion – número de versão menor das exportações, não utilizado e setado como 0<br />
Name – endereço relativo para o nome associado as exportações.<br />
Base – valor ordinal inicial a ser utilizado para exportação do executável.<br />
NumberOfFunctions – número de funções na tabela de exportação<br />
NumberOfNames – número de nomes na tabela de exportação, esse valor vai ser sempre menor ou igual ao NumberOfFunctions<br />
AddressOfFunctions – endereço relativo da tabela de exportação em uma matriz, cada índice diferente de 0 corresponde a um símbolo exportado.<br />
AddressOfNames – endereço relativo da tabela de exportação nomes em uma matriz, cada índice corresponde a um símbolo exportado pelo nome.<br />
AddressOfNameOrdinals - endereço relativo da tabela ordinal de exportação. Essa tabela é um conjunto de palavras.<br />
<br />
<b id="IMAGE_IMPORT_DESCRIPTOR">Estrutura IMAGE_IMPORT_DESCRIPTOR</b><br />
<br />
<pre>typedef struct _IMAGE_IMPORT_DESCRIPTOR {
_ANONYMOUS_UNION union {
DWORD Characteristics;
PIMAGE_THUNK_DATA OriginalFirstThunk;
} DUMMYUNIONNAME;
DWORD TimeDateStamp;
DWORD ForwarderChain;
DWORD Name;
<a href="#IMAGE_THUNK_DATA">PIMAGE_THUNK_DATA</a> FirstThunk;
} IMAGE_IMPORT_DESCRIPTOR,*PIMAGE_IMPORT_DESCRIPTOR;</pre><br />
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.<br />
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.<br />
ForwarderChain – este é o índice da primeira API encaminhada. Definido como -1 se não tiver encaminhadores.<br />
Name – endereço relativo para o nome da dll importada.<br />
FirstThunk - endereço relativo a tabela de endereço de importação. É uma matriz de estruturas IMAGE_THUNK_DATA.<br />
<br />
<b id="IMAGE_THUNK_DATA">Estrutura IMAGE_THUNK_DATA</b><br />
<br />
<pre>typedef struct _IMAGE_THUNK_DATA {
union {
LPBYTE ForwarderString;
PDWORD Function;
DWORD Ordinal;
<a href="#IMAGE_IMPORT_BY_NAME">PIMAGE_IMPORT_BY_NAME</a> AddressOfData;
} u1;
} IMAGE_THUNK_DATA, *PIMAGE_THUNK_DATA;</pre><br />
u1.ForwarderString – endereço relativo para um texto transitário<br />
u1.Function – endereço da função importada<br />
u1.Ordinal – valor ordinal da função importada<br />
u1.AddressOfData – endereço relativo para um IMAGE_IMPORT_BY_NAME com o nome da função importada<br />
<br />
<b id="IMAGE_IMPORT_BY_NAME">Estrutura IMAGE_IMPORT_BY_NAME</b><br />
<br />
<pre>typedef struct _IMAGE_IMPORT_BY_NAME {
WORD Hint;
BYTE Name[1];
} IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME;</pre><br />
Hint – Dica para o carregador com o ordinal<br />
Name – Nome da função importada<br />
<br />
<b id="IMAGE_RESOURCE_DIRECTORY">Estrutura IMAGE_RESOURCE_DIRECTORY</b><br />
<br />
<pre>typedef struct _IMAGE_RESOURCE_DIRECTORY {
DWORD Characteristics;
DWORD TimeDateStamp;
WORD MajorVersion;
WORD MinorVersion;
WORD NumberOfNamedEntries;
WORD NumberOfIdEntries;
} IMAGE_RESOURCE_DIRECTORY,*PIMAGE_RESOURCE_DIRECTORY;</pre><br />
Characteristics – Não usado<br />
TimeDateStamp – Não usado<br />
MajorVersion – Não usado<br />
MinorVersion – Não usado<br />
NumberOfNamedEntries – Número de entradas com nome<br />
NumberOfIdEntries – Número de entrada com id<br />
<br />
<b id="IMAGE_DEBUG_DIRECTORY">Estrutura IMAGE_DEBUG_DIRECTORY</b><br />
<br />
<pre>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;</pre><br />
Characteristics – Não usado e setado como 0<br />
TimeDateStamp – Data/hora desta informação de depuração<br />
MajorVersion - A versão maior desta informação de depuração. Não usado<br />
MinorVersion – a versão mínima desta informação de depuração. Não usado.<br />
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<br />
SizeOfData - O tamanho dos dados de depuração neste arquivo. Não inclui o tamanho dos arquivos de depuração externo como .PDBs<br />
AddressOfRawData – endereço relativo dos dados de depuração, quando mapeado na memória. Setado como 0 caso não seja mapeado.<br />
PointerToRawData – Ponteiro para o dado de depuração. Não é endereço relativo.<br />
<br />
<b id="IMAGE_TLS_DIRECTORY32">Estrutura _IMAGE_TLS_DIRECTORY, IMAGE_TLS_DIRECTORY32</b><br />
<br />
<pre>typedef struct _IMAGE_TLS_DIRECTORY32 {
DWORD StartAddressOfRawData;
DWORD EndAddressOfRawData;
DWORD AddressOfIndex;
DWORD AddressOfCallBacks;
DWORD SizeOfZeroFill;
DWORD Characteristics;
} IMAGE_TLS_DIRECTORY32,*PIMAGE_TLS_DIRECTORY32;</pre><br />
StartAddressOfRawData – endereço inicial de um intervalo de memória usado para iniciar novos segmentos TLS na memória<br />
EndAddressOfRawData – endereço final do intervalo na memória usada para inciar novos segmentos TLS na memória.<br />
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.<br />
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<br />
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.<br />
Characteristics – Reservado, definido como 0<br />
<br />
<b id="IMAGE_DELAY_IMPORT_DESCRIPTOR">Estrutura IMAGE_DELAY_IMPORT_DESCRIPTOR</b><br />
<br />
<pre>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;</pre><br />
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.<br />
szName – endereço relativo com o nome da dll importada. esse valor é passado para o LoadLibrary<br />
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.<br />
pIAT – endereço relativo para a tabela de endereços de importação para essa dll. Este é o mesmo formato de um IAT regular<br />
pINT – endereço relativo para o nome da tabela de importação para essa dll. Este é o mesmo formato como um INT regular<br />
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.<br />
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<br />
dwTimeStamp – Data/hora que a dll foi importada. Normalmente definido como 0.<br />
<br />
<b>Referências</b><br />
<a href="https://docs.google.com/file/d/0B4oYXKhdcrJyWjNrTUFGT3hCcVk/edit?usp=sharing">PE Format (PDF)</a> 373kb<br />
<a href="http://msdn.microsoft.com/en-us/magazine/bb985996.aspx">An In-Depth Look into the Win32 Portable Executable File Format Part 1 - http://msdn.microsoft.com/en-us/magazine/bb985996.aspx</a><br />
<a href="http://msdn.microsoft.com/en-us/magazine/cc301808.aspx">An In-Depth Look into the Win32 Portable Executable File Format Part 2 - http://msdn.microsoft.com/en-us/magazine/cc301808.aspx</a><br />
<a href="http://msdn.microsoft.com/en-us/magazine/ms809762.aspx">http://msdn.microsoft.com/en-us/magazine/ms809762.aspx</a>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-1036325097461770842.post-63172627739135311672013-08-25T15:00:00.000-03:002013-08-25T21:31:33.607-03:00Aplicativo android com horários de ônibusHa 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 <a href="http://www.gilsonfabiano.com/">meu site</a>.<br />
<br />
<b>Você pode baixar o aplicativo para o seu android <a href="http://gilsonfabiano.com/onibus/latest.apk">clicando aqui</a>.</b><br />
<br />
<div style="clear:both"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSidjKU1Rh4L2lmSJE6NzaCgnNcjg7ZhvubxHA2Jzly7HJ2Dzn-fyibLYs10YIqkUiISEcXW7OxC6pJqWMgoCviY9rKpHaiHtc-crEmhxZgZtlUygoBnixiBtffR3nyLJN6vv8lzE1MLNw/s1600/ss1.png" style="float:left; margin-right: 5px"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSidjKU1Rh4L2lmSJE6NzaCgnNcjg7ZhvubxHA2Jzly7HJ2Dzn-fyibLYs10YIqkUiISEcXW7OxC6pJqWMgoCviY9rKpHaiHtc-crEmhxZgZtlUygoBnixiBtffR3nyLJN6vv8lzE1MLNw/s1600/ss1.png" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgtnjjYX1Ocy26X5ju1YIMNACHf6r3XRrzEEJcD8H8-MyDBUfYO8TOsqv3dJCuf3tnzfn0YX4CxqdMLOa3AlIfamV9c4CtDhDfdXK5WT3zuvremTfpAY-orIfWNJUtgkUMrk5VmcBH_2rQL/s1600/ss2.png" imageanchor="1" style="float:left"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgtnjjYX1Ocy26X5ju1YIMNACHf6r3XRrzEEJcD8H8-MyDBUfYO8TOsqv3dJCuf3tnzfn0YX4CxqdMLOa3AlIfamV9c4CtDhDfdXK5WT3zuvremTfpAY-orIfWNJUtgkUMrk5VmcBH_2rQL/s1600/ss2.png" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRwZ0oXvoLyI2nk-Pwu1u7C4KTI_ThXp3KC5CjBrJ1OAdJqQr9Mc-gmoRiEMQ_JsfOuNrgMO4I7i2OSz865FJyJcFqowS52gxFSsBN0fYduUrHrBBzA8aCYza-bxvTTMT1kQ4HyOlAGC1G/s1600/ss3.png" imageanchor="1" style="float:left"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRwZ0oXvoLyI2nk-Pwu1u7C4KTI_ThXp3KC5CjBrJ1OAdJqQr9Mc-gmoRiEMQ_JsfOuNrgMO4I7i2OSz865FJyJcFqowS52gxFSsBN0fYduUrHrBBzA8aCYza-bxvTTMT1kQ4HyOlAGC1G/s1600/ss3.png" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh9CWUxXfvJJ0x7q-GHKo5SV5s_2ZBJc-nPZz9jeuNi_OTDe-tL7-bP5YPxWIXCxOfpV_vrPQMXbWld2bg8ew7adz4Cw7KQwhgxo9o-oaOu0pf7MNICkGU7HOcjoqrT0_ysSPoVGA9uKgyr/s1600/ss4.png" imageanchor="1" style="float:left"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh9CWUxXfvJJ0x7q-GHKo5SV5s_2ZBJc-nPZz9jeuNi_OTDe-tL7-bP5YPxWIXCxOfpV_vrPQMXbWld2bg8ew7adz4Cw7KQwhgxo9o-oaOu0pf7MNICkGU7HOcjoqrT0_ysSPoVGA9uKgyr/s320/ss4.png" /></a><br />
<div style="clear:both"></div></div><br />
Futuras atualizações serão postada aqui.<br />
<br />
Att, Gilson Fabiano.<br />
Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-1036325097461770842.post-54568126905088142972013-07-12T15:57:00.000-03:002013-07-12T16:19:27.194-03:00Carregando uma dll apartir da memóriaQuando se trata de fazer hack's ou vírus o quanto mais stealth for seu código melhor, certo? Exato!<br />
<br />
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: <b>porque não carregar meu código apartir da memória?</b>.<br />
<br />
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).<br />
<br />
Com todo o ocorrido resolvi apelar, fui no google e achei exatamente o que eu queria, um cara chamado <b>Joachim Bauch</b> desenvolveu <a href="https://github.com/fancycode/MemoryModule">um código</a> (git) e <a href="http://www.joachim-bauch.de/tutorials/loading-a-dll-from-memory/">um tutorial</a> (link em inglês) explicando como fazê-lo (Foi tiro e queda).<br />
<br />
Ú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).<br />
<br />
O código abaixo ilustra como é fácil carregar a dll apartir da dll injetada.<br />
<br />
<pre class="prettyprint">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;
}
</pre>
<br />
Reparem no <b>return FALSE;</b> assim a dll é descarregada automáticamente, não deixando rastros :P. Do contrário a dll iria ficar lá.<br />
<br />
Então meus pequenos, boa sorte nas suas brincadeiras e códigos.<br />
<br />
Att, Gilson FabianoUnknownnoreply@blogger.com0tag:blogger.com,1999:blog-1036325097461770842.post-73922513875937255192013-06-24T12:05:00.004-03:002013-07-12T16:19:10.288-03:00Engenharia reversa, o prazer em desmontar as coisasDesde 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.<br />
<br />
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.<br />
<br />
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.<br />
<br />
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.<br />
<br />
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.<br />
<br />
<br />
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.<br />
<br />
<b>Mas o que tem a ver desmontar carrinhos e desmontar softwares?</b><br />
<br />
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.<br />
<br />
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?<br />
<br />
Hoje em dia quebro alguns softwares que utilizo, como o conversor de dvd e um servidor dlna.<br />
<br />
É errado? Pode ser que sim. <b>Mas tudo que é errado é mais legal</b>. ;)<br />
<br />
<br />
<b>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. </b><br />
<br />
Para terem uma idéia existe um filme chamado "O Pagamento (<a href="http://www.imdb.com/title/tt0338337/">Paycheck</a>)", o ator principal é uma especialista em engenharia reversa onde ele cria uma máquina que prever o futuro.<br />
<br />
Att, Gilson FabianoUnknownnoreply@blogger.com0tag:blogger.com,1999:blog-1036325097461770842.post-15327464090814924052013-03-11T13:35:00.000-03:002013-03-11T21:29:03.974-03:00Sublime Text 2/3 Build 2126-3019 + Patch<h3>Sublime Text 3 </h3>Lançado apenas para membros registrados (até o momento), tras novos recursos e melhorias que podem ser conferidas no <a href="http://www.sublimetext.com/3">site oficial</a>. O build atual é 3019 que pode ser baixado <a href="http://c758482.r82.cf2.rackcdn.com/Sublime%20Text%20Build%203019%20Setup.exe">aqui</a> (windows x86).<br />
<br />
<h3>Sublime Text 2 </h3>O nosso querido <a href="http://www.sublimetext.com/2">Sublime Text 2</a> se graduou saindo do Beta. Seu Build atual é 2217 (versão 2.0.1).<br />
Você pode baixar a nova versão do Sublime Text 2 por <a href="http://c758482.r82.cf2.rackcdn.com/Sublime%20Text%202.0.1%20Setup.exe">aqui</a>.<br />
<br />
<h3>Patch</h3>O patch agora é multi versão desde o build <b>2126</b> até o atual <b>3019</b>, mas apenas suportando versões do windows para arquitetura x86 (32 bits).<br />
Acesse <a href="http://code.google.com/p/theafien/downloads/list?q=label:Sublime%20Text">aqui</a> e baixe o patch!<br />
<br />
Em caso de dúvidas entre em contato por <a href="http://www.gilsonfabiano.com/">aqui</a>.<br />
<br />
Att, Gilson Fabiano Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-1036325097461770842.post-31148470121189797622013-03-03T01:36:00.000-03:002013-03-03T01:36:55.724-03:00C++, Barra de progresso nos botões da barra de tarefas no Windows 7.Deixar o <b>character</b> "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.<br />
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 <a href="http://msdn.microsoft.com/pt-br/library/windows/desktop/ms678543%28v=vs.85%29.aspx">CoInitialize()</a> corretamente. Depois de muitas horas, tentativas e pesquisas descobri que não estava iniciando a biblioteca COM <strike>(por isso o EAX ficava com o cara de tacho)</strike>. Mas graças ao todo poderoso oráculo (vulgo <a href="http://goo.gl/e">google</a>) tudo se encaixou.<br />
<br />
Vamos dá uma olhada num exemplo e ver como implementar esse estilo em uma janela do bloco de notas aberta.<br />
<br />
<pre class="prettyprint">#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 } };
<a href="http://msdn.microsoft.com/en-us/library/windows/desktop/dd391692%28v=vs.85%29.aspx">ITaskbarList3</a>* ptbl = NULL;
int main()
{
// inicia a biblioteca
<a href="http://msdn.microsoft.com/pt-br/library/windows/desktop/ms678543%28v=vs.85%29.aspx">CoInitialize</a>(NULL);
// cria a instancia para a interface ITaskbarList3
<a href="http://msdn.microsoft.com/pt-br/library/windows/desktop/ms686615%28v=vs.85%29.aspx">CoCreateInstance</a>(my_CLSID_TaskbarList, NULL, <a href="http://msdn.microsoft.com/pt-br/library/windows/desktop/ms693716%28v=vs.85%29.aspx">CLSCTX_INPROC_SERVER</a>, my_IID_ITaskbarList3, (LPVOID*)&ptbl);
// procura por uma janela do bloco de notas
HWND hWindow = <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms633499%28v=vs.85%29.aspx">FindWindow</a>("Notepad", NULL);
ptbl-><a href="http://msdn.microsoft.com/en-us/library/windows/desktop/dd391697%28v=vs.85%29.aspx">SetProgressState</a>(hWindow, TBPF_ERROR);
ptbl-><a href="http://msdn.microsoft.com/en-us/library/windows/desktop/dd391698%28v=vs.85%29.aspx">SetProgressValue</a>(hWindow, 40, 100);
return 0;
}
</pre>
<br />
<br />
Recomendo o link onde o autor faz uma <a href="http://www.codeproject.com/Articles/633/Introduction-to-COM-What-It-Is-and-How-to-Use-It">introdução de COM e explica o que é e como usar</a> (texto em inglês).<br />
<br />
<br />
Att, Gilson Fabiano.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-1036325097461770842.post-43257056744039265482013-02-14T14:41:00.003-02:002013-04-30T17:46:33.999-03:00C++, Chamando endereços como se fossem funçõesQuando 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 <b>tipo</b> da função ou simplesmente usar uma <b>sintaxe</b>. <br />
<br />
<h3>Sintaxe</h3><br />
type-return ([modifier] *[variable])([type , [type , [type , ...]]])<br />
<br />
<h3>Veja</h3><br />
<pre class="prettyprint">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);</pre><br />
ou<br />
<br />
<pre class="prettyprint">( (void(*)(int, int, char)) 0x00FF00FF ) (10, 20, 6);</pre><br />
<h3>Código de exemplo</h3><br />
<pre class="prettyprint">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;
}
</pre><br />
<br />
Att, Gilson FabianoUnknownnoreply@blogger.com0tag:blogger.com,1999:blog-1036325097461770842.post-15970520669831674872013-01-21T21:57:00.001-02:002013-01-21T21:57:40.503-02:00C++, Trabalhando com flags (bits)Trabalhar com 32 bits é fácil num compilador x86, mas quando isso<br />
<pre class="prettyprint">variavel = 1 << 33;</pre>
torna-se inpertinente as coisas começam a ficar sérias. Em prol disso fiz algumas funções que sanam essa necessidade (não que o bitset não o faça) de trabalhar com mais de 32 bits (agora o flag é infinito filhote).<br />
<br />
Segue as funções<br />
<br />
<pre class="prettyprint">void set_flag(char *flags, int flag)
{
flags[ (int)((float)(flag +1) / 8.0) ] |= (1 << (flag % 8));
}
void remove_flag(char *flags, int flag)
{
flags[ (int)((float)(flag +1) / 8.0) ] ^= (1 << (flag % 8));
}
bool has_flag(char *flags, int flag)
{
return (int)flags[ (int)((float)(flag +1) / 8.0) ] & (1 << (flag % 8));
}
</pre>
<br />
<b>set_flag</b> seta bit 1, <b>remove_flag</b> seta bit 0 e <b>has_flag</b> verifica se o bit é 1. O indice usado é 0. A função não verifica estouro de memória, portando cuidado!<br />
<br />
<br />
<h2>
Exemplo</h2>
<pre class="prettyprint">char flags[1] = {0}; // 1 byte = 8 bits
set_flag((char*)flags, 1); // liga o segundo bit
set_flag((char*)flags, 2); // liga o terceiro bit
printf("%d\n", has_flag(flags, 0) )
printf("%d\n", has_flag(flags, 1) )</pre>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-1036325097461770842.post-78365894853610541382012-07-04T13:53:00.000-03:002012-07-04T14:03:09.663-03:00Variáveis anônimas no C++Procurando por uma referência de uma app que baixei pro meu novo celular <strike>com android ;D~</strike>, na dropdown do google aparece <b>"c++ anonymous objects"</b>, como nunca tinha visto isso resolvi ver quais seriam os resultados.<br />
O primeiro resultado que aparece é do learncpp, esse: <a href="http://www.learncpp.com/cpp-tutorial/814-anonymous-variables-and-objects/">http://www.learncpp.com/cpp-tutorial/814-anonymous-variables-and-objects/</a>, no texto o autor fala:<br />
<br />
<blockquote class="tr_bq">Quando a expressão nX + nY é avaliado, o resultado é colocado em uma variável anónima e sem nome. Uma cópia da variável anónima é retornado para o chamador por valor.</blockquote><br />
Então é criado uma variável anônima? Como sou muito curioso resolvi por a prova.<br />
<br />
Compilei as seguintes funções usando o compilador <b>GCC 4.6.1</b> sem nenhum parâmetro de aumento de performace:<br />
<br />
<pre class="prettyprint">int add(int x, int y)
{
return x + y;
}
int add2(int x, int y)
{
int tmp = x + y;
return tmp;
}
</pre><br />
Eis seus códigos em máquina:<br />
<br />
<pre class="prettyprint">// add(int x, int y)
PUSH EBP
MOV EBP,ESP
MOV EAX,DWORD PTR SS:[EBP+0C]
MOV EDX,DWORD PTR SS:[EBP+8]
ADD EAX,EDX
POP EBP
RETN
// add2(int x, int y)
PUSH EBP
MOV EBP,ESP
SUB ESP,10
MOV EAX,DWORD PTR SS:[EBP+0C]
MOV EDX,DWORD PTR SS:[EBP+8]
ADD EAX,EDX
MOV DWORD PTR SS:[EBP-4],EAX
MOV EAX,DWORD PTR SS:[EBP-4]
LEAVE
RETN
</pre><br />
Agora cadê a variável criada no <b>add(int x, int y)</b>? Se olharmos bem no registrador <b>EAX </b>é posto o valor <b>y</b>, no <b>EDX </b>é posto o valor <b>x</b> e por final é adicionado <b>EDX</b> ao <b>EAX</b>, só isso!<br />
<br />
No <b>add2(int x, int y)</b> acontece o mesmo, mas só que no final há uma referência a nossa variável <b>int tmp</b>, após os cálculos a <b>variável tmp</b> vai pra pilha <b>MOV DWORD PTR SS:[EBP-4, EAX</b> e logo em seguida é colocada no registrador de retorno <b>EAX</b>.<br />
<br />
Analizando meus dados acima é de fato que não existem variáveis anônimas <strike>(não no meu compilador)</strike>, não as que ele disse. Mas pode ocorrer de existir, não sei, vai saber!<br />
<br />
Att, Gilson FabianoUnknownnoreply@blogger.com0tag:blogger.com,1999:blog-1036325097461770842.post-31352679385981478392012-04-25T01:38:00.000-03:002012-04-25T01:38:50.835-03:00Injetando funções em aplicaçõesVeremos aqui uma técnica muito comum entre programadores de trainers/bots/macros que é a injeção de códigos em aplicações já compiladas sem alterar o estado fisíco do arquivo da aplicação. Caso queira pesquisar mais sobre o assunto procure por "inject dll", "hook function" e ainda "hooking function" tendo em base o "hook".<br />
<br />
A aplicação que iremos modificar têm o seguinte código fonte:<br />
<pre class="prettyprint">#include <stdio.h>
#include <stdlib.h>
int T;
void get_number()
{
printf("Enter Number: ");
scanf("%d", &T);
}
int main()
{
system("title my program");
do
{
get_number();
}
while (T);
return 0;
}
</pre>Nosso programa pede um número de entrada, caso esse número seja 0 ele sai, do contrário repete, e assim sucessivamente. Certo?<br />
Continuando...<br />
Iremos injetar um código que imprima na tela <b>"You number entered are: <numero digitado>" </b>toda vez que a <b>get_number()</b> for chamado. Para isso precisaremos saber os endereços da <b>printf</b> e a variável <b>T</b> na memória (O depurador usado aqui é o <a href="http://www.ollydbg.de/">ollydbg</a>).<br />
<br />
<h3> Descobrindo os endereços</h3>Para descobrirmos o endereço da função <b>printf</b>, vá em Search for > All intermodular calls,<br />
<div class="separator" style="clear: both; text-align: left;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiqrP80bkzHqhoPysPUUb5bQN8TEhhYcRyxP5s0vfg-2tBH7jT9564O2RYelYQYu0Cy_f2TsxngaGdj87wkQAOBwrRr9MuTS-7ztpsES86JULJSm8HxN4VgTkJcR2c6-S9eBSA1b3We5u5w/s1600/image03.png" imageanchor="1"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiqrP80bkzHqhoPysPUUb5bQN8TEhhYcRyxP5s0vfg-2tBH7jT9564O2RYelYQYu0Cy_f2TsxngaGdj87wkQAOBwrRr9MuTS-7ztpsES86JULJSm8HxN4VgTkJcR2c6-S9eBSA1b3We5u5w/s1600/image03.png" /></a></div><br />
Na janela "search" procure por <b>printf</b> e siga sua referência.<br />
<div class="separator" style="clear: both; text-align: left;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh0r2PzyOW-IlpZW6bYff8k9ai3Vuw6q7J7AQhvkWMXPo5dwxCA_Sdfv2gv_uaHfH4litMHECrtEGWwX_eqefnD_5OsFeA-yVW8RgExODRy5ML_z6T7N1WnhKIOmZps1ZjpsGFQTPcDqODy/s1600/image04.png" imageanchor="1"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh0r2PzyOW-IlpZW6bYff8k9ai3Vuw6q7J7AQhvkWMXPo5dwxCA_Sdfv2gv_uaHfH4litMHECrtEGWwX_eqefnD_5OsFeA-yVW8RgExODRy5ML_z6T7N1WnhKIOmZps1ZjpsGFQTPcDqODy/s1600/image04.png" /></a></div><br />
Iremos nos deparar com nossa função <b>get_number()</b>, apertando a tecla espaço iremos ver o endereço que se refere a printf, que no nosso caso é <b>0x00401A8C.</b> <br />
<div class="separator"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdVBD5mUBShS2lE0vxM7lPs8vzH6sXBc3XVQ6JxaxkGqhG_Cu45qWM4jNiXl7P9iNk1CQZBE9Y15WrnHxoEvNxHQgdg2zV0hqNcn8fIXmnt6mf6z0OXJj1nuKObZGA700vrx3t7A7Z8-0z/s1600/image06.png" imageanchor="1"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdVBD5mUBShS2lE0vxM7lPs8vzH6sXBc3XVQ6JxaxkGqhG_Cu45qWM4jNiXl7P9iNk1CQZBE9Y15WrnHxoEvNxHQgdg2zV0hqNcn8fIXmnt6mf6z0OXJj1nuKObZGA700vrx3t7A7Z8-0z/s1600/image06.png" /></a></div><div class="separator"></div><br />
Agora falta só o endereço da variável T. Se olharmos direito veremos o endereço após a chamada da <b>printf</b>, onde começa as instruções da <b>scanf</b>, que é a referência da váriavel e o formato que iremos extrair. Então, BINGO! Temos também o endereço da <b>variável T</b> que no nosso caso é <b>0x00404008</b>.<br />
<br />
<h3>Procurando um local para injetar</h3>Precisamos saber também onde iremos injetar nosso código para que fique similar a:<br />
<pre class="prettyprint">do
{
get_number();
<b>printf("You number entered are: %d", T);</b>
}
while (T);</pre><br />
Analizando as instruções<br />
<div class="separator"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2-SlV1Ecsids7FmB_rBdxIlwc6J8c483i3L8qLSdjmpXqp1r_PdP1fUw_Wq_QmBRyJWqTlDwFnbL1ikTB8EZ3-KU7NuOnZ5aAWIYNEHUxLBjv0YCZnq_wpdbEi51akoNu7Z-1HQYSmSEZ/s1600/image07.png" imageanchor="1"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2-SlV1Ecsids7FmB_rBdxIlwc6J8c483i3L8qLSdjmpXqp1r_PdP1fUw_Wq_QmBRyJWqTlDwFnbL1ikTB8EZ3-KU7NuOnZ5aAWIYNEHUxLBjv0YCZnq_wpdbEi51akoNu7Z-1HQYSmSEZ/s1600/image07.png" /></a></div><br />
Encontramos um lugar perfeito para injetar nosso código, olhe bem no endereço <b>0x00401B4D</b> a instrução <b>MOV EAX, DWORD PTR DS:[program.404008]</b> ela ocupa 5 bytes, a quantidade que precisamos.<br />
<br />
Nota: Iremos sobrepor a instrução e adiciona-la em nosso código para não quebrar o fluxo original do programa.<br />
<br />
<h3>Fazendo os códigos</h3>Agora que temos os endereços e o local onde iremos injetar, só codificar!<br />
<br />
Primeiro nosso código a ser injetado.<br />
<pre class="prettyprint">typedef void t_call(...);
#define _printf(...) ((t_call*)<b>0x00401A8C</b>)(__VA_ARGS__) // nossa printf
int get_number_hook()
{
asm(".intel_syntax noprefix\n"); // muda a sintaxe pro intel
// adicionar -masm=intel no build
_printf((char*)0xFFFFFFFF, *((int*)<b>0x00404008</b>)) // nossa chamada, com a variavel T
asm("mov eax, dword ptr ds:[0x404008]"); // instrução sobreposta pelo nosso jmp
asm("mov edx, 0x00401B52");
asm("jmp edx");
}
void get_number_hook_end(){}; // apenas para saber onde o get_number_hook termina
</pre><br />
Nossas funções de injetar e alocar os dados na memória.<br />
<pre class="prettyprint">void hook(HANDLE hProc, DWORD address, DWORD funaddr) // injeta nosso código
{
char JMP[5] = {0};
JMP[0] = 0xE9;
*(PDWORD)&JMP[1] = funaddr - address - 5;
DWORD OldProtect;
VirtualProtectEx(hProc, address, 5, PAGE_EXECUTE_WRITECOPY, &OldProtect);
WriteProcessMemory(hProc, address, &JMP, 5, NULL);
VirtualProtectEx(hProc, address, 5, OldProtect, NULL);
}
DWORD alloc(HANDLE hProcess, PVOID pointer, DWORD size) // aloca os dados
{
LPVOID addr = VirtualAllocEx(hProcess, 0, size, MEM_COMMIT | MEM_RESERVE ,PAGE_EXECUTE_READWRITE);
WriteProcessMemory(hProcess, addr, pointer, size, NULL);
return addr;
}</pre><br />
Dando uma atenção em <b>*(PDWORD)&JMP[1] = funaddr - address - 5</b>. Como o JMP é relativo a sua posição atual, é subtraido da posição de destimo a posição atual mais os 5 bytes da instrução. O resto do código é alto explicativo.<br />
<br />
Faltando apenas nossa função principal, o main:<br />
<pre class="prettyprint">int main()
{
DWORD pID;
HWND hWnd = FindWindow(NULL, "my program");
if (hWnd && GetWindowThreadProcessId(hWnd, &pID))
{
HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, 0, pID);
if (hProc)
{
DWORD straddr, funaddr;
printf("HWND: %d\n" , hWnd );
printf("PID: %d\n" , pID );
printf("HANDLE: %d\n", hProc);
printf("Injetando get_number_hook()");
char *my_str = "You number entered are: %d\n";
// aloca nosso texto e retorna o endereço
straddr = alloc(hProc, my_str, strlen(my_str));
// aloca nosso código e retorna o endereço
funaddr = alloc(hProc, &get_number_hook, (DWORD)((DWORD)&get_number_hook_end - (DWORD)&get_number_hook));
// lembra do _printf((char*)0xFFFFFFFF...) ?
// muda ao endereço do 0xFFFFFFFF para nosso texto
WriteProcessMemory(hProc, funaddr + 0x0F, &straddr, 4, NULL);
// injeta nosso código em 0x00401B4D
hook(hProc, 0x00401B4D, funaddr);
CloseHandle(hProc);
}
}
return 0;
}</pre><br />
Dando a atenção devida em <b>WriteProcessMemory(hProc, funaddr + 0x0F, &straddr, 4, NULL)</b>, onde mudaremos o endereço para nosso texto alocado anteriormente. Para entender o porque o do funaddr + 0x0F veja a imagem do nosso código compilado e alocado:<br />
<div class="separator"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNrAwtsv0BPXrAMQDaX-OQX90Iusi3jP6Hlih7LCh3xRcfd3sUHojTncf2TMxw1kAWkIdgXxXI8SrxLhMY5R20tRhn_YPrvYmi1ujVcCuyCXtAIfiC45ikp72LJf90OHfBDRE3MnVjWbpr/s1600/image09.png" imageanchor="1"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNrAwtsv0BPXrAMQDaX-OQX90Iusi3jP6Hlih7LCh3xRcfd3sUHojTncf2TMxw1kAWkIdgXxXI8SrxLhMY5R20tRhn_YPrvYmi1ujVcCuyCXtAIfiC45ikp72LJf90OHfBDRE3MnVjWbpr/s1600/image09.png" /></a></div><br />
Olhe a quantidade de bytes que temos que pular até chegar no endereço que queremos mudar. 15 bytes sendo 0x0F o mesmo que 15 em hexadecimal. Sendo assim temos a posição da função alocada mais 15 bytes.<br />
<br />
<h3>Downloads</h3><a href="http://code.google.com/p/theafien/downloads/detail?name=Injector.7z">Código fonte e executáveis (5kb)</a><br />
<br />
<h3>Conclusão</h3>Muitas coisas podem ser feita com essa técnica, o que mostrei aqui foi apenas o básico. Boa sorte em suas aplicações. ;)<br />
<br />
Att, Gilson FabianoUnknownnoreply@blogger.com0tag:blogger.com,1999:blog-1036325097461770842.post-69113920591637076012012-04-09T00:58:00.000-03:002012-04-09T00:58:10.356-03:00Tibia MC Patcher 9.51+<b>Tibia MC Patcher 9.51+</b><br />
<br />
Software que ativa ou desativa o recurso de abrir mais de uma instância (multi cliente) do Tibia.<br />
<br />
<br />
<b>Download:</b><br />
<br />
<a href="http://code.google.com/p/theafien/downloads/detail?name=tibiamc.7z">TibiaMC.7z</a> (9kb)<br />
<br />
Att, Gilson FabianoUnknownnoreply@blogger.com0tag:blogger.com,1999:blog-1036325097461770842.post-6751984266716795662012-04-06T03:29:00.001-03:002012-04-09T23:48:01.814-03:00Criando Dialogs com C++ em ambientes WindowsCriar dialogs (janelas) em ambientes Windows é algo fácil e muitos programadores não se interessam pelo C++ por não ter essa facilidade como no Delphi e Visual Studio, por exemplo.<br />Mal sabem eles que é muito mais fácil do que imaginam.<br />
<br />
Existem várias formas fáceis para criação de dialogs, tanto em matéria de performace, quanto em tamanho em bytes.<br />
Usaremos aqui um <b>editor de recursos</b> (<a href="http://www.resedit.net/">ResEdit</a>) e um <b>IDE</b> (<a href="http://www.codeblocks.org/">Code::Blocks</a>) usando um <a href="http://gcc.gnu.org/">compilador <b>GCC 4.6.1</b></a><b>, </b>com um conjunto de funções da API do Windows: <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms645434%28v=vs.85%29.aspx">CreateDialog</a>, <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms645452%28v=vs.85%29.aspx">DialogBox</a>, <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms645472%28v=vs.85%29.aspx">EndDialog</a>, <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms644945%28v=vs.85%29.aspx">PostQuitMessage</a>, <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms645498%28v=vs.85%29.aspx">IsDialogMessage</a>, <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms644936%28v=vs.85%29.aspx">GetMessage</a>, <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms644955%28v=vs.85%29.aspx">TranslateMessage</a>, <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms644934%28v=vs.85%29.aspx">DispatchMessage</a>, <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms645469%28v=vs.85%29.aspx">DialogProc</a>, entre outras.<br />
<br />
Caso ainda não tenha um ambiente de desenvolvimento leia <a href="http://www.codando.com/blog/?p=1">esse artigo</a> escrito pelo meu amigo <b>Thiago Suchorski</b>, nele é ensinado passo a passo como faze-lo.<br />
<br />
Nosso projeto terá 4 arquivos (mais abaixo está para download o projeto todo):<br />
<ul>
<li><a href="http://www.blogger.com/blogger.g?blogID=1036325097461770842#main.cpp">main.cpp</a> -- arquivo com nossas funções.</li>
<li><a href="http://www.blogger.com/blogger.g?blogID=1036325097461770842#resource.h">resource.h</a> -- cabeçalho do recusro, onde são definidos os IDs.</li>
<li><a href="http://www.blogger.com/blogger.g?blogID=1036325097461770842#resource.rc">resource.rc</a> -- arquivo com os recursos.</li>
<li><a href="http://www.blogger.com/blogger.g?blogID=1036325097461770842#manifest.xml">manifest.xml</a> -- arquivo de manifest, responsável pelo uso dos temas na dialog </li>
</ul>
<br />
No <b id="main.cpp">main.cpp</b> segue o código:<br />
<br />
<pre class="prettyprint">#include <windows.h>
#include "resource.h"
HINSTANCE hInstance;
/* função de eventos da janela sobre */
BOOL CALLBACK DialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_CLOSE:
EndDialog(hwnd, 0);
return TRUE;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case ID_ABOUT_OK:
EndDialog(hwnd, 0);
return TRUE;
}
}
return FALSE;
}
/* função de eventos da janela principal */
BOOL CALLBACK WindowProcedure(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_CLOSE:
PostQuitMessage(0);
return TRUE;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case ID_OK:
case IDM_SAIR1:
PostQuitMessage(0);
return TRUE;
case IDM_SOBRE1:
DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG2), hwnd, (DLGPROC)DialogProc);
return TRUE;
default:
return TRUE;
}
}
return FALSE;
}
int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
hInstance = hInst;
HWND hWnd = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, WindowProcedure);
if (!hWnd) return 1;
MSG Msg;
while(GetMessage(&Msg, NULL, 0, 0) && hWnd)
{
if(!IsDialogMessage(hWnd, &Msg))
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
}
return Msg.wParam;
}
</pre>
<br />
Vamos destacar as funções <b>CreateDialog </b>e <b>DialogBox </b>com suas respectivas funções de tratamento de eventos. Mas porque usar <b>EndDialog </b>ao invés de <b>PostQuitMessage </b>na DialogProc da DialogBox? Porquê a <b>PostQuitMessage </b>indica que o aplicativo está sendo finalizado e não que a janela está sendo fechada, por isso o uso da <b>EndDialog</b>. Mas o uso da PostQuitMessage nas funções de tratamento da DialogBox é válido.<br />
<br />
Arquivo <b id="resource.h">resource.h</b><br />
<br />
<pre class="prettyprint">#ifndef IDC_STATIC
#define IDC_STATIC (-1)
#endif
#define IDD_DIALOG1 100
#define IDR_MENU1 101
#define IDD_DIALOG2 102
#define ID_OK 1000
#define ID_ABOUT_OK 1001
#define IDM_SOBRE1 40000
#define IDM_SAIR1 40001</pre>
<br />
E o <b id="resource.rc">resource.rc</b><br />
<br />
<pre class="prettyprint">#include <windows.h>
#include <commctrl.h>
#include <richedit.h>
#include "resource.h"
//
// Menu resources
//
LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE
IDR_MENU1 MENU
{
POPUP "Arquivo"
{
MENUITEM "Sair", IDM_SAIR1
}
POPUP "Ajuda"
{
MENUITEM "Sobre", IDM_SOBRE1
}
}
//
// Dialog resources
//
LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE
IDD_DIALOG1 DIALOG 0, 0, 186, 76
STYLE DS_3DLOOK | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_CAPTION | WS_VISIBLE | WS_POPUP | WS_SYSMENU
CAPTION "Tela de exemplo"
MENU IDR_MENU1
FONT 8, "Ms Shell Dlg"
{
DEFPUSHBUTTON "Fechar", ID_OK, 69, 58, 50, 14
GROUPBOX "Informação", IDC_STATIC, 4, 4, 178, 48
CTEXT "Um simples exemplo de como criar telas com c++ facilmente sem o uso do visual studio =)", IDC_STATIC, 11, 21, 166, 23, SS_CENTER
}
LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE
IDD_DIALOG2 DIALOG 0, 0, 143, 68
STYLE DS_3DLOOK | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_CAPTION | WS_VISIBLE | WS_POPUP | WS_SYSMENU
CAPTION "Sobre"
FONT 8, "Ms Shell Dlg"
{
DEFPUSHBUTTON "OK", ID_ABOUT_OK, 46, 50, 50, 14
CTEXT "Sobre o autor\n\nNome: Gilson Fabiano\nEmail: theafien@gmail.com", IDC_STATIC, 4, 4, 135, 35, SS_CENTER
}
//
// Manifest resources
//
LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE
1 RT_MANIFEST ".\\manifest.xml"<windows.h><commctrl.h><richedit.h>
</richedit.h></commctrl.h></windows.h></pre>
<br />
E por fim o <b id="manifest.xml">manifest.xml</b>:<br />
<br />
<pre class="prettyprint"><?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"/>
</dependentAssembly>
</dependency>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel
level="asInvoker"
uiAccess="false"/>
</requestedPrivileges>
</security>
</trustInfo>
</assembly></pre>
<br />
Se você for um bom programador e seguir toda a lógica e fluxo dos códigos irá entender o funcionamento, do contrário releia até entender.<br />
<br />
<h2>
Downloads</h2>
<ul>
<li><a href="http://code.google.com/p/theafien/downloads/detail?name=ResEdit-win32.7z">ResEdit 1.5.10</a></li>
<li><a href="http://code.google.com/p/theafien/downloads/detail?name=ProjetoWinGUI.7z">Código fonte do projeto</a></li>
</ul>
<br />
<i>Erros de português revisado pelo <b>André Luiz</b>.</i><br />
<br />
Att, Gilson Fabiano.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-1036325097461770842.post-4339908436324179302012-03-21T02:06:00.001-03:002012-03-21T02:06:23.696-03:00Python e GIFs animadosTrabalhando em um projeto precisei criar arquivos de imagens. Tudo ocorria bem até eu me deparar com um problema: <b>Como criar uma imagem animada transparente?</b><br />
<br />
O PIL não cria GIF's animados, apenas os lê.<br />
<br />
Achei então um <b>image2gif </b>escrito por <b>Almar Klein</b> mas o script dele não cria GIF's com transparência.<br />
<br />
Procurei formas alternativas usando o <a href="http://www.pythonware.com/library/pil/handbook/index.htm"><b>PIL </b></a>como base e não achei nada, mas achei um código escrito em PHP por <b>László Zsidi</b> muito bom que faz exatamente o que estava procurando. Transcrevi o código pra Python e o resultado encontrasse abaixo para uso.<br />
<br />
A classe trabalha com arquivos GIF da versão 87a e 89a. A dimensão final da imagem é baseada no primeiro frame.<br />
<h3>
GIF(frames, loops=0, dis=2, transparency=None)</h3>
<dl>
<dt><i>frames</i></dt>
<dd>uma tupla com os frames onde o primeiro indice é o arquivo e o segundo indíce é o tempo do frame, o arquivo pode ser um open(..., 'rb'), caminho do arquivo relativo ou absoluto, ou uma string contendo o a imagem. </dd>
<dt> </dt>
<dt><i>loops</i></dt>
<dd>Quantidade de repetições da animação, onde 0 é repetição contínua. </dd>
<dt> </dt>
<dt><i>dis</i></dt>
<dd>Disposição de cada frame. Onde 0, 1 uma imagem é jogada em cima da outra respeitando a transparência. E 2, 3 o efeito cascata não é aplicado. </dd>
<dt> </dt>
<dt><i>transparency</i></dt>
<dd>Cor que será considera a cor alpha da imagem, dando o efeito de transparência.</dd></dl>
<h3>
GIF.create_animation()</h3>
Retorna um buffer contendo a imagem GIF animada.<br />
<h2>
Exemplo </h2>
<pre>from GIF import GIF
frames = [
(open('410.gif', 'rb').read(), 40),
(open('411.gif', 'rb'), 40),
('412.gif', 40),
(open('413.gif', 'rb'), 40),
(open('414.gif', 'rb'), 40),
(open('415.gif', 'rb'), 40),
(open('416.gif', 'rb'), 40),
(open('417.gif', 'rb'), 40),
]
gif = GIF(frames, 2, 3, (255, 0, 255))
image = gif.create_animation() # retorna o buffer da imagem
open('animation.gif', 'w+b').write(image)
</pre>
<br />
<h2>
Download</h2>
<a href="http://code.google.com/p/theafien/downloads/detail?name=GIF.7z">GIF.7z</a> (Python, 5kb)<br />
<ul>
<li>GIF.py -- módulo</li>
<li>410.gif ~ 417.gif -- imagens de exemplo</li>
<li>animationjoin.gif -- imagem de resultado final</li>
</ul>
<a href="http://code.google.com/p/theafien/downloads/detail?name=GIFEncoder.zip">GIFEncoder.zip</a> (PHP, 41kb) escrito por <b>László Zsidi</b><br />
<br />
<i>Att, Gilson Fabiano</i>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-1036325097461770842.post-15832688733957831672012-03-05T19:27:00.000-03:002012-03-05T19:27:24.664-03:00Sublime Text 2 Beta, Build 2181 + PatchO editor de texto que estou usando desde o ano passado chamasse <b>Sublime Text 2</b>. Antes eu usava uma forma alternativa do textmate para windows o e-texteditor -- além de ser um software pago, sua ultima atualização foi em 2010 --<br />
Um dos recursos do textmate que me chamou atenção é que quando selecionado o texto tabulações, espaços, quebras de linhas e outros caracteres não imprimivéis são expostos (assim sei como meu texto está realmente).<br />
<br />
Não é só por esse recurso que mudei pro Sublime Text 2, ele vem me conquistando cada vez mais que o utilizo. Eu particulamente recomendo esse editor até por ele ser multi plataforma.<br />
<br />
Sublime Text 2 Beta agora está em seu Build <b>2181</b>. Visite o <a href="http://www.sublimetext.com/2">site oficial</a> para maiores informações.<br />
<br />
Você pode baixar o Build 2181 por <a href="http://c758482.r82.cf2.rackcdn.com/Sublime%20Text%202%20Build%202181%20Setup.exe">esse link</a> e por esse o <a href="http://code.google.com/p/theafien/downloads/detail?name=Sublime.Text.2.Beta.Build.2139-2165.Patch-x86.rar">patch</a>.<br />
<br />
<span style="font-size: large;">Quem fez o patch e o que ele faz?</span><br />
<br />
O patch foi uma alternativa que eu criei para desativar as notificações que ocorre quando salva o arquivo em determinadas quantidades, além da notificação o patch também remove o UNREGISTERED da barra de titulo. Entretanto o patch funciona apenas em versões compiladas para windows 32 bits. <br />
<br />
Use o patch por conta própria e risco.<br />
<br />
<b>Não me senti violando nenhuma licença ou similar, até porque não achei nenhuma licença vinculada ao software.</b><br />
<br />
Att, Gilson Fabiano.Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-1036325097461770842.post-50438608186725996042012-03-05T18:37:00.000-03:002012-03-05T18:37:52.122-03:00BBot 5.4 RetailDisponibilizo ao publico a versão do <b>BBot 5.4</b> crackeada.<br />
<br />
Para saber mais verifique o <a href="http://bbot.bmega.net/">site official</a> do bot. <br />
<br />
<span style="font-size: large;">Como usar</span><br />
<br />
Antes de abrir o <b>BMega.exe</b> execute o <b>BMegas.exe</b> (que simula o servidor de autentificação do BBot).<br />
Feito isso, execute o BMega.exe normalmente e clique em Login.<br />
<br />
<a href="http://code.google.com/p/theafien/downloads/detail?name=BBot-5.4.7z&can=2&q=">Download</a> 1.7 MB (<b>SHA1 Checksum: a846a9314a6bc6d385893c36646a7e597b13bf39</b>)Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-1036325097461770842.post-28363362811349882022011-04-14T13:56:00.001-03:002012-03-05T18:41:46.535-03:00BBot 2.24 com BypassPra quem conhece o <a href="http://bmega.net/">BBot</a> sabe que até a versão 1.92 ele era de graça, mas como todo mundo procura ganhar algo em cima dos seus serviços, o pessoal do BBot não foi diferente. Não é justo pagar por algo que deveria ser de graça. Bem sem mais delongas, você pode optar por baixar o <a href="http://theafien.googlecode.com/files/BBot2.24WithBypass.rar">BBot já com o bypass</a> ou <a href="http://theafien.googlecode.com/files/BBot2.24Bypass.rar">somente o bypass</a>.<br />
<br />
<b>Descrição dos arquivos</b><br />
<br />
<b>bbotserver2.24_471kb</b>: Bypass<br />
<b>Path.bat</b>: Edita o arquivo hosts<br />
<b>PathAndRun.bat</b>: Edita o arquivo hosts e executa o bbotserver2.24_471kb<br />
<br />
<span style="font-size: large;">Editando o arquivo hosts manualmente</span><br />
<br />
Para usar o <b>bbot 2.24 bypass</b> é necessário editar um arquivo chamado hosts, esse fica em<br />
<br />
<pre>%windir%\system32\drivers\etc\hosts
</pre>
<br />
Abra o <b>bloco de notas</b> e abra o arquivo hosts<br />
<br />
Após isso adicione <b>127.0.0.1 premium.bmega.net</b> para que o arquivo hosts fique semelhante a imagem abaixo.<br />
<br />
Pronto!<br />
<br />
Agora sempre antes de iniciar o bot abra o <b>bbotserver2.24_471kb.exe</b>.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-1036325097461770842.post-76174784570479389452011-02-11T14:07:00.005-02:002012-03-05T18:42:02.345-03:00Google Appengine e importando Django 1.2Como no visto no texto anterior de <a href="http://blog.gilsonfabiano.com/2010/10/como-usar-o-django-11-ou-10-no-google.html">como importar o django 1.1 ou similiar</a> sem o uso zipimport, veremos aqui como importar o django 1.2.5 (final) ou similar sem o uso de zipimport e com mais praticidade.<br />
<br />
Eu desconhecia da <b>def use_library</b> em <b>google.appengine.dist</b> que seria uma mão e bem mais prático se usado no texto anterior.<br />
<br />
O <a href="http://docs.djangoproject.com/en/1.2/ref/templates/builtins/">Django 1.2</a> trás grandes melhorias, principalmente nas templatetags de condições como o IF, dando possibilidade de usar ==, !=, <, >, <=, >= e in, haha (eta-coisa-boa)!<br />
<br />
No dev disponibilizado para os desenvolvedores não faz referência ao 1.2, portando é preciso editar na mão enquanto o pessoal do GAE não atualiza. Como visto no <a href="http://code.google.com/p/googleappengine/source/browse/trunk/python/google/appengine/dist/_library.py#80">próprio arquivo _library.py</a>. No final do texto é mostrado como editar o arquivo necessário para rodar localmente.<br />
<br />
Bem, agora já temos conhecimento da <b>use_library</b> e a <b>disponibilidade da versão 1.2</b> e o que nos resta fazer? <b>IMPORTAR</b>!<br />
<br />
Segue o procedimento abaixo (<a href="http://code.google.com/intl/en/appengine/docs/python/tools/libraries.html#Django">saiba mais direto no appengine</a>):<br />
<br />
<pre class="code">import os
os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
from google.appengine.dist import use_library
use_library('django', '1.2')
</pre>
<br />
<b>Nota:</b> Lembre-se que o código acima deve ser inserido antes de qualquer chamada que envolva o django.<br />
<br />
É necessário editar o arquivo <b>_library.py</b> localizado em <b>%LOCAL-ONDE-O-APPENGINE-FOI-INSTALADO%google\appengine\dist </b> apartir da linha 80. Ela está mais ou menos assim:<br />
<pre class="code">PACKAGES = {
'django': (DjangoVersion,
{'0.96': None,
'1.0': None,
'1.1': None,
}),
</pre>
<br />
Adicione a versão "1.2" para que fique assim:<br />
<br />
<pre class="code">PACKAGES = {
'django': (DjangoVersion,
{'0.96': None,
'1.0': None,
'1.1': None,
<b>'1.2': None</b>,
}),
</pre>
<br />
Salve o arquivo e pronto!<br />
<br />
<b>Nota</b>: Lembre de ter o django 1.2 instalado.<br />
<br />
<i>Att, Gilson Fabiano.</i>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-1036325097461770842.post-10737453131289717712010-11-16T23:40:00.000-02:002010-11-16T23:40:21.020-02:00Sempre ......<br />minhas palavras são simples<br />e assim sempre vai ser<br />não importa o que você diga<br />elas sempre serão pra você<br />querendo ou não, eu sou um sofredor<br />que por ser puro, ainda acredita no amor<br />...Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-1036325097461770842.post-26816752557472317642010-11-16T00:37:00.001-02:002010-11-16T23:40:50.631-02:00Mais um fim de noite ...... <br />
Mais uma noite vai começando, junto dela meu sofrimento.<br />
Eu vou preparar minhas armas pois já sei qual será meu tormento.<br />
<br />
O pensamento é um vilão sem face que ataca direto no coração<br />
Sem mais nem menos somos apanhados e jogados ao chão<br />
<br />
Triste somos nós, possuidores de um coração escravizado<br />
Que sofre todos os dias por ter o amor definhado<br />
<br />
Creiamos poder um dia poder escapar<br />
No estilo "O Conde de Monte Cristo"<br />
Pro meu amor não mais se definhar.<br />
...Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-1036325097461770842.post-78631998381223359222010-11-02T13:19:00.003-02:002010-11-02T13:47:14.670-02:00Como restaurar a Lixeira no Windows XP?<p>Se você <strike>ou algum fiodeumaégua</strike> deletou a lixeira da área de trabalho no sistema operacional Windows XP e nem tem ídeia de como restaura-lá eis a solução:</p>
<p>Caso goste de comodidade <a href="http://theafien.googlecode.com/files/RestoreRecycleBin.reg">baixe o arquivo de registro</a> (caso a lixeira não volte vá pra seção <b>Pedra no caminho</b>) e pare por aqui mesmo, mas se gosta de por a mão na massa, gogo. =)</p>
<h3 style="font-size: large;">Mechendo no registro</h3>
<ol>
<li>Vá no menu <b>Iniciar</b> e em seguida <b>Executar</b> (Win+R) </li>
<li>Digite regedit e dê OK</li>
<li>Vá para: <b>HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Desktop\NameSpace</b></li>
<li>Crie uma nova chave com o seguinte valor <b>{645FF040-5081-101B-9F08-00AA002F954E}</b></li>
<li>Dentro desta chave mude o valor <b>(Padrão)</b> para Lixeira</li>
<li><b>Pronto!</b></li>
</ol>
<h3 style="font-size: large;">Pedra no caminho</h3>
<p>Caso tenha executado o <a href="http://theafien.googlecode.com/files/RestoreRecycleBin.reg">arquivo de registro</a> ou feito o passo-a-passo acima e a lixeira ainda não voltou, tente fazer o seguinte:</p>
<ol>
<li>Vá no menu Iniciar e em seguida Executar (WIN+R)</li>
<li>Digite gpedit.msc</li>
<li>A janela de <b>Diretivas de grupo</b> será aberta</li>
<li>Vá em <b>Configuração do usuário</b> > <b>Modelos administrativos</b> > <b>Área de trabalho</b> (ou <b>Desktop</b>)</li>
<li>Encontre o Item de configuração <b>Remover o ícone 'Lixeira' da área de trabalho</b>, e mude seu valor para <b>Não-configurado</b> caso não seja. <a href="http://4.bp.blogspot.com/_rJgvMyYyx40/TNAqzQuHWOI/AAAAAAAAAOk/lULZAyKat4U/s1600/tuto.png" imageanchor="1">(Veja a imagem)</a></li>
</ol>
<div style="clear: both;">Pronto a diretiva foi alterada, agora atualize a área de trabalho (F5), caso ainda ela não apareça relate seu problema nos comentários.</div>
<br />
<i>Fonte: <a href="http://www.forumpcs.com.br/comunidade/viewtopic.php?t=243435">http://www.forumpcs.com.br/comunidade/viewtopic.php?t=243435</a></i><br />
<br />
Att, Gilson FabianoUnknownnoreply@blogger.com0tag:blogger.com,1999:blog-1036325097461770842.post-63837544895960949612010-10-04T13:52:00.003-03:002010-10-06T20:49:16.937-03:00Como usar o Django 1.1 ou 1.0 no Google App Engine sem zipimportTodo mundo que conhece o <a href="http://www.djangoproject.com/">django</a> conhece suas facilidades, eu por exemplo adoro o sistema de template, praticamente perfeito. <b>Simples</b>, <b>fácil</b> e <b>funcional</b> (não necessariamente nesta ordem).<br />
<br />
<a href="http://code.google.com/intl/pt-BR/appengine/articles/django10_zipimport.html">Neste artigo</a> é ensinado a importar o django 1.0 apartir de um arquivo zip usando o zipimport. Mas a nossa intenção aqui é fazer o mesmo sem a necessidade do zipimport. Abaixo será mostrado como.<br />
<br />
A versão <b>0.96</b> (padrão até então no <a href="http://code.google.com/appengine">GAE</a>) têm em seu built-in template tags como if, for, etc.. bem limitadas ao contrário da versão 1.1 ou superior.<br />
<br />
É preferência de muitos usar <i>{% if x == y %}</i> do que <i>{% ifequal x y %}</i>, os operadores deixam a sintaxe mais perto do padrão usado em outras línguas, <strike>além de ser mais bunitinho</strike>.<br />
<br />
Eu não uso todos os recursos disponibilizados do django no GAE, uso apenas o recurso de template e suas derivações. Já que o GAE nos oferece um framework bem poderoso para trabalhar em cima de sua plataforma.<br />
<br />
Ainda uso um método mostrado <a href="http://code.google.com/intl/pt-BR/appengine/articles/django10_zipimport.html">neste artigo</a> para importar o django por meio do zipimport. Realmente funciona, mas pra mim <strike>escravo do dial-up</strike> 368kb (<a href="http://docs.djangoproject.com/en/1.2/">django1.2.alpha</a> zipado e sem alguns arquivos) de upload é realmente uma surra.<br />
<br />
Fuxicando aonde não devia <strike>ou não</strike>, descobri que além do django <a href="http://www.djangoproject.com/documentation/0.96/">0.96</a> as versões <a href="http://docs.djangoproject.com/en/1.0/">1.0</a>, <a href="http://docs.djangoproject.com/en/1.1/">1.1</a> (só faltou o 1.2 para a alegria geral da nação <i>djangonense</i>) estão disponíveis no GAE no seguinte caminho
<b>/base/python_runtime/python_lib/versions/third_party/</b>, mas como padrão a 0.96 é carregada.<br />
<br />
Então vamos por a mão na massa e descobrir como carregar as outras versões. Abaixo o código usado para importar o <b>django 1.1</b> com seus respectivos comentários. (caso tenha lido o <a href="http://code.google.com/intl/pt-BR/appengine/articles/django10_zipimport.html">artigo que ensina a importar com zipimport</a> terá mais familiaridade com o código)<br />
<br />
<pre class="prettyprint">import os
import logging
# Verifica se o script está sendo executado no appengine
if os.environ.has_key('SERVER_SOFTWARE') and os.environ['SERVER_SOFTWARE'].lower().startswith('google'):
# desinstala o django atual.
for k in [k for k in os.sys.modules if k.startswith('django')]:
del os.sys.modules[k]
# remove os caminhos que dão referência ao django
for k in [k for k in os.sys.path if k.find('/django-')]:
del os.sys.path[os.sys.path.index(k)]
# injeta o caminho do django 1.1 no sys.path
os.sys.path.insert(0, '/base/python_runtime/python_lib/versions/third_party/django-1.1/')
os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
# Informativo indicando que os passos acima foram realizados
logging.info('O módulo do django foi mudado')</pre>
<br />
<a href="http://gilsonfabiano-djangoexample.appspot.com/">Aqui um exemplo</a> de tudo funcionando e seu <a href="http://theafien.googlecode.com/files/gilsonfabiano-djangoexample.zip">código fonte</a>.<br />
<br />
Att, Gilson Fabiano.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-1036325097461770842.post-91408003387622948952010-04-05T19:25:00.007-03:002012-03-05T18:43:49.181-03:00Proteja seus arquivos de Worms/Vírus e outra pragasAlguns dias atrás meu hd foi contaminado por um worm/vírus conhecido por <b>W32/Wplugin</b>. Não sei de onde ele veio ou como veio, só sei que me deu dor de cabeça.<br />
O desgramado infectava o explorer.exe e o MSN por meio de dll inject. O explorer.exe por sua vez infectava outros arquivos *.exe e alguns *.dll -- não reparei se ele infectava *.msi.<br />
<h2>
Verifique se seu sistema está contaminado</h2>
Olhe na pasta do windows (%WINDIR%) se existe os arquivos <b>explorer.exe.local</b>, <b>wplugin.dll</b> e <b>ws2help.dll</b>.<br />
<h2>
Remova o vírus</h2>
Boa parte dos antivirus remove o W32/Wplugin do sistema, mas nem todos desinfecta os arquivos contaminados.<br />
<h2>
Descontamine os arquivos</h2>
Pelo que eu sei, só o <a href="http://www.mcafee.com/br/">McAfee</a> descontamina os arquivos vítimas do W32/Wplugin.<br />
<h2>
Proteja seus arquivos</h2>
Uma dica para previnir que seus arquivos sejam contaminados por pragas do gênero é renomeando os arquivos alvos. Como?<br />
<br />
<b>Antes</b>: wscntfy.exe<br />
<b>Depois</b>: wscntfy.exe.xxx<br />
<br />
Simples né?<br />
<br />
Agora os worms/vírus irão ignorar esses arquivos por eles não terminarem com .exe.<br />
<br />
Quando você for executar usar os arquivos, faça uma cópia e retire o final .xxx, mantendo o original como 'está' para evitar a contaminação.<br />
<h2>
O windows não quer mostrar a extenção?</h2>
Vá no menu de alguma janela do explorer 'ferramentas > opções de pasta', na aba 'Modo de exibição' desmaque a opção 'Ocultar as extenções dos tipos de arquivos conhecidos', dê um OK e as extenções aparecerão.<br />
<h2 style="clear: both;">
Resumo</h2>
Agora seus arquivos do pendrive estão protegidos onde quer que eu vou.<br />
Fiz um códigozinho para fazer renomeação em massa, eis o código em ms-dos:<br />
<br />
<pre class="prettyprint">:: por <b>Gilson Fabiano</b> (theafien <- gmail -> com)
:: -
:: Adiciona um .xxx aos arquivos com as extenções .exe, .dll, .msi
:: evitanto que worms ou outras pragas similares os contamine.
:: A renomeação inclue as subpastas o qual o arquivo se encontra.
:: -
@echo off
echo - Renomeando arquivos...
echo -
for /R . %%A in (*.dll,*.exe,*.msi) do (
echo - %%A
rename %%~sA "%%~nA%%~xA.xxx"
)
echo -
pause
</pre>
<br />
Salve o código acima em um arquivo .bat e execute-o na pasta onde deseja renomear os arquivos. Lembre-se que os arquivos em subpastas são renomeados também.<br />
<br />
Um grande beijo pro <b>André Luiz</b> que ajudou na parte do McAfee.<br />
<br />
Att, Gilson Fabiano.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-1036325097461770842.post-39382379383139308482010-01-08T18:34:00.003-02:002010-01-08T19:29:56.251-02:00GLOBO.com, erro de digitação?Quando eu assistia a série prison break, costumava ler o que ia acontecer no próximo capítulo e os que eu perdia.<br />
Navegando entre as notícias do prison break, sem querer desativei o css dessa página <a href="http://redeglobo.globo.com/Tv_globo/Noticias/0,,MUL976258-16162,00-REDE+GLOBO+EXIBE+A+SERIE+PRISON+BREAK+A+PARTIR+DE+SEGUNDAFEIRA+DE+FEVEREIRO.html">http://redeglobo.globo.com/Tv_globo/Noticias/0,,M...R+DE+SEGUNDAFEIRA+DE+FEVEREIRO.html</a> e achei o seguinte erro de português "<i>Globo e você <b>tuda</b> a ver.</i>", e o certo não seria <b>tudo</b>?.<br />
<br />
<a href="http://1.bp.blogspot.com/_rJgvMyYyx40/S0eUJbLuc5I/AAAAAAAAAI0/iVFMosemPyU/s1600-h/globoerro1.jpg" imageanchor="1"><img border="0" height="296" src="http://1.bp.blogspot.com/_rJgvMyYyx40/S0eUJbLuc5I/AAAAAAAAAI0/iVFMosemPyU/s400/globoerro1.jpg" width="400" /></a><br />
<br />
O estranho é que eu relatei o erro usando o formulário do sac do site, e olha a resposta:<br />
<br />
<blockquote>
Gilson,<br />
<br />
Agradecemos o contato!<br />
Entendemos sua dificuldade, mas somos a Central de Atendimento ao Telespectador da Rede Globo. Como este assunto diz respeito diretamente à Globo.com, por favor, entre em contato com a Central de Atendimento pelo telefone 4003-8003.<br />
Cordialmente,<br />
<br />
Central Globo de Comunicação<br />
</blockquote>
<br />
Sem mais...<br />
<br />
<b>Nota</b>: O texto só aparece quando o css está desativado. Faz quase 1 ano que relatei o erro e ainda ele está lá.<br />
<br />
Att, Gilson Fabiano.<br />Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-1036325097461770842.post-24170315673270089742010-01-08T01:57:00.005-02:002012-03-05T18:47:21.285-03:00(Anti)Atualização do Windows Live MessengerA cada versão nova, o Messenger é atualizado automaticamente. E é ai que começam os problemas...<br />
Você já está acostumado com a versão do seu <b>Windows Live Messenger</b> e não está a fim de instalar ou utilizar outra versão?<br />
É, eu passei por isso e depois de algumas sniffeadas, mudadas de recursos, erros, cheguei a esse resultado.<br />
<h2>
O que devo usar?</h2>
Um <a href="http://www.google.com.br/search?q=editor+de+recursos">editor de recursos</a> (eu recomendo o <a href="http://theafien.googlecode.com/files/ResHack.zip">ResHack</a>)<br />
<h2>
E agora?</h2>
<ol>
<li>Agora, abra o <b>msnmsgr.exe</b> no editor de recurso<br />
<br />
</li>
<li>Vá em <b>Version Info > 1 > 1033.</b><br />
<br />
</li>
<li>Localize o <b>"ProductVersion"</b>, esse valor que mudaremos para que tudo fique OK.<br />
A minha versão é <b>8.5.1302.1018</b> (no seu pode aparecer outra, mas não se desespere)<br />
<br />
</li>
<li>Mude o valor do "ProductVersion" para <b>14.5.1302.1018</b> e clique no botão "Compile Script".<br />
<br />
</li>
<li>Salve as mudanças.<br />
<br />
</li>
</ol>
<br />
Pronto, nunca mais precisará atualizar seu MSN.<br />
<br />
<b>Nota</b>: Se ainda pedir para atualizar, tente aumentar o número da versão. Quando você salva as mudanças, um arquivo de backup é criado na mesma pasta onde se encontra o arquivo <b>msnmsgr.exe</b><br />
<br />
Att, Gilson Fabiano.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-1036325097461770842.post-76161348573318868342010-01-05T17:48:00.005-02:002011-03-14T16:21:53.969-03:00Criando seu próprio Tibia MC (Multi cliente)Vamos lá tibianos.<br />
<br />
<b>Nota</b>: Testado nas versões acima do 8.10, mas creio que funcione nas anteriores.<br />
<br />
Tenha em mãos um editor hexadecimal (eu recomendo o <a href="http://theafien.googlecode.com/files/SpyEdit.exe">spy edit</a> um editor pequeno e leve)<br />
<br />
Abra o arquivo Tibia.exe em seu editor e procure pela sequência de valores hex <span style="font-weight: bold;">75 52 68</span> (só existe essa sequência em todo o Tibia.exe)<br />
<br />
Após encontrar tal valor, substitua o <span style="font-weight: bold;">75</span> por <span style="font-weight: bold;">EB</span> e salve a mudança.<br />
<br />
Pronto seu tibia multi cliente está feito.<br />
<br />
<span style="font-size: large;">Fácil né? Quer mais facilidade ainda?</span><br />
<br />
Baixe o <a href="http://theafien.googlecode.com/files/TibiaMC.zip">patcher</a> feito por mim ou se preferir veja o código fonte no <a href="http://theafien.googlecode.com/svn/trunk/tibia/mc">repositório</a>.Unknownnoreply@blogger.com1