# Quick start in the module writing
###### tags: `tutorial` `documentation`
<br>
> :fire: This is an easy guide to the module writing. :fire:
>
> :arrow_right: Read it to quickly understand the fundamentals. :arrow_left:
> :memo: Official documentation: https://cryptosploit.re86.ru/
<br>
## ❓ What should my module do?
All the modules are made for **encryption/decryption/attacking** of the different **cryptographic alogrithms** or **encodings**.
You can write any other modules with additional functionality related to cryptography, for example, **file encryption/decryption**.
## 📁 What is the directory structure of the module?
Also, you can add any files you need.
```
.
├── config.json
├── do_install.sh
├── __init__.py
└── requirements.txt
```
Let's check every file more detailed.
### config.json
```json
{
"mode": {
"value": "attack",
"description": "Operation mode. May be attack/decrypt/encrypt"
},
"key": {
"value": "13",
"description": "Value of key"
},
"input": {
"value": "",
"description": "String to be processed"
},
"contains": {
"value": "",
"description": "Used in attack mode, algo will search this substring.\nIf value is an empty string, all possible lines will be printed"
}
}
```
This is just an example of the *config.json* file.
Rename and add any variables required for your module that can be set by the user. To specify a default value for any variable use ```"value"```. Write clear description, all this information can be obtained by the ```get``` command.
```
crsconsole (templates.examplemodule)> get
╒══════════╤════════════════════════════╤═════════════════════════════════════════════════════════════════╕
│ Name │ Value │ Description │
╞══════════╪════════════════════════════╪═════════════════════════════════════════════════════════════════╡
│ mode │ attack │ Operation mode. May be attack/decrypt/encrypt │
├──────────┼────────────────────────────┼─────────────────────────────────────────────────────────────────┤
│ key │ 13 │ Value of key │
├──────────┼────────────────────────────┼─────────────────────────────────────────────────────────────────┤
│ input │ │ String to be processed │
├──────────┼────────────────────────────┼─────────────────────────────────────────────────────────────────┤
│ contains │ │ Used in attack mode, algo will search this substring. │
│ │ │ If value is an empty string, all possible lines will be printed │
╘══════════╧════════════════════════════╧═════════════════════════════════════════════════════════════════╛
```
### do_install.sh
Optional file, create it if your module need any dependencies/builds.
Write commands to install any dependencies you need. This script will be executed during the build.
Example:
```
pip install -r requirements.txt
git clone https://github.com/Ganapati/RsaCtfTool.git
```
Python modules will be installed in the python **virtual enviroment** and can be accessed by your module.
Installed **projects/binaries** will be stored **at the modules directory**.
### \_\_init\__.py
File with your module class. You can write module only in python or use python as a wrapper for your compiled module written in another programming language.
Also, you can add other python files you need in module directory.
**`__init__.py` must contain your module class.**
**Check the templates of binary and python module below.**
### requirements.txt
Just an example of the `requirements.txt` file.
```
pycryptodome==3.14.1
```
Also, you can add any files you need in module directory.
## 💣 Templates
### Essential requirements
1) Your module class must be inherited from the BaseModule class.
2) Your `__init__` function must call super `super().__init__` function to load module variables.
3) Your module class must contain `run` function that is called by the user.
4) You must create an instance of the module class with name `'module'`
### Template of the module written only in python
```python
from cryptosploit.cprint import Printer
from cryptosploit_modules import BaseModule
class ExamplePythonModuleName(BaseModule):
def __init__(self):
super().__init__()
self.env.check_var = self.check_var
@staticmethod
def check_var(name, value):
match name:
case "key":
if value.isdigit():
return True, ""
return False, "Must be a digit!"
case "mode":
if value in ("encrypt", "decrypt", "attack"):
return True, ""
return False, "Possible values: encrypt/decrypt/attack"
case _:
return True, ""
def encrypt_command(self):
"""Encrypt function"""
def decrypt_command(self):
"""Decrypt function"""
def attack_command(self):
"""Attack cipher function"""
def run(self):
"""
A function that is called when the user
uses the run command
"""
func = getattr(self, self.env.get_var("mode").value + "_command")
return func()
module = ExamplePythonModuleName
```
### Template of the wrapper in python for other programming languages
```python
from cryptosploit.cprint import Printer
from cryptosploit_modules import BaseModule
class ExampleBinaryModuleName(BaseModule):
def __init__(self):
super().__init__()
self.env.check_var = self.check_var
@staticmethod
def check_var(name, value):
"""Must return isvalid_variable: bool, error_msg: str"""
match name:
case "key":
if value.isdigit():
return True, ""
return False, "Must be a digit!"
case _:
return True, ""
def run(self):
"""
A function that is called when the user
uses the run command
"""
key = self.env.get_var("key").value
ciphertext = self.env.get_var("ciphertext").value
if key and ciphertext:
return self.command_exec(f"your_binary -k {key} -ct {ciphertext}")
return Printer.error("All paramaters must be set")
module = ExampleBinaryModuleName
```
### Basics of the module writing
#### BaseModule class
[BaseModule class](https://cryptosploit.re86.ru/docs/modules/#BaseModule) has `check_file` and `command_exec` methods.
##### `check_file`
You can return `check_file` in check_var if you want to check existance of the file.
```python
@staticmethod
def check_var(name, value):
match name:
case "path_to_file":
return self.check_file(value)
case _:
return True, ""
```
##### `command_exec`
Use this method to execute shell commands.
```python
return self.command_exec(f"your_binary -k {key} -ct {ciphertext}")
```
#### `self.env` - Enviroment class
With [enviroment class](https://cryptosploit.re86.ru/docs/modules/#Environment) you can override `check_var` function and get variables of your module.
##### `check_var`
```python
self.env.check_var = self.check_var
```
`check_var` - function that is called before setting a value to module variable, you can write your validation function. It must return `isvalid: bool` and `error_msg: str`.
If it returns False, `error_msg` will be printed to the user.
```
crsconsole (templates.examplemodule)> set key test
[!] Must be a digit!
crsconsole (templates.examplemodule)> set key 13
[>] Setting key -> 13
```
##### Get a variable of your module
To get value of any variable use method `self.env.get_var("vairable_name_you_need").value`.
```python
key = self.env.get_var("key").value
```
#### Printer class
With [cryptosploit.Printer](https://cryptosploit.re86.ru/docs/cryptosploit/cprint.html#Printer) you can print any data with special prefix and colorize it.
```python
return Printer.error("All paramaters must be set")
```
Will print red text with blinking `[!]` prefix.

You can use: `Printer.positive`, `Printer.negative`, `Printer.info`, `Printer.error`.
#### Exceptions
Instead of `Printer.error` you can raise [cryptosploit.exceptions](https://cryptosploit.re86.ru/docs/cryptosploit/exceptions.html).
```python
from cryptosploit.exceptions import ArgError
def run(self):
key = self.env.get_var("key").value
inp = self.env.get_var("input").value
if key and inp:
...
else:
raise ArgError("All variables must be set!")
```
Error message will be printed to console.
### Extra information
Always you can visit our [documentation site](https://cryptosploit.re86.ru/docs/modules/) to get more complex information about each class and method.