hexforge_modules/crypto_modules.py (237 lines of code) (raw):
import binascii
import ida_kernwin
import re
from Crypto.Cipher import AES as CryptoAES
from Crypto.Cipher import ARC4 as CryptoARC4
from Crypto.Cipher import ChaCha20 as CryptoChaCha20
from hexforge_modules import helper
REGEX_HEX = re.compile(r"[^0-9a-fA-F]")
class ChaCha20(helper.ModuleTemplate):
def __init__(self):
self.ACTION_NAME = "hexforge::ChaCha20"
self.ACTION_TEXT = "ChaCha20 decrypt"
self.ACTION_TOOLTIP = "ChaCha20 decrypt"
# function to execute
def _action(self) -> None:
key, nonce = self._show()
encrypted_data = helper.get_selected_bytes()
if not encrypted_data or not key or not nonce:
return None
cipher = CryptoChaCha20.new(key=key, nonce=nonce)
decrypted = cipher.decrypt(encrypted_data)
helper.write_bytes_to_selected(decrypted)
def _show(self):
f = self.InputFormT()
f, _ = f.Compile()
# Show form
f.Execute()
chacha20_key_input = None
chacha20_nonce_input = None
try:
chacha20_key_input = f.chacha20_key.value
chacha20_nonce_input = f.chacha20_nonce.value
if f.Chacha20Key_UTF8.checked: # ascii data
chacha20_key_input = chacha20_key_input.encode()
else: # hex data
chacha20_key_input = binascii.unhexlify(
re.sub(REGEX_HEX, "", chacha20_key_input)
)
if f.Chacha20Key_UTF8.checked: # ascii data
chacha20_nonce_input = chacha20_nonce_input.encode()
else: # hex data
chacha20_nonce_input = binascii.unhexlify(
re.sub(REGEX_HEX, "", chacha20_nonce_input)
)
except binascii.Error as e:
print(e)
f.Free()
return chacha20_key_input, chacha20_nonce_input
class InputFormT(ida_kernwin.Form):
def __init__(self):
self.__n = 0
F = ida_kernwin.Form
F.__init__(
self,
r"""BUTTON YES* Ok
CHACHA20 Settings
{FormChangeCb}
<CHACHA20 key UTF8:{Chacha20Key_UTF8}>{cChacha20Key_UTF8Group}> | <## :{chacha20_key}>
<CHACHA20 nonce UTF8:{Chacha20Nonce_UTF8}>{cChacha20Nonce_UTF8Group}> | <## :{chacha20_nonce}>
""",
{
"FormChangeCb": F.FormChangeCb(self.OnFormChange),
"cChacha20Key_UTF8Group": F.ChkGroupControl(("Chacha20Key_UTF8",)),
"cChacha20Nonce_UTF8Group": F.ChkGroupControl(
("Chacha20Nonce_UTF8",)
),
"chacha20_key": F.StringInput(),
"chacha20_nonce": F.StringInput(),
},
)
def OnFormChange(self, fid):
return 1
class Aes(helper.ModuleTemplate):
def __init__(self):
self.ACTION_NAME = "hexforge::AES"
self.ACTION_TEXT = "AES decrypt"
self.ACTION_TOOLTIP = "AES decrypt"
# function to execute
def _action(self) -> None:
aes_mods_dict = {"CBC": CryptoAES.MODE_CBC, "ECB": CryptoAES.MODE_ECB}
aes_key, aes_iv, aes_mod = self._show(
[item for item in list(aes_mods_dict.keys())]
)
encrypted_data = helper.get_selected_bytes()
if aes_mods_dict[aes_mod] == CryptoAES.MODE_CBC:
cipher = CryptoAES.new(aes_key, aes_mods_dict[aes_mod], aes_iv)
elif aes_mods_dict[aes_mod] == CryptoAES.MODE_ECB:
cipher = CryptoAES.new(aes_key, aes_mods_dict[aes_mod])
if not encrypted_data or not aes_key or not aes_iv:
return None
decrypted_data = cipher.decrypt(encrypted_data)
helper.write_bytes_to_selected(decrypted_data)
def _show(self, aes_mods_list):
f = self.InputFormT(aes_mods_list)
f, _ = f.Compile()
# Show form
f.Execute()
aes_key = None
aes_iv = None
mod_chooser = None
try:
aes_key_input = f.aes_key.value
aes_iv_input = f.aes_iv.value
if f.AesKey_UTF8.checked: # ascii data
aes_key = aes_key_input.encode()
else: # hex data
aes_key = binascii.unhexlify(re.sub(REGEX_HEX, "", aes_key_input))
if f.AesIv_UTF8.checked: # ascii data
aes_iv = aes_iv_input.encode()
else: # hex data
aes_iv = binascii.unhexlify(re.sub(REGEX_HEX, "", aes_iv_input))
mod_chooser = f.cModChooser[f.cModChooser.value]
except binascii.Error as e:
print(e)
f.Free()
return aes_key, aes_iv, mod_chooser
class InputFormT(ida_kernwin.Form):
class mod_chooser_t(ida_kernwin.Choose):
"""
A simple chooser to be used as an embedded chooser
"""
def __init__(self, aes_mods_list):
ida_kernwin.Choose.__init__(
self,
"",
[
["AES mod", 9],
["", 9],
],
flags=0,
embedded=True,
width=30,
height=6,
)
self.items = aes_mods_list
self.icon = None
def OnGetLine(self, n):
return self.items[n]
def OnGetSize(self):
return len(self.items)
def __init__(self, aes_mods_list):
self.__n = 0
F = ida_kernwin.Form
F.__init__(
self,
r"""BUTTON YES* Ok
AES Settings
{FormChangeCb}
<AES KEY UTF8:{AesKey_UTF8}>{cAesKey_UTF8Group}> | <## :{aes_key}>
<AES IV UTF8:{AesIv_UTF8}>{cAesIv_UTF8Group}> | <## :{aes_iv}>
<##AES mod:{cModChooser}>
""",
{
"FormChangeCb": F.FormChangeCb(self.OnFormChange),
"cAesKey_UTF8Group": F.ChkGroupControl(("AesKey_UTF8",)),
"cAesIv_UTF8Group": F.ChkGroupControl(("AesIv_UTF8",)),
"aes_key": F.StringInput(),
"aes_iv": F.StringInput(),
"cModChooser": F.DropdownListControl(
items=aes_mods_list, readonly=True, selval=0
),
},
)
def OnFormChange(self, fid):
return 1
class Xor(helper.ModuleTemplate):
def __init__(self):
self.ACTION_NAME = "hexforge::XOR"
self.ACTION_TEXT = "XOR decrypt"
self.ACTION_TOOLTIP = "XOR decrypt"
# function to execute
def _action(self) -> None:
xor_value = self._show()
data = helper.get_selected_bytes()
if not data or not xor_value:
return None
for i in range(0, len(data)):
data[i] ^= xor_value[i % len(xor_value)]
helper.write_bytes_to_selected(data)
def _show(self):
f = self.InputFormT()
f, _ = f.Compile()
# Show form
f.Execute()
xor_key = None
try:
xor_key_input = f.xor_key.value
if f.XorKey_UTF8.checked: # ascii data
xor_key = xor_key_input.encode()
else: # hex data
xor_key = binascii.unhexlify(re.sub(REGEX_HEX, "", xor_key_input))
except binascii.Error as e:
print(e)
f.Free()
return xor_key
class InputFormT(ida_kernwin.Form):
def __init__(self):
self.__n = 0
F = ida_kernwin.Form
F.__init__(
self,
r"""BUTTON YES* Ok
XOR Settings
{FormChangeCb}
<XOR key UTF8:{XorKey_UTF8}>{cXorKey_UTF8Group}> | <## :{xor_key}>
""",
{
"FormChangeCb": F.FormChangeCb(self.OnFormChange),
"cXorKey_UTF8Group": F.ChkGroupControl(("XorKey_UTF8",)),
"xor_key": F.StringInput(),
},
)
def OnFormChange(self, fid):
return 1
class Rc4((helper.ModuleTemplate)):
def __init__(self):
self.ACTION_NAME = "hexforge::RC4"
self.ACTION_TEXT = "RC4 decrypt"
self.ACTION_TOOLTIP = "RC4 decrypt"
# function to execute
def _action(self) -> None:
rc4_key = self._show()
encrypted_data = helper.get_selected_bytes()
if not encrypted_data or not rc4_key:
return None
cipher = CryptoARC4.new(rc4_key)
decrypted_data = cipher.encrypt(encrypted_data)
helper.write_bytes_to_selected(decrypted_data)
def _show(self):
f = self.InputFormT()
f, _ = f.Compile()
# Show form
f.Execute()
rc4_key = None
try:
rc4_key_input = f.rc4_key.value
if f.Rc4Key_UTF8.checked: # ascii data
rc4_key = rc4_key_input.encode()
else: # hex data
rc4_key = binascii.unhexlify(re.sub(REGEX_HEX, "", rc4_key_input))
except binascii.Error as e:
print(e)
f.Free()
return rc4_key
class InputFormT(ida_kernwin.Form):
def __init__(self):
self.__n = 0
F = ida_kernwin.Form
F.__init__(
self,
r"""BUTTON YES* Ok
RC4 Settings
{FormChangeCb}
<RC4 key UTF8:{Rc4Key_UTF8}>{cRc4Key_UTF8Group}> | <## :{rc4_key}>
""",
{
"FormChangeCb": F.FormChangeCb(self.OnFormChange),
"cRc4Key_UTF8Group": F.ChkGroupControl(("Rc4Key_UTF8",)),
"rc4_key": F.StringInput(),
},
)
def OnFormChange(self, fid):
return 1