Jump to content
  • libag: convertendo em biblioteca a ferramenta de busca em arquivos ag

       (1 review)

    Theldus
     Share

    Introdução

    Há poucas semanas, um amigo comentou que estava buscando automatizar um processo que envolvia buscas por expressões regulares em arquivos binários. Essa tarefa normalmente é realizada com ferramentas de linha de comando específicas (grep, git-grep, ack-grepagripgrepugrep, entre outras), e um script pode invocá-las e fazer o parsing do output. A ripgrep em particular oferece resultados em JSON, o que facilita bastante o processo.

    Apesar disso, chamar um processo externo e intepretar a saída não é a maneira ideal de incorporar uma funcionalidade em um programa, sendo a mais correta o uso de uma biblioteca, mas surpreendi-me ao perceber que não havia nenhuma que cumprisse tal propósito.

    E assim nasceu a libag, um fork da ferramenta ag com o objetivo de transformá-la em uma biblioteca para facilitar a incorporação, em outros programas, do recurso de busca avançada no conteúdo de arquivos.

    Uso e recursos

    A libag requer as mesmas dependências do ag: liblzma, libpcre e zlib.

    No Ubuntu (e possivelmente em outras distribuições Debian-like):

    $ sudo apt install libpcre3-dev zlib1g-dev liblzma-dev

    Uma vez resolvidas as dependências o processo de build é bastante simples.

    Basta clonar o repositório:

    $ git clone https://github.com/Theldus/libag
    $ cd libag/

    e compilar:

    Makefile

    $ make -j4
    $ make install # Opcional

    CMake

    $ mkdir build && cd build/
    $ cmake .. -DCMAKE_BUILD_TYPE=Release
    $ make -j4

    O uso da biblioteca é bastante simples e consiste no uso de três funções básicas: ag_init()ag_search() e ag_finish() (embora funções mais avançadas também estejam disponíveis).

    Um exemplo mínimo e completo segue abaixo:

    #include <libag.h>
    
    int main(void) {
        struct ag_result **results;
        size_t nresults;
    
        char *query    = "foo";
        char *paths[1] = {"."};
    
        /* Initiate Ag library with default options. */
        ag_init();
    
        /* Searches for foo in the current path. */
        results = ag_search(query, 1, paths, &nresults);
        if (!results) {
            printf("No result found\n");
            return (1);
        }
    
        printf("%zu results found\\n", nresults);
    
        /* Show them on the screen, if any. */
        for (size_t i = 0; i < nresults; i++) {
            for (size_t j = 0; j < results[i]->nmatches; j++) {
                printf("file: %s, match: %s\n",
                    results[i]->file, results[i]->matches[j]->match);
            }
        }
    
        /* Free all results. */
        ag_free_all_results(results, nresults);
    
        /* Release Ag resources. */
        ag_finish();
        return 0;
    }

    Uma vez que a libag possui bindings para Python e Node.js, seguem os mesmos exemplos abaixo:

    Python:

    from libag import *
    
    # Initiate Ag library with default options.
    ag_init()
    
    # Search.
    nresults, results = ag_search("foo", ["."])
    if nresults == 0:
        print("no result found")
    else:
        print("{} results found".format(nresults))
    
        # Show them on the screen, if any.
        for file in results:
            for match in file.matches:
                print("file: {}, match: {}, start: {} / end: {}".
                format(file.file, match.match, match.byte_start, match.byte_end))
    
    # Free all resources.
    if nresults:
        ag_free_all_results(results)
    
    # Release Ag resources.
    ag_finish()

    Node.js (sujeito a alterações):

    const libag = require('./build/Release/libag_wrapper');
    
    libag.ag_init();
    
    r = libag.ag_search("foo", ["."]);
    
    r.results.forEach((file, i) => {
        file.matches.forEach((match, j) => {
            console.log(
                "File: " + file.file + ", match: " + match.match +
                ", start: " + match.byte_start + " / end: " + match.byte_end
            );
        });
    });
    
    libag.ag_finish();

    Uso "avançado" e pesquisa em arquivos binários

    O uso básico é como ilustrado acima e representa também as opções padrões do ag. Entretanto, a libag permite um controle fino sobre as opções de busca e também sobre as worker threads.

    As opções podem ser tunadas a partir da estrutura struct ag_config, que contém uma série de inteiros que representam diretamente o recurso desejado. Opções como num_workers e search_binary_files definem a quantidade de worker threads e habilitam a busca em arquivos binários, respectivamente.

    Um exemplo mais interessante segue abaixo, vamos localizar arquivos ELF e PE32 que também contenham meu nome de usuário neles:

    from libag import *
    
    pattern       = "david";
    elf_signature = "^\x7f\x45\x4c\x46";
    pe_signature  = "^\x4d\x5a";
    signatures    = elf_signature + "|" + pe_signature;
    
    # Enable binary files search
    config = ag_config()
    config.search_binary_files = 1
    
    # Initiate Ag library with custom options.
    ag_init_config(config)
    
    # Search.
    nresults, results = ag_search(signatures, ["dir/"])
    if nresults == 0:
        print("no result found")
        sys.exit(1)
    
    print("{} pe+elf found".format(nresults))
    for file in results:
        print("file: {}".format(file.file))
    
    pe_elf = []
    
    # Add to our list
    for file in results:
        pe_elf.append(file.file);
    ag_free_all_results(results)
    
    # Search again looking for pattern
    nresults, results = ag_search(pattern, pe_elf)
    if nresults == 0:
        print("no result found")
        sys.exit(1)
    
    # Show them
    print("{} binaries found that matches {}".format(nresults, pattern))
    for file in results:
        for match in file.matches:
            print("file: {}, match: {}, start: {} / end: {}".
                format(file.file, match.match, match.byte_start, match.byte_end))
    
    # Free all resources.
    ag_free_all_results(results)
    
    # Release Ag resources.
    ag_finish()

    A pasta dir/ contém um arquivo ELF, um PE32+, um plaintext e uma imagem .png. Note que o range informado pode ser verificado com dd+hexdump, como segue abaixo:

    $ file dir/*
    dir/hello:      PE32+ executable (console) x86-64, for MS Windows
    dir/img.png:    PNG image data, 1247 x 711, 8-bit/color RGB, non-interlaced
    dir/libag.so:   ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, with debug_info, not stripped
    dir/random.txt: ASCII text
    
    $ ./elf_pe.py 
    2 pe+elf found
    file: dir/libag.so
    file: dir/hello
    1 binaries found that matches david
    file: dir/libag.so, match: david, start: 90094 / end: 90098
    
    $ dd if=dir/libag.so bs=1 skip=90094 count=5 | hexdump -C
    5+0 records in
    5+0 records out
    5 bytes copied, 2.1437e-05 s, 233 kB/s
    00000000  64 61 76 69 64                                    |david|
    00000005

    É claro que o exemplo acima é bastante simplório e serve apenas para ilustrar possíveis casos de uso da biblioteca.

    O processo de "libificação"

    A escolha do fork do ag foi bem natural: eu já tinha alguma familiaridade com o código fonte do ag e eu já havia brincado com ele alguns meses atrás. Além disso, o código do ag não é tão grande e eu sou um programador C em 99.9% do meu tempo, o que elimina alternativas como ripgrep (Rust) e ugrep (C++).

    O processo de "libificação" não foi tão complicado: primeiro eu extraí apenas o código fonte do projeto e escrevi meus próprios/novos scripts de build por cima (Makefile e CMake). Depois disso, foi investigar o processo de search original do ag e trazer isso para a minha biblioteca.

    De forma resumida, o ag original pode ser divido em três grandes etapas:

    1. Inicialização
      1. Configura o log_level (para propósitos de debug);
      2. Inicializa as estruturas de .gitignore (o ag é capaz de ignorar esse tipo de arquivo);
      3. Inicializa as opções default da linha de comando;
      4. Realiza o parsing das opções de linha de comando;
      5. Compila a regex via PCRE;
      6. Inicializa os mutexes e as worker threads.
    2. Busca
      1. O processo de busca e path traversal é realizado por uma única thread, que a partir da lista de paths recuperados via linha de comando invoca a rotina search_dir(), que para cada novo path encontrado o adiciona em uma "work_queue_t" e acorda todas as worker threads (se estiverem dormindo) para recuperar mais trabalhos.

        O processo de sincronização é feito via mutexes, mas em defesa do maintainer original do ag, um profiling no Intel VTune mostra que o tempo de hold de cada thread é mínímo, o que realmente torna o ag (e libag) escalável com o aumento da quantidade de cores.

    3. Resultados
      1. Uma vez que uma worker thread (WT) obtém um novo "job", ela então começa a leitura do arquivo: seja via mmap (padrão) ou todo o arquivo de uma só vez. Para buscas de texto literal, a "WT" utiliza os algoritmos de BoyerMoore e de hash para identificação da string. Em caso de expressão regular, utiliza-se a biblioteca PCRE. A decisão dos algoritmos é feita automaticamente, para maior desempenho.

        À medida que novos resultados são encontrados (para um único arquivo), eles são adicionados em uma lista de matches, definida pelo tipo match_t e ao finalizar a leitura do arquivo os resultados encontrados são impressos na tela, protegidos por um mutex.

    Salvando os resultados

    Uma vez obtidos os resultados, entra então a maior "incisão" da libag: interferir no processo de dump dos resultados e salvá-los de forma estruturada e facilmente recuperável posteriormente.

    Para isso, foi introduzido um vetor de resultados (dinâmico) por WT, que armazena os dados obtidos até o momento. Além disso, a rotina principal das worker threads (search_file_worker()) foi levemente modificada para notificar do término das threads e também permitir facilmente manipular o "start/stop" delas sob demanda.

    Uma vez que toda a work queue foi preenchida e processada, a rotina de search (da biblioteca) pode resumir sua execução, fazendo o join dos resultados parciais das threads e retornando um "struct ag_search**", que contém uma lista de resultados por arquivo, a string do match, flags e byte de início e fim da ocorrência, algo como:

    /**
     * Structure that holds a single result, i.e: a file
     * that may contains multiples matches.
     */
    struct ag_result
    {
        char *file;
        size_t nmatches;
        struct ag_match
        {
            size_t byte_start;
            size_t byte_end;
            char *match;
        } **matches;
        int flags;
    };

    Bindings

    Para facilitar a utilização da libag, o projeto também possui bindings experimentais para Python 2/3 e também Node.js (em desenvolvimento). 

    Python

    Os bindings para Python foram escritos utilizando o SWIG: um programa que, dado um arquivo de interface, é capaz de gerar um "glue-code" que, quando compilado em conjunto com o código original, funciona como um wrapper/binding para a linguagem em questão.

    O SWIG gera código compilável para CPython e os tipos não-primitivos (como as duas estruturas introduzidas pela biblioteca) são mapeados via "type-maps".

    Node.js

    Embora o SWIG suporte Node.js, ele parece utilizar diretamente a API da v8 engine, que está sempre em constante mudanças, e portanto, o código gerado não compila na última versão estável (v14.17.1 LTS) do Node.

    Para contornar isso, os bindings para Node.js foram escritos em cima da Node-API, uma API em C (também disponível em C++, com nome de node-addon-api) que oferece um conjunto mínimo de recursos em cima da v8 e que têm como objetivo manter a estabilidade de addons escritos mesmo entre versões distintas do Node e v8.

    Limitações

    Ao contrário de programas construídos em cima de uma biblioteca, como o cURL+ libcurl, ag (aparentemente) nunca foi idealizado como tal e portanto o código fonte impõe certas restrições ao adaptá-lo para uma biblioteca, das quais vale destacar:

    • Apenas uma única configuração "global": não é possível (no momento) utilizar opções distintas de search para múltiplos searchs; Uma alternativa a isso é manter múltiplos "ag_config" e setá-los com ag_set_config() antes de cada busca. Esta limitação se deve ao ag utilizar uma única estrutura global para armazenar os parâmetros de linha de comando, estrutura essa utilizada em diversos pontos em todo o código fonte.
    • Uma busca de cada vez: assim como no item anterior, o ag também usa diversas estruturas globais para manter o estado da busca durante um ag_search(), o que impossibilita de utilizar múltiplos searchs simultaneamente. Uma solução temporária foi adicionada com o uso da função ag_search_ts(), que internamente utiliza locks para serializar todas as chamadas a ag_search().

    Dentre outros. Qualquer contribuição em pontos como esses e outros é muito bem vinda =).

    Conclusão

    Por fim, convido todos a conhecerem a página da libag no GitHub. Trata-se de um projeto de código aberto e, portanto, está aberto a contribuições. Espero que ele possa ser tão útil para mais pessoas quanto está sendo para os que já o utilizam!

    ~ Theldus signing off!


    Revisão: Leandro Fróes
    • Agradecer 1
    • Curtir 1
     Share


    User Feedback

    Join the conversation

    You can post now and register later. If you have an account, sign in now to post with your account.
    Note: Your post will require moderator approval before it will be visible.

    Guest

    • This will not be shown to other users.
    • Add a review...

      ×   Pasted as rich text.   Paste as plain text instead

        Only 75 emoji are allowed.

      ×   Your link has been automatically embedded.   Display as a link instead

      ×   Your previous content has been restored.   Clear editor

      ×   You cannot paste images directly. Upload or insert images from URL.


    anderson_leite

       3 of 3 members found this review helpful 3 / 3 members

    Parabéns pelo projeto!

    Excelente contribuição, sempre achei que o AG já tinha uma lib junto com ele.

    Response from the author:

    Oi Anderson, muito obrigado. Pois é, facilitaria bastante a minha vida (e a de outras pessoas) se ele tivesse sido feito dessa forma, ainda tenho bastante coisa a ser feita na libag. Curioso que não encontrei nenhum projeto similar, e todos outros 'concorrentes' diretos do ag, como rg, ugrep dentre outros, aparentemente também não criam essa separação. O ripgrep em especial até possui uma nota sobre isso (em crates/core/README.md):

    ... Currently, there are no plans to make ripgrep core available as an independent library. However, much of the heavy lifting of ripgrep is done via its constituent crates, which can be reused independent of ripgrep. Unfortunately, there is no guide or tutorial to teach folks how to do this yet. ...

     

    • Curtir 3
    Link to review
    Share on other sites


  • Similar Content

    • By Bruna Chieco
      O livro Programação Shell Linux é uma referência completa sobre programação Shell nos sistemas operacionais Unix/Linux, e chegou na sua 12ª edição depois de mais de 22 anos que o autor, Julio Cezar Neves, veio adaptando essa obra. Apresentando o assunto de forma didática e descontraída, Julio se utiliza de exemplos e dicas de fácil compreensão para explicar para seu público como programar em Shell. Quem pensa que esse é um livro de cabeceira está enganado. É um material prático para ser usado do lado do computador, sendo uma referência completa da linguagem Shell. "Esse livro não é para estudar, é um guia de referência, porque ele está completo", diz o próprio autor, Julio Neves. 
      Ele conta para o Mente Binária como foi seu processo de construção desse rico material. "Tudo começou como uma brincadeira. Durante muitos anos eu fui gestor e de repente eu estava de saco cheio do meu departamento, não queria ficar administrando pessoas. Então resolvi abandonar essa área e voltar para a área técnica". Foi assim que Julio passou a atuar no suporte técnico. No início dos anos 1980, ele já tinha trabalhado desenvolvendo um Unix na Cobra Computadores e Sistemas Brasileiros, hoje BB Tecnologia e Serviços (BBTS). "Eu continuei usando o Unix, porque quando apareceu o primeiro sistema operacional da Microsoft, o DOS, ele saiu da costela do Unix. Se eu já tinha o Shell, para que eu iria usar o DOS?", diz. 
      Assim, Julio decidiu fazer um sistema para protocolo, transferência e check de integridade de arquivos via FTP para a empresa na qual trabalhava. "Eu fiz tudo em Shell". Ele passou a fazer treinamentos com seus colegas na empresa, e acabou escrevendo um manual no qual conta que tinha muita piada e conteúdo descontraído. "A cada treinamento que eu dava eu ia melhorando. Um belo dia minha esposa falou que isso tudo daria um livro", conta Julio. Foi assim que ele publicou a primeira edição do livro Programação Shell Linux, em 2000.
      Motivação
      Os treinamentos internos que Julio fazia em sua empresa sempre davam muita audiência. Ele conta que quando trabalhou na Cobra Computadores, foi feito um convênio com a Universidade Estácio de Sá, do Rio de Janeiro, que cedia as instalações para o pessoal da Cobra dar treinamentos. Em contrapartida, a Cobra dava suporte para a Estácio de graça. "Foi minha primeira experiência dando aula. Eu fiz um curso de didática com técnicas de apresentação e quando fui dar os treinamentos na empresa, anos depois, já tinha essa prática de didática. É uma coisa que gosto de fazer", conta. Hoje, Julio oferece treinamentos sobre Shell Script junto a Rubens Queiroz De Almeida (saiba mais sobre os treinamentos).
      Além do gosto por dar aulas, Julio conta que o livro é uma maneira de disseminar o conteúdo sobre Shell em uma linguagem fácil e acessível, o que não existe em outros materiais. Ele cita o Linux man pages, um manual escrito em inglês rebuscado, sem exemplos. "Praticamente tudo que tem no man pages tem no meu livro, só que o livro tem um monte de exemplo e bom humor. O man page não te ensina a programar, mas só a usar uma instrução. O meu livro mostra as instruções, de forma ordenada, e o funcionamento do Shell. Eu mesmo aprendi Shell pelo man pages, mas é muito chato!", avalia.

      "Meu livro mostra as instruções, de forma ordenada, e o funcionamento do Shell" – Julio Neves
       
      Por que um profissional precisa ter conhecimento de Shell?
      "Uma vez eu dei uma palestra sobre Shell e na hora das perguntas um cara falou que não gostava da linguagem. E eu falei que sem o Shell, o Linux não existe. Quando você dá boot na máquina, ela executa centenas de scripts em Shell; quando você loga, ela roda dezenas de scripts em Shell. Tudo que é feito na máquina está em C ou em Shell. O administrador de sistemas antigamente era obrigado a conhecer profundamente Shell", explica. 
      Na área de segurança, a necessidade desse conhecimento é igualmente importante, conforme explica Fernando Mercês, que é pesquisador na Trend Micro e fundador do Mente Binária. "O Linux é um sistema operacional obrigatório na área de segurança. Quem não conhece Linux, não consegue andar nessa área. E o Shell é o coração do Linux, é por onde um usuário controla o sistema inteiro e usa todos os recursos. Programar em Shell é obrigatório para automatizar o que precisa ser automatizado no Linux", explica Mercês.
      Ele conta que no lado dos ataques, por exemplo, do ponto de vista de segurança ofensiva, e também para criar defesas e ações de proteção de um servidor Linux diante de algum ataque, é preciso usar programação em Shell. "Se seu sistema Linux está sob ataque, você detectou isso e vai bloquear a comunicação do atacante para com o seu servidor, e isso vai ser um comando em Shell do Linux. Além do Linux ser um sistema operacional que precisa ser conhecido, programá-lo bem e saber operá-lo em nível de programação via Shell é essencial para um bom profissional, e um grande diferencial para profissionais de tecnologia em geral", destaca Mercês. 
      Para Julio Neves, não saber programar em Shell pode ser inclusive um risco de segurança. "A pessoa tem que saber Shell, porque a interface gráfica não sabe tudo sobre a digitação, e aí se ele tiver alguma dúvida, vai recorrer à Internet. Se ela fizer isso, pode colocar dentro do computador algo que pode ser ruim, um malware", diz.
      "Meu nível de Shell depois desse livro ficou muito acima da média", diz Fernando Mercês 
      Na experiência de Mercês, de fato o livro Programação Shell Linux é o material mais completo que se tem em língua portuguesa sobre o assunto. "Quando comecei a estudar Linux, em 2008, vi que os materiais que tratam do assunto introduzem o Shell, mas não vão muito além disso. Aí comprei a 6ª edição desse livro do Julio e me impressionei, porque além de ser muito mais profundo que as introduções que eu tinha lido, a didática é impecável. O livro realmente ensina a programar com alguém que sabe muito", conta. 
      "Meu nível de Shell depois desse livro ficou muito acima da média, mesmo no meio do mundo Linux, porque esse conhecimento veio de alguém que não simplesmente estudou, aprendeu e escreveu um livro. O Julio fez parte do time de desenvolvimento de um Unix. Ele foi capaz de criar um Shell. É uma pérola no Brasil". 
      12ª edição
      Julio Neves conta que ao longo do tempo, as edições do livro foram "engordando", cada vez contendo mais material. Mas nessa 12ª edição, ele acabou publicando o livro em uma nova editora, a Novatec, muito motivado a baixar o custo. "Eu estava achando o preço do livro um absurdo e resolvi pegar o livro, que tinha duas partes, um Shell básico e um Shell programação, e tirei o Shell básico para diminuir o custo do livro". 
      Ainda assim, o material continua com 600 páginas, já que ao longo do tempo Julio foi agregando mais conhecimento. "Na primeira edição eu disse que o intuito do livro não era ser um compêndio sobre Shell. Hoje, coloco ele como uma referência sobre Shell", destaca.
      O livro pode ser comprado online nesse link, e tem um cupom de 25% de desconto válido até o dia 30 de julho. Para utilizar, basta digitar PROGSHELL na hora de realizar a compra.

      Capa do livro Programação Shell Linux – 12ª Edição
       
      Falando em referência, o Julio também é uma inspiração para nós do Mente Binária, afinal foi o primeiro entrevistado no programa Papo Binário, em janeiro de 2016. Assista na íntegra:
       
    • By Bruna Chieco
      Virar um desenvolvedor de jogos pode ser o grande sonho dos apaixonados por games. São esses os profissionais que projetam e criam jogos para computadores, celulares e consoles, se envolvendo desde a concepção até a execução do projeto junto a uma equipe composta por produtores, designers, artistas, engenheiros de som e testadores. Essa galera trabalha para levar os melhores produtos a uma indústria que hoje é composta por 2,8 bilhões de jogadores em todo o mundo, gerando receitas de US$ 189,3 bilhões, segundo dados da empresa de pesquisa Newzoo.
      No Brasil, a Newzoo aponta que o mercado de jogos terá uma receita de US$ 2,3 bilhões em 2021. Ainda que aqui a indústria seja menor, as oportunidades para trabalhar na área estão crescendo mesmo para quem não é um aficionado pela profissão, como é o caso de Rodrigo Duarte Louro. Ao procurar estágio enquanto cursava a faculdade de Ciência da Computação, ele acabou se deparando com uma vaga em uma empresa de jogos pequena que tinha acabado de começar. 
      Na época, Rodrigo tinha 21 anos e confessa que esse não era seu sonho, mas acabou encarando o desafio. "Quando entrei na faculdade, eu não tinha muita ideia para onde ir. Nunca quis muito uma carreira específica, mas as possibilidades de mercado para quem é programador são grandes", diz Rodrigo ao Mente Binária. "Eu não manjava nada de games, mas estagiei nessa empresa por um ano, e foi onde eu comecei a gostar e aprender sobre desenvolvimento de games", conta. 
      Rodrigo saiu desse estágio para conseguir concluir a faculdade, mas no último semestre voltou a estagiar em outra empresa de games, a Tapps, onde está até hoje trabalhando com desenvolvimento de jogos para mobile. "Quando comecei a estagiar com jogos, eu gostei, e a menos que aparecesse uma oportunidade muito boa, eu decidi que não ia mais sair da área", relata.

      "A menos que aparecesse uma oportunidade muito boa, eu decidi que não ia mais sair da área" - Rodrigo Duarte Louro
      Já o caso de Murilo Costa é o mais tradicional para quem trabalha com desenvolvimento de jogos: ser apaixonado pela área. "Desde dos 12 anos de idade eu já estava certo da vida que queria trabalhar com jogos, e nessa idade já tinha começado a programar", conta Murilo ao Mente Binária. Foi assim que ele acabou fazendo um curso técnico em informática aos 15 anos. "Eu já queria entrar na área de jogos, mas no Brasil era difícil", destaca.
      Por certa falta de oportunidade, Murilo acabou entrando no mercado de TI como desenvolvedor de software, atuando nessa área por cerca de 7 anos. Enquanto isso, ele também cursou a faculdade de Ciência da Computação. "Eu tinha 22 anos quando consegui meu primeiro emprego como estagiário em jogos. Eu ia para essa profissão de qualquer jeito, mesmo que por conta própria. Mandei muito currículo, porque o mais importante era começar de algum jeito, e depois ir encontrando meu espaço", ressalta. "Eu me permiti voltar para a estaca zero quando entrei na indústria de games. Quando decidi sair do emprego de desenvolvedor de software e ir pra jogos, eu já era CLT e estava quase virando um profissional pleno dentro da empresa, mas decidi voltar a ser estagiário para começar na área", conta. 

      "Eu me permiti voltar para a estaca zero quando entrei na indústria de games" - Murilo Costa
      Murilo ficou durante 5 anos e meio nessa empresa, começando como programador de jogos mobile, e aos poucos foi crescendo internamente, até virar coordenador. "Passei a trabalhar como gestor, participava da contratação e desenvolvimento de outros programadores", diz. Mas no ano passado, Murilo decidiu que queria voltar a programar, e foi aí que começou a trabalhar no estúdio Rogue Snail como programador sênior. "O que eu gosto é da área de programação", pontua.
      O que precisa para ser um desenvolvedor de jogos
      A complexidade da profissão pode variar dependendo do tipo de jogo que será desenvolvido, mas para quem quer começar, é preciso saber o básico de programação. "Na faculdade não tem nada específico para o mercado de trabalho. Se você tem uma base de programação forte, está preparado para tudo, mas não é especialista em nada", diz Rodrigo. Ele conta que apesar disso, há cursos mais focados em jogos. "Na Tapps muita gente que trabalha comigo fez um curso de design de jogos na Fatec e na Anhembi. No meu caso, não fiz nenhum curso específico. Agora, com 7 anos de experiência, tenho uma noção das outras áreas, mas o background de programação dá total liberdade para fazer os jogos", diz.
      A dica é saber duas linguagens de programação, que são as mais adotadas em desenvolvimento de games: C# e C++. A primeira é utilizada pelo motor de jogos (game engine) chamado Unity, enquanto a segunda é utilizada pela engine Unreal. Apesar de essas serem as duas linguagens mais utilizadas, muitas empresas querem fazer suas próprias engines. "Na Unity você consegue fazer e exportar o jogo para cada plataforma específica, mas na Tapps a gente exporta só mobile, então usamos uma engine própria", diz Rodrigo. 
      O mais recomendável é estudar não somente a linguagem, mas aprender como a engine funciona e pode ser manipulada para se obter resultados. "Eu já praticava isso sozinho", diz Murilo. "Normalmente, quando as pessoas vão trabalhar com jogos, já tiveram contato com engines ou produção de algum jogo". Ele destaca que o ideal para treinar é participar de game jams, que são encontros de desenvolvedores de jogos com a proposta de planejar e criar um ou mais jogos em pouco tempo, geralmente variando entre 24 e 72 horas. "Isso ajuda as pessoas a terem contato com as engines e tecnologias. Mas precisa de um conhecimento básico em programação. Essa é uma recomendação para desenvolvedores de software no geral", destaca.
      Matemática e inglês são pré-requisitos
      Além de saber o básico de programação, é preciso ter uma noção tanto de matemática quanto de inglês para quem quer evoluir na carreira de desenvolvedor de games. "Os dois são bem importantes. Não é um impeditivo total não saber isso, mas vai facilitar muito sua vida", destaca Rodrigo. Tanto ele quanto Murilo recomendam no mínimo o conhecimento de leitura em inglês para que a atuação na área seja mais fácil. Isso porque muitos dos materiais de estudo em programação são nesse idioma. "Isso é uma barreira que pode atrapalhar", diz Rodrigo. 
      Os conhecimentos de matemática também são importantes para programação, na visão de Rodrigo. "Dependendo do jogo que você fizer, a matemática é utilizada mais ou menos na prática, mas ter esse conhecimento mais forte te faz um programador melhor sempre", afirma. Ele diz ainda que em alguns casos a geometria analítica é utilizada. "Se estou fazendo um jogo de tiro, preciso saber com qual força a bala sai da arma", explica.
      Mobile x console
      Tendo navegado no mundo mobile e agora no de jogos para computadores, Murilo conta um pouco sobre a diferença entre programar em um e para outro universo. "Jogos mobile gratuitos normalmente têm compras dentro, e os usuários podem assistir anúncios para obter recompensas. Também é preciso pensar que essa indústria é gigantesca, tanto em número de devices quanto de usuários. Você atinge o público de maneira mais global e tem que se preparar para lidar com menos recursos, porque o celular é menos potente que o console", diz. 

      Ele destaca ainda que a usabilidade é bem diferente no celular e no PC. "No mobile, precisamos pensar em como integrar compras e propagandas em tempo de execução do jogo, e games de console normalmente não têm isso. No PC, o jogo tende a ser mais fácil, por outro lado, que os demais jogos de console, por ser mais flexível em relação aos inputs de teclado, mouse, ou controle", relata Murilo.
      Mercado de trabalho
      O mercado de trabalho brasileiro para a indústria de games está crescendo, apesar das oportunidades ainda serem maiores em outros países. Na visão de Murilo, esse ainda é um setor de poucas empresas no Brasil, com algumas companhias grandes dominando, mas praticamente todas para desenvolvimento mobile, ressaltando que os jogos para celulares compõem a maior parte do mercado consolidado no país. 
      Murilo diz ainda que há alguns estúdios pequenos se desenvolvendo localmente, mas muitos ainda dependem de investimento externo ou de projetos institucionais que estimulem seu funcionamento. "Ainda temos poucas oportunidades e não temos tanta escolha". Ele adiciona que na área de programação, ainda há uma diferenciação para quem trabalha com desenvolvimento para bancos ou para web, e quem trabalha com jogos. "Tem uma procura muito alta de pessoas querendo trabalhar na área, mas a remuneração não é competitiva, e temos poucos estúdios. Mas tem crescido", avalia.
       
      "Não ter medo e não desistir da área"
      Para Rodrigo, o gargalo também aparece do lado da mão de obra especializada. "Sempre vejo vaga aberta, mas é difícil preencher. As empresas estrangeiras acabam tendo maior competitividade. Também é o sonho das pessoas trabalharem em grandes companhias como Blizzard, King, etc. O mercado de jogos mexe com o sonho das pessoas, por isso muitas delas já escolheram a faculdade porque queriam fazer games. Mas ainda vejo que faltam profissionais especializados, e isso é na área de programação em geral", pontua. 
      Mesmo com esses desafios, não ter medo e não desistir da área é a dica de Rodrigo para quem quer atuar como desenvolvedor de games. "Se você tem um background de programação, já é um programador e quer migrar de área, pesquise o mercado, pois tem muita empresa sólida. E quem não é programador e quer fazer jogos, precisa começar a estudar programação em geral, ter um nível mediano. Não precisa focar em jogos inicialmente, mas depois comece a pegar tutoriais, estudar engines e fazer jogos simples. Explore a parte criativa, porque isso gera muito conhecimento", indica.
      "A participação em game jams ajuda muito"
      Murilo também destaca a importância de tentar construir um portfólio, reforçando que a participação em game jams ajuda muito nesse sentido. "É uma oportunidade de conhecer pessoas da área, estabelecer contatos e mostrar o trabalho. É preciso ter a experiência de fazer um jogo para entender quais são as partes que precisam ser melhor desenvolvidas", ressalta. 🎮
    • By Felipe.Silva
      Livro em Português sobre Assembly em constante desenvolvimento. É de autoria do @Felipe.Silva, membro da comunidade aqui! 🤗
    • By Fabiano Furtado
      Pessoal, disponibilizei no meu GitHub o meu primeiro projeto OpenSource, como forma de retornar para a comunidade o que tenho aprendido nestes últimos anos.
      O projeto se chama LIBCPF (C Plugin Framework - https://github.com/fabianofurtado/libcpf/) e se trata de uma biblioteca/framework pra gerenciamento de Plugins (".so") no Linux, feita em C. Para maiores detalhes, veja a documentação no arquivo README.md.
      Ela foi lançada utilizando-se a licença GPL v2, uma vez que não entendo muito sobre esse assunto e precisava de uma licença para o projeto.
      Espero que, de alguma forma, este projeto possa ser útil para você. Mesmo que não exista a necessidade de utilização desta lib em sua aplicação, a mesma pode ser usada para listar os nomes das funções e os offsets que existem dentro de uma shared library, algo que considero bem interessante. Veja no exemplo como isso funciona.
      Como qualquer programa em C, o desenvolvimento deu muito trabalho pois tentei desenvolvê-la com foco na segurança, tentando evitar possíveis "buffer overflows" ou qualquer outro tipo de vulnerabilidades.
      Sugestões e críticas serão sempre bem-vindas!
      Desde já, agradeço.
    • By Leandro Fróes
      Depois de muita espera a NSA anunciou oficialmente a inclusão de um debugger no Guidra na sua versão 10.0. Depois de muita discussão sobre esta possibilidade o time de desenvolvimento do framework lançou uma release beta da versão 10.0 ontem!
      Neste momento o debugger suporta analisar aplicações em userland e consegue debuggar tanto binários Windows quanto Linux (utilizando o gdb neste caso). Para quem quer começar logo de cara o Guidra disponibiliza um tutorial de início rápido em Help -> Guidra Functionality -> Debugger -> Getting Started:

      Existem várias formas de iniciar o debugger, desde clicando com o Botão direito -> Open With -> Debugger até direto da sua Project Window do Guidra clicando no ícone de "bug" debaixo de "Tool Chest", como mostrado abaixo:

      Uma vez que a ferramenta é inicializada você deve importar o arquivo a ser depurado para a ferramenta. Uma das formas de fazer isto é simplesmente o arrastando da Project Window. Uma fez carregado podemos ver a cara do mais novo debugger do Guidra:

      Algumas das funcionalidades são: debugging remoto utilizando GDB e windbg, rodar o debugger direto no programa do qual você está analizando estaticamente e tracing de memória.
      Além disso ele também conta com as funcionalidades básicas de um debugger como utilização de breakpoints, listagem de regiões de memória mapeadas, estados dos registradores e uma interface de linha de comando própria.
      Todas as funcionalidades listadas aqui possuem sua própria View, isto é, sua própria janela dentro da ferramenta:


      Vale lembrar que esta release está em sua versão beta e tem como objetivo principal coletar o feedback da comunidade. Caso queira dar uma testada e/ou dar um feedback pra galera do Guidra basta baixar a release clicando no botão abaixo 😉.

×
×
  • Create New...