parent
ebc411c139
commit
fb710005c2
@ -0,0 +1,101 @@
|
|||||||
|
AccessModifierOffset: -4
|
||||||
|
AlignAfterOpenBracket: AlwaysBreak
|
||||||
|
AlignConsecutiveAssignments: false
|
||||||
|
AlignConsecutiveDeclarations: false
|
||||||
|
AlignEscapedNewlines: DontAlign
|
||||||
|
AlignOperands: true
|
||||||
|
AllowAllParametersOfDeclarationOnNextLine: false
|
||||||
|
AllowShortBlocksOnASingleLine: false
|
||||||
|
AllowShortCaseLabelsOnASingleLine: false
|
||||||
|
AllowShortFunctionsOnASingleLine: Inline
|
||||||
|
AllowShortIfStatementsOnASingleLine: false
|
||||||
|
AllowShortLoopsOnASingleLine: false
|
||||||
|
AlwaysBreakAfterReturnType: TopLevel
|
||||||
|
AlwaysBreakBeforeMultilineStrings: false
|
||||||
|
AlwaysBreakTemplateDeclarations: true
|
||||||
|
BinPackArguments: false
|
||||||
|
BinPackParameters: false
|
||||||
|
BraceWrapping:
|
||||||
|
AfterClass: true
|
||||||
|
AfterControlStatement: true
|
||||||
|
AfterEnum: true
|
||||||
|
AfterFunction: true
|
||||||
|
AfterNamespace: false
|
||||||
|
AfterStruct: true
|
||||||
|
AfterUnion: true
|
||||||
|
AfterExternBlock: false
|
||||||
|
BeforeCatch: true
|
||||||
|
BeforeElse: true
|
||||||
|
BreakBeforeBraces: Custom
|
||||||
|
BreakBeforeBinaryOperators: None
|
||||||
|
BreakBeforeTernaryOperators: true
|
||||||
|
BreakConstructorInitializers: AfterColon
|
||||||
|
BreakStringLiterals: false
|
||||||
|
ColumnLimit: 120
|
||||||
|
CommentPragmas: '^begin_wpp|^end_wpp|^FUNC |^USESUFFIX |^USESUFFIX '
|
||||||
|
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
||||||
|
ConstructorInitializerIndentWidth: 4
|
||||||
|
ContinuationIndentWidth: 4
|
||||||
|
Cpp11BracedListStyle: true
|
||||||
|
DerivePointerAlignment: false
|
||||||
|
ExperimentalAutoDetectBinPacking: false
|
||||||
|
IndentCaseLabels: false
|
||||||
|
IndentPPDirectives: AfterHash
|
||||||
|
IndentWidth: 4
|
||||||
|
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||||
|
Language: Cpp
|
||||||
|
MacroBlockBegin: '^BEGIN_MODULE$|^BEGIN_TEST_CLASS$|^BEGIN_TEST_METHOD$'
|
||||||
|
MacroBlockEnd: '^END_MODULE$|^END_TEST_CLASS$|^END_TEST_METHOD$'
|
||||||
|
MaxEmptyLinesToKeep: 1
|
||||||
|
NamespaceIndentation: None
|
||||||
|
PointerAlignment: Right
|
||||||
|
ReflowComments: true
|
||||||
|
SortIncludes: false
|
||||||
|
SpaceAfterCStyleCast: false
|
||||||
|
SpaceBeforeAssignmentOperators: true
|
||||||
|
SpaceBeforeCtorInitializerColon: true
|
||||||
|
SpaceBeforeCtorInitializerColon: true
|
||||||
|
SpaceBeforeParens: ControlStatements
|
||||||
|
SpaceBeforeRangeBasedForLoopColon: true
|
||||||
|
SpaceInEmptyParentheses: false
|
||||||
|
SpacesInAngles: false
|
||||||
|
SpacesInCStyleCastParentheses: false
|
||||||
|
SpacesInParentheses: false
|
||||||
|
SpacesInSquareBrackets: false
|
||||||
|
Standard: Cpp11
|
||||||
|
StatementMacros: [
|
||||||
|
'EXTERN_C',
|
||||||
|
'PAGED',
|
||||||
|
'PAGEDX',
|
||||||
|
'NONPAGED',
|
||||||
|
'PNPCODE',
|
||||||
|
'INITCODE',
|
||||||
|
'_At_',
|
||||||
|
'_When_',
|
||||||
|
'_Success_',
|
||||||
|
'_Check_return_',
|
||||||
|
'_Must_inspect_result_',
|
||||||
|
'_IRQL_requires_',
|
||||||
|
'_IRQL_requires_max_',
|
||||||
|
'_IRQL_requires_min_',
|
||||||
|
'_IRQL_saves_',
|
||||||
|
'_IRQL_restores_',
|
||||||
|
'_IRQL_saves_global_',
|
||||||
|
'_IRQL_restores_global_',
|
||||||
|
'_IRQL_raises_',
|
||||||
|
'_IRQL_lowers_',
|
||||||
|
'_Acquires_lock_',
|
||||||
|
'_Releases_lock_',
|
||||||
|
'_Acquires_exclusive_lock_',
|
||||||
|
'_Releases_exclusive_lock_',
|
||||||
|
'_Acquires_shared_lock_',
|
||||||
|
'_Releases_shared_lock_',
|
||||||
|
'_Requires_lock_held_',
|
||||||
|
'_Use_decl_annotations_',
|
||||||
|
'_Guarded_by_',
|
||||||
|
'__drv_preferredFunction',
|
||||||
|
'__drv_allocatesMem',
|
||||||
|
'__drv_freesMem',
|
||||||
|
]
|
||||||
|
TabWidth: '4'
|
||||||
|
UseTab: Never
|
@ -0,0 +1,403 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <fltKernel.h>
|
||||||
|
#include <intrin.h>
|
||||||
|
|
||||||
|
namespace clonestd {
|
||||||
|
// STRUCT TEMPLATE remove_reference
|
||||||
|
template <class _Ty>
|
||||||
|
struct remove_reference
|
||||||
|
{
|
||||||
|
using type = _Ty;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class _Ty>
|
||||||
|
struct remove_reference<_Ty &>
|
||||||
|
{
|
||||||
|
using type = _Ty;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class _Ty>
|
||||||
|
struct remove_reference<_Ty &&>
|
||||||
|
{
|
||||||
|
using type = _Ty;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class _Ty>
|
||||||
|
using remove_reference_t = typename remove_reference<_Ty>::type;
|
||||||
|
|
||||||
|
// STRUCT TEMPLATE remove_const
|
||||||
|
template <class _Ty>
|
||||||
|
struct remove_const
|
||||||
|
{ // remove top-level const qualifier
|
||||||
|
using type = _Ty;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class _Ty>
|
||||||
|
struct remove_const<const _Ty>
|
||||||
|
{
|
||||||
|
using type = _Ty;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class _Ty>
|
||||||
|
using remove_const_t = typename remove_const<_Ty>::type;
|
||||||
|
} // namespace clonestd
|
||||||
|
|
||||||
|
namespace kli {
|
||||||
|
constexpr auto Time = __TIME__;
|
||||||
|
constexpr auto Seed = static_cast<unsigned long long>(Time[7]) + static_cast<unsigned long long>(Time[6]) * 10 +
|
||||||
|
static_cast<unsigned long long>(Time[4]) * 60 + static_cast<unsigned long long>(Time[3]) * 600 +
|
||||||
|
static_cast<unsigned long long>(Time[1]) * 3600 +
|
||||||
|
static_cast<unsigned long long>(Time[0]) * 36000;
|
||||||
|
constexpr auto Seed2 = static_cast<unsigned long long>(Time[7]) + static_cast<unsigned long long>(Time[6]) * 10 +
|
||||||
|
static_cast<unsigned long long>(Time[4]) * 60;
|
||||||
|
constexpr auto Seed3 = static_cast<unsigned long long>(Time[7]) + static_cast<unsigned long long>(Time[5]) * 10 +
|
||||||
|
static_cast<unsigned long long>(Time[2]) * 60;
|
||||||
|
constexpr auto Seed4 = static_cast<unsigned long long>(Time[7]) + static_cast<unsigned long long>(Time[3]) * 10 +
|
||||||
|
static_cast<unsigned long long>(Time[1]) * 60;
|
||||||
|
|
||||||
|
namespace cache {
|
||||||
|
constexpr unsigned long long base_init = Seed3;
|
||||||
|
inline unsigned long long base = base_init;
|
||||||
|
} // namespace cache
|
||||||
|
|
||||||
|
namespace hash {
|
||||||
|
namespace detail {
|
||||||
|
template <typename Size>
|
||||||
|
struct fnv_constants;
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct fnv_constants<unsigned int>
|
||||||
|
{
|
||||||
|
constexpr static unsigned int default_offset_basis = 0x811C9DC5UL;
|
||||||
|
constexpr static unsigned int prime = 0x01000193UL;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct fnv_constants<unsigned long long>
|
||||||
|
{
|
||||||
|
constexpr static unsigned long long default_offset_basis = 0xCBF29CE484222325ULL;
|
||||||
|
constexpr static unsigned long long prime = 0x100000001B3ULL;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
// Dumb hack to force a constexpr value to be evaluated in compiletime
|
||||||
|
template <typename Type, Type Value>
|
||||||
|
struct force_cx
|
||||||
|
{
|
||||||
|
constexpr static auto value = Value;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Type, typename Char>
|
||||||
|
__forceinline constexpr Type
|
||||||
|
hash_fnv1a(const Char *str)
|
||||||
|
{
|
||||||
|
Type val = detail::fnv_constants<Type>::default_offset_basis;
|
||||||
|
|
||||||
|
// random
|
||||||
|
val += Seed;
|
||||||
|
|
||||||
|
for (; *str != static_cast<Char>(0); ++str)
|
||||||
|
{
|
||||||
|
Char c = *str;
|
||||||
|
val ^= static_cast<Type>(c);
|
||||||
|
val *= static_cast<Type>(detail::fnv_constants<Type>::prime);
|
||||||
|
}
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define KLI_HASH_RTS(str) \
|
||||||
|
(::kli::hash:: \
|
||||||
|
hash_fnv1a<unsigned long long, clonestd::remove_const_t<clonestd::remove_reference_t<decltype(*(str))>>>( \
|
||||||
|
(str)))
|
||||||
|
|
||||||
|
#define KLI_HASH_STR(str) \
|
||||||
|
(::kli::hash::force_cx< \
|
||||||
|
unsigned long long, \
|
||||||
|
::kli::hash:: \
|
||||||
|
hash_fnv1a<unsigned long long, clonestd::remove_const_t<clonestd::remove_reference_t<decltype(*(str))>>>( \
|
||||||
|
(str))>::value)
|
||||||
|
|
||||||
|
} // namespace hash
|
||||||
|
|
||||||
|
namespace crypto {
|
||||||
|
typedef struct s_rc4_state
|
||||||
|
{
|
||||||
|
int x, y;
|
||||||
|
unsigned char m[256];
|
||||||
|
} rc4_state;
|
||||||
|
|
||||||
|
__forceinline void
|
||||||
|
rc4_init_key(rc4_state *s, unsigned char *key, int length)
|
||||||
|
{
|
||||||
|
int i, j, k, a;
|
||||||
|
|
||||||
|
unsigned char *m;
|
||||||
|
|
||||||
|
s->x = 0;
|
||||||
|
s->y = 0;
|
||||||
|
m = s->m;
|
||||||
|
|
||||||
|
for (i = 0; i < 256; i++)
|
||||||
|
{
|
||||||
|
m[i] = (unsigned char)i;
|
||||||
|
}
|
||||||
|
|
||||||
|
j = k = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < 256; i++)
|
||||||
|
{
|
||||||
|
a = m[i];
|
||||||
|
j = (unsigned char)(j + a + key[k]);
|
||||||
|
m[i] = m[j];
|
||||||
|
m[j] = (unsigned char)a;
|
||||||
|
if (++k >= length)
|
||||||
|
k = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__forceinline void
|
||||||
|
rc4_crypt(rc4_state *s, unsigned char *data, int length)
|
||||||
|
{
|
||||||
|
int i, x, y, a, b;
|
||||||
|
|
||||||
|
unsigned char *m;
|
||||||
|
|
||||||
|
x = s->x;
|
||||||
|
y = s->y;
|
||||||
|
m = s->m;
|
||||||
|
|
||||||
|
for (i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
x = (unsigned char)(x + 1);
|
||||||
|
a = m[x];
|
||||||
|
y = (unsigned char)(y + a);
|
||||||
|
m[x] = b = m[y];
|
||||||
|
m[y] = (unsigned char)a;
|
||||||
|
data[i] ^= m[(unsigned char)(a + b)];
|
||||||
|
}
|
||||||
|
|
||||||
|
s->x = x;
|
||||||
|
s->y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
__forceinline void
|
||||||
|
rc4_crypt_all_in_once(unsigned char *key_buff, unsigned long key_len, unsigned char *enc_buff, unsigned long enc_len)
|
||||||
|
{
|
||||||
|
rc4_state state;
|
||||||
|
rc4_init_key(&state, key_buff, key_len);
|
||||||
|
rc4_crypt(&state, enc_buff, enc_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Type>
|
||||||
|
__forceinline Type
|
||||||
|
RC4Base(Type Ptr)
|
||||||
|
{
|
||||||
|
unsigned long long rc4_key = Seed2;
|
||||||
|
unsigned long long rc4_data = Seed4;
|
||||||
|
crypto::rc4_crypt_all_in_once(
|
||||||
|
(unsigned char *)(&rc4_key), sizeof(rc4_key), (unsigned char *)(&rc4_data), sizeof(rc4_data));
|
||||||
|
return (Type)((unsigned long long)Ptr ^ rc4_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Type>
|
||||||
|
__forceinline Type
|
||||||
|
RC4Func(Type Ptr)
|
||||||
|
{
|
||||||
|
unsigned long long rc4_key = Seed4;
|
||||||
|
unsigned long long rc4_data = Seed2;
|
||||||
|
crypto::rc4_crypt_all_in_once(
|
||||||
|
(unsigned char *)(&rc4_key), sizeof(rc4_key), (unsigned char *)(&rc4_data), sizeof(rc4_data));
|
||||||
|
return (Type)((unsigned long long)Ptr ^ rc4_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace crypto
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
typedef struct _IMAGE_DOS_HEADER
|
||||||
|
{ // DOS .EXE header
|
||||||
|
unsigned short e_magic; // Magic number
|
||||||
|
unsigned short e_cblp; // Bytes on last page of file
|
||||||
|
unsigned short e_cp; // Pages in file
|
||||||
|
unsigned short e_crlc; // Relocations
|
||||||
|
unsigned short e_cparhdr; // GetSize of header in paragraphs
|
||||||
|
unsigned short e_minalloc; // Minimum extra paragraphs needed
|
||||||
|
unsigned short e_maxalloc; // Maximum extra paragraphs needed
|
||||||
|
unsigned short e_ss; // Initial (relative) SS value
|
||||||
|
unsigned short e_sp; // Initial SP value
|
||||||
|
unsigned short e_csum; // Checksum
|
||||||
|
unsigned short e_ip; // Initial IP value
|
||||||
|
unsigned short e_cs; // Initial (relative) CS value
|
||||||
|
unsigned short e_lfarlc; // File address of relocation table
|
||||||
|
unsigned short e_ovno; // Overlay number
|
||||||
|
unsigned short e_res[4]; // Reserved words
|
||||||
|
unsigned short e_oemid; // OEM identifier (for e_oeminfo)
|
||||||
|
unsigned short e_oeminfo; // OEM information; e_oemid specific
|
||||||
|
unsigned short e_res2[10]; // Reserved words
|
||||||
|
int e_lfanew; // File address of new exe header
|
||||||
|
} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
|
||||||
|
|
||||||
|
typedef struct _IMAGE_FILE_HEADER
|
||||||
|
{
|
||||||
|
unsigned short Machine;
|
||||||
|
unsigned short NumberOfSections;
|
||||||
|
unsigned int TimeDateStamp;
|
||||||
|
unsigned int PointerToSymbolTable;
|
||||||
|
unsigned int NumberOfSymbols;
|
||||||
|
unsigned short SizeOfOptionalHeader;
|
||||||
|
unsigned short Characteristics;
|
||||||
|
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
|
||||||
|
|
||||||
|
typedef struct _IMAGE_DATA_DIRECTORY
|
||||||
|
{
|
||||||
|
unsigned int VirtualAddress;
|
||||||
|
unsigned int Size;
|
||||||
|
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
|
||||||
|
|
||||||
|
typedef struct _IMAGE_OPTIONAL_HEADER64
|
||||||
|
{
|
||||||
|
unsigned short Magic;
|
||||||
|
unsigned char MajorLinkerVersion;
|
||||||
|
unsigned char MinorLinkerVersion;
|
||||||
|
unsigned int SizeOfCode;
|
||||||
|
unsigned int SizeOfInitializedData;
|
||||||
|
unsigned int SizeOfUninitializedData;
|
||||||
|
unsigned int AddressOfEntryPoint;
|
||||||
|
unsigned int BaseOfCode;
|
||||||
|
unsigned long long ImageBase;
|
||||||
|
unsigned int SectionAlignment;
|
||||||
|
unsigned int FileAlignment;
|
||||||
|
unsigned short MajorOperatingSystemVersion;
|
||||||
|
unsigned short MinorOperatingSystemVersion;
|
||||||
|
unsigned short MajorImageVersion;
|
||||||
|
unsigned short MinorImageVersion;
|
||||||
|
unsigned short MajorSubsystemVersion;
|
||||||
|
unsigned short MinorSubsystemVersion;
|
||||||
|
unsigned int Win32VersionValue;
|
||||||
|
unsigned int SizeOfImage;
|
||||||
|
unsigned int SizeOfHeaders;
|
||||||
|
unsigned int CheckSum;
|
||||||
|
unsigned short Subsystem;
|
||||||
|
unsigned short DllCharacteristics;
|
||||||
|
unsigned long long SizeOfStackReserve;
|
||||||
|
unsigned long long SizeOfStackCommit;
|
||||||
|
unsigned long long SizeOfHeapReserve;
|
||||||
|
unsigned long long SizeOfHeapCommit;
|
||||||
|
unsigned int LoaderFlags;
|
||||||
|
unsigned int NumberOfRvaAndSizes;
|
||||||
|
IMAGE_DATA_DIRECTORY DataDirectory[16];
|
||||||
|
} IMAGE_OPTIONAL_HEADER64, *PIMAGE_OPTIONAL_HEADER64;
|
||||||
|
|
||||||
|
typedef struct _IMAGE_NT_HEADERS64
|
||||||
|
{
|
||||||
|
unsigned int Signature;
|
||||||
|
IMAGE_FILE_HEADER FileHeader;
|
||||||
|
IMAGE_OPTIONAL_HEADER64 OptionalHeader;
|
||||||
|
} IMAGE_NT_HEADERS64, *PIMAGE_NT_HEADERS64;
|
||||||
|
|
||||||
|
typedef struct _IMAGE_EXPORT_DIRECTORY
|
||||||
|
{
|
||||||
|
unsigned int Characteristics;
|
||||||
|
unsigned int TimeDateStamp;
|
||||||
|
unsigned short MajorVersion;
|
||||||
|
unsigned short MinorVersion;
|
||||||
|
unsigned int Name;
|
||||||
|
unsigned int Base;
|
||||||
|
unsigned int NumberOfFunctions;
|
||||||
|
unsigned int NumberOfNames;
|
||||||
|
unsigned int AddressOfFunctions; // RVA from base of image
|
||||||
|
unsigned int AddressOfNames; // RVA from base of image
|
||||||
|
unsigned int AddressOfNameOrdinals; // RVA from base of image
|
||||||
|
} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;
|
||||||
|
|
||||||
|
__declspec(naked) __forceinline unsigned long long get_kernel_base()
|
||||||
|
{
|
||||||
|
_asm {
|
||||||
|
mov rax, qword ptr gs:[18h]
|
||||||
|
mov rcx, [rax+38h]
|
||||||
|
mov rax, 0FFFFFFFFFFFFF000h
|
||||||
|
and rax, [rcx+4h]
|
||||||
|
jmp while_begin
|
||||||
|
search_begin:
|
||||||
|
add rax, 0FFFFFFFFFFFFF000h
|
||||||
|
while_begin:
|
||||||
|
xor ecx, ecx
|
||||||
|
jmp search_cmp
|
||||||
|
search_next:
|
||||||
|
add rcx, 1
|
||||||
|
cmp rcx, 0FF9h
|
||||||
|
jz search_begin
|
||||||
|
search_cmp:
|
||||||
|
cmp byte ptr[rax+rcx], 48h
|
||||||
|
jnz search_next
|
||||||
|
cmp byte ptr[rax+rcx+1], 8Dh
|
||||||
|
jnz search_next
|
||||||
|
cmp byte ptr[rax+rcx+2], 1Dh
|
||||||
|
jnz search_next
|
||||||
|
cmp byte ptr[rax+rcx+6], 0FFh
|
||||||
|
jnz search_next
|
||||||
|
mov r8d,[rax+rcx+3]
|
||||||
|
lea edx,[rcx+r8]
|
||||||
|
add edx, eax
|
||||||
|
add edx, 7
|
||||||
|
test edx, 0FFFh
|
||||||
|
jnz search_next
|
||||||
|
mov rdx, 0FFFFFFFF00000000h
|
||||||
|
and rdx, rax
|
||||||
|
add r8d, eax
|
||||||
|
lea eax,[rcx+r8]
|
||||||
|
add eax, 7
|
||||||
|
or rax, rdx
|
||||||
|
ret
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
__forceinline unsigned long long
|
||||||
|
find_kernel_export(unsigned long long export_hash)
|
||||||
|
{
|
||||||
|
if (cache::base == cache::base_init)
|
||||||
|
{
|
||||||
|
cache::base = crypto::RC4Base(detail::get_kernel_base());
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto dos_header = (detail::PIMAGE_DOS_HEADER)crypto::RC4Base(cache::base);
|
||||||
|
const auto nt_headers = (detail::PIMAGE_NT_HEADERS64)(crypto::RC4Base(cache::base) + dos_header->e_lfanew);
|
||||||
|
const auto export_directory = (detail::PIMAGE_EXPORT_DIRECTORY)(
|
||||||
|
crypto::RC4Base(cache::base) + nt_headers->OptionalHeader.DataDirectory[0].VirtualAddress);
|
||||||
|
|
||||||
|
const auto address_of_functions =
|
||||||
|
(unsigned int *)(crypto::RC4Base(cache::base) + export_directory->AddressOfFunctions);
|
||||||
|
const auto address_of_names = (unsigned int *)(crypto::RC4Base(cache::base) + export_directory->AddressOfNames);
|
||||||
|
const auto address_of_name_ordinals =
|
||||||
|
(unsigned short *)(crypto::RC4Base(cache::base) + export_directory->AddressOfNameOrdinals);
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < export_directory->NumberOfNames; ++i)
|
||||||
|
{
|
||||||
|
const auto export_entry_name = (char *)(crypto::RC4Base(cache::base) + address_of_names[i]);
|
||||||
|
const auto export_entry_hash = KLI_HASH_RTS(export_entry_name);
|
||||||
|
|
||||||
|
// address_of_functions is indexed through an ordinal
|
||||||
|
// address_of_name_ordinals gets the ordinal through our own index - i.
|
||||||
|
if (export_entry_hash == export_hash)
|
||||||
|
{
|
||||||
|
auto func = crypto::RC4Base(cache::base) + address_of_functions[address_of_name_ordinals[i]];
|
||||||
|
return crypto::RC4Func(func);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0ULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// once
|
||||||
|
#define KLI_CALL(name, ...) \
|
||||||
|
((decltype(&name))(kli::crypto::RC4Func(kli::find_kernel_export(KLI_HASH_STR(#name)))))(__VA_ARGS__)
|
||||||
|
|
||||||
|
// cached
|
||||||
|
#define KLI_CACHED_DEF(name) decltype(&name) KLI##name = nullptr
|
||||||
|
#define KLI_CACHED_SET(name) KLI##name = (decltype(&name))(kli::find_kernel_export(KLI_HASH_STR(#name)))
|
||||||
|
#define KLI_CACHED_CALL(name, ...) ((decltype(&name))(kli::crypto::RC4Func(KLI##name)))(__VA_ARGS__)
|
||||||
|
|
||||||
|
} // namespace kli
|
@ -0,0 +1,12 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "../kli.hpp"
|
||||||
|
|
||||||
|
KLI_CACHED_DEF(ExAllocatePoolWithTag);
|
||||||
|
KLI_CACHED_DEF(ExFreePoolWithTag);
|
||||||
|
|
||||||
|
__forceinline void
|
||||||
|
IATInitCached()
|
||||||
|
{
|
||||||
|
KLI_CACHED_SET(ExAllocatePoolWithTag);
|
||||||
|
KLI_CACHED_SET(ExFreePoolWithTag);
|
||||||
|
}
|
@ -0,0 +1,69 @@
|
|||||||
|
#include "IAT.cached.h"
|
||||||
|
|
||||||
|
#define dprintf(...) DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, __VA_ARGS__)
|
||||||
|
|
||||||
|
void
|
||||||
|
DriverUnload(PDRIVER_OBJECT DriverObject)
|
||||||
|
{
|
||||||
|
UNREFERENCED_PARAMETER(DriverObject);
|
||||||
|
dprintf("exit world\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
DECLSPEC_NOINLINE
|
||||||
|
void
|
||||||
|
test_once()
|
||||||
|
{
|
||||||
|
auto pExAllocatePoolWithTag = KLI_CALL(ExAllocatePoolWithTag, NonPagedPool, PAGE_SIZE, 'enoN');
|
||||||
|
if (pExAllocatePoolWithTag)
|
||||||
|
{
|
||||||
|
dprintf("test_once:ExAllocatePoolWithTag=%p\n", pExAllocatePoolWithTag);
|
||||||
|
KLI_CALL(ExFreePoolWithTag, pExAllocatePoolWithTag, 'enoN');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DECLSPEC_NOINLINE
|
||||||
|
void
|
||||||
|
test_cached_init()
|
||||||
|
{
|
||||||
|
// Make cache
|
||||||
|
IATInitCached();
|
||||||
|
}
|
||||||
|
|
||||||
|
DECLSPEC_NOINLINE
|
||||||
|
void
|
||||||
|
test_cached()
|
||||||
|
{
|
||||||
|
auto pAddr = KLI_CACHED_CALL(ExAllocatePoolWithTag, NonPagedPool, PAGE_SIZE, 'x1x1');
|
||||||
|
if (pAddr)
|
||||||
|
{
|
||||||
|
dprintf("test_cached:pAddr=%p\n", pAddr);
|
||||||
|
KLI_CACHED_CALL(ExFreePoolWithTag, pAddr, 'x1x1');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DECLSPEC_NOINLINE
|
||||||
|
void
|
||||||
|
test_cached2()
|
||||||
|
{
|
||||||
|
auto pAddr = KLI_CACHED_CALL(ExAllocatePoolWithTag, NonPagedPool, PAGE_SIZE, 'xxxx');
|
||||||
|
if (pAddr)
|
||||||
|
{
|
||||||
|
dprintf("test_cached2:pAddr=%p\n", pAddr);
|
||||||
|
KLI_CACHED_CALL(ExFreePoolWithTag, pAddr, 'xxxx');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
|
||||||
|
{
|
||||||
|
dprintf("new world\n");
|
||||||
|
DriverObject->DriverUnload = DriverUnload;
|
||||||
|
|
||||||
|
test_once();
|
||||||
|
|
||||||
|
test_cached_init();
|
||||||
|
test_cached();
|
||||||
|
test_cached2();
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="Source.cpp" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="..\kli.hpp" />
|
||||||
|
<ClInclude Include="IAT.cached.h" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
Loading…
Reference in new issue