📄 injectmanager.c
字号:
}
return (DWORD)TRUE;
}
void AfterOriginalFunction( DWORD hookIndex, PDWORD originalStack, DWORD* returnParameter, IN_PROCESS_DATA* callData )
{
}
// EndOfInjectedCode - DetourFunction = size of injected code
// Content doesn't matter, so just trap a debug exception
void __declspec(naked) EndOfInjectedCode( void )
{
__asm int 3
}
////////////////////////////////
// End injected functions
////////////////////////////////
PCHAR allocateUserMemory()
{
LONG memorySize;
LONG tableSize;
LONG codeSize;
LONG dataSize;
ULONG buffer[2];
NTSTATUS status;
PCHAR pMemory;
IN_PROCESS_DATA* pData;
// Calculate sizes
// table = (DetourFunction - HookTable) * TOTAL_HOOKS
// code = EndOfInjectedCode - DetourFunction
// data = sizof( IN_PROCESS_DATA )
__asm
{
lea eax, HookTable
lea ebx, DetourFunction
lea ecx, EndOfInjectedCode
mov edx, ebx
sub edx, eax
mov tableSize, edx
mov edx, ecx
sub edx, ebx
mov codeSize, edx
}
tableSize = tableSize * TOTAL_HOOKS;
dataSize = sizeof( IN_PROCESS_DATA );
memorySize = tableSize + codeSize + dataSize;
// Allocate memory
buffer[0] = 0;
buffer[1] = memorySize;
status = ZwAllocateVirtualMemory( (HANDLE)-1, (PVOID*)buffer, 0, &buffer[1], MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE );
pMemory = (PCHAR)(buffer[0]);
if( !NT_SUCCESS( status ) || !pMemory )
return NULL;
// initialize memory
memset( pMemory, 0x90, tableSize + codeSize );
pData = (IN_PROCESS_DATA*)(pMemory + tableSize + codeSize );
memset( (PVOID)pData, 0, dataSize );
return pMemory;
}
ULONG getx86Instruction( PCHAR originalCode, PCHAR instructionBuffer, ULONG bufferLength )
{
PBYTE source = NULL;
PBYTE destination = NULL;
ULONG ulCopied = 0;
PBYTE jumpAddress = NULL;
LONG extra = 0;
memset( instructionBuffer, 0, bufferLength );
source = (PBYTE)originalCode;
destination = (PBYTE)instructionBuffer;
jumpAddress = NULL;
extra = 0;
// start with 5 bytes
for( ulCopied = 0; ulCopied < 5; )
{
source = transferInstruction( destination, source, &jumpAddress, &extra );
if( !source )
{
memset( instructionBuffer, 0, bufferLength );
ulCopied = 0;
break;
}
ulCopied = (DWORD)source - (DWORD)originalCode;
if( ulCopied >= bufferLength )
{
ASSERT( FALSE );
break;
}
destination = (PBYTE)instructionBuffer + ulCopied;
}
return ulCopied;
}
BOOL makeWritable( PVOID address, ULONG size )
{
NTSTATUS status;
ULONG pageAccess;
ULONG ZwProtectArray[3] = { 0 };
pageAccess = PAGE_EXECUTE_READWRITE;
ZwProtectArray[0] = (ULONG)address;
ZwProtectArray[1] = size;
ZwProtectArray[2] = 0;
status = OldZwProtectVirtualMemory( (HANDLE)-1,
(PVOID *)(&(ZwProtectArray[0])),
&(ZwProtectArray[1]),
pageAccess,
&(ZwProtectArray[2]) );
if( !NT_SUCCESS( status ) )
return FALSE;
return TRUE;
}
// Parse first instruction of original function.
// Replace first instruction with jump to hook.
// Save first instruction to trampoline function.
// Only call original function through trampoline.
BOOL createTrampoline( PCHAR originalAddress, PCHAR tableAddress, PCHAR trampolineAddress )
{
ULONG newOriginalAddress = 0;
char instruction[MAX_INSTRUCTION] = { 0 };
ULONG instructionLength;
instructionLength = getx86Instruction( originalAddress, instruction, sizeof(instruction) );
newOriginalAddress = (ULONG)(originalAddress + instructionLength);
// see if it's a jump
if( isJump( instruction, instructionLength ) )
{
PVOID pOldDstAddr = (PVOID)(GET_JUMP( instruction ));
if( pOldDstAddr )
{
// If first instruction of original function
// is a jump, trampoline instruction is NO-OP
// and jump target is original jump target
memset( instruction, 0x90, sizeof(instruction) );
instructionLength = 0;
newOriginalAddress = (ULONG)pOldDstAddr;
}
else
{
return FALSE;
}
}
if( makeWritable( (PVOID)trampolineAddress, MAX_INSTRUCTION + 5 ) )
{
// write trampoline function
memset( trampolineAddress, 0x90, MAX_INSTRUCTION + 5 );
memcpy( trampolineAddress, instruction, instructionLength );
INJECT_JUMP( trampolineAddress + instructionLength, newOriginalAddress );
// set original function to jump to trampoline function
if( makeWritable( originalAddress, instructionLength + 5 ) )
{
INJECT_JUMP( originalAddress, tableAddress );
return TRUE;
}
}
return FALSE;
}
BOOL getHookPointers( PCHAR pMemory, PCHAR* pTable, PCHAR* pCode, PCHAR* pData )
{
LONG tableSize = 0;
LONG codeSize = 0;
LONG dataSize = 0;
__asm
{
lea eax, HookTable
lea ebx, DetourFunction
lea ecx, EndOfInjectedCode
mov edx, ebx
sub edx, eax
mov tableSize, edx
mov edx, ecx
sub edx, ebx
mov codeSize, edx
}
tableSize = tableSize * TOTAL_HOOKS;
dataSize = sizeof(IN_PROCESS_DATA);
*pTable = pMemory;
*pCode = *pTable + tableSize;
*pData = *pCode + codeSize;
return TRUE;
}
BOOL processInject( CALL_DATA_STRUCT* pCallData, int hooks, PCHAR pMemory )
{
int loop;
int offsetToPattern;
PCHAR pNewTable;
PCHAR pNewCode;
IN_PROCESS_DATA* pNewData;
PCHAR pOldTable;
PCHAR pOldCode;
PCHAR pOldData;
DWORD tableLength;
DWORD tableOffset;
PCHAR callDataOffset;
if( !kernel32Base )
return FALSE;
if( !getHookPointers( pMemory, &pNewTable, &pNewCode, (PCHAR*)&pNewData ) )
return FALSE;
pNewData->pOutputDebugStringA = (PROTOTYPE_OutputDebugStringA)GetFunctionAddress( kernel32Base, "OutputDebugStringA", NULL, 0 );
pNewData->pOutputDebugStringW = (PROTOTYPE_OutputDebugStringW)GetFunctionAddress( kernel32Base, "OutputDebugStringW", NULL, 0 );
pNewData->pCloseHandle = (PROTOTYPE_CloseHandle)GetFunctionAddress( kernel32Base, "CloseHandle", NULL, 0 );
pNewData->pSleep = (PROTOTYPE_Sleep)GetFunctionAddress( kernel32Base, "Sleep", NULL, 0 );
pNewData->pCreateFileW = (PROTOTYPE_CreateFileW)GetFunctionAddress( kernel32Base, "CreateFileW", NULL, 0 );
pNewData->plstrlenA = (PROTOTYPE_lstrlenA)GetFunctionAddress( kernel32Base, "lstrlenA", NULL, 0 );
pNewData->plstrlenW = (PROTOTYPE_lstrlenW)GetFunctionAddress( kernel32Base, "lstrlenW", NULL, 0 );
pNewData->plstrcpynA = (PROTOTYPE_lstrcpynA)GetFunctionAddress( kernel32Base, "lstrcpynA", NULL, 0 );
pNewData->plstrcpynW = (PROTOTYPE_lstrcpynW)GetFunctionAddress( kernel32Base, "lstrcpynW", NULL, 0 );
pNewData->plstrcpyA = (PROTOTYPE_lstrcpyA)GetFunctionAddress( kernel32Base, "lstrcpyA", NULL, 0 );
pNewData->plstrcpyW = (PROTOTYPE_lstrcpyW)GetFunctionAddress( kernel32Base, "lstrcpyW", NULL, 0 );
pNewData->plstrcmpiA = (PROTOTYPE_lstrcmpiA)GetFunctionAddress( kernel32Base, "lstrcmpiA", NULL, 0 );
pNewData->plstrcmpiW = (PROTOTYPE_lstrcmpiW)GetFunctionAddress( kernel32Base, "lstrcmpiW", NULL, 0 );
pNewData->plstrcmpA = (PROTOTYPE_lstrcmpA)GetFunctionAddress( kernel32Base, "lstrcmpA", NULL, 0 );
pNewData->plstrcmpW = (PROTOTYPE_lstrcmpW)GetFunctionAddress( kernel32Base, "lstrcmpW", NULL, 0 );
pNewData->plstrcatA = (PROTOTYPE_lstrcatA)GetFunctionAddress( kernel32Base, "lstrcatA", NULL, 0 );
pNewData->plstrcatW = (PROTOTYPE_lstrcatW)GetFunctionAddress( kernel32Base, "lstrcatW", NULL, 0 );
sprintf( pNewData->debugString, "This is a string contained in injected memory\n" );
__asm
{
lea eax, HookTable
mov pOldTable, eax
lea eax, DetourFunction
mov pOldCode, eax
lea eax, EndOfInjectedCode
mov pOldData, eax
}
memcpy( pNewCode, pOldCode, pOldData - pOldCode );
tableLength = pOldCode - pOldTable;
for( loop = 0; loop < (int)tableLength - 4; loop ++ )
{
if( *(PDWORD)(pOldTable+loop) == (DWORD)START_OF_TRAMPOLINE_PATTERN )
{
offsetToPattern = loop;
break;
}
}
for( loop = 0; loop < hooks; loop ++ )
{
tableOffset = tableLength * pCallData[loop].index;
callDataOffset = pNewTable + tableOffset + offsetToPattern;
memcpy( pNewTable + tableOffset, pOldTable, tableLength );
*((PDWORD)(callDataOffset + CALLDATA_INDEX_LOCATION)) = pCallData[loop].index;
*((PDWORD)(callDataOffset + CALLDATA_PARAMETERS_LOCATION)) = pCallData[loop].parameters;
*((PDWORD)(callDataOffset + CALLDATA_CALLTYPE_LOCATION)) = pCallData[loop].callType;
*((PDWORD)(callDataOffset + CALLDATA_STACK_OFFSET_LOCATION)) = pCallData[loop].stackOffset;
INJECT_JUMP( callDataOffset + JUMP_TO_DETOUR_LOCATION, pNewCode );
createTrampoline( pCallData[loop].hookFunction,
pNewTable + tableOffset,
callDataOffset + TRAMPOLINE_LOCATION);
}
return TRUE;
}
#pragma optimize( "", on )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -