> For the complete documentation index, see [llms.txt](https://stacked-rwx.gitbook.io/public/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://stacked-rwx.gitbook.io/public/malware-development/linux-kernel-module.md).

# Linux Kernel Module

<figure><img src="/files/XMUEgp29Jz478xhspUhC" alt=""><figcaption></figcaption></figure>

Bom, temos aqui então todo nosso cabeçalho de includes de bibliotecas. Vamos fazer uma explicação sobre cada biblioteca dessa de uma forma mais completa, já que expliquei de forma resumida no projeto.

## Linux/Kernel.h:

É o cabeçalho para construção de modulos, é o cabeçalho que faz parte do código-fonte do kernel do linux e é a library que importei para trabalhar com a construção de módulos.

## Linux/Module.h:

É o cabeçalho que trabalha com modulos do Kernel, é o cabeçalho que nos ajudará na construção do nosso módulo e também faz parte do código-fonte do kernel do linux.

## Linux/init.h:

É o cabeçalho que trabalha com a inicialização e término de dados como algum dos módulos finais.

* Setando módulos

<figure><img src="/files/RxPlsvD0LkDXh76UKq50" alt=""><figcaption></figcaption></figure>

Aqui setamos alguns módulos como módulos de descrição, autor, licença e até a versão do nosso projeto LKM.

## Estrutura geral do Linux Kernel Module (LKM)

* Início da classe init\_modsys

<figure><img src="/files/qEXf8BTq9sM1XtE73Tcz" alt=""><figcaption></figcaption></figure>

Aqui vamos falar sobre toda essa estrutura e explicar sobre a diferença entre printk() e printf().

### static int \_\_init init\_modsys(void):

Esta é a primeira função que fiz para iniciar o nosso LKM. Essa função é carregada assim que o módulo é executado. Ou seja, o conteúdo que colocamos dentro dela aparecerá dentro dos logs do kernel. Confira abaixo:

<figure><img src="/files/LyIthXolBi8DdBwFnFCq" alt=""><figcaption></figcaption></figure>

O mesmo ocorre quando descarregamos o LKM na nossa função \[static int \_\_exit exit\_modsys(void)]. Confira abaixo.

<figure><img src="/files/jHNaNYb1EyG4IM009ngV" alt=""><figcaption></figcaption></figure>

*Mas daí surge uma dúvida. Como essas mensagens foram chegar ali...?*

### Conhecendo o printk():

* Vamos entender como o printk() funciona e qual é a sua diferença com o printf()

**Init Function:**

<figure><img src="/files/Pk21zMbaxFeHAVHLHcel" alt=""><figcaption></figcaption></figure>

**Exit Function:**

<figure><img src="/files/odBbUfaPPNfvYrw9Xqbq" alt=""><figcaption></figcaption></figure>

## Printk() vs Printf()

printk() \~# Essa função C da interface do Linux é uma função que imprime mensagens em diferentes níveis de logs do Kernel. Essa função trabalha com um parâmetro denominado string de formato, que é um método que renderiza um número arbitrário de tipos de dados variados em uma string e essa string é a string que é impressa no log do kernel.

printf() \~# Essa função C uma das principais funções de output do C. As strings de formato printf são complementares da função de string de formato\
do scanf() que oferecem um input formatado. Resumidamente, essa função imprime uma mensagem ou resultado no seu terminal após ela ter sido executada.

-> Diferenças entre ambos: Por mais que a função printk() seja baseada no printf(), em algumas situações é impossível usa-la da mesma forma que o printf().

Vejamos o motivo:\
\
*Níveis de registro*

⭐️ A função printk() permite que um chamador especifique o tipo e a importância de uma mensagem que está sendo enviada. Este especificador é chamado de nível de log. O nível de registro especifica o tipo de mensagem que está sendo enviada para o registro do Kernel. O nível de kernel é especificado prefixando uma string que descreve o nível de log até o início da mensagem ser reproduzida.\
\
Por exemplo: Uma mensagem pode ser reproduzida no KERN\_INFO usando a seguinte função em que eu usei no LKM.\
\
`printk(KERN_INFO "Estou aqui, amigo :)\n");`

Mas o que é essa função KERN\_INFO? O que ela faz?

💥 Bom, aqui contém alguns exemplo de tipos de níveis de registros. [clique aqui](https://elinux.org/Debugging_by_printing#Log_Levels)\
Mas explicando de forma rápida, básicamente é o tipo de Registro de Nível em que queremos que seja enviado para o Kernel.

## Init e Exit Modules

\- Temos então duas funções simples que estão no final de nosso projeto. - Essas funções como já diz, executam uma função do nosso LKM e essa função é a init\_modsys e a exit\_modsys.

Exemplificando: Básicamente o sistema vai entender quando é hora de executarmos o nosso LKM e quando é hora de descarregar o Kernel.

* Abaixo estarei deixando os comandos para que você possa executar o LKM em seu sistema. (Recomendo que utilize alguma VM, pois não me responsabilizo por danos causados em sua máquina.)

## Executando o nosso LKM

* Primeiro passo é você clonar o Git desse projeto utilizando o seguinte comando: \
  git clone <https://github.com/balesgreen/Linux-Kernel-Module-basic-explanation.git&#x20>;
* Segundo passo é você entrar no diretório desse projeto e digitar os seguintes comandos para montarmos o LKM: make && clear && ls
* Você verá que apareceram novos arquivos mas o que devemos nos preocupar é com o file .ko (Kernel Object).&#x20;
* Digite o seguinte comando: insmod kernel\_module.ko

Após ter digitado este comando, você precisa digitar o seguinte comando para ver a mensagem armazenada nos registros do kernel.

**dmesg**&#x20;

E você vai poder observar que aparecerá uma mensagem bem no final do Registro do Kernel.

Mas como eu irei descarregar o Kernel? Bom, digite o seguinte comando: rmmod kernel\_module.ko e após isso digite dmesg novamente e você verá que o nosso Registro de Kernel apareceu com outra mensagem, mas foi totalmente descarregado após a execução deste comando.

Agradeço imensamente a todos por terem lido até aqui e caso vocês encontrarem algum erro aqui, fale comigo pelo discord! É isso ai gente, até o próximo repositório!
