Skip to content

balesgreen/LKM-Command-Line-Parsing

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

26 Commits
 
 
 
 
 
 

Repository files navigation

LKM-Command-Line-Parsing

👾 Hoje iremos falar sobre Command Line Parsing diretamente no LKM. Esse é a segunda parte da nossa série de estudos para Rootkits.

  • Compreendendo a estrutura do nosso LKM.
  • Criando novos módulos e funções de int, string, long, array e short.
  • Imprimindo as funções nos Registros do Kernel.
    • Entendendo para que servem as FLAGS de Registros.
    • Entendendo sobre as novas bibliotecas.


Compreendendo a estrutura do nosso LKM.


- Temos então todo nosso cabeçalho de #include's com algumas bibliotecas que expliquei no artigo passado que ensinei a construir um LKM simples. Nesse artigo estarei explicando sobre as novas bibliotecas que foram importadas.

- Possuímos abaixo do nosso cabeçalho as funções de licenciamento e descrição. Como não expliquei no artigo passado, nesse artigo irei explicar para que elas servem e como vê-las em nosso LKM montado.

Bom, podemos notar pela seguinte função após a montagem do nosso LKM: A partir da versão do Kernel 2.6, tiveram algumas mudanças na nomenclatura de arquivos que são compilados para trabalhar com Kernel. A antiga extensão .o que hoje é utilizada a .ko (Kernel Object) é uma forma mais fácil de distinguir os arquivos de objetos convencionais. O motivo pela qual isso ocorre se dá ao fato da existência de um arquivo chamado .modinfo onde são mantidas as informações adicionais sobre os módulos.

Podemos checar nosso LKM para sabermos qual é o tipo de informação dele. Digite o comando ( modinfo CommandParsing.ko ) e veja os resultados que são retornados em seu terminal.




Podemos então verificar que as opções que foram escritas dentro do campo MODULE_LICENSE e MODULE_DESCRIPTION tiveram um retorno dentro do terminal. Podemos notar que além dessas informações, foram retornadas outras informações do PARM que estaremos falando sobre elas daqui a pouco. Bom, acredito que surgiu uma dúvida em sua mente a respeito disso, certo? "Para que essas informações servem?" Respondendo a essa dúvida, essas informações dão mais credibilidade ao usuário do nosso LKM. As funções como MODULE_AUTHOR, MODULE_LICENSE, MODULE_DESCRIPTION e etc, servem para as informações abaixo.

  • MODULE_AUTHOR -> Identifica quem é o autor do módulo escrito.
  • MODULE_LICENSE -> Identifica de quem é a licença do módulo escrito.
  • MODULE_DESCRIPTION -> Essa função permite que o autor do módulo explique um pouco mais sobre a sua finalidade para que o usuário não fique com um pé atrás a respeito do módulo a ser usado.

Uma coisa interessante que vale ressaltar, é que todas essas macros estão no linux/modules.h que foi importado em nosso projeto. Ou seja! Elas não são usadas pelo próprio kernel. Elas são apenas documentações e podem ser visualizadas pelo objdump e caso você tenha dúvida de como elas são usadas, procure em linux/drivers e entenda como os desenvolvedores de módulos utilizam elas em seus projetos.


  • Bom, agora vamos falar sobre toda essa estrutura do nosso LKM na qual definimos todas essas variáveis no corpo do nosso LKM.

    • Definimos então as seguintes variáveis: short, int, char e long .

      🌟 - short/long: assim como long, ele é um modificador do tipo inteiro que altera o tamanho dos bytes.
      🌟 - int: a variável do tipo inteiro é declarada como uma função que trabalha apenas com números.
      🌟 - char: a variável do tipo char é declarada como uma função que trabalha apenas com caracteres.

  • O que é a module_param()?

    • Bom, ela é um macro que é importadas da biblioteca linux/moduleparam.h para configurar o mecanismo das variáveis que setamos em nosso código. A macro module_param() oferece suporte para 3 argumentos: o nome da nossa variável, seu tipo e permissão para os arquivos que correspondem ao sysfs. Variáveis do tipo inteiro podem ser assinados normalmente mas caso você desejar usar arrays de inteiros e strings, recomendo que procure por module_param_array() e module_param_string().

    • Vale ressaltar que arrays também são suportados mas a história é totalmente diferente do que era na versão do Kernel 2.4. Para que você possa controlar o número de parametros, é necessário que você passe um ponteiro por uma variável de contagem como terceiro parâmetro. A seu critério você pode ignorar a contagem e passar NULL.

  • O que é MODULE_PARM_DESC()?

    • Assim como a sua companheira module_param(), ela é uma macro que é usada para documentar argumentos que o módulo pode receber. Ela oferece suporte para 2 argumentos: o nome da nossa variável e uma string de formato livre.


  • Temos então as nossas duas funções de inicialização e saída do nosso LKM. Essas funções são compostas por alguns argumentos que foram escritos dentro delas. Vamos analisar!

Possuímos então a nossa variável do tipo inteiro I que foi setada para trabalharmos a nossa função de intArray. Logo abaixo, temos a nossa função printk() que imprime mensagens no Registro do Kernel. E se você deseja entender sobre ela e qual a sua diferença para o printf(), clique aqui. Mas vamos dar continuidade ao nosso documento. Dentro do printk() existe uma flag chamada KERN_INFO. Essa flag, assim como as suas irmãs, é uma função que permite registrar o nível de logs dentro do buffer de registros do kernel. No final de cada printk() contém o nome de uma variável, pois, isso permitirá que cada valor das variáveis sejam impressos no registro do kernel. Temos a função FOR que foi escrita para trazer dois tipos de valores: valor 0 e valor 1. O valor 0 sempre será o valor que foi passado por linha de comando e o valor 1 será o valor que foi setado na variável intArray.

Confira abaixo:


Além da primeira função de inicialização, possuímos também a função de saída, ou seja, de descarregamento do buffer no Registros do Kernel. A mensagem aparecerá após digitarmos { rmmod CommandParsing.ko } e com isso a gente reconhece que nosso buffer do kernel foi descarregado..



- E por fim, temos os nossos macros de inicialização e descarregamento do nosso LKM no Kernel que são importadas da biblioteca linux/modules.h.

Como funciona o Makefile?



- 🔥 Possuimos o nosso arquivo de Makefile e irei explicar sobre como ele funciona mas basicamente do ponto de vista técnico, a única função importante dele é o primeiro comando, já que as funções "all" e "clean" foram adicionados por pura conveniência. Sabendo disso, apenas digite o queridíssimo make para que seu LKM seja criado com sucesso.

- 💥 Após a compilação de todo projeto, digite insmod CommandParsing.ko e logo afrente passe um parametro como por exemplo: insmod CommandParsing.ko intArray=-1337 strings="Hello World!". E para que você descarregue seu buffer de registros do kernel, digite rmmod CommandParsing.ko.




Bom, isso é tudo pessoal! Vou continuar postando artigos sobre LKM e RK aqui em meu GitHub! Espero vocês no próximo Git!

~# Mark Disconnected...

About

LKM Command Line Parsing - Parte 2

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published