2025-04-27 07:49:33 -04:00

326 lines
6.8 KiB
C++

/*++
Copyright (C) 1996-2001 Microsoft Corporation
Module Name:
ProvFact.cpp
Abstract:
History:
--*/
#include "PreComp.h"
#include <stdio.h>
// this redefines the DEFINE_GUID() macro to do allocation.
//
#include <initguid.h>
#ifndef INITGUID
#define INITGUID
#endif
#include <wbemint.h>
#include <Allocator.h>
#include <HelperFuncs.h>
#include "Globals.h"
#include "Task.h"
#include "CThread.h"
/******************************************************************************
*
* Name:
*
*
* Description:
*
*
*****************************************************************************/
#ifndef _WIN64
#include <malloc.h>
struct HEAP_ENTRY {
WORD Size;
WORD PrevSize;
BYTE SegmentIndex;
BYTE Flags;
BYTE UnusedBytes;
BYTE SmallTagIndex;
};
FARPROC Real_RtlAlloc;
FARPROC Real_RtlFree;
#define SIZE_JUMP_ADR 5
#define SIZE_RET_0C 3
DWORD __RtlFreeHeap(VOID * pHeap,DWORD Flags,VOID * pBlock)
{
ULONG * pLong = (ULONG *)_alloca(sizeof(DWORD));
if (pBlock)
{
HEAP_ENTRY * pEntry = (HEAP_ENTRY *)pBlock-1;
//DWORD Size = pEntry->Size * sizeof(HEAP_ENTRY) - sizeof(HEAP_ENTRY);
DWORD Size = pEntry->Size * sizeof(HEAP_ENTRY) - pEntry->UnusedBytes;
memset(pBlock,0x00,Size);
//if (pEntry->Size & 0xF000)
//{
// // too big, warn the user
// DebugBreak();
//}
if (pEntry->Size >=4)
{
RtlCaptureStackBackTrace (1,
(4 == pEntry->Size)?4:6,
(PVOID *)(pEntry+2),
pLong);
}
}
return 0;
}
void __declspec(naked) Foo()
{
_asm {
// 3 bytes comes from 'ret c'
// two bytes for getting up to 5, this is 'push ebp' ; mov ebp,esp'; 'push ff'
nop
nop
;
nop // here is the space for JUMP rel32
nop
nop
nop
nop
}
}
DWORD intercept()
{
Real_RtlAlloc = GetProcAddress(GetModuleHandleW(L"ntdll.dll"),"RtlAllocateHeap");
Real_RtlFree = GetProcAddress(GetModuleHandleW(L"ntdll.dll"),"RtlFreeHeap");
MEMORY_BASIC_INFORMATION MemBI;
DWORD dwOldProtect;
BOOL bRet;
DWORD dwRet = VirtualQuery(Real_RtlFree,&MemBI,sizeof(MemBI));
bRet = VirtualProtect(MemBI.BaseAddress,
MemBI.RegionSize,
PAGE_EXECUTE_WRITECOPY,
&dwOldProtect);
if (bRet)
{
//__RtlFreeHeap
VirtualQuery(__RtlFreeHeap,&MemBI,sizeof(MemBI));
bRet = VirtualProtect(MemBI.BaseAddress,
MemBI.RegionSize,
PAGE_EXECUTE_WRITECOPY,
&dwOldProtect);
if (bRet)
{
VOID * pToJump = (VOID *)__RtlFreeHeap;
BYTE Arr[SIZE_JUMP_ADR] = { 0xe9 };
BYTE StorageFree[SIZE_JUMP_ADR];
LONG * pOffset = (LONG *)&Arr[1];
* pOffset = (LONG)__RtlFreeHeap - (LONG)Real_RtlFree - SIZE_JUMP_ADR ;
// save the old code
memcpy(StorageFree,Real_RtlFree,SIZE_JUMP_ADR);
// put the new code
memcpy(Real_RtlFree,Arr,SIZE_JUMP_ADR);
// prepare the exit code of the interceptor to call back the old code
BYTE * pRestore = (BYTE *)Foo-SIZE_RET_0C;
memcpy(pRestore,StorageFree,SIZE_JUMP_ADR);
pRestore[SIZE_JUMP_ADR] = 0xe9;
pOffset = (LONG *)&pRestore[SIZE_JUMP_ADR+1];
*pOffset = (LONG)Real_RtlFree + SIZE_JUMP_ADR - (LONG)pRestore - SIZE_JUMP_ADR - SIZE_JUMP_ADR;
}
}
else
{
//printf("VirtualProtect err %d\n",GetLastError());
DebugBreak();
}
return 0;
}
#endif
/******************************************************************************
*
* Name:
*
* `
* Description:
*
*
*****************************************************************************/
IntegerCacheController *g_CacheController = NULL ;
/******************************************************************************
*
* Name:
*
* `
* Description:
*
*
*****************************************************************************/
HRESULT Process_MultiThread ( ULONG a_OperationCount )
{
HRESULT t_Result = S_OK ;
WmiAllocator t_Allocator ;
WmiStatusCode t_StatusCode = t_Allocator.Initialize () ;
if ( t_StatusCode == e_StatusCode_Success )
{
WmiStatusCode t_StatusCode = WmiThread <ULONG> :: Static_Initialize ( t_Allocator ) ;
ClientThread **t_ThreadContainer = new ClientThread * [ 4 ] ;
if ( t_ThreadContainer )
{
for ( ULONG t_Index = 0 ; t_Index < 4 ; t_Index ++ )
{
t_ThreadContainer [ t_Index ] = new ClientThread ( t_Allocator , a_OperationCount ) ;
ClientThread *t_Thread = t_ThreadContainer [ t_Index ] ;
if ( t_Thread )
{
t_Thread->AddRef () ;
t_StatusCode = t_Thread->Initialize () ;
t_Thread->EnQueue ( 0 , *t_Thread->GetTask () ) ;
}
}
for ( t_Index = 0 ; t_Index < 4 ; t_Index ++ )
{
ClientThread *t_Thread = t_ThreadContainer [ t_Index ] ;
t_Thread->GetTask ()->WaitInterruptable () ;
}
for ( t_Index = 0 ; t_Index < 4 ; t_Index ++ )
{
ClientThread *t_Thread = t_ThreadContainer [ t_Index ] ;
HANDLE t_ThreadHandle = NULL ;
BOOL t_Status = DuplicateHandle (
GetCurrentProcess () ,
t_Thread->GetHandle () ,
GetCurrentProcess () ,
& t_ThreadHandle,
0 ,
FALSE ,
DUPLICATE_SAME_ACCESS
) ;
t_Thread->Release () ;
WaitForSingleObject ( t_ThreadHandle , INFINITE ) ;
CloseHandle ( t_ThreadHandle ) ;
}
delete [] t_ThreadContainer ;
}
t_StatusCode = WmiThread <ULONG> :: Static_UnInitialize ( t_Allocator ) ;
}
else
{
t_Result = WBEM_E_OUT_OF_MEMORY ;
}
return t_Result ;
}
/******************************************************************************
*
* Name:
*
*
* Description:
*
*
*****************************************************************************/
void Process ( ULONG a_OperationCount )
{
HRESULT t_Result = Process_MultiThread ( a_OperationCount );
}
/******************************************************************************
*
* Name:
*
*
* Description:
*
*
*****************************************************************************/
EXTERN_C int __cdecl wmain (
int argc ,
char **argv
)
{
// intercept();
srand ( GetTickCount () ) ;
WmiAllocator t_Allocator ;
WmiStatusCode t_StatusCode = t_Allocator.Initialize () ;
if ( t_StatusCode == e_StatusCode_Success )
{
g_CacheController = new IntegerCacheController (
t_Allocator
) ;
if ( g_CacheController )
{
g_CacheController->AddRef () ;
if ( g_CacheController->Initialize () == e_StatusCode_Success )
{
ULONG t_OperationCount = 0x30000000 ;
Process ( t_OperationCount ) ;
g_CacheController->UnInitialize () ;
}
g_CacheController->Release () ;
}
}
return 0 ;
}