-
Posts
1,570 -
Joined
-
Last visited
-
Days Won
202
Content Type
Forums
Courses
News
Articles
Contributing
Professions
Studying materials
Research
Downloads
Store
Events
Blogs
Gallery
Posts posted by Fernando Mercês
-
-
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!
- 1
-
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.
- 1
-
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.
-
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.
-
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!
-
Opa,
Em 04/07/2024 em 13:14, Guilherme23 disse:vai informar pelo Youtube também ?
Sim, por todos os nossos canais. 🙂
Em 04/07/2024 em 13:14, Guilherme23 disse:Será necessário algum conhecimento prévio?
Sim, os requisitos estão no fim do texto aqui.
Abraço!
-
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!
-
A Arte da Engenharia Reversa
-
Olá! Por favor, leia esse tópico:
Aí você edita o seu e vamos em frente. 🙂
Abraço!
- 1
-
Em 05/06/2024 em 14:37, rsievering@hotmail.com disse:
Existe algum certificado que eu possa emitir.???
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!
-
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
-
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!
- 1
-
Teremos prazer em ajudar, mas você precisa ler isso e adaptar seu tópico:
Abraço!
-
Salve, tudo bem e você?
Quando parar na MessageBoxW, olha na Call stack para ver quem a chamou (tô assumindo que você tá no x64dbg).
Abraço!
-
De quebra, acabei lendo o artigo. Parabéns pela pesquisa! 🙂
E nem foi nada. Por um momento achei que fosses spammers se aproveitando do conteúdo da PRIDE, mas tá tudo certo já! 😎
- 1
- 1
-
Que legal!
No exercício 4, a ideia é você dar, de cabeça, a resposta em hexadecimal. 😉
No 5, pensa como seria 0x10 - 4 e aí aplica a regra na operação que ele sugere.
Ajudou?
Abraço e obrigado por estudar com a gente! ❤️
-
Gostei dos nomes das seções. 🙂
Maneiro seu projeto!
- 1
-
@miguelblefari falta um ponto-e-vírgula no fim da definição da classe, ou seja, no fim de tudo. 😉
- 1
-
Eu ajudaria, mas segurança ofensiva não é minha praia. Ouço falar bem da DCPT, mas não conheço a Exin. 😞
Vamos esperar se alguém com conhecimento sobre o assunto ajuda mais. 🙂
-
Em 26/02/2024 em 07:55, Kevin Almeida disse:
vou subir um commit com o binario para facilitar a vida da galera e fazer alguns desafios mais divertidos haha
hahah tranquilo! No GitHub, em geral, binários vão na seção Releases. 😉
Abraço!
-
Oi @Kevin Almeida! Que maneiro! Parabéns! 🙂
Uma pergunta: algum motivo especial pra você não disponibilizar o binário ao invés do código? Acho que facilitaria para que as pessoas de fato tentassem resolver (antes de ver o código).
Abraço!
-
Tenta nesse: https://mega.nz/folder/pYgWESjQ#QLwgzyeW18EjO7OASCgXug😉
- 1
-
Tem esse link de backup, pessoal: https://mega.nz/folder/pYgWESjQ#QLwgzyeW18EjO7OASCgXug
- 1
-
Opa, bem vindo @Crystoppher!
Em algum momento da vida, o x64dbg passou a criar um símbolo exportado (na aba Símbolos/Symbols) chamado OptionalHeader.AddressOfEntryPoint. O nome deste símbolo vem do fato de o endereço do entrypoint ser um campo do cabeçalho chamado Optional Header. No disassembly, se você estiver diante de um endereço de um símbolo, o x64dbg coloca o nome do símbolo do lado. 😉
Abraço.
- 1
- 1
-
Legais as perguntas! 🙂
Em 17/10/2023 em 21:39, Nitczi disse:Na linha onde está "sar rax,cl" vi que isso é uma operação de bit shifting para a direita, pesquisei em alguns sites para ver como ficaria essa operação e o resultado é sempre 5, mas rodando o programa o resultado é 1, por que?
O nome é deslocamento aritimético para a direita. Tem o deslocamento lógico também, que é feito pela instrução SHL. 😉
O que essa instrução faz é, tomando o número em binário, "empurrar" todos os bits para a direita e aí o bit que "sobra" à esquerda é preenchido com zero ou um (caso ele já seja 1). Por exemplo:
0011 SAR 1 = 0001 1100 SAR 1 = 1110
O código faz 0x1122334455667788 SAR 0x3c (60) na primeira iteração do loop. Para entender, você teria que converter 0x1122334455667788 para binário e fazer a operação de deslocamento aritimético para a direita sessenta vezes, entende? Então vamos lá:
0x1122334455667788 em binário é: 0001 0001 0010 0010 0011 0011 0100 0100 0101 0101 0110 0110 0111 0111 1000 1000 (observe a parte em negrito, que será deslocada para a direita).
Deslocando somente uma vez para a direita, teremos:
0000 1000 1001 0001 0001 1001 1010 0010 0010 1010 1011 0011 0011 1011 1100 0100
O zero foi colocado à esquerda porque o bit original era zero.
Agora você teria que fazer o processo mais 59 vezes para chegar no resultado 1. 🙂
Fiz um programa em Python aqui para simular, trabalhando com o número como se fosse uma string. Espero que não confunda mais. 🤣
rax = '0001000100100010001100110100010001010101011001100111011110001000' print(f'rax = {rax}') for i in range(1, 61): if rax[0] == '0': rax = '0' + rax[:-1] else: rax = '1' + rax[:-1] print(f'rax SAR {i:02d} = {rax}')
A saída é:
rax = 0001000100100010001100110100010001010101011001100111011110001000 rax SAR 01 = 0000100010010001000110011010001000101010101100110011101111000100 rax SAR 02 = 0000010001001000100011001101000100010101010110011001110111100010 rax SAR 03 = 0000001000100100010001100110100010001010101011001100111011110001 rax SAR 04 = 0000000100010010001000110011010001000101010101100110011101111000 rax SAR 05 = 0000000010001001000100011001101000100010101010110011001110111100 rax SAR 06 = 0000000001000100100010001100110100010001010101011001100111011110 rax SAR 07 = 0000000000100010010001000110011010001000101010101100110011101111 rax SAR 08 = 0000000000010001001000100011001101000100010101010110011001110111 rax SAR 09 = 0000000000001000100100010001100110100010001010101011001100111011 rax SAR 10 = 0000000000000100010010001000110011010001000101010101100110011101 rax SAR 11 = 0000000000000010001001000100011001101000100010101010110011001110 rax SAR 12 = 0000000000000001000100100010001100110100010001010101011001100111 rax SAR 13 = 0000000000000000100010010001000110011010001000101010101100110011 rax SAR 14 = 0000000000000000010001001000100011001101000100010101010110011001 rax SAR 15 = 0000000000000000001000100100010001100110100010001010101011001100 rax SAR 16 = 0000000000000000000100010010001000110011010001000101010101100110 rax SAR 17 = 0000000000000000000010001001000100011001101000100010101010110011 rax SAR 18 = 0000000000000000000001000100100010001100110100010001010101011001 rax SAR 19 = 0000000000000000000000100010010001000110011010001000101010101100 rax SAR 20 = 0000000000000000000000010001001000100011001101000100010101010110 rax SAR 21 = 0000000000000000000000001000100100010001100110100010001010101011 rax SAR 22 = 0000000000000000000000000100010010001000110011010001000101010101 rax SAR 23 = 0000000000000000000000000010001001000100011001101000100010101010 rax SAR 24 = 0000000000000000000000000001000100100010001100110100010001010101 rax SAR 25 = 0000000000000000000000000000100010010001000110011010001000101010 rax SAR 26 = 0000000000000000000000000000010001001000100011001101000100010101 rax SAR 27 = 0000000000000000000000000000001000100100010001100110100010001010 rax SAR 28 = 0000000000000000000000000000000100010010001000110011010001000101 rax SAR 29 = 0000000000000000000000000000000010001001000100011001101000100010 rax SAR 30 = 0000000000000000000000000000000001000100100010001100110100010001 rax SAR 31 = 0000000000000000000000000000000000100010010001000110011010001000 rax SAR 32 = 0000000000000000000000000000000000010001001000100011001101000100 rax SAR 33 = 0000000000000000000000000000000000001000100100010001100110100010 rax SAR 34 = 0000000000000000000000000000000000000100010010001000110011010001 rax SAR 35 = 0000000000000000000000000000000000000010001001000100011001101000 rax SAR 36 = 0000000000000000000000000000000000000001000100100010001100110100 rax SAR 37 = 0000000000000000000000000000000000000000100010010001000110011010 rax SAR 38 = 0000000000000000000000000000000000000000010001001000100011001101 rax SAR 39 = 0000000000000000000000000000000000000000001000100100010001100110 rax SAR 40 = 0000000000000000000000000000000000000000000100010010001000110011 rax SAR 41 = 0000000000000000000000000000000000000000000010001001000100011001 rax SAR 42 = 0000000000000000000000000000000000000000000001000100100010001100 rax SAR 43 = 0000000000000000000000000000000000000000000000100010010001000110 rax SAR 44 = 0000000000000000000000000000000000000000000000010001001000100011 rax SAR 45 = 0000000000000000000000000000000000000000000000001000100100010001 rax SAR 46 = 0000000000000000000000000000000000000000000000000100010010001000 rax SAR 47 = 0000000000000000000000000000000000000000000000000010001001000100 rax SAR 48 = 0000000000000000000000000000000000000000000000000001000100100010 rax SAR 49 = 0000000000000000000000000000000000000000000000000000100010010001 rax SAR 50 = 0000000000000000000000000000000000000000000000000000010001001000 rax SAR 51 = 0000000000000000000000000000000000000000000000000000001000100100 rax SAR 52 = 0000000000000000000000000000000000000000000000000000000100010010 rax SAR 53 = 0000000000000000000000000000000000000000000000000000000010001001 rax SAR 54 = 0000000000000000000000000000000000000000000000000000000001000100 rax SAR 55 = 0000000000000000000000000000000000000000000000000000000000100010 rax SAR 56 = 0000000000000000000000000000000000000000000000000000000000010001 rax SAR 57 = 0000000000000000000000000000000000000000000000000000000000001000 rax SAR 58 = 0000000000000000000000000000000000000000000000000000000000000100 rax SAR 59 = 0000000000000000000000000000000000000000000000000000000000000010 rax SAR 60 = 0000000000000000000000000000000000000000000000000000000000000001
Com isso você prova que 0x1122334455667788 SAR 60 é igual a 1. Mas na próxima iteração do loop, RAX sofrerá uma operação SAR com 56, que já não é 1, e por aí vai... Ou seja, não é que é sempre 1. 😉
O objetivo deste programa é você imprimir na tela cada dígito hexa do registrador RAX, não importa o que você coloque lá. Testa com 0xf0f0caf0f0ca2023 por exemplo. 😉
Abraço!
- 1
Log Stealer em .NET
in Malware Analysis
Posted
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!