mirror of
https://github.com/Cracked5pider/LdrLibraryEx
synced 2026-06-06 15:34:27 +00:00
init commit
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
##
|
||||
## this file can be ignored
|
||||
##
|
||||
|
||||
cmake_minimum_required( VERSION 3.25 )
|
||||
project( LdrLibraryEx C )
|
||||
|
||||
set( CMAKE_C_STANDARD 11 )
|
||||
set( CMAKE_C_COMPILER x86_64-w64-mingw32-gcc )
|
||||
|
||||
include_directories( include )
|
||||
|
||||
# source code files
|
||||
set( SOURCE
|
||||
src/LdrLibraryEx.c
|
||||
|
||||
tests/TestCryptsp.c
|
||||
tests/TestCryptspEx.c
|
||||
tests/TestRundll32Exe.c
|
||||
tests/TestCryptspMemory.c
|
||||
tests/TestApiSet.c
|
||||
)
|
||||
|
||||
add_compile_definitions( LIBRARYEX_TEST )
|
||||
|
||||
add_executable( LdrLibraryEx ${SOURCE} )
|
||||
@@ -0,0 +1,166 @@
|
||||
|
||||
# LdrLibraryEx
|
||||
|
||||
A small x64 library to load dll's into memory.
|
||||
|
||||
### Features
|
||||
- low dependencies & function use (only ntdll.dll used)
|
||||
- position independent code
|
||||
- lightweight and minimal
|
||||
- easy to use
|
||||
- load modules from memory
|
||||
- load modules from disk
|
||||
- api sets support
|
||||
- bypass image load callbacks (using private memory)
|
||||
- support for images with delayed import, tls, seh, etc.
|
||||
|
||||
### Documentation
|
||||
|
||||
#### Library Flags
|
||||
|
||||
Flags can be combined
|
||||
|
||||
`LIBRARYEX_NONE`: Map module from disk into memory and execute entrypoint.
|
||||
|
||||
`LIBRARYEX_BYPASS_LOAD_CALLBACK`: Map module from disk into private memory (unbacked) which bypasses image load callbacks (`PsSetLoadImageNotifyRoutine`)
|
||||
|
||||
`LIBRARYEX_NO_ENTRY`: Do not execute the entrypoint of the module.
|
||||
|
||||
`LIBRARYEX_BUFFER`: Map the module from memory instead from disk.
|
||||
|
||||
#### Function: `LdrLibrary` and `LdrLibraryFree`
|
||||
Easy to use function to load a library into memory. The first param, based on what flags has been specified, can be either a wide string module name to load or memory address where the PE is located at.
|
||||
|
||||
```c
|
||||
/*!
|
||||
* @brief
|
||||
* load library into memory
|
||||
*
|
||||
* @param Buffer
|
||||
* buffer context to load library
|
||||
* either a wide string or a buffer pointer
|
||||
* the to PE file to map (LIBRARYEX_BUFFER)
|
||||
*
|
||||
* @param Library
|
||||
* loaded library pointer
|
||||
*
|
||||
* @param Flags
|
||||
* flags
|
||||
*
|
||||
* @return
|
||||
* status of function
|
||||
*/
|
||||
NTSTATUS LdrLibrary(
|
||||
_In_ PVOID Buffer,
|
||||
_Out_ PVOID* Library,
|
||||
_In_ ULONG Flags
|
||||
);
|
||||
```
|
||||
|
||||
This example shows how to load a module from disk (from the System32 path):
|
||||
```c
|
||||
PVOID Module = { 0 };
|
||||
ULONG Flags = { 0 };
|
||||
|
||||
//
|
||||
// mapping flags to be used by the library
|
||||
//
|
||||
Flags = LIBRARYEX_NONE;
|
||||
|
||||
//
|
||||
// map file into memory
|
||||
//
|
||||
if ( ! NT_SUCCESS( Status = LdrLibrary( L"advapi32.dll", &Module, Flags ) ) ) {
|
||||
printf( "[-] LdrLibraryEx Failed: %p\n", Status );
|
||||
return;
|
||||
}
|
||||
|
||||
printf( "[*] Module @ %p\n", Module );
|
||||
```
|
||||
|
||||
This examples shows how to load a module from a memory buffer:
|
||||
```c
|
||||
PVOID Module = { 0 };
|
||||
ULONG Flags = { 0 };
|
||||
|
||||
//
|
||||
// mapping flags to be used by the library
|
||||
//
|
||||
Flags = LIBRARYEX_NONE |
|
||||
LIBRARYEX_BUFFER;
|
||||
|
||||
//
|
||||
// read file on disk into memory
|
||||
//
|
||||
if ( ! ( Image = ReadFileBuffer( L"C:\\Windows\\System32\\advapi32.dll", NULL ) ) ) {
|
||||
puts( "[-] ReadFileBuffer Failed" );
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// map file into memory
|
||||
//
|
||||
if ( ! NT_SUCCESS( Status = LdrLibrary( Image, &Module, Flags ) ) ) {
|
||||
printf( "[-] LdrLibraryEx Failed: %p\n", Status );
|
||||
return;
|
||||
}
|
||||
|
||||
printf( "[*] Module @ %p\n", Module );
|
||||
```
|
||||
|
||||
It is also possible to load modules based on their api set (win10+ support only):
|
||||
```c
|
||||
//
|
||||
// map file into memory
|
||||
//
|
||||
if ( ! NT_SUCCESS( Status = LdrLibrary( L"api-ms-win-base-util-l1-1-0.dll", &Module, Flags ) ) ) {
|
||||
printf( "[-] LdrLibraryEx Failed: %p\n", Status );
|
||||
return;
|
||||
}
|
||||
|
||||
printf( "[*] Module @ %p\n", );
|
||||
```
|
||||
|
||||
#### Function: `LdrLibraryEx`
|
||||
LdrLibraryEx allows to hook certain functions to modify the behaviour of how a library should be mapped into memory.
|
||||
```c
|
||||
//
|
||||
// mapping flags to be used by the library
|
||||
// and insert the loaded module into Peb
|
||||
//
|
||||
Flags = LIBRARYEX_BYPASS_LOAD_CALLBACK |
|
||||
LIBRARYEX_NO_ENTRY;
|
||||
|
||||
//
|
||||
// init LibraryEx context
|
||||
//
|
||||
if ( ! NT_SUCCESS( Status = LdrLibraryCtx( &Ctx, Flags ) ) ) {
|
||||
printf( "[-] LdrLibraryCtx Failed: %d\n", Status );
|
||||
goto END;
|
||||
}
|
||||
|
||||
//
|
||||
// hook function
|
||||
//
|
||||
Ctx.LdrLoadDll = C_PTR( HookLdrLoadDll );
|
||||
|
||||
//
|
||||
// map file into memory
|
||||
//
|
||||
if ( ! NT_SUCCESS( Status = LdrLibraryEx( &Ctx, L"cryptsp.dll", &Module, Flags ) ) ) {
|
||||
printf( "[-] LdrLibraryEx Failed: %p\n", Status );
|
||||
return;
|
||||
}
|
||||
```
|
||||
|
||||
### Note
|
||||
This codebase is written and optimized for x86_64-mingw and it most likely not going to work and or compile under Visual Studio.
|
||||
|
||||
## Credits
|
||||
Huge credit goes out to following resources and projects:
|
||||
- [DarkLoadLibrary](https://github.com/bats3c/DarkLoadLibrary)
|
||||
- [MDSec: Bypassing Image loader kernel callbacks](https://www.mdsec.co.uk/2021/06/bypassing-image-load-kernel-callbacks/)
|
||||
- [ReactOS LdrLoadDll](https://doxygen.reactos.org/d7/d55/ldrapi_8c.html#a7671bda932dbb5096570f431ff83474c)
|
||||
- [Vergilius Project](https://www.vergiliusproject.com/)
|
||||
|
||||
this project shouldn't be used in a real world env or operation. I mainly wrote this to understand and learn more about how windows loader works. I wrote it as a library because I wanted to use this for other type of public and private projects. I achieved my goal. Cya.
|
||||
@@ -0,0 +1,377 @@
|
||||
#ifndef LDRLIBRARYEX_LDRLIBRARYEX_H
|
||||
#define LDRLIBRARYEX_LDRLIBRARYEX_H
|
||||
|
||||
#include <Native.h>
|
||||
#include <windows.h>
|
||||
|
||||
//
|
||||
// LdrLibraryEx Flags
|
||||
//
|
||||
#define LIBRARYEX_NONE 0b00000000 // just load it into memory and execute it
|
||||
#define LIBRARYEX_RESERVED0 0b00000001 // reserved 0
|
||||
#define LIBRARYEX_BYPASS_LOAD_CALLBACK 0b00000010 // bypass image load callbacks by allocating the module in a virtual private memory
|
||||
#define LIBRARYEX_RESERVED1 0b00000100 // reserved 1
|
||||
#define LIBRARYEX_NO_ENTRY 0b00001000 // do not execute the entrypoint
|
||||
#define LIBRARYEX_BUFFER 0b00010000 // load image from memory/buffer
|
||||
#define LIBRARYEX_RESERVED2 0b00100000 // reserved 2
|
||||
|
||||
//
|
||||
// LdrLibraryEx defines and macros
|
||||
//
|
||||
#define C_PTR( x ) ( ( PVOID ) x )
|
||||
#define U_PTR( x ) ( ( ULONG_PTR ) x )
|
||||
#define U_PTR32( x ) ( ( ULONG32 ) x )
|
||||
#define U_PTR64( x ) ( ( ULONG64 ) x )
|
||||
#define C_DEF64( x ) ( *( ULONG64* ) x )
|
||||
#define C_DEF32( x ) ( *( ULONG32* ) x )
|
||||
|
||||
#define LdrFunction( m, f ) LdrFunctionEx( m, ( ( LPSTR ) f ), FALSE )
|
||||
#define WIN32_FUNC( x ) __typeof__( x ) * x;
|
||||
#define MemCopy __builtin_memcpy
|
||||
#define MemSet __stosb
|
||||
#define MemZero( b, s ) MemSet( ( PUCHAR ) b, 0, s )
|
||||
|
||||
//
|
||||
// Context
|
||||
//
|
||||
typedef struct _LIBRARYEX_CTX {
|
||||
|
||||
/* Nt functions */
|
||||
WIN32_FUNC( NtOpenFile )
|
||||
WIN32_FUNC( NtReadFile )
|
||||
WIN32_FUNC( NtQueryInformationFile )
|
||||
WIN32_FUNC( NtCreateSection )
|
||||
WIN32_FUNC( NtMapViewOfSection )
|
||||
WIN32_FUNC( NtUnmapViewOfSection )
|
||||
WIN32_FUNC( NtAllocateVirtualMemory )
|
||||
WIN32_FUNC( NtFreeVirtualMemory )
|
||||
WIN32_FUNC( NtProtectVirtualMemory )
|
||||
WIN32_FUNC( NtFlushInstructionCache )
|
||||
WIN32_FUNC( NtClose )
|
||||
|
||||
/* Ldr functions */
|
||||
WIN32_FUNC( LdrGetProcedureAddress )
|
||||
WIN32_FUNC( LdrLoadDll )
|
||||
|
||||
/* Rlt functions */
|
||||
WIN32_FUNC( RtlAddFunctionTable )
|
||||
|
||||
} LIBRARYEX_CTX, *PLIBRARYEX_CTX;
|
||||
|
||||
|
||||
//
|
||||
// Public LdrLibraryEx Functions
|
||||
//
|
||||
NTSTATUS LdrLibrary(
|
||||
_In_ PVOID Buffer,
|
||||
_Out_ PVOID* Library,
|
||||
_In_ ULONG Flags
|
||||
);
|
||||
|
||||
NTSTATUS LdrLibraryCtx(
|
||||
_Out_ PLIBRARYEX_CTX Ctx,
|
||||
_In_ ULONG Flags
|
||||
);
|
||||
|
||||
NTSTATUS LdrLibraryEx(
|
||||
_In_ PLIBRARYEX_CTX Ctx,
|
||||
_In_ PVOID Buffer,
|
||||
_Out_ PVOID* Library,
|
||||
_In_ ULONG Flags
|
||||
);
|
||||
|
||||
PVOID LdrModulePeb(
|
||||
_In_ PVOID Buffer,
|
||||
_In_ BOOL Hashed
|
||||
);
|
||||
|
||||
ULONG LdrHashString(
|
||||
_In_ PVOID String,
|
||||
_In_ ULONG Length
|
||||
);
|
||||
|
||||
PVOID LdrFunctionEx(
|
||||
_In_ PVOID Library,
|
||||
_In_ PVOID Function,
|
||||
_In_ BOOL Hashed
|
||||
);
|
||||
|
||||
//
|
||||
// Private LdrLibraryEx Functions
|
||||
//
|
||||
#ifdef LIBRARYEX_PRIVATE
|
||||
|
||||
#define H_MAGIC_KEY 5381
|
||||
|
||||
/* modules */
|
||||
#define H_MODULE_NTDLL 0x70e61753
|
||||
|
||||
/* apis */
|
||||
#define H_API_NTOPENFILE 0x46dde739
|
||||
#define H_API_NTREADFILE 0xb2d93203
|
||||
#define H_API_NTQUERYINFORMATIONFILE 0xc25ebe23
|
||||
#define H_API_NTQUERYSYSTEMTIME 0x4d80f0d1
|
||||
#define H_API_NTCREATESECTION 0xb80f7b50
|
||||
#define H_API_NTMAPVIEWOFSECTION 0xd6649bca
|
||||
#define H_API_NTUNMAPVIEWOFSECTION 0x6aa412cd
|
||||
#define H_API_NTALLOCATEVIRTUALMEMORY 0xf783b8ec
|
||||
#define H_API_NTFREEVIRTUALMEMORY 0x2802c609
|
||||
#define H_API_NTPROTECTVIRTUALMEMORY 0x50e92888
|
||||
#define H_API_NTFLUSHINSTRUCTIONCACHE 0x6269b87f
|
||||
#define H_API_NTCLOSE 0x40d6e69d
|
||||
#define H_API_LDRGETPROCEDUREADDRESS 0xfce76bb6
|
||||
#define H_API_LDRLOADDLL 0x9e456a43
|
||||
#define H_API_RTLALLOCATEHEAP 0x3be94c5a
|
||||
#define H_API_RTLFREEHEAP 0x73a9e4d7
|
||||
#define H_API_RTLADDFUNCTIONTABLE 0x81a887ce
|
||||
|
||||
//
|
||||
// some defines
|
||||
//
|
||||
#define HASH_STRING_ALGORITHM_DEFAULT 0
|
||||
#define HASH_STRING_ALGORITHM_X65599 1
|
||||
#define HASH_STRING_ALGORITHM_INVALID 0xffffffff
|
||||
|
||||
//
|
||||
// structs
|
||||
//
|
||||
typedef struct
|
||||
{
|
||||
WORD Offset : 0xc;
|
||||
WORD Type : 0x4;
|
||||
} IMAGE_RELOC, *PIMAGE_RELOC;
|
||||
|
||||
typedef BOOLEAN ( * DLL_ENTRY ) (
|
||||
_In_ PVOID,
|
||||
_In_ ULONG,
|
||||
_Inout_opt_ PVOID
|
||||
);
|
||||
|
||||
typedef FILE_STANDARD_INFORMATION FILE_STD_INFO;
|
||||
typedef PIMAGE_SECTION_HEADER PIMG_SEC_HDR;
|
||||
|
||||
PIMAGE_NT_HEADERS LdrpImageHeader(
|
||||
_In_ PVOID Image
|
||||
);
|
||||
|
||||
NTSTATUS LdrpLibraryMap(
|
||||
_In_ PLIBRARYEX_CTX Ctx,
|
||||
_In_ PVOID Buffer,
|
||||
_In_ ULONG Flags,
|
||||
_Out_ PVOID* Module
|
||||
);
|
||||
|
||||
NTSTATUS LdrpImageSanityCheck(
|
||||
_In_ PVOID Hdr
|
||||
);
|
||||
|
||||
NTSTATUS LdrpProcessImg(
|
||||
_In_ PLIBRARYEX_CTX Ctx,
|
||||
_In_ PVOID Image,
|
||||
_In_ ULONG Flags
|
||||
);
|
||||
|
||||
NTSTATUS LdrpProcessSec(
|
||||
_In_ PLIBRARYEX_CTX Ctx,
|
||||
_In_ PVOID Image,
|
||||
_In_ BOOL Restore
|
||||
);
|
||||
|
||||
NTSTATUS LdrpProcessIat(
|
||||
_In_ PLIBRARYEX_CTX Ctx,
|
||||
_In_ PVOID Image,
|
||||
_In_ PVOID Dir
|
||||
);
|
||||
|
||||
NTSTATUS LdrpProcessDly(
|
||||
_In_ PLIBRARYEX_CTX Ctx,
|
||||
_In_ PVOID Image,
|
||||
_In_ PVOID Dir
|
||||
);
|
||||
|
||||
NTSTATUS LdrpProcessTls(
|
||||
_In_ PVOID Image,
|
||||
_In_ PVOID Dir
|
||||
);
|
||||
|
||||
VOID LdrpProcessRel(
|
||||
_In_ PVOID Image,
|
||||
_In_ ULONG ImageSize,
|
||||
_In_ PVOID Base,
|
||||
_In_ PVOID Dir,
|
||||
_In_ ULONG DirSize
|
||||
);
|
||||
|
||||
NTSTATUS LdrpProcessSeh(
|
||||
_In_ PLIBRARYEX_CTX Ctx,
|
||||
_In_ PVOID Img,
|
||||
_In_ PVOID Dir
|
||||
);
|
||||
|
||||
BOOL LdrpCheckApiSet(
|
||||
_In_ PWSTR Name
|
||||
);
|
||||
|
||||
NTSTATUS LdrpResolveApiSet(
|
||||
_In_ PWSTR ApiSetName,
|
||||
_In_ PWSTR* ApiSetRes,
|
||||
_Out_ PULONG ResSize
|
||||
);
|
||||
|
||||
ULONG LdrpInitNtSys32Path(
|
||||
_In_ LPWSTR Name,
|
||||
_Out_ LPWSTR Path
|
||||
);
|
||||
|
||||
ULONG LdrpSanityCheckNtPath(
|
||||
_In_ LPWSTR Path,
|
||||
_Out_ LPWSTR Sanitised
|
||||
);
|
||||
|
||||
//
|
||||
// Util functions
|
||||
//
|
||||
|
||||
SIZE_T LdrpUtilStrLenA(
|
||||
_In_ PCSTR String
|
||||
);
|
||||
|
||||
SIZE_T LdrpUtilStrLenW(
|
||||
_In_ PCWSTR String
|
||||
);
|
||||
|
||||
SIZE_T LdrpUtilStrCmpW(
|
||||
_In_ LPCWSTR String1,
|
||||
_In_ LPCWSTR String2
|
||||
);
|
||||
|
||||
SIZE_T LdrpUtilStrCmpExW(
|
||||
_In_ PWSTR String1,
|
||||
_In_ PWSTR String2,
|
||||
_In_ ULONG Size
|
||||
);
|
||||
|
||||
SIZE_T LdrpUtilAnsiToUnicode(
|
||||
_Out_ PWCHAR Destination,
|
||||
_In_ PCHAR Source,
|
||||
_In_ SIZE_T MaximumAllowed
|
||||
);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef LIBRARYEX_DEBUG
|
||||
|
||||
#include <stdio.h>
|
||||
#define dprintf( f, ... ) printf( "[%s:%04d] " f, __FUNCTION__, __LINE__, __VA_ARGS__ )
|
||||
|
||||
#else
|
||||
|
||||
#define dprintf( f, ... ) { ; }
|
||||
|
||||
#endif
|
||||
|
||||
typedef struct _API_SET_VALUE_ENTRY_V6
|
||||
{
|
||||
ULONG Flags;
|
||||
ULONG NameOffset;
|
||||
ULONG NameLength;
|
||||
ULONG ValueOffset;
|
||||
ULONG ValueLength;
|
||||
} API_SET_VALUE_ENTRY_V6, *PAPI_SET_VALUE_ENTRY_V6;
|
||||
|
||||
typedef struct _API_SET_NAMESPACE_HASH_ENTRY_V6
|
||||
{
|
||||
ULONG Hash;
|
||||
ULONG Index;
|
||||
} API_SET_NAMESPACE_HASH_ENTRY_V6, *PAPI_SET_NAMESPACE_HASH_ENTRY_V6;
|
||||
|
||||
typedef struct _API_SET_NAMESPACE_ENTRY_V6
|
||||
{
|
||||
ULONG Flags;
|
||||
ULONG NameOffset;
|
||||
ULONG Size;
|
||||
ULONG NameLength;
|
||||
ULONG DataOffset;
|
||||
ULONG Count;
|
||||
} API_SET_NAMESPACE_ENTRY_V6, *PAPI_SET_NAMESPACE_ENTRY_V6;
|
||||
|
||||
typedef struct _API_SET_NAMESPACE_ARRAY_V6
|
||||
{
|
||||
ULONG Version;
|
||||
ULONG Size;
|
||||
ULONG Flags;
|
||||
ULONG Count;
|
||||
ULONG DataOffset;
|
||||
ULONG HashOffset;
|
||||
ULONG Multiplier;
|
||||
API_SET_NAMESPACE_ENTRY_V6 Array[ANYSIZE_ARRAY];
|
||||
} API_SET_NAMESPACE_ARRAY_V6, *PAPI_SET_NAMESPACE_ARRAY_V6;
|
||||
|
||||
typedef struct _API_SET_VALUE_ENTRY_V4
|
||||
{
|
||||
ULONG Flags;
|
||||
ULONG NameOffset;
|
||||
ULONG NameLength;
|
||||
ULONG ValueOffset;
|
||||
ULONG ValueLength;
|
||||
} API_SET_VALUE_ENTRY_V4, *PAPI_SET_VALUE_ENTRY_V4;
|
||||
|
||||
typedef struct _API_SET_VALUE_ARRAY_V4
|
||||
{
|
||||
ULONG Flags;
|
||||
ULONG Count;
|
||||
API_SET_VALUE_ENTRY_V4 Array[ANYSIZE_ARRAY];
|
||||
} API_SET_VALUE_ARRAY_V4, *PAPI_SET_VALUE_ARRAY_V4;
|
||||
|
||||
typedef struct _API_SET_NAMESPACE_ENTRY_V4
|
||||
{
|
||||
ULONG Flags;
|
||||
ULONG NameOffset;
|
||||
ULONG NameLength;
|
||||
ULONG AliasOffset;
|
||||
ULONG AliasLength;
|
||||
ULONG DataOffset;
|
||||
} API_SET_NAMESPACE_ENTRY_V4, *PAPI_SET_NAMESPACE_ENTRY_V4;
|
||||
|
||||
typedef struct _API_SET_NAMESPACE_ARRAY_V4
|
||||
{
|
||||
ULONG Version;
|
||||
ULONG Size;
|
||||
ULONG Flags;
|
||||
ULONG Count;
|
||||
API_SET_NAMESPACE_ENTRY_V4 Array[ANYSIZE_ARRAY];
|
||||
} API_SET_NAMESPACE_ARRAY_V4, *PAPI_SET_NAMESPACE_ARRAY_V4;
|
||||
|
||||
typedef struct _API_SET_VALUE_ENTRY_V2
|
||||
{
|
||||
ULONG NameOffset;
|
||||
ULONG NameLength;
|
||||
ULONG ValueOffset;
|
||||
ULONG ValueLength;
|
||||
} API_SET_VALUE_ENTRY_V2, *PAPI_SET_VALUE_ENTRY_V2;
|
||||
|
||||
typedef struct _API_SET_VALUE_ARRAY_V2
|
||||
{
|
||||
ULONG Count;
|
||||
API_SET_VALUE_ENTRY_V2 Array[ANYSIZE_ARRAY];
|
||||
} API_SET_VALUE_ARRAY_V2, *PAPI_SET_VALUE_ARRAY_V2;
|
||||
|
||||
typedef struct _API_SET_NAMESPACE_ENTRY_V2
|
||||
{
|
||||
ULONG NameOffset;
|
||||
ULONG NameLength;
|
||||
ULONG DataOffset;
|
||||
} API_SET_NAMESPACE_ENTRY_V2, *PAPI_SET_NAMESPACE_ENTRY_V2;
|
||||
|
||||
typedef struct _API_SET_NAMESPACE_ARRAY_V2
|
||||
{
|
||||
ULONG Version;
|
||||
ULONG Count;
|
||||
API_SET_NAMESPACE_ENTRY_V2 Array[ANYSIZE_ARRAY];
|
||||
} API_SET_NAMESPACE_ARRAY_V2, *PAPI_SET_NAMESPACE_ARRAY_V2;
|
||||
|
||||
#define API_SET_VERSION_V6 6
|
||||
#define API_SET_VERSION_V4 4
|
||||
#define API_SET_VERSION_V2 2
|
||||
|
||||
#endif
|
||||
+22543
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,50 @@
|
||||
MAKEFLAGS += "-s"
|
||||
|
||||
##
|
||||
## Compilers
|
||||
##
|
||||
CC_X64 := x86_64-w64-mingw32-gcc
|
||||
|
||||
##
|
||||
## Compiler flags
|
||||
##
|
||||
CFLAGS := -Os -fno-asynchronous-unwind-tables
|
||||
CFLAGS += -fno-ident -fpack-struct=8 -falign-functions=1
|
||||
CFLAGS += -s -ffunction-sections -falign-jumps=1 -w
|
||||
CFLAGS += -falign-labels=1 -fPIC
|
||||
CFLAGS += -Wl,-s,--no-seh,--enable-stdcall-fixup -municode
|
||||
CFLAGS += -Iinclude -masm=intel -DLIBRARYEX_DEBUG
|
||||
|
||||
test: clean-builds test-cryptsp.exe test-cryptsp-ex.exe test-cryptsp-buffer.exe test-rundll32.exe test-api-set.exe
|
||||
|
||||
test-cryptsp.exe:
|
||||
printf "[*] build test test-cryptsp.exe..."
|
||||
$(CC_X64) tests/TestCryptsp.c src/LdrLibraryEx.c -o test-cryptsp.exe $(CFLAGS)
|
||||
echo " done"
|
||||
|
||||
test-cryptsp-ex.exe:
|
||||
printf "[*] build test test-cryptsp-ex.exe..."
|
||||
$(CC_X64) tests/TestCryptspEx.c src/LdrLibraryEx.c -o test-cryptsp-ex.exe $(CFLAGS)
|
||||
echo " done"
|
||||
|
||||
test-cryptsp-buffer.exe:
|
||||
printf "[*] build test test-cryptsp-buffer.exe..."
|
||||
$(CC_X64) tests/TestCryptspMemory.c src/LdrLibraryEx.c -o test-cryptsp-buffer.exe $(CFLAGS)
|
||||
echo " done"
|
||||
|
||||
test-rundll32.exe:
|
||||
printf "[*] build test test-rundll32.exe..."
|
||||
$(CC_X64) tests/TestRundll32Exe.c src/LdrLibraryEx.c -o test-rundll32.exe $(CFLAGS)
|
||||
echo " done"
|
||||
|
||||
test-api-set.exe:
|
||||
printf "[*] build test test-api-set.exe..."
|
||||
$(CC_X64) tests/TestApiSet.c src/LdrLibraryEx.c -o test-api-set.exe $(CFLAGS)
|
||||
echo " done"
|
||||
|
||||
clean-builds:
|
||||
rm -rf *.exe
|
||||
|
||||
clean: clean-builds
|
||||
rm -rf .idea
|
||||
rm -rf cmake-build-debug
|
||||
@@ -0,0 +1,22 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding:utf-8 -*-
|
||||
import sys
|
||||
|
||||
# this is by Austin from https://github.com/SecIdiot/TitanLdr/blob/master/python3/hashstring.py. Full credit goes to him.
|
||||
|
||||
def hash_string( string ):
|
||||
try:
|
||||
hash = 5381
|
||||
|
||||
for x in string.upper():
|
||||
hash = (( hash << 5 ) + hash ) + ord(x)
|
||||
|
||||
return hash & 0xFFFFFFFF
|
||||
except:
|
||||
pass
|
||||
|
||||
if __name__ in '__main__':
|
||||
try:
|
||||
print('#define H_API_%s 0x%x' % ( sys.argv[ 1 ].upper(), hash_string( sys.argv[ 1 ] ) ));
|
||||
except IndexError:
|
||||
print('usage: %s [string]' % sys.argv[0])
|
||||
+2110
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,59 @@
|
||||
#include <LdrLibraryEx.h>
|
||||
#include <stdio.h>
|
||||
|
||||
BOOL ApiSetLoad(
|
||||
VOID
|
||||
);
|
||||
|
||||
int wmain(
|
||||
int argc,
|
||||
wchar_t** argv
|
||||
) {
|
||||
printf( "press enter to start..." );
|
||||
getchar();
|
||||
|
||||
//
|
||||
// map and test against advapi32.dll
|
||||
//
|
||||
puts( "[*] trying to resolve api set" );
|
||||
if ( ! ApiSetLoad() ) {
|
||||
puts( "[-] failed to resolve and load api set" );
|
||||
}
|
||||
puts( "[*] finished" );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
BOOL ApiSetLoad(
|
||||
VOID
|
||||
) {
|
||||
BOOL Success = FALSE;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
PVOID Module = { 0 };
|
||||
ULONG Flags = { 0 };
|
||||
|
||||
//
|
||||
// mapping flags to be used by the library
|
||||
// and insert the loaded module into Peb
|
||||
//
|
||||
Flags = LIBRARYEX_NONE;
|
||||
|
||||
//
|
||||
// map file into memory
|
||||
//
|
||||
if ( ! NT_SUCCESS( Status = LdrLibrary(
|
||||
L"api-ms-win-base-util-l1-1-0.dll",
|
||||
&Module,
|
||||
Flags
|
||||
) ) ) {
|
||||
printf( "[-] LdrLibraryEx Failed: %p\n", Status );
|
||||
goto END;
|
||||
}
|
||||
|
||||
printf( "[*] Module @ %p\n", Module );
|
||||
|
||||
Success = TRUE;
|
||||
|
||||
END:
|
||||
return Success;
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
#include <LdrLibraryEx.h>
|
||||
#include <stdio.h>
|
||||
|
||||
VOID PrintBytes(
|
||||
_In_ LPSTR Name,
|
||||
_In_ PCSTRING Data
|
||||
);
|
||||
|
||||
BOOL MapCryptSp(
|
||||
VOID
|
||||
);
|
||||
|
||||
int wmain(
|
||||
int argc,
|
||||
wchar_t** argv
|
||||
) {
|
||||
printf( "press enter to start..." );
|
||||
getchar();
|
||||
|
||||
//
|
||||
// map and test against advapi32.dll
|
||||
//
|
||||
puts( "[*] trying to load cryptsp.dll" );
|
||||
if ( ! MapCryptSp() ) {
|
||||
puts( "[-] failed to load & test cryptsp.dll" );
|
||||
}
|
||||
puts( "[*] finished" );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief
|
||||
* load cryptsp into memory and test some functions
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
BOOL MapCryptSp(
|
||||
VOID
|
||||
) {
|
||||
BOOL Success = { 0 };
|
||||
NTSTATUS Status = { 0 };
|
||||
PVOID Module = { 0 };
|
||||
ULONG Flags = { 0 };
|
||||
PVOID Sys32 = { 0 };
|
||||
CSTRING CKey = { 0 };
|
||||
CSTRING CDat = { 0 };
|
||||
CHAR Dat[] = { 0x01, 0x01, 0x01, 0x01 };
|
||||
CHAR Key[] = { 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55 };
|
||||
|
||||
//
|
||||
// mapping flags to be used by the library
|
||||
//
|
||||
Flags = LIBRARYEX_BYPASS_LOAD_CALLBACK |
|
||||
LIBRARYEX_NO_ENTRY;
|
||||
|
||||
//
|
||||
// map file into memory
|
||||
//
|
||||
if ( ! NT_SUCCESS( Status = LdrLibrary(
|
||||
L"cryptsp.dll",
|
||||
&Module,
|
||||
Flags
|
||||
) ) ) {
|
||||
printf( "[-] LdrLibraryEx Failed: %p\n", Status );
|
||||
goto END;
|
||||
}
|
||||
|
||||
//
|
||||
// test functions
|
||||
//
|
||||
if ( ( Sys32 = LdrFunction( Module, "SystemFunction032" ) ) ) {
|
||||
|
||||
CKey.Length = CKey.MaximumLength = sizeof( Key );
|
||||
CKey.Buffer = Key;
|
||||
|
||||
CDat.Length = CKey.MaximumLength = sizeof( Dat );
|
||||
CDat.Buffer = Dat;
|
||||
|
||||
PrintBytes( "Data", &CDat );
|
||||
|
||||
( ( NTSTATUS( * ) ( PCSTRING, PCSTRING ) ) Sys32 )( &CDat, &CKey );
|
||||
PrintBytes( "Data", &CDat );
|
||||
( ( NTSTATUS( * ) ( PCSTRING, PCSTRING ) ) Sys32 )( &CDat, &CKey );
|
||||
|
||||
PrintBytes( "Data", &CDat );
|
||||
|
||||
} else puts( "[-] Failed to load SystemFunction032" );
|
||||
|
||||
printf( "[*] Module @ %p\n", Module );
|
||||
|
||||
Success = TRUE;
|
||||
|
||||
END:
|
||||
return Success;
|
||||
}
|
||||
|
||||
VOID PrintBytes(
|
||||
_In_ LPSTR Name,
|
||||
_In_ PCSTRING Data
|
||||
) {
|
||||
printf( "[*] %s :: [ ", Name );
|
||||
|
||||
for ( USHORT i = 0; i < Data->Length; i++ ) {
|
||||
printf( "%x " , Data->Buffer[ i ] );
|
||||
}
|
||||
|
||||
puts( "]" );
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
#define LIBRARYEX_DEBUG
|
||||
|
||||
#include <LdrLibraryEx.h>
|
||||
#include <stdio.h>
|
||||
|
||||
VOID PrintBytes(
|
||||
_In_ LPSTR Name,
|
||||
_In_ PCSTRING Data
|
||||
);
|
||||
|
||||
BOOL MapCryptSp(
|
||||
VOID
|
||||
);
|
||||
|
||||
int wmain(
|
||||
int argc,
|
||||
wchar_t** argv
|
||||
) {
|
||||
printf( "press enter to start..." );
|
||||
getchar();
|
||||
|
||||
//
|
||||
// map and test against advapi32.dll
|
||||
//
|
||||
puts( "[*] trying to load cryptsp.dll" );
|
||||
if ( ! MapCryptSp() ) {
|
||||
puts( "[-] failed to load & test cryptsp.dll" );
|
||||
}
|
||||
puts( "[*] finished" );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
// lazy hook example
|
||||
//
|
||||
NTSTATUS NTAPI HookLdrLoadDll(
|
||||
_In_opt_ PWCHAR PathToFile,
|
||||
_In_opt_ ULONG Flags,
|
||||
_In_ PUNICODE_STRING ModuleFileName,
|
||||
_Out_ PHANDLE ModuleHandle
|
||||
) {
|
||||
NTSTATUS ( *pLdrLoadDll )(
|
||||
_In_opt_ PWCHAR PathToFile,
|
||||
_In_opt_ ULONG Flags,
|
||||
_In_ PUNICODE_STRING ModuleFileName,
|
||||
_Out_ PHANDLE ModuleHandle
|
||||
) = NULL;
|
||||
NTSTATUS Status = STATUS_UNSUCCESSFUL;
|
||||
|
||||
if ( ( pLdrLoadDll = C_PTR( GetProcAddress( GetModuleHandleA( "ntdll" ), "LdrLoadDll" ) ) ) ) {
|
||||
printf( "[*] Hook called: LdrLoadDll( %ls, %ld, %ls, %p ) -> ", PathToFile, Flags, ModuleFileName->Buffer, ModuleHandle );
|
||||
|
||||
Status = pLdrLoadDll( PathToFile, Flags, ModuleFileName, ModuleHandle );
|
||||
|
||||
printf( "%p\n", Status );
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief
|
||||
* load cryptsp into memory and test some functions
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
BOOL MapCryptSp(
|
||||
VOID
|
||||
) {
|
||||
LIBRARYEX_CTX Ctx = { 0 };
|
||||
BOOL Success = { 0 };
|
||||
NTSTATUS Status = { 0 };
|
||||
PVOID Module = { 0 };
|
||||
ULONG Flags = { 0 };
|
||||
PVOID Sys32 = { 0 };
|
||||
CSTRING CKey = { 0 };
|
||||
CSTRING CDat = { 0 };
|
||||
CHAR Dat[] = { 0x01, 0x01, 0x01, 0x01 };
|
||||
CHAR Key[] = { 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55 };
|
||||
|
||||
//
|
||||
// mapping flags to be used by the library
|
||||
// and insert the loaded module into Peb
|
||||
//
|
||||
Flags = LIBRARYEX_BYPASS_LOAD_CALLBACK |
|
||||
LIBRARYEX_NO_ENTRY;
|
||||
|
||||
//
|
||||
// init LibraryEx context
|
||||
//
|
||||
if ( ! NT_SUCCESS( Status = LdrLibraryCtx( &Ctx, Flags ) ) ) {
|
||||
printf( "LdrLibraryCtx Failed: %d\n", Status );
|
||||
goto END;
|
||||
}
|
||||
|
||||
//
|
||||
// hook function
|
||||
//
|
||||
Ctx.LdrLoadDll = C_PTR( HookLdrLoadDll );
|
||||
|
||||
//
|
||||
// map file into memory
|
||||
//
|
||||
if ( ! NT_SUCCESS( Status = LdrLibraryEx(
|
||||
&Ctx,
|
||||
L"cryptsp.dll",
|
||||
&Module,
|
||||
Flags
|
||||
) ) ) {
|
||||
printf( "[-] LdrLibraryEx Failed: %p\n", Status );
|
||||
goto END;
|
||||
}
|
||||
|
||||
//
|
||||
// test functions
|
||||
//
|
||||
if ( ( Sys32 = LdrFunction( Module, "SystemFunction032" ) ) ) {
|
||||
|
||||
CKey.Length = CKey.MaximumLength = sizeof( Key );
|
||||
CKey.Buffer = Key;
|
||||
|
||||
CDat.Length = CKey.MaximumLength = sizeof( Dat );
|
||||
CDat.Buffer = Dat;
|
||||
|
||||
PrintBytes( "Data", &CDat );
|
||||
|
||||
( ( NTSTATUS( * ) ( PCSTRING, PCSTRING ) ) Sys32 )( &CDat, &CKey );
|
||||
PrintBytes( "Data", &CDat );
|
||||
( ( NTSTATUS( * ) ( PCSTRING, PCSTRING ) ) Sys32 )( &CDat, &CKey );
|
||||
|
||||
PrintBytes( "Data", &CDat );
|
||||
|
||||
} else puts( "[-] Failed to load SystemFunction032" );
|
||||
|
||||
printf( "[*] Module @ %p\n", Module );
|
||||
|
||||
Success = TRUE;
|
||||
|
||||
END:
|
||||
return Success;
|
||||
}
|
||||
|
||||
VOID PrintBytes(
|
||||
_In_ LPSTR Name,
|
||||
_In_ PCSTRING Data
|
||||
) {
|
||||
printf( "[*] %s :: [ ", Name );
|
||||
|
||||
for ( USHORT i = 0; i < Data->Length; i++ ) {
|
||||
printf( "%x " , Data->Buffer[ i ] );
|
||||
}
|
||||
|
||||
puts( "]" );
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
#define LIBRARYEX_DEBUG
|
||||
|
||||
#include <LdrLibraryEx.h>
|
||||
#include <stdio.h>
|
||||
|
||||
VOID PrintBytes(
|
||||
_In_ LPSTR Name,
|
||||
_In_ PCSTRING Data
|
||||
);
|
||||
|
||||
BOOL MapCryptSp(
|
||||
VOID
|
||||
);
|
||||
|
||||
PVOID ReadFileBuffer(
|
||||
LPWSTR Path,
|
||||
PDWORD MemorySize
|
||||
);
|
||||
|
||||
int wmain(
|
||||
int argc,
|
||||
wchar_t** argv
|
||||
) {
|
||||
printf( "press enter to start..." );
|
||||
getchar();
|
||||
|
||||
puts( "[*] trying to load cryptsp.dll" );
|
||||
if ( ! MapCryptSp() ) {
|
||||
puts( "[-] failed to load & test cryptsp.dll" );
|
||||
}
|
||||
puts( "[*] finished" );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief
|
||||
* load cryptsp into memory and test some functions
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
BOOL MapCryptSp(
|
||||
VOID
|
||||
) {
|
||||
BOOL Success = { 0 };
|
||||
NTSTATUS Status = { 0 };
|
||||
PVOID Module = { 0 };
|
||||
ULONG Flags = { 0 };
|
||||
PVOID Sys32 = { 0 };
|
||||
CSTRING CKey = { 0 };
|
||||
CSTRING CDat = { 0 };
|
||||
PVOID Image = { 0 };
|
||||
CHAR Dat[] = { 0x01, 0x01, 0x01, 0x01 };
|
||||
CHAR Key[] = { 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55 };
|
||||
|
||||
//
|
||||
// mapping flags to be used by the library
|
||||
// and insert the loaded module into Peb
|
||||
//
|
||||
Flags = LIBRARYEX_BYPASS_LOAD_CALLBACK |
|
||||
LIBRARYEX_BUFFER |
|
||||
LIBRARYEX_NO_ENTRY;
|
||||
|
||||
//
|
||||
// read file on disk into memory
|
||||
//
|
||||
if ( ! ( Image = ReadFileBuffer( L"C:\\Windows\\System32\\cryptsp.dll", NULL ) ) ) {
|
||||
puts( "[-] ReadFileBuffer Failed" );
|
||||
goto END;
|
||||
}
|
||||
|
||||
//
|
||||
// map file into memory
|
||||
//
|
||||
if ( ! NT_SUCCESS( Status = LdrLibrary(
|
||||
Image,
|
||||
&Module,
|
||||
Flags
|
||||
) ) ) {
|
||||
printf( "[-] LdrLibraryEx Failed: %p\n", Status );
|
||||
goto END;
|
||||
}
|
||||
|
||||
//
|
||||
// test functions
|
||||
//
|
||||
if ( ( Sys32 = LdrFunction( Module, "SystemFunction032" ) ) ) {
|
||||
|
||||
CKey.Length = CKey.MaximumLength = sizeof( Key );
|
||||
CKey.Buffer = Key;
|
||||
|
||||
CDat.Length = CKey.MaximumLength = sizeof( Dat );
|
||||
CDat.Buffer = Dat;
|
||||
|
||||
PrintBytes( "Data", &CDat );
|
||||
|
||||
( ( NTSTATUS( * ) ( PCSTRING, PCSTRING ) ) Sys32 )( &CDat, &CKey );
|
||||
PrintBytes( "Data", &CDat );
|
||||
( ( NTSTATUS( * ) ( PCSTRING, PCSTRING ) ) Sys32 )( &CDat, &CKey );
|
||||
|
||||
PrintBytes( "Data", &CDat );
|
||||
|
||||
} else puts( "[-] Failed to load SystemFunction032" );
|
||||
|
||||
printf( "[*] Module @ %p\n", Module );
|
||||
|
||||
Success = TRUE;
|
||||
|
||||
END:
|
||||
if ( Image ) {
|
||||
LocalFree( Image );
|
||||
Image = NULL;
|
||||
}
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
PVOID ReadFileBuffer(
|
||||
_In_ LPWSTR Path,
|
||||
_Out_ PDWORD MemorySize
|
||||
) {
|
||||
PVOID ImageBuffer = { 0 };
|
||||
DWORD dwBytesRead = { 0 };
|
||||
HANDLE hFile = { 0 };
|
||||
ULONG Size = { 0 };
|
||||
|
||||
if ( ( hFile = CreateFileW( Path, GENERIC_READ, 0, 0, OPEN_ALWAYS, 0, 0 ) ) == INVALID_HANDLE_VALUE ) {
|
||||
printf( "CreateFileA Failed: %ld\n", GetLastError() );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Size = GetFileSize( hFile, 0 );
|
||||
|
||||
if ( MemorySize ) {
|
||||
*MemorySize = Size;
|
||||
}
|
||||
|
||||
if ( ( ImageBuffer = LocalAlloc( LPTR, Size ) ) ) {
|
||||
ReadFile( hFile, ImageBuffer, Size, &dwBytesRead, 0 );
|
||||
}
|
||||
|
||||
CloseHandle( hFile );
|
||||
|
||||
return ImageBuffer;
|
||||
}
|
||||
|
||||
VOID PrintBytes(
|
||||
_In_ LPSTR Name,
|
||||
_In_ PCSTRING Data
|
||||
) {
|
||||
printf( "[*] %s :: [ ", Name );
|
||||
|
||||
for ( USHORT i = 0; i < Data->Length; i++ ) {
|
||||
printf( "%x " , Data->Buffer[ i ] );
|
||||
}
|
||||
|
||||
puts( "]" );
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
#define LIBRARYEX_DEBUG
|
||||
|
||||
#include <LdrLibraryEx.h>
|
||||
#include <stdio.h>
|
||||
|
||||
VOID PrintBytes(
|
||||
_In_ LPSTR Name,
|
||||
_In_ PCSTRING Data
|
||||
);
|
||||
|
||||
BOOL MapRunDll32(
|
||||
VOID
|
||||
);
|
||||
|
||||
int wmain(
|
||||
int argc,
|
||||
wchar_t** argv
|
||||
) {
|
||||
printf( "press enter to start..." );
|
||||
getchar();
|
||||
|
||||
//
|
||||
// map and test against advapi32.dll
|
||||
//
|
||||
puts( "[*] trying to load rundll32.exe" );
|
||||
if ( ! MapRunDll32() ) {
|
||||
puts( "[-] failed to load & test rundll32.exe" );
|
||||
}
|
||||
puts( "[*] finished" );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief
|
||||
* load rundll32 into memory
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
BOOL MapRunDll32(
|
||||
VOID
|
||||
) {
|
||||
BOOL Success = FALSE;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
PVOID Module = { 0 };
|
||||
ULONG Flags = { 0 };
|
||||
|
||||
//
|
||||
// mapping flags to be used by the library
|
||||
// and insert the loaded module into Peb
|
||||
//
|
||||
Flags = LIBRARYEX_NONE;
|
||||
|
||||
//
|
||||
// map file into memory
|
||||
//
|
||||
if ( ! NT_SUCCESS( Status = LdrLibrary(
|
||||
L"rundll32.exe",
|
||||
&Module,
|
||||
Flags
|
||||
) ) ) {
|
||||
printf( "[-] LdrLibraryEx Failed: %p\n", Status );
|
||||
goto END;
|
||||
}
|
||||
|
||||
printf( "[*] Module @ %p\n", Module );
|
||||
|
||||
Success = TRUE;
|
||||
|
||||
END:
|
||||
return Success;
|
||||
}
|
||||
Reference in New Issue
Block a user