Skip to content

Commit 76b626a

Browse files
committed
Driver: MMap: fixed APC_INDEX_MISMATCH BSOD
1 parent 99cfd03 commit 76b626a

File tree

5 files changed

+64
-27
lines changed

5 files changed

+64
-27
lines changed

src/BlackBoneDrv/Inject.c

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include "Private.h"
22
#include "Routines.h"
33
#include "Loader.h"
4+
#include "Utils.h"
45
#include <Ntstrsafe.h>
56

67
#define CALL_COMPLETE 0xC0371E7E
@@ -56,13 +57,11 @@ NTSTATUS BBInjectDll( IN PINJECT_DLL pData )
5657
PVOID LdrLoadDll = NULL;
5758
PVOID systemBuffer = NULL;
5859
BOOLEAN isWow64 = (PsGetProcessWow64Process( pProcess ) != NULL) ? TRUE : FALSE;
59-
LARGE_INTEGER procTimeout = { 0 };
6060

6161
// Process in signaled state, abort any operations
62-
if (KeWaitForSingleObject( pProcess, Executive, KernelMode, FALSE, &procTimeout ) == STATUS_WAIT_0)
62+
if (BBCheckProcessTermination( PsGetCurrentProcess() ))
6363
{
6464
DPRINT( "BlackBone: %s: Process %u is terminating. Abort\n", __FUNCTION__, pData->pid );
65-
6665
if (pProcess)
6766
ObDereferenceObject( pProcess );
6867

@@ -109,8 +108,7 @@ NTSTATUS BBInjectDll( IN PINJECT_DLL pData )
109108
);
110109
}
111110
__except (EXCEPTION_EXECUTE_HANDLER){
112-
DPRINT( "BlackBone: %s: Fatal exception in BBMapUserImage. Exception code 0x%x\n",
113-
__FUNCTION__, GetExceptionCode() );
111+
DPRINT( "BlackBone: %s: Fatal exception in BBMapUserImage. Exception code 0x%x\n", __FUNCTION__, GetExceptionCode() );
114112
}
115113

116114
KeUnstackDetachProcess( &apc );
@@ -384,11 +382,23 @@ NTSTATUS BBApcInject( IN PINJECT_BUFFER pUserBuf, IN HANDLE pid, IN ULONG initRV
384382
LARGE_INTEGER interval = { 0 };
385383
interval.QuadPart = -(5LL * 10 * 1000);
386384

387-
for (ULONG i = 0; pUserBuf->complete != CALL_COMPLETE && i < 10000; i++)
388-
KeDelayExecutionThread( KernelMode, FALSE, &interval );
385+
for (ULONG i = 0; i < 10000; i++)
386+
{
387+
if (BBCheckProcessTermination( PsGetCurrentProcess() ) || PsIsThreadTerminating( pThread ))
388+
{
389+
status = STATUS_PROCESS_IS_TERMINATING;
390+
break;
391+
}
392+
393+
if(pUserBuf->complete == CALL_COMPLETE)
394+
break;
395+
396+
if (!NT_SUCCESS( status = KeDelayExecutionThread( KernelMode, FALSE, &interval ) ))
397+
break;
398+
}
389399

390400
// Call init routine
391-
if (pUserBuf->module != 0 && initRVA != 0)
401+
if (NT_SUCCESS( status ) && pUserBuf->module != 0 && initRVA != 0)
392402
{
393403
RtlCopyMemory( (PUCHAR)pUserBuf->buffer, InitArg, sizeof( pUserBuf->buffer ) );
394404
BBQueueUserApc( pThread, (PUCHAR)pUserBuf->module + initRVA, pUserBuf->buffer, NULL, NULL, TRUE );
@@ -397,8 +407,8 @@ NTSTATUS BBApcInject( IN PINJECT_BUFFER pUserBuf, IN HANDLE pid, IN ULONG initRV
397407
interval.QuadPart = -(100LL * 10 * 1000);
398408
KeDelayExecutionThread( KernelMode, FALSE, &interval );
399409
}
400-
else if (pUserBuf->module == 0)
401-
DPRINT( "BlackBone: %s: Module base = 0. Aborting\n", __FUNCTION__ );
410+
else
411+
DPRINT( "BlackBone: %s: APC injection abnormal termination, status 0x%X\n", __FUNCTION__, status );
402412
}
403413
}
404414
else

src/BlackBoneDrv/MMap.c

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,8 @@ NTSTATUS BBResolveSxS( IN PMMAP_CONTEXT pContext, IN PUNICODE_STRING name, OUT P
8080
/// </summary>
8181
/// <param name="pContext">Map context</param>
8282
/// <param name="noTLS">If TRUE - TLS callbacks will no be invoked</param>
83-
void BBCallInitializers( IN PMMAP_CONTEXT pContext, IN BOOLEAN noTLS );
83+
/// <returns>Status code</returns>
84+
NTSTATUS BBCallInitializers( IN PMMAP_CONTEXT pContext, IN BOOLEAN noTLS );
8485

8586
/// <summary>
8687
/// Call TLS callbacks
@@ -295,11 +296,11 @@ NTSTATUS BBMapUserImage(
295296
if (NT_SUCCESS( status ))
296297
{
297298
__try{
298-
BBCallInitializers( &context, (flags & KNoTLS) != 0 );
299+
status = BBCallInitializers( &context, (flags & KNoTLS) != 0 );
299300
}
300301
__except (EXCEPTION_EXECUTE_HANDLER) {
301-
DPRINT( "BlackBone: %s: Exception during initialization phase.Exception code 0x%X\n", __FUNCTION__, GetExceptionCode() );
302-
status = STATUS_UNHANDLED_EXCEPTION;
302+
status = GetExceptionCode();
303+
DPRINT( "BlackBone: %s: Exception during initialization phase.Exception code 0x%X\n", __FUNCTION__, status );
303304
}
304305
}
305306

@@ -318,7 +319,8 @@ NTSTATUS BBMapUserImage(
318319
// Event
319320
if (context.pSync)
320321
ObDereferenceObject( context.pSync );
321-
if (context.hSync)
322+
323+
if (context.hSync && !BBCheckProcessTermination( PsGetCurrentProcess() ))
322324
ZwClose( context.hSync );
323325

324326
// Worker thread
@@ -1194,7 +1196,8 @@ NTSTATUS BBResolveImagePath(
11941196
/// </summary>
11951197
/// <param name="pContext">Map context</param>
11961198
/// <param name="noTLS">If TRUE - TLS callbacks will no be invoked</param>
1197-
void BBCallInitializers( IN PMMAP_CONTEXT pContext, IN BOOLEAN noTLS )
1199+
/// <returns>Status code</returns>
1200+
NTSTATUS BBCallInitializers( IN PMMAP_CONTEXT pContext, IN BOOLEAN noTLS )
11981201
{
11991202
for (PLIST_ENTRY pListEntry = pContext->modules.Flink; pListEntry != &pContext->modules; pListEntry = pListEntry->Flink)
12001203
{
@@ -1209,10 +1212,18 @@ void BBCallInitializers( IN PMMAP_CONTEXT pContext, IN BOOLEAN noTLS )
12091212
if (noTLS == FALSE)
12101213
BBCallTlsInitializers( pContext, pEntry->baseAddress );
12111214

1215+
NTSTATUS status = STATUS_SUCCESS;
12121216
if (HEADER_VAL_T( pHeaders, AddressOfEntryPoint ))
12131217
{
12141218
PUCHAR entrypoint = pEntry->baseAddress + HEADER_VAL_T( pHeaders, AddressOfEntryPoint );
1215-
BBCallRoutine( FALSE, pContext, entrypoint, 3, pEntry->baseAddress, (PVOID)1, NULL );
1219+
status = BBCallRoutine( FALSE, pContext, entrypoint, 3, pEntry->baseAddress, (PVOID)1, NULL );
1220+
}
1221+
1222+
// Check if process is terminating
1223+
if (status != STATUS_SUCCESS && BBCheckProcessTermination( PsGetCurrentProcess() ))
1224+
{
1225+
DPRINT( "BlackBone: %s: Process is terminating, map aborted\n", __FUNCTION__ );
1226+
return STATUS_PROCESS_IS_TERMINATING;
12161227
}
12171228

12181229
//
@@ -1270,6 +1281,8 @@ void BBCallInitializers( IN PMMAP_CONTEXT pContext, IN BOOLEAN noTLS )
12701281

12711282
pEntry->initialized = TRUE;
12721283
}
1284+
1285+
return STATUS_SUCCESS;
12731286
}
12741287

12751288
/// <summary>
@@ -1692,7 +1705,7 @@ NTSTATUS BBCallRoutine( IN BOOLEAN newThread, IN PMMAP_CONTEXT pContext, IN PVOI
16921705

16931706
if (newThread)
16941707
{
1695-
status = BBExecuteInNewThread( pContext->userMem->code, NULL, THREAD_CREATE_FLAGS_HIDE_FROM_DEBUGGER, TRUE, NULL );
1708+
status = BBExecuteInNewThread( pContext->userMem->code, NULL, 0/*THREAD_CREATE_FLAGS_HIDE_FROM_DEBUGGER*/, TRUE, NULL );
16961709
}
16971710
else
16981711
{

src/BlackBoneDrv/Remap.c

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "Remap.h"
2+
#include "Utils.h"
23
#include <Ntstrsafe.h>
34

45
RTL_AVL_TABLE g_ProcessPageTables; // Mapping table
@@ -686,7 +687,6 @@ NTSTATUS BBMapMemory( IN PMAP_MEMORY pRemap, OUT PPROCESS_MAP_ENTRY* ppEntry )
686687
PROCESS_MAP_ENTRY processEntry = { 0 };
687688
PPROCESS_MAP_ENTRY pFoundEntry = NULL;
688689
BOOLEAN newEntry = FALSE;
689-
LARGE_INTEGER timeout = { 0 };
690690

691691
// Sanity checks
692692
// Can't remap self
@@ -707,7 +707,7 @@ NTSTATUS BBMapMemory( IN PMAP_MEMORY pRemap, OUT PPROCESS_MAP_ENTRY* ppEntry )
707707
}
708708

709709
// Process in signaled state, abort any operations
710-
if (KeWaitForSingleObject( pProcess, Executive, KernelMode, FALSE, &timeout ) == STATUS_WAIT_0)
710+
if (BBCheckProcessTermination( pProcess ))
711711
{
712712
DPRINT( "BlackBone: %s: Process %u is terminating. Abort\n", __FUNCTION__, processEntry.target.pid );
713713

@@ -815,7 +815,6 @@ NTSTATUS BBMapMemoryRegion( IN PMAP_MEMORY_REGION pRegion, OUT PMAP_MEMORY_REGIO
815815
BOOLEAN alreadyExists = FALSE;
816816
ULONG_PTR removedBase = 0;
817817
ULONG removedSize = 0;
818-
LARGE_INTEGER timeout = { 0 };
819818

820819
// Don't allow remapping of kernel addresses
821820
if (pRegion->base >= (ULONGLONG)MM_HIGHEST_USER_ADDRESS || pRegion->base + pRegion->size > (ULONGLONG)MM_HIGHEST_USER_ADDRESS)
@@ -842,7 +841,7 @@ NTSTATUS BBMapMemoryRegion( IN PMAP_MEMORY_REGION pRegion, OUT PMAP_MEMORY_REGIO
842841
}
843842

844843
// Process in signaled state, abort any operations
845-
if (KeWaitForSingleObject( pProcess, Executive, KernelMode, FALSE, &timeout ) == STATUS_WAIT_0)
844+
if (BBCheckProcessTermination( pProcess ))
846845
{
847846
DPRINT( "BlackBone: %s: Process %u is terminating. Abort\n", __FUNCTION__, processEntry.target.pid );
848847

@@ -995,7 +994,6 @@ NTSTATUS BBUnmapMemoryRegion( IN PUNMAP_MEMORY_REGION pRegion )
995994
PPROCESS_MAP_ENTRY pFoundEntry = NULL;
996995
PMAP_ENTRY pPageEntry = NULL;
997996
PEPROCESS pProcess = NULL;
998-
LARGE_INTEGER timeout = { 0 };
999997
ULONG pageCount = ADDRESS_AND_SIZE_TO_SPAN_PAGES(pRegion->base, pRegion->size);
1000998

1001999
// Sanity check
@@ -1013,7 +1011,7 @@ NTSTATUS BBUnmapMemoryRegion( IN PUNMAP_MEMORY_REGION pRegion )
10131011
}
10141012

10151013
// Process in signaled state, abort any operations
1016-
if (KeWaitForSingleObject( pProcess, Executive, KernelMode, FALSE, &timeout ) == STATUS_WAIT_0)
1014+
if (BBCheckProcessTermination( pProcess ))
10171015
{
10181016
DPRINT( "BlackBone: %s: Process %u is terminating. Abort\n", __FUNCTION__, pRegion->pid );
10191017

@@ -1107,8 +1105,6 @@ VOID BBCleanupPageList( IN BOOLEAN attached, IN PLIST_ENTRY pList )
11071105
/// <returns>Status code</returns>
11081106
NTSTATUS BBSafeHandleClose( IN PEPROCESS pProcess, IN HANDLE handle, IN KPROCESSOR_MODE mode )
11091107
{
1110-
LARGE_INTEGER timeout = { 0 };
1111-
11121108
ASSERT( pProcess != NULL );
11131109
if (pProcess == NULL)
11141110
return STATUS_INVALID_PARAMETER;
@@ -1117,7 +1113,7 @@ NTSTATUS BBSafeHandleClose( IN PEPROCESS pProcess, IN HANDLE handle, IN KPROCESS
11171113
// If process is in signaled state, ObjectTable is already NULL
11181114
// Thus is will lead to crash in ObCloseHandle->ExpLookupHandleTableEntry
11191115
//
1120-
if (KeWaitForSingleObject( pProcess, Executive, KernelMode, FALSE, &timeout ) == STATUS_WAIT_0)
1116+
if (BBCheckProcessTermination( pProcess ))
11211117
return STATUS_PROCESS_IS_TERMINATING;
11221118

11231119
return ObCloseHandle( handle, mode );

src/BlackBoneDrv/Utils.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,17 @@ NTSTATUS BBSearchPattern( IN PCUCHAR pattern, IN UCHAR wildcard, IN ULONG_PTR le
224224
return STATUS_NOT_FOUND;
225225
}
226226

227+
/// <summary>
228+
/// Check if process is terminating
229+
/// </summary>
230+
/// <param name="imageBase">Process</param>
231+
/// <returns>If TRUE - terminating</returns>
232+
BOOLEAN BBCheckProcessTermination( PEPROCESS pProcess )
233+
{
234+
LARGE_INTEGER zeroTime = { 0 };
235+
return KeWaitForSingleObject( pProcess, Executive, KernelMode, FALSE, &zeroTime ) == STATUS_WAIT_0;
236+
}
237+
227238
ULONG GenPrologue32( IN PUCHAR pBuf )
228239
{
229240
*pBuf = 0x55;

src/BlackBoneDrv/Utils.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,13 @@ NTSTATUS BBSearchPattern( IN PCUCHAR pattern, IN UCHAR wildcard, IN ULONG_PTR le
6868
/// <returns>Status code</returns>
6969
NTSTATUS BBCreateCookie( IN PVOID imageBase );
7070

71+
/// <summary>
72+
/// Check if process is terminating
73+
/// </summary>
74+
/// <param name="imageBase">Process</param>
75+
/// <returns>If TRUE - terminating</returns>
76+
BOOLEAN BBCheckProcessTermination( PEPROCESS pProcess );
77+
7178
//
7279
// Machine code generation routines
7380
//

0 commit comments

Comments
 (0)