Skip to content

Commit

Permalink
grimreaper: Successfully ported over to LLVM-MINGW
Browse files Browse the repository at this point in the history
  • Loading branch information
realoriginal committed Mar 17, 2024
1 parent 0b9ee1b commit 1ff1328
Show file tree
Hide file tree
Showing 7 changed files with 103 additions and 18 deletions.
1 change: 1 addition & 0 deletions Common.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

#include <windows.h>
#include <ntstatus.h>
#include <intrin.h>
#include "Native.h"
#include "Macros.h"
#include "Labels.h"
Expand Down
10 changes: 5 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
CC_X64 := x86_64-w64-mingw32-gcc
CC_X86 := i686-w64-mingw32-gcc
CC_X64 := clang -target x86_64-w64-mingw32-gnu
CC_X86 := clang -target i686-w64-mingw32-gnu
SOURCE := $(wildcard *.c)

HSHKEY := $(shell python3 -c "import random; print(hex(random.getrandbits(32)))")
Expand All @@ -8,7 +8,7 @@ CFLAGS := $(CFLAGS) -Os -fno-asynchronous-unwind-tables -nostdlib
CFLAGS := $(CFLAGS) -fno-ident -fpack-struct=8 -falign-functions=1
CFLAGS := $(CFLAGS) -s -ffunction-sections -falign-jumps=1 -w
CFLAGS := $(CFLAGS) -falign-labels=1 -Wl,-TSectionLink.ld
CFLAGS := $(CFLAGS) -fdata-sections
CFLAGS := $(CFLAGS) -fdata-sections -fms-extensions -mno-sse
LFLAGS := $(LFLAGS) -Wl,-s,--no-seh,--enable-stdcall-fixup

OUTX64 := grimreaper.x64.exe
Expand All @@ -26,8 +26,8 @@ all: $(SOURCE)
@ nasm -f win64 asm/x64/Start.asm -o bin/Start.x64.o
@ nasm -f win32 asm/x86/GetIp.asm -o bin/GetIp.x86.o
@ nasm -f win32 asm/x86/Start.asm -o bin/Start.x86.o
@ $(CC_X64) bin/Start.x64.o bin/GetIp.x64.o bin/*.c -I. $(CFLAGS) $(LFLAGS) -o bin/$(OUTX64)
@ $(CC_X86) bin/Start.x86.o bin/GetIp.x86.o bin/*.c -I. $(CFLAGS) $(LFLAGS) -o bin/$(OUTX86)
@ $(CC_X64) bin/Start.x64.o bin/GetIp.x64.o bin/*.c crt/*.c -I. $(CFLAGS) $(LFLAGS) -o bin/$(OUTX64)
@ $(CC_X86) bin/Start.x86.o bin/GetIp.x86.o bin/*.c crt/*.c -I. $(CFLAGS) $(LFLAGS) -o bin/$(OUTX86)
@ python3 scripts/extract.py -f bin/$(OUTX64) -o $(SHLX64)
@ python3 scripts/extract.py -f bin/$(OUTX86) -o $(SHLX86)

Expand Down
51 changes: 38 additions & 13 deletions Obf.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ typedef struct
static D_SEC( B ) DECLSPEC_NOINLINE NTSTATUS NTAPI ThreadCallbackFrameCaptureInternal( _In_ PTHREAD_PARAM Parameter )
{
/* Set the frame pointer */
Parameter->Csp = C_PTR( U_PTR( __builtin_frame_address( 0 ) ) + sizeof( PVOID ) );
Parameter->Csp = C_PTR( U_PTR( _AddressOfReturnAddress() ) );

/* Execute ntdll!NtSignalAndWaitForSingleObject */
( ( __typeof__( NtSignalAndWaitForSingleObject ) * )( PeGetFuncEat(
Expand Down Expand Up @@ -361,7 +361,7 @@ static D_SEC( B ) DECLSPEC_NOINLINE NTSTATUS ThreadSetCallInternal( _Out_ PHANDL
Ctx->Rip = U_PTR( Function );

/* Read the return value */
Ret = *( ULONG_PTR * )( Ctx->Rsp );
Ret = C_PTR( *( ULONG_PTR * )( U_PTR( Ctx->Rsp ) ) );

/* Unset the return address */
*( ULONG_PTR * )( Ctx->Rsp ) = U_PTR( NULL );
Expand Down Expand Up @@ -416,7 +416,7 @@ static D_SEC( B ) DECLSPEC_NOINLINE NTSTATUS ThreadSetCallInternal( _Out_ PHANDL
Ctx->Eip = U_PTR( Function );

/* Read the return value */
Ret = *( ULONG_PTR * )( Ctx->Esp );
Ret = C_PTR( *( ULONG_PTR * )( Ctx->Esp ) );

/* Unset the return address */
*( ULONG_PTR * )( Ctx->Esp ) = U_PTR( NULL );
Expand Down Expand Up @@ -449,7 +449,7 @@ static D_SEC( B ) DECLSPEC_NOINLINE NTSTATUS ThreadSetCallInternal( _Out_ PHANDL
};

/* Queue an APC to block the call setup until this handle has been signaled */
Nst = Api.NtQueueApcThread( Thd, Api.NtWaitForSingleObject, BlockingHandle, FALSE, NULL );
Nst = Api.NtQueueApcThread( Thd, C_PTR( Api.NtWaitForSingleObject ), BlockingHandle, FALSE, NULL );

/* Failed to queue the APC */
if ( ! NT_SUCCESS( Nst ) ) {
Expand Down Expand Up @@ -528,6 +528,7 @@ D_SEC( B ) NTSTATUS NTAPI ObfNtWaitForSingleObject( _In_ HANDLE Handle, _In_ BOO
HANDLE Th3 = NULL;
HANDLE Th4 = NULL;
HANDLE Th5 = NULL;
HANDLE Th6 = NULL;
LPVOID Mem = NULL;

DWORD Cln = 0;
Expand Down Expand Up @@ -654,12 +655,32 @@ D_SEC( B ) NTSTATUS NTAPI ObfNtWaitForSingleObject( _In_ HANDLE Handle, _In_ BOO
break;
};

/* Call NtWaitForSingleOBject */
/* Call NtAllocateVirtualMemory */
Nst = ThreadSetCallInternal(
&Th2,
Th1,
Sfp,
Sfl,
PeGetFuncEat( PebGetModule( OBF_HASH_MAKE( "ntdll.dll" ) ), OBF_HASH_MAKE( "NtAllocateVirtualMemory" ) ),
6,
NtCurrentProcess(),
&Mem,
0,
&Len,
MEM_COMMIT,
PAGE_READWRITE
);

if ( ! NT_SUCCESS( Nst ) ) {
/* ABrot! */
};

/* Call NtWaitForSingleOBject */
Nst = ThreadSetCallInternal(
&Th3,
Th2,
Sfp,
Sfl,
PeGetFuncEat( PebGetModule( OBF_HASH_MAKE( "ntdll.dll" ) ), OBF_HASH_MAKE( "NtWaitForSingleObject" ) ),
3,
Handle,
Expand All @@ -675,8 +696,8 @@ D_SEC( B ) NTSTATUS NTAPI ObfNtWaitForSingleObject( _In_ HANDLE Handle, _In_ BOO

/* Call NtAllocateVirtualMemory */
Nst = ThreadSetCallInternal(
&Th3,
Th2,
&Th4,
Th3,
Sfp,
Sfl,
PeGetFuncEat( PebGetModule( OBF_HASH_MAKE( "ntdll.dll" ) ), OBF_HASH_MAKE( "NtAllocateVirtualMemory" ) ),
Expand All @@ -697,8 +718,8 @@ D_SEC( B ) NTSTATUS NTAPI ObfNtWaitForSingleObject( _In_ HANDLE Handle, _In_ BOO

/* Call RtlDecompressBufferEx */
Nst = ThreadSetCallInternal(
&Th4,
Th3,
&Th5,
Th4,
Sfp,
Sfl,
PeGetFuncEat( PebGetModule( OBF_HASH_MAKE( "ntdll.dll" ) ), OBF_HASH_MAKE( "RtlDecompressBufferEx" ) ),
Expand All @@ -720,8 +741,8 @@ D_SEC( B ) NTSTATUS NTAPI ObfNtWaitForSingleObject( _In_ HANDLE Handle, _In_ BOO

/* Call NtProtectVirtualMemory */
Nst = ThreadSetCallInternal(
&Th5,
Th4,
&Th6,
Th5,
Sfp,
Sfl,
PeGetFuncEat( PebGetModule( OBF_HASH_MAKE( "ntdll.dll" ) ), OBF_HASH_MAKE( "NtProtectVirtualMemory" ) ),
Expand All @@ -740,15 +761,15 @@ D_SEC( B ) NTSTATUS NTAPI ObfNtWaitForSingleObject( _In_ HANDLE Handle, _In_ BOO
};

/* Signal and wait for the last call to complete */
Nst = Api.NtSignalAndWaitForSingleObject( Evt, Th5, FALSE, NULL );
Nst = Api.NtSignalAndWaitForSingleObject( Evt, Th6, FALSE, NULL );

/* Failed to signal/and or wait on the thread */
if ( ! NT_SUCCESS( Nst ) ) {
break;
};

/* Query the exit status of the NtWaitForSingleObject call */
Nst = Api.NtQueryInformationThread( Th2, ThreadBasicInformation, &Tbi, sizeof( Tbi ), NULL );
Nst = Api.NtQueryInformationThread( Th3, ThreadBasicInformation, &Tbi, sizeof( Tbi ), NULL );

/* Failed to query its basic information */
if ( ! NT_SUCCESS( Nst ) ) {
Expand All @@ -759,6 +780,10 @@ D_SEC( B ) NTSTATUS NTAPI ObfNtWaitForSingleObject( _In_ HANDLE Handle, _In_ BOO
Nst = Tbi.ExitStatus;
} while ( 0 );

if ( Th6 != NULL ) {
Api.NtTerminateThread( Th6, STATUS_SUCCESS );
Api.NtClose( Th6 );
};
if ( Th5 != NULL ) {
Api.NtTerminateThread( Th5, STATUS_SUCCESS );
Api.NtClose( Th5 );
Expand Down
30 changes: 30 additions & 0 deletions Pipe.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*!
*
* GRIMREAPER
*
* Austin Hudson
*
* suspicious.actor
*
!*/

#include "Common.h"

typedef struct
{
D_API( NtCreateNamedPipeFile );
D_API( NtDeviceIoControlFile );
D_API( NtClose );
} API ;

/*!
*
* Purpose:
*
* Opens a named pipe as a server and awaits for a connection.
*
!*/
D_SEC( B ) NTSTATUS PipeOpen( _In_ LPWSTR PipeName )
{

};
13 changes: 13 additions & 0 deletions crt/memcpy.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/* Public domain. */
#include <stddef.h>

__attribute__(( section( ".text$B" ) ))
void *
memcpy (void *dest, const void *src, size_t len)
{
char *d = dest;
const char *s = src;
while (len--)
*d++ = *s++;
return dest;
}
12 changes: 12 additions & 0 deletions crt/memset.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/* Public domain. */
#include <stddef.h>

__attribute__(( section( ".text$B" ) ))
void *
memset (void *dest, int val, size_t len)
{
unsigned char *ptr = dest;
while (len-- > 0)
*ptr++ = val;
return dest;
}
4 changes: 4 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
click==8.1.7
Mako==1.3.2
MarkupSafe==2.1.5
pefile==2023.2.7

0 comments on commit 1ff1328

Please sign in to comment.