// injDllStartHLP.cpp : Defines the entry point for the DLL application.
//

#include "stdafx.h"
#include "injDllStartHLP.h"
#include "NTWriteProcessMemory.h"


#ifdef _MANAGED
#pragma managed(push, off)
#endif

BOOL WINAPI _DllMainCRTStartup(
    HMODULE hModule,
    DWORD  ul_reason_for_call,
    LPVOID lpReserved
	)
{
    hModule;
    lpReserved;
	switch (ul_reason_for_call)
	{
	case DLL_PROCESS_ATTACH:
	case DLL_THREAD_ATTACH:
	case DLL_THREAD_DETACH:
	case DLL_PROCESS_DETACH:
		break;
	}
    return TRUE;
}

#ifdef _MANAGED
#pragma managed(pop)
#endif

INJDLLSTARTHLP_API WCHAR g_wsInjDllName[260];
INJDLLSTARTHLP_API WCHAR g_wsInjHelpDllName[260];
INJDLLSTARTHLP_API BYTE g_baSaveStartIns[sizeof(JumpIndInstAddress)];
INJDLLSTARTHLP_API PBYTE g_pEntryPoint;
INJDLLSTARTHLP_API LDR_DATA_TABLE_ENTRY g_stProcessModuleInfo;
INJDLLSTARTHLP_API LDR_DATA_TABLE_ENTRY g_stNtDllModuleInfo;
INJDLLSTARTHLP_API LDR_DATA_TABLE_ENTRY g_stInjDllModuleInfo;
INJDLLSTARTHLP_API WCHAR g_wsProcessModuleFileName[260];
INJDLLSTARTHLP_API WCHAR g_wsNtDllModuleFileName[260];
INJDLLSTARTHLP_API PEB_LDR_DATA g_stModuleListTable;
INJDLLSTARTHLP_API TStartupRoutine g_pfStartupRoutine = NULL;
INJDLLSTARTHLP_API TStartupRoutine g_pfInjectDllStartup = NULL;

/* Subsystem initialization stuff */
void __cdecl _RTC_Shutdown(void)
{
}

void __cdecl _RTC_InitBase(void)
{
}


INJDLLSTARTHLP_API int NTAPI injectDllStartup(void)
{
    UNICODE_STRING usInjDllName;
    HANDLE  hInjDllHandle;
    NTSTATUS nNtStatus = 0;
    //::DbgBreakPoint();
    RtlInitUnicodeString(
        &usInjDllName,
        g_wsInjDllName
        );
    nNtStatus = LdrLoadDll(
        NULL,
        0,
        &usInjDllName,
        &hInjDllHandle
        );
    if (nNtStatus < 0)
    {
        ::DbgBreakPoint();
        return nNtStatus;
    }
    nNtStatus = NTWriteProcessMemory(
        NtCurrentProcess(),
        (PVOID) g_pEntryPoint,
        (PVOID) g_baSaveStartIns,
        sizeof(g_baSaveStartIns),
        NULL
        );
    if (nNtStatus < 0)
    {
        ::DbgBreakPoint();
        return nNtStatus;
    }
    return g_pfStartupRoutine();
}

INJDLLSTARTHLP_API void NTAPI remoteThreadRoutine(void* Argument)
{
    UNICODE_STRING usInjDllName;
    HANDLE  hInjDllHandle;
    NTSTATUS nNtStatus = 0;
    Argument;
    //::DbgBreakPoint();
    RtlInitUnicodeString(
        &usInjDllName,
        g_wsInjDllName
        );
    nNtStatus = LdrLoadDll(
        NULL,
        0,
        &usInjDllName,
        &hInjDllHandle
        );
    RtlExitUserThread(nNtStatus);
}
