Jump to content

Fernando Mercês

Administrators
  • Posts

    1,627
  • Joined

  • Last visited

  • Days Won

    214

Everything posted by Fernando Mercês

  1. Talvez você conheça o Hiew (abreviação de Hacker's View), um poderoso editor hexadecimal que reconhece formatos de executáveis como PE e ELF e é capaz de editar suas características, disassemblar código em x86 e ARM e muito mais. Se ainda não conhece, comenta aí que num momento oportuno volto para falar mais dele. 😉 Neste artigo apresento o Hiewix, um novo programa feito pelo mesmo desenvolvedor do Hiew, Eugeny Suslikov, mais conhecido por seu nick SEN. Nesta leitura, você vai descobrir: Para que serve o Hiewix e o problema que ele vem resolver. Os poderes e limitações do Hiewix. Se vale a pena ou não comprá-lo. 💸 O Hiewix é para os momentos em que você não conhece a estrutura de determinado arquivo binário. Logo, seu intuito não é servir para editar arquivos PE, ELF ou Mach-O. Na real, a versão atual nem é capaz de modificar arquivos abertos, mas sim de trabalhar para reconhecer, com a sua ajuda, arquivos desconhecidos. Nada melhor que um exemplo para entender o poder do Hiewix. Recomendo acompanhar o artigo baixando a versão demo do Hiewix no site oficial e a ISO do Math Invaders para extrair o GAME.PAK que vamos utilizar como exemplo. Considere um formato de arquivo binários, ou seja, cuja estrutura e conteúdo não sejam facilmente deduzíveis, utilizado num jogo qualquer. O nome do nosso arquivo é GAME.PAK, então vamos chamá-lo de arquivo PAK, mas não conhecemos sua estrutura ainda. A figura 1 mostra a tela do Hiewix v1.10.633 ao abrir o arquivo pela primeira vez. Figura 1 - Tela inicial do Hiewix ao abrir o arquivo GAME.PAK O Hiewix nos dá algumas opções iniciais para carregar o arquivo: Main parser é o parser principal. O padrão é Binary(internal), que não faz nenhuma análise no arquivo. É nossa única opção numa primeira vez. Base address configura o primeiro endereço mostrado na tela do Hiewix para o conteúdo do arquivo. Por exemplo, se você digitar "10" (sem aspas), o primeiro byte do arquivo começará no endereço 0x10 e todos os comandos do Hiewix vão trabalhar a partir deste endereço base. Codesize permite configurar, se o arquivo contiver bytecode, (bytes que representam instruções para a CPU) o tipo de código para 16, 32 ou 64-bits. O Hiewix assume a arquitetura x86. Para arquivos de dados, a opção é Data. Second parser permite carregar um segundo parser além do principal para rodar sobre o arquivo. Mais sobre parsers em breve. Ao clicar em OK com as opções padrão selecionadas somos apresentados a uma tela bem parecida com a de um editor hexadecimal comum, mostrada na figura 2. Figura 2 - arquivo GAME.PAK aberto no Hiewix NOTA: Se ao bater o olho nos bytes deste arquivo você achou esse formato familiar, provavelmente já fez engenharia reversa em jogos antigos ou assistiu a um dos vídeos sobre a engenharia reversa que fiz no jogo Math Invaders (veja a parte 1 e a parte 2). Na parte 1, usei o Kaitai Struct e o Hiew. Já na parte 2, utilizei também o ImHex editor. Na época ainda não tinha Hiewix. 😄 O Hiewix criou um segmento padrão de dados de tamanho 0x15EB759, que no caso é o tamanho total do arquivo (22,984,537 bytes). Este segmento, assim como outros que porventura sejam criados, só fazem sentido na interface do Hiewix e servem para organizar diferentes segmentos de dados ou código que você descubra. Nada no arquivo é alterado com a criação deles. Alías, lembre-se: o Hiewix abre o arquivo com permissão de leitura somente. Uma vez o arquivo aberto, cabe a nós entender sua estrutura. Isso pode ser feito diretamente para formatos simples, mas formatos mais complexos podem exigir a engenharia reversa do executável que abre o arquivo analisado. Conforme formos compreendendo os dados no arquivo, vamos dando comandos no Hiewix que reflitam o que entendemos sobre tais dados. Comandos do Hiewix Os comandos são para você descrever o tipo de dado no qual o cursor se encontra. Por exemplo, por conta da análise deste arquivo PAK que já fiz, sei que os primeiros quatro bytes deste arquivo representam uma DWORD (double word), ou seja, um número de 4 bytes que nos diz quantos arquivos existem neste .PAK (o .PAK é uma espécie de sistema de arquivos rústico implementado num único arquivo que contém vários arquivos). Para descobrir como cheguei a esta conclusão, assista os vídeos de engenharia reversa no Math Invaders. 😉 Se os primeiros quatro bytes são uma DWORD, eu dou um clique no primeiro byte da DWORD (0x56 na figura 3) e clico no pequeno botão de um balãozinho com as lestras dd (de define dword) para produzir o efeito mostrado na figura 3. Figura 3 - Primeira DWORD definida com o Hiewix no GAME.PAK Perceba o efeito: O Hiewix pula uma linha na visualização após o fim da DWORD (ou seja, após o quarto byte) e muda a representação na coluna da direita para "dd 00000056", que indica que ela é uma DWORD e seu valor é 0x56 em little-endian. Ao definir números, é possível ter algum controle sobre sua representação. Por exemplo, posso selecionar os mesmos quatro bytes da minha DWORD e clicar novamente no botão dd para definir um array de um elemento com representação decimal. Dessa forma, o valor é apresentado em decimal na coluna da direita, como mostra a figura 4. Figura 4 - DWORD redefinida como array de um elemento com visualização em decimal A ideia é que você vá descrevendo os conjuntos de bytes do arquivo com os comandos disponíveis no Hiewix, o que me lembra bastante o IDA, da Hex-Rays. Os principais comandos disponíveis no Hiewix estão a seguir (o texto do ícone de cada botão, quando existe, está entre parênteses): Name (ab), define um nome para o byte, que aparecerá na aba Names, mostrada como Names(0) na Figura 2. Code (add), diz que o byte deve ser interpretado como código. Está desabilitado pois estamos num segmento de dados. Byte (db), define um byte. Word (dw), define uma WORD de dois bytes. Dword (dd), define uma DWORD de quatro bytes. Qword (dq), define uma QWORD de oito bytes. Float (df), define o tipo de dados float para números reais. Double (dF), define o tipo de dados double para números reais. Dump, ainda não entendi. 😄 Byteline, define um conjunto de bytes sem interpretação. Asciiz (a), define uma string ASCII. Unicode, define uma string Unicode. Comment line, insere um comentário acima da linha. Comment on line, insere um comentário à direita da linha (na coluna da direita). A figura 5 mostra as três primeiras entradas do arquivo PAK totalmente definidas e com comentários e nomes criados. Figura 5 - Definições dos campos da estrutura do PAK O texto em vermelho descreve o tipo de definição que usei, ou seja, os botões que apertei para definir os dados. Como também usei nomes, a aba Names à esquerda mostra os quatro nomes que defini. A ideia é poder dar um duplo-clique no endereço do nome (coluna address) para que o Hiewix navegue direto para lá. Também é possível marcar pontos como favoritos no arquivo que serão mostrados na aba Bookmarks. Para isso, basta selecionar o byte desejado clicar à esquerda da linha. Com estes poderes, o Hiewix nos permite ter uma visualização muito melhor do conteúdo do arquivo. Algo similar aos Templates no 010 Editor ou às structs do Kaitai Struct. A diferença é que o Hiewix nos permite criar a estrutura interativamente e não só programaticamente. Criando parsers Na versão paga, você até pode salvar o estado atual (com suas definições feitas) para este arquivo específico e depois carregá-lo. No entanto, se uma definição se repete muito (como é o caso das 86 entradas neste arquivo PAK) ou se você precisar abrir outros arquivos com a mesma estrutura, não faria sentido ter que definir todos os campos manualmente. Para estes casos, o Hiewix oferece o recurso de criação de parsers, ou seja, de pequenos programas que irão entender o conteúdo do arquivo para você. O software oferece duas APIs, uma em C e outra em Lua para tal. O pacote da versão paga vem com um exemplo em C++ um pouco difícil de entender e um esqueleto em Lua, sem um exemplos completo. Com alguma luta, consegui escrever um parser em C/C++ e compilá-lo com o Visual Studio 2022. O código basicamente automatiza o que fizemos na mão, mas com algumas ressalvas. A principal função é a ParseFile(), que mostro abaixo: HWX_EXPORT bool ParseFile(HWX_FILE_DATA *p_hwx_file_data) { uint32_t nentries = 0; const int file_index = p_hwx_file_data->_file_index; __int64 addr = 0; struct _stat st; // Abre o arquivo para ler os primeiros bytes, que contém o número // de entradas no PAK e também seu tamanho int fd = ::_wopen(p_hwx_file_data->_filename, _O_RDONLY); if (fd == -1) return false; // Lê os primeiros quatro bytes do arquivo e armazena em nentries if ( ::_read(fd, &nentries, sizeof(nentries)) != sizeof(nentries) ) return false; // Preenche a estrutura para pegar o tamanho do arquivo if (::_fstat(fd, &st) != 0) return false; ::_close(fd); // Adiciona um segmento de dados chamado "PAK_Header" const __int64 headerSize = (nentries + 1) * sizeof(entry) + sizeof(uint32_t); HwxFileAddDataSegment(file_index, 0, 0, headerSize, 0); HwxFileSegmentName(file_index, 0, L"PAK_Header"); HwxFileSegmentCollapse(file_index, 0, false); // Adiciona um segundo segmento de dados logo após o header HwxFileAddDataSegment(file_index, headerSize, headerSize, st.st_size-headerSize, 0); HwxFileSegmentName(file_index, headerSize, L"PAK_Contents"); HwxFileSegmentCollapse(file_index, headerSize, false); // Adiciona o comentário acima da primeira linha HwxFileCommentline(file_index, 0, L"Inicio do PAK"); // Define uma Dword (dd) no endereço 0 e avança 4 bytes HwxFileMakeDword(file_index, addr); addr += sizeof(uint32_t); // Loop que define e comenta os dois campos de cada estrutura for (int i=0; i < nentries; i++) { // Define e comenta uma string Asciiz, depois avança o tamanho total // do campo name da estrutura HwxFileMakeStringAsciiz(file_index, addr, NAME_LEN); HwxFileCommentOnline(file_index, addr, L"caminho do arquivo"); addr += NAME_LEN; // Define e comenta uma Dword que é o offset, depois avança quatro bytes HwxFileMakeDword(file_index, addr); HwxFileCommentOnline(file_index, addr, L"offset"); addr += sizeof(uint32_t); } return true; } O código completo será disponibilizado em breve. Após compilado, o arquivo é uma DLL com extensão .hwx32 que deve ser colocado no diretório raiz do Hiewix. Dessa forma, ao abrir um novo arquivo, será possível escolher o nosso parser personalizado como mostra a figura 6. Figura 6 - Nosso parser personalizado para escolha ao carregar um novo arquivo O resultado você vê na figura 7. O arquivo é totalmente parseado (sim, um neologismo - e por que não?), dois segmentos são criados e vários comentários feitos. Figura 7 - PAK parseado com nosso parser personalizado Neste parser optei por não criar nomes para o código ficar menor. Ao invés de nomes, criei um segundo segmento, algo que só parece ser possível através da API por enquanto. Já dá para perceber o poder que o Hiewix tem. Imagine que você pode criar parsers para qualquer tipo de arquivo que desejar. Se somar o poder o Kaitai Struct (que emite parsers em C++), fica mais poderoso ainda. No entanto, o Hiewix ainda está em desenvolvimento e é possível que muitas coisas mudem, inclusive na API, então recomendo segurar sua peteca antes de sair por aí criando parsers. Vale a pena comprar? O software me pareceu muito bom, mas há alguns pontos que requerem atenção na minha opinião, embora as coisas possam mudar muito em breve. São eles: Prós Velocidade. O Hiewix é escrito em C/C++ como tudo o que o SEN faz. E tudo acontece muito rápido no software. Isso é algo que eu valorizo muito, especialmente depois da invasão destes apps escritos em JavaScript para desktop que são uma carroça. Há quatro opções para marcar um endereço: nome, comentário acima da linha, comentário à direita da linha e favorito (bookmark). Muito legal essa versatilidade e muito similar ao Hiew, com o comentário acima talvez inspirado no IDA? Possibilidade de rodar um segundo parser, deixando ainda mais versátil. A API também sugere parsers reentrantes, mas não encontrei muita informação a respeito. A criação de tabelas (abas na parte de baixo da janela), que não mostrei aqui, mas é exibida na captura de tela aqui (abas Header, Dir, Sections, etc). Para um software pago, o preço é razoável: 50 dólares (aproximadamente R$ 300,00) por um ano e você renova se quiser as atualizações depois deste período. Para quem trabalha com arquivos desconhecidos com frequência, pode justificar o investimento. Contras Em minha opinião, o software ainda não está maduro. Há um pequeno bug na visualização das colunas e não dá para controlar o tamanho da janela inicial do software, por exemplo. Outros recursos dos quais senti a falta: Criação de novos segmentos através da interface gráfica. Possibilidade de exportar os bytes, como no Hiew. Redefinir uma Dword como decimal pela API como fiz na interface gráfica. Bem, pode ser que haja uma maneira, mas ainda não descobri. Suporte a outras arquiteturas além de x86 para segmentos de código. A API, por enquanto, é um pouco difícil de usar e não há qualquer documentação além de um arquivo de cabeçalho com os protótipos das funções da API. Como todos os outros softwares do SEN, o Hiewix é nativo para Windows, embora eu tenha conseguido rodar no Ubuntu com Wine sem problemas aparentes. Espero que este artigo tenha sido útil para conhecer esta nova ferramenta e/ou como uma introdução no conceito de parsing de arquivos binários. Como sempre, fique junto e lembre-se que você pode apoiar a Mente Binária para que artigos como esse continuem sendo publicados. Um abraço e happy hacking!
  2. until
    Mais informações: https://latinoware.org/
  3. Mais informações: https://www.instagram.com/hackin.rio/
  4. Site do evento: https://www.sympla.com.br/evento/xibesec-2024/2639304
  5. 1 download

    Projeto de tradução do livro "Manual da Linguagem GNU C" da Free Software Foundation. Nossa tradução (em andamento): https://menteb.in/gnuc Série de vídeos sobre cada capítulo: https://www.youtube.com/playlist?list=PLIfZMtpPYFP6Lwvd5M53806wMDd307DoU Livro original (em inglês): https://www.gnu.org/software/c-intro-and-ref/
  6. Ontem, 11 de Novembro de 2024 às 13h18, Darshit Shah anunciou na lista info-gnu: Estamos felizes em anunciar o lançamento do wget 1.25.0, a mais nova versão estável deste utilitário essencial para transferências de arquivos via HTTP, HTTPS e FTP, os protocolos mais utilizados na Internet. O GNU wget é um software livre de linha de comando, amplamente usado por sua capacidade de ser facilmente integrado em scripts, agendado em cron jobs e operado em terminais sem suporte ao X Window System. Mudanças Disruptivas Essa nova versão traz duas mudanças significativas: 1. Remoção do Formato Abreviado de URLs HTTP e FTP: O formato abreviado, anteriormente desaconselhado, foi removido permanentemente. Isso significa que invocações como: $ wget usuário:senha@servidor agora resultarão em erro de URL. Usuários devem utilizar o formato completo: $ wget http://usuário:senha@servidor 2. Leitura non-blocking de arquivos de entrada: Em invocações como: $ print_urls | wget -i- o wget agora lê continuamente da entrada padrão (stdin) até que a outra extremidade do pipe seja fechada. Antes, o wget tentava ler tudo no início, fechava a entrada padrão e processava as URLs. Esse recurso não está disponível no Windows. Além dessas mudanças, a versão 1.25.0 inclui várias melhorias de estabilidade e pequenas correções, com um total de 46 commits realizados por 3 desenvolvedores nas 35 semanas desde a versão 1.24.5. Como Atualizar o wget no Linux Para atualizar sua versão do wget no Linux, utilize o gerenciador de pacotes de sua distribuição. Por exemplo: - Em distribuições baseadas no Debian/Ubuntu sudo apt update && sudo apt install wget - Em distribuições baseadas no Red Hat/Fedora: sudo dnf update wget Para compilar a versão mais recente a partir do código-fonte, acesse o site oficial do GNU wget e baixe o pacote tarball, depois siga as instruções de compilação. Como Instalar o wget no Windows O wget também está disponível no Windows através do gerenciador de pacotes Scoop (mas não tá na última versão). Siga as instruções abaixo para instalá-lo: 1. Primeiro, instale o Scoop, caso ainda não o tenha, executando o seguinte comando no PowerShell: irm get.scoop.sh | iex 2. Em seguida, instale o wget usando o Scoop: scoop install wget Após a instalação, o wget estará disponível para uso diretamente no terminal. Quem usa Chocolatey ou winget (conheça-o no artigo Windows 10 para hackers), o wget tá neles também. Agradecimentos Agradecemos aos colaboradores que contribuíram para essa versão: Darshit Shah (13 commits) Sam James (2 commits) Tim Rühsen (31 commits) Confira o arquivo NEWS para um resumo completo das novidades (em inglês). Tem também o wget2, que segue em desenvolvimento paralelo ao wget 1.x. Um dia vou testar e conto aqui pra vocês como usar. 🙂
  7. until
    Mais informações: https://www.bhack.com.br
  8. until
    Mais informações: https://www.h2hc.com.br
  9. Olá! Recomendo remover suas informações de contato.. principalmente telefone e e-mail, para evitar receber spam. 😉 Quanto ao problema, de fato o API monitor só monitora chamadas externas. Se as funções que lêem os parâmetros do INI estiverem em uma DLL, você pode adicioná-la no API Monitor para ele monitorar, mas se as funções estiverem no próprio EXE alvo, aí não dá com ele. Penso que você pode usar breakpoints de hardware no acesso aos dados. Localize-os no dump do x64dbg e aí põe breakpoint de leitura no primeiro byte da string traduzida que você quer. Isso vai fazer o debugger parar quando algum código ler tal string. Aí deve ficar mais fácil encontrar o código defeituoso, que não põe a string na tela por algum motivo. Abraço!
  10. Oi @mateus.mota, Apesar do infeliz ocorrido, o tópico é muito interessante, valeu por compartilhar com a gente! A comunidade gamer é bastante talentosa, então eu não descartaria ameaças mais avançadas (rootkits), movimentações laterais e coisas do tipo. Eu não sei nos Windows atuais se uma reinstalação de fato formata ou só zera as configurações e restaura arquivos a partir de alguma partição. Se o malware infectou tal partição, ele pode estar persistente ainda. Você tem outros dispositivos na sua rede? Desconfiando de movimentação lateral, poderia ser possível que o atacante infectou outro dispositivo mantém persistência lá? Roteadores, câmeras de segurança, etc, qualquer coisa que tenha uma shell na real. Eu resetaria tudo para as configurações de fábrica. Sobre as contas em si, além de mudar a senha, recomendo: Verificar se o 2FA está habilitado. Se não, habilitar por app (não por SMS). É legal desabilitar e reabilitar também para mudar a chave. Verificar as sessões ativas e desconectar todas elas (inclusive a sua). Se você sincroniza dados de browser, apagar tudo (cookies, arquivos temporários, extensões, etc). Tem a possibilidade de você estar reinstalando o malware de algum lugar.. OneDrive, Dropbox, etc? Sobre AV, eu compraria um se fosse possível. Uma vez um vídeo sobre o assunto. Vamos falando aí. Tem muita gente boa aqui na comunidade que pode dar várias ideias legais! Abraço!
  11. Olá! Eu sou da opinião de que quanto mais base, melhor, mas a escolha, ao meu ver, precisa levar em consideração outros fatores como qualidade da instituição de ensino, preço, proximidade da sua residência, segurança do caminho, etc. Em geral, penso que Ciência da Computação é a opção que daria a maior base (quatro anos). Junto a este há o de Engenharia da Computação (foco maior em hardware) e Sistemas de Informação (foco maior em sistema). Se não me engano, todos são de quatro anos. Como segunda opção, vem os tecnólogos (um pouco menos de base, de dois a três anos) que compreendem ADS e Redes. Dá pra perceber que não existe uma resposta que funciona como uma bala de prata né? Um bom curso de ADS é provavelmente melhor que um curso de CC meia-bomba. Assim como um curso de Redes perto pode ser melhor pra você que um curso de SI do outro lado da cidade (não queremos perrengue né?). O importante é estudar bastante e na melhor instituição possível dentro das suas possibilidades geográficas e financeiras, penso. Para pentest e forense, se eu tivesse que escolher um entre ADS e Redes do mesmo nível, ficaria com o primeiro. Posso estar enganado, mas os cursos de Redes focam em profissionais de administração de redes? Adoraria ler outras opiniões. 🙂 Grande abraço!
  12. until
    Mais informações: https://www.tempest.com.br/tempest_talk/tempest-academy-conference/
  13. until
    Curso A Arte da Engenharia Reversa ao vivo e online que pode ser adquirido aqui.
  14. Olá! Se o código malicioso dela tá na DllMain(), você precisa parar lá. Tem duas alternativas simples: por um breakpoint na LoadLibrary() ao debugar o rundll32.exe (passando sua DLL como argumento) ou setando o EIP na mão para a DllMain() ao abrir a DLL direto no x64dbg. Também acho importante ver como o processo chama a DLL. Aï você pode imitar e fazer igual para ver o comportamento malicioso. 🙂 Vê se a aula 21 do AMO te ajuda. 😉 Abraço e boa sorte!
  15. Oi @Jorge Luiz_, Construções como if, else, for, while, etc são de alto nível. Em Assembly, elas são implementadas utilizando saltos (em x86, são as instruções começando com "J", de "jump"). Por exemplo, analise o código abaixo: cmp eax, 0 jne exit ; código se EAX é zero exit: ; resto do código No exemplo, há uma comparação de EAX com zero. Se não for zero, o programa vai saltar (JNE - Jump If Not Equals) para o rótulo (label) exit. Mas se EAX for zero, o código logo abaixo do salto (JNE) será executado (e depois o que está sob o rótulo exit também). O que acontece é que alguns compiladores de Assembly possuem macroinstruções que facilitam este trabalho e funcionam de forma similar às instruções de alto nível. Por exemplo, no fasm você pode fazer: .if eax = 0 ; código se EAX é zero .endif ; resto do código Mas no binário compilado, você verá os saltos de qualquer maneira, pois estas são instruções "reais" que o processador entende (enquanto .if só o compilador Assembly entende). Além disso, os rótulos somem pois os destinos da maioria dos saltos são deslocamentos (X bytes para frente ou para trás), o que na prática vira endereços de memória. Veja: Dá uma olhada: http://flatassembler.net/docs.php?article=win32#2.2 Abraço!
  16. A explicação é complicada (para os meus parâmetros hehe), mas vou tentar. 🙂 *argv[] na main() já é um ponteiro para um array de chars. Mas é uma variável, e tem um endereço de memória (supomos, 0x200). Para a sum(), ao fazer &argv você passa o endereço de argv, ou seja, 0x200. Na sum() você recebe esse endereço como um ponteiro para ponteiro para um array de chars: **args[]. O que está certo. Na sum(), args contém um único elemento (o ponteiro para um array chars e não o array de chars em si). Com *args[i], sabendo que a precedência de [] é maior que a de *, então vamos analisar o loop: args[0] é o primeiro (e único) elemento de args. *args[0] o acessa. args[1] falha, pois args só contém um elemento. Segfault aqui. Agora, com (*args)[i]: (*args) é resolvido primeiro em todas as iterações do loop. O resultado é um ponteiro para um array de chars. (*args)[0] funciona, assim como (*args)[1], (*args)[2], até argc-1. Um desenho certamente explicaria melhor, ou talvez com o uso do GDB. Se não entender, avisa aí que eu tento de outra forma. Ou talvez outra pessoa explique melhor. 🙂 Em tempo, você complicou mais do que precisa. O que eu faria é: sum(int n, char *args[]) { // código strtol(args[i], ...); } main(int argc, char *argv[]) { // código sum(argc, argv); } Dessa forma você passa o argv, que já é um ponteiro para um array de char (C strings, neste caso) para sum() e ela acessa por args, que é do mesmo tipo. Outras ideias, só por curiosidade: Economizando a variável i ao somar do último para o primeiro elemento (ou seja, na ordem reversa): int sum(int n, char *args[]) { int result = 0; n--; while (n > 0) { result += strtol(args[n], NULL, 10); n--; } return result; } Economizando o uso de argc, já que o último elemento de argv é sempre nulo - ou seja, argv[argc] == NULL: int sum(char *args[]) { int result = 0; while (*args) { result += strtol(*args, NULL, 10); args++; } return result; } Ou uma versão menorzinha, aproveitando que ++ é um operador de pós-incremento (primeiro o valor é lido e depois é incrementado): int sum(char *args[]) { int result = 0; while (*args) result += strtol(*args++, NULL, 10); return result; } Mas aí já entram mais conceitos.. por exemplo *args é o mesmo que fazer *args != NULL. E args++ é aritmética de ponteiros. Não é "mais um" e sim "mais X bytes", onde X é o tamanho do tipo. Versão "olha mãe, sem as mãos": int sum(char *args[]) { return *args ? strtol(*args, NULL, 10) + sum(args + 1) : 0; } Aqui já entra recursividade (pode esgotar a pilha) e o ternário. Fiz essas coisas só para despertar a curiosidade mesmo e provar que C é a linguagem na qual o universo foi escrito. 😄 Abraço.
  17. Não existe um suporte nativo, mas tem gambiarras possíveis: ; Opção 1 - Simplesmente um ponto-e-vírgula no início de cada linha (mas essa você já sabe) ; linha1 ; linha2 ; linha3 ; Opção 2 - Começa com ponto-e-vírtugla e protege o caractere de fim de linha com a contra-barra ; linha1\ linha2\ linha3 Opção 3 - Testar se uma macro inexistente existe %ifdef COMENTARIO ; pode ser qualquer coisa, contanto que não exista - ou seja, não esteja definida linha1 linha2 linha3 %endif Opção 4 - Avaliar uma expressão numérica que retorne falso sempre %if 0 linha1 linha2 linha3 %endif Abraço.
  18. Acho que se você postar o código - e o programa alvo se puder, ajuda mais. 🙂 Pensando aqui que pode ser alguma proteção no programa alvo, para evitar isso, mas pode não ser também. hehe Abraço.
  19. Oi @SERGIO A BERGAMIN, tudo certo? Seria o caso de o executável ser de 32-bits e a máquina do seu cliente de 64-bits? Que versão do Windows tá no cliente? Já tentou o modo de compatibilidade? Abraço!
  20. Opa, Sim, por todos os nossos canais. 🙂 Sim, os requisitos estão no fim do texto aqui. Abraço!
  21. Oi @Guilherme23, tudo em paz e contigo? Estamos planejando uma turma do curso A Arte da Engenharia Reversa (pago, online e ao vivo). Em relação aos cursos gratuitos, não lançaremos outros sobre estes tópicos este ano. Segue um resumo do que temos sobre ER e 😄 A Arte da Engenharia Reversa Pago, online, ao vivo. Duração de 16h (normalmente sábado e domingo das 9h às 18h). Não decidimos data ainda, mas vamos divulgar quando abrirmos inscrições. Sempre atualizado e permite tirar as dúvidas ao vivo com o instrutor ou instrutora. Curso de Engenharia Reversa Online (CERO) Gratuito, em vídeo no YouTube. Não temos como atualizar os vídeos, mas o conhecimento ainda é útil. 🙂 Livro: Fundamentos de Engenharia Reversa Gratuito. Para quem prefere ler no seu tempo. Livro: Aprendendo Assembly Gratuito. Para um estudo detalhado da linguagem (com base em Linux). Sobre C, temos: Programação Moderna em C Gratuito, em vídeo no YouTube. Não temos como atualizar os vídeos, mas C demora bastante a mudar, então super vale! Livro: Manual da Linguagem GNU C Gratuito. Para quem prefere ler no seu tempo. Tradução do livro do Stallman sobre GNU C. Esta tradução está em andamento. Liberamos novos capítulos a cada 15 dias, seguidos de um vídeo na playlist Manual da Linguagem GNU C. Há ainda um livro muito legal de dicas de C e Assembly que o autor nos permitiu disponibilizar para download aqui. Chama-se Dicas - C e Assembly para arquitetura x86-64. Por hora, isto é tudo. 🙂 Grande abraço e bons estudos. Qualquer outra dúvida é só falar. Abraço!
  22. Olá! Por favor, leia esse tópico: Aí você edita o seu e vamos em frente. 🙂 Abraço!
  23. Opa, tudo bem? Obrigado por terminar o curso! No momento não emitidos certificados para os cursos livres pois não temos nenhuma maneira automatizada de fazê-lo. Um abraço!
  24. Olá! Se alguém tiver tempo, pode ser que consiga te ajudar sim, mas se você quiser aprender e fazer você mesmo, ou se unir com alguém da comunidade e fazer junto, recomendo que comece pelos nossos treinamentos gratuitos aqui. Dependendo do quanto você já conhece, pode ser interessante fazer o de C primeiro e depois o CERO. Aí você pode estudar também pelo livro Fundamentos de Engenharia Reversa e o de Assembly, ambos gratuitos. Tá tudo no menu Ensino aqui mesmo no nosso site. 🙂 Abraço, Fernando
  25. Eu nunca usei essas funções da GDI, mas pelo que vi na documentação da LineTo(), ela usa a “caneta” padrão: The line is drawn by using the current pen and, if the pen is a geometric pen, the current brush. Meus conhecimentos de Paint me dizem que o caminho é alterar a caneta antes de chamar a LineTo(). Pelo que vi, tem que criar a caneta no seu código com a CreatePen(): HPEN caneta = CreatePen(PS_SOLID, 2, RGB(0, 0, 0)); No exemplo acima usei uma caneta sólida, de espessura 2 e cor preta. Depois precisa atribuir a caneta à sua tela: SelectObject(tela, caneta); Se tudo der certo a LineTo vai usar essa caneta ao invés da padrão, mas não testei viu? Tô no celular. hehe Abraço!
×
×
  • Create New...