示例#1
0
BOOL InitializeW64oWoW64()
{

	void * lvpNtdll = GetModuleBase64( L"ntdll.dll" );
	UNICODE_STRING64 sUnicodeString;
	__int8 * lvpKernelBaseBase;
	__int8 * lvpKernel32Base;
	PLDR_DATA_TABLE_ENTRY64 lpsKernel32Ldr;
	PLDR_DATA_TABLE_ENTRY64 lpsKernelBaseLdr;

	sFunctions.LdrGetKnownDllSectionHandle = GetProcAddress64( lvpNtdll, 
		"LdrGetKnownDllSectionHandle" );
	sFunctions.NtFreeVirtualMemory = GetProcAddress64( lvpNtdll, 
		"NtFreeVirtualMemory" );
	sFunctions.NtMapViewOfSection = GetProcAddress64( lvpNtdll, 
		"NtMapViewOfSection" );
	sFunctions.NtUnmapViewOfSection = GetProcAddress64( lvpNtdll, 
		"NtUnmapViewOfSection" );

	if( FreeKnownDllPage( L"kernel32.dll" ) == FALSE) return FALSE;
	if( FreeKnownDllPage( L"user32.dll" ) == FALSE ) return FALSE;

	sUnicodeString.Length = 0x18;
	sUnicodeString.MaximumLength = 0x1a;
	sUnicodeString.Buffer = (DWORD64)L"kernel32.dll";
	if( X64Call( GetProcAddress64( lvpNtdll, "LdrLoadDll" ), 4, 
		(DWORD64)0, 
		(DWORD64)0, 
		(DWORD64)&sUnicodeString, 
		(DWORD64)&lvpKernel32Base ) != NULL ) {
			PrintLastError();
			return FALSE;
	}

	lvpKernelBaseBase = (__int8 *)GetModuleBase64( L"KERNELBASE.dll");
	X64Call( ( lvpKernelBaseBase + (int)GetModule64EntryRVA( lvpKernelBaseBase ) ), 
		3, 
		(DWORD64)lvpKernelBaseBase, 
		(DWORD64)DLL_PROCESS_ATTACH, 
		(DWORD64)0 );

	X64Call( ( lvpKernel32Base + (int)GetModule64EntryRVA( lvpKernel32Base ) ), 
		3, 
		(DWORD64)lvpKernel32Base, 
		(DWORD64)DLL_PROCESS_ATTACH, 
		(DWORD64)0 );

	lpsKernel32Ldr = GetModule64LdrTable( L"kernel32.dll" );
	lpsKernel32Ldr->LoadCount = 0xffff;
	lpsKernel32Ldr->Flags += LDRP_ENTRY_PROCESSED | LDRP_PROCESS_ATTACH_CALLED;

	lpsKernelBaseLdr = GetModule64LdrTable( L"KERNELBASE.dll" );
	lpsKernelBaseLdr->LoadCount = 0xffff;
	lpsKernelBaseLdr->Flags += LDRP_ENTRY_PROCESSED | LDRP_PROCESS_ATTACH_CALLED;

	return TRUE;
}
示例#2
0
extern __declspec(dllexport) void * LoadLibrary64A( char * lpcLibraryName )
{
	if( sFunctions.LoadLibraryA == NULL ) {
		sFunctions.LoadLibraryA = 
			GetProcAddress64( GetModuleBase64( L"kernel32.dll" ), "LoadLibraryA" );
	}
	return (void *)X64Call( sFunctions.LoadLibraryA, 1, (DWORD64)lpcLibraryName );
}
示例#3
0
	DWORD64 Wow64Local::LoadLibrary64(const wchar_t* path) {
		_UNICODE_STRING_T<DWORD64> upath = {0};
		DWORD64 hModule = 0;
		DWORD64 pfnLdrLoad = GetProcAddress64(GetNTDLL64(), "LdrLoadDll");
		upath.Length = (WORD)wcslen(path) * sizeof(wchar_t);
		upath.MaximumLength = (WORD)upath.Length;
		upath.Buffer = (DWORD64)path;
		X64Call(pfnLdrLoad, NULL, 0, &upath, &hModule);
		return hModule;
	};
示例#4
0
extern "C" SIZE_T __cdecl VirtualQueryEx64(HANDLE hProcess, DWORD64 lpAddress, MEMORY_BASIC_INFORMATION64* lpBuffer, SIZE_T dwLength)
{
    static DWORD64 ntqvm = 0;
    if (0 == ntqvm)
    {
        ntqvm = GetProcAddress64(getNTDLL64(), "NtQueryVirtualMemory");
        if (0 == ntqvm)
            return 0;
    }
    DWORD64 ret = 0;
    DWORD64 status = X64Call(ntqvm, 6, (DWORD64)hProcess, lpAddress, (DWORD64)0, (DWORD64)lpBuffer, (DWORD64)dwLength, (DWORD64)&ret);
	if (STATUS_SUCCESS != status)
		SetLastErrorFromX64Call(status);
	return (SIZE_T)ret;
}
示例#5
0
extern "C" BOOL __cdecl SetThreadContext64(HANDLE hThread, _CONTEXT64_2* lpContext)
{
    static DWORD64 stc = 0;
    if (0 == stc)
    {
        stc = GetProcAddress64(getNTDLL64(), "NtSetContextThread");
        if (0 == stc)
            return 0;
    }
    DWORD64 ret = X64Call(stc, 2, (DWORD64)hThread, (DWORD64)lpContext);
	if (STATUS_SUCCESS != ret)
	{
		SetLastErrorFromX64Call(ret);
		return FALSE;
	}
    else
        return TRUE;
}
示例#6
0
DWORD64 WoW64dm::LoadLibrary64( const wchar_t* path )
{
    BOOL isWOW = FALSE;
    IsWow64Process(_hProcess, &isWOW);

    // Inject into x64
    if(isWOW == FALSE)
    {
        DWORD64 memptr = 0;

        VirtualAllocEx64(memptr, 0x1000, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);

        if(memptr != 0)
        {
            DWORD size = 0;

            DWORD64 hKernel32 = GetModuleHandle64(L"Kernel32.dll", &size);
            DWORD64 pLoadLib  = GetProcAddress64(hKernel32, size, "LoadLibraryW");

            if(pLoadLib != 0 && WriteProcessMemory64(memptr, (LPVOID)path, (wcslen(path) + 1)*sizeof(wchar_t), 0) == STATUS_SUCCESS)
            {
                DWORD64 status = 0;

                if(CreateRemoteThread64(pLoadLib, memptr, status, true) != FALSE && status == STATUS_SUCCESS)
                {
                    VirtualFreeEx64(memptr, 0x1000, MEM_RELEASE);
                    return status;
                }
            }

            VirtualFreeEx64(memptr, 0x1000, MEM_FREE);
        }

        return FALSE;
    }
    // Inject into WOW64
    else
    {
        return LoadLibraryRemoteWOW64(path);
    }
}
示例#7
0
extern "C" BOOL __cdecl VirtualProtectEx64(HANDLE hProcess, DWORD64 lpAddress, SIZE_T dwSize, DWORD flNewProtect, DWORD* lpflOldProtect)
{
    static DWORD64 ntpvm = 0;
    if (0 == ntpvm)
    {
        ntpvm = GetProcAddress64(getNTDLL64(), "NtProtectVirtualMemory");
        if (0 == ntpvm)
            return 0;
    }

    DWORD64 tmpAddr = lpAddress;
    DWORD64 tmpSize = dwSize;
    DWORD64 ret = X64Call(ntpvm, 5, (DWORD64)hProcess, (DWORD64)&tmpAddr, (DWORD64)&tmpSize, (DWORD64)flNewProtect, (DWORD64)lpflOldProtect);
	if (STATUS_SUCCESS != ret)
	{
		SetLastErrorFromX64Call(ret);
		return FALSE;
	}
    else
        return TRUE;
}
示例#8
0
extern "C" BOOL __cdecl VirtualFreeEx64(HANDLE hProcess, DWORD64 lpAddress, SIZE_T dwSize, DWORD dwFreeType)
{
    static DWORD64 ntfvm = 0;
    if (0 == ntfvm)
    {
        ntfvm = GetProcAddress64(getNTDLL64(), "NtFreeVirtualMemory");
        if (0 == ntfvm)
            return 0;
    }

    DWORD64 tmpAddr = lpAddress;
    DWORD64 tmpSize = dwSize;
    DWORD64 ret = X64Call(ntfvm, 4, (DWORD64)hProcess, (DWORD64)&tmpAddr, (DWORD64)&tmpSize, (DWORD64)dwFreeType);
	if (STATUS_SUCCESS != ret)
	{
		SetLastErrorFromX64Call(ret);
		return FALSE;
	}
    else
        return TRUE;
}
示例#9
0
extern "C" DWORD64 __cdecl VirtualAllocEx64(HANDLE hProcess, DWORD64 lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect)
{
    static DWORD64 ntavm = 0;
    if (0 == ntavm)
    {
        ntavm = GetProcAddress64(getNTDLL64(), "NtAllocateVirtualMemory");
        if (0 == ntavm)
            return 0;
    }

    DWORD64 tmpAddr = lpAddress;
    DWORD64 tmpSize = dwSize;
    DWORD64 ret = X64Call(ntavm, 6, (DWORD64)hProcess, (DWORD64)&tmpAddr, (DWORD64)0, (DWORD64)&tmpSize, (DWORD64)flAllocationType, (DWORD64)flProtect);
	if (STATUS_SUCCESS != ret)
	{
		SetLastErrorFromX64Call(ret);
		return FALSE;
	}
    else
        return tmpAddr;
}
示例#10
0
extern "C" BOOL __cdecl WriteProcessMemory64(HANDLE hProcess, DWORD64 lpBaseAddress, LPVOID lpBuffer, SIZE_T nSize, SIZE_T *lpNumberOfBytesWritten)
{
    static DWORD64 nrvm = 0;
    if (0 == nrvm)
    {
        nrvm = GetProcAddress64(getNTDLL64(), "NtWriteVirtualMemory");
        if (0 == nrvm)
            return 0;
    }
    DWORD64 numOfBytes = lpNumberOfBytesWritten ? *lpNumberOfBytesWritten : 0;
    DWORD64 ret = X64Call(nrvm, 5, (DWORD64)hProcess, lpBaseAddress, (DWORD64)lpBuffer, (DWORD64)nSize, (DWORD64)&numOfBytes);
	if (STATUS_SUCCESS != ret)
	{
		SetLastErrorFromX64Call(ret);
		return FALSE;
	}
    else
    {
        if (lpNumberOfBytesWritten)
            *lpNumberOfBytesWritten = (SIZE_T)numOfBytes;
        return TRUE;
    }
}
示例#11
0
	bool injectdll_x64(const PROCESS_INFORMATION& pi, const std::wstring& dll) {
		static unsigned char sc[] = {
			0x9c,                                                                   // pushfq
			0x50,                                                                   // push rax
			0x51,                                                                   // push rcx
			0x52,                                                                   // push rdx
			0x53,                                                                   // push rbx
			0x55,                                                                   // push rbp
			0x56,                                                                   // push rsi
			0x57,                                                                   // push rdi
			0x41, 0x50,                                                             // push r8
			0x41, 0x51,                                                             // push r9
			0x41, 0x52,                                                             // push r10
			0x41, 0x53,                                                             // push r11
			0x41, 0x54,                                                             // push r12
			0x41, 0x55,                                                             // push r13
			0x41, 0x56,                                                             // push r14
			0x41, 0x57,                                                             // push r15
			0x48, 0x83, 0xEC, 0x28,                                                 // sub rsp, 0x28
			0x49, 0xB9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,             // mov  r9, 0  // DllHandle
			0x49, 0xB8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,             // mov  r8, 0  // DllPath
			0x48, 0xB8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,             // mov  rax,0  // LdrLoadDll
			0x48, 0x31,                                                             // xor  rcx,rcx
			0xC9, 0x48,                                                             // xor  rdx,rdx
			0xFF, 0xD0,                                                             // call rax   LdrLoadDll
			0x48, 0x83, 0xC4, 0x28,                                                 // add rsp, 0x28
			0x41, 0x5F,                                                             // pop r15
			0x41, 0x5E,                                                             // pop r14
			0x41, 0x5D,                                                             // pop r13
			0x41, 0x5C,                                                             // pop r12
			0x41, 0x5B,                                                             // pop r11
			0x41, 0x5A,                                                             // pop r10
			0x41, 0x59,                                                             // pop r9
			0x41, 0x58,                                                             // pop r8
			0x5F,                                                                   // pop rdi
			0x5E,                                                                   // pop rsi
			0x5D,                                                                   // pop rbp
			0x5B,                                                                   // pop rbx
			0x5A,                                                                   // pop rdx
			0x59,                                                                   // pop rcx
			0x58,                                                                   // pop rax
			0x9D,                                                                   // popfq
			0xFF, 0x25, 0x00, 0x00, 0x00, 0x00,                                     // jmp offset
			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00                          // rip
		};
		
		InitWow64ext();
		DWORD64 pfLoadLibrary = (DWORD64)GetProcAddress64(GetModuleHandle64(L"ntdll.dll"), "LdrLoadDll");
		if (!pfLoadLibrary) {
			return false;
		}

		struct UNICODE_STRING {
			USHORT    Length;
			USHORT    MaximumLength;
			DWORD64   Buffer;
		};
		SIZE_T memsize = sizeof(DWORD64) + sizeof(UNICODE_STRING) + (dll.size() + 1) * sizeof(wchar_t);
		DWORD64 memory = VirtualAllocEx64(pi.hProcess, NULL, memsize, MEM_COMMIT, PAGE_READWRITE);
		if (!memory) {
			return false;
		}
		DWORD64 shellcode = VirtualAllocEx64(pi.hProcess, NULL, sizeof(sc), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
		if (!shellcode) {
			return false;
		}

		UNICODE_STRING us;
		us.Length = (USHORT)(dll.size() * sizeof(wchar_t));
		us.MaximumLength = us.Length + sizeof(wchar_t);
		us.Buffer = memory + sizeof(UNICODE_STRING);

		SIZE_T written = 0;
		BOOL ok = FALSE;
		ok = WriteProcessMemory64(pi.hProcess, memory, &us, sizeof(UNICODE_STRING), &written);
		if (!ok || written != sizeof(UNICODE_STRING)) {
			return false;
		}
		ok = WriteProcessMemory64(pi.hProcess, us.Buffer, (void*)dll.data(), us.MaximumLength, &written);
		if (!ok || written != us.MaximumLength) {
			return false;
		}

		_CONTEXT64 ctx = { 0 };
		ctx.ContextFlags = CONTEXT_CONTROL;
		if (!GetThreadContext64(pi.hThread, &ctx)) {
			return false;
		}

		DWORD64 handle = us.Buffer + us.MaximumLength;
		memcpy(sc + 30, &handle, sizeof(handle));
		memcpy(sc + 40, &memory, sizeof(memory));
		memcpy(sc + 50, &pfLoadLibrary, sizeof(pfLoadLibrary));
		memcpy(sc + 98, &ctx.Rip, sizeof(ctx.Rip));
		ok = WriteProcessMemory64(pi.hProcess, shellcode, &sc, sizeof(sc), &written);
		if (!ok || written != sizeof(sc)) {
			return false;
		}

		ctx.ContextFlags = CONTEXT_CONTROL;
		ctx.Rip = shellcode;
		if (!SetThreadContext64(pi.hThread, &ctx)) {
			return false;
		}
		return true;
	}
示例#12
0
/*
    Memory layout. 
    Function additionally writes Activation Context pointer into TEB for RtlQueryInformationActivationContext.

    ------------------------------------------------------------------------------------
    |  Return handle  |   UNICODE_STRING   |  dll path  |  padding  | executable code  | 
    ------------------------------------------------------------------------------------
*/
DWORD64 WoW64dm::LoadLibraryRemoteWOW64( const wchar_t* path )
{
    DWORD64 memptr = 0;
    int idx = 0;
    _UNICODE_STRING_T<DWORD64> upath = {0};

    VirtualAllocEx64(memptr, 0x1000, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);

    if(memptr != 0)
    {
        DWORD size = 0;
        DWORD64 hNtdll = GetModuleHandle64(L"ntdll.dll", &size);
        DWORD64 pfnLdrLoadDll = GetProcAddress64(hNtdll, size, "LdrLoadDll");

        upath.Length        = wcslen(path) * sizeof(wchar_t);
        upath.MaximumLength = upath.Length;
        upath.Buffer        = memptr + 0x100;
        DWORD64 codeAddr    = memptr + 0xA00;

        uint8_t code[] = 
        { 
            // Enter x64 mode
            0x6A, 0x33, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x83, 0x04, 0x24, 0x05, 0xCB,         

            0x65, 0x48, 0x8B, 0x04, 0x25, 0x30, 0x00, 0x00, 0x00,           // mov rax, gs:[30]
            0x48, 0xBA, 0xEF, 0xBE, 0xAD, 0xDE, 0xEF, 0xBE, 0xAD, 0xDE,     // movabs rdx, memptr + 0x700
            0x48, 0x89, 0x90, 0xC8, 0x02, 0x00, 0x00,                       // mov QWORD PTR [rax + 0x2c8],rdx
            0x48, 0x89, 0xE5,                                               // mov rbp, rsp
            0x48, 0x83, 0xE4, 0xF0,                                         // and rsp, 0xfffffffffffffff0
            0x48, 0x83, 0xEC, 0x28,                                         // sub rsp, 0x30
            0x48, 0x31, 0xC9,                                               // xor rcx, rcx
            0x48, 0x31, 0xD2,                                               // xor rdx, rdx
            0x49, 0xB8, 0xEF, 0xBE, 0xAD, 0xDE, 0xEF, 0xBE, 0xAD, 0xDE,     // movabs r8, &upath                        
            0x49, 0xB9, 0xEF, 0xBE, 0xAD, 0xDE, 0xEF, 0xBE, 0xAD, 0xDE,     // movabs r9, &memptr
            0x48, 0xB8, 0xEF, 0xBE, 0xAD, 0xDE, 0xEF, 0xBE, 0xAD, 0xDE,     // movabs rax, LdrLoadDll
            //0xCC, 
            0xFF, 0xD0,                                                     // call rax
            0x48, 0x89, 0xEC,                                               // mov rsp, rbp

            // Leave x64 mode
            0xE8, 0x00, 0x00, 0x00, 0x00, 0xC7, 0x44, 0x24, 0x04, 0x23, 0x00, 0x00, 0x00, 0x83, 0x04, 0x24, 0x0D, 0xCB, 
            0xC2, 0x04, 0x00    // retn 0x4
        };

        DWORD64 patch[] = { memptr + 0x700, memptr + 0x10, memptr, pfnLdrLoadDll };

        // Patch immediate memory values
        for(uint8_t* ptr = code; ptr < (code + sizeof(code) - 8); ptr++)
        {
            if(*(DWORD64*)ptr == (DWORD64)0xDEADBEEFDEADBEEF)
            {
                *(DWORD64*)ptr = patch[idx];
                idx++;
            }
        }

        if(WriteProcessMemory64(memptr + 0x10, &upath, sizeof(upath), 0) == STATUS_SUCCESS &&
           WriteProcessMemory64(upath.Buffer, (LPVOID)path, upath.Length + sizeof(wchar_t), 0) == STATUS_SUCCESS &&
           WriteProcessMemory64(codeAddr, code, sizeof(code), 0) == STATUS_SUCCESS)
        {
            DWORD64 status = 0;

            if(CreateRemoteThread64(codeAddr, 0, status, true) != FALSE && (status & 0xFFFFFFFF) == STATUS_SUCCESS)
            {
                DWORD64 module = 0;

                ReadProcessMemory64(memptr, &module, sizeof(module), 0);
                VirtualFreeEx64(memptr, 0x1000, MEM_RELEASE);

                return module;
            }
        }

        VirtualFreeEx64(memptr, 0x1000, MEM_FREE);
    }        

    return 0;
}
示例#13
0
DWORD64 WoW64dm::GetProcAddress64( DWORD64 hModule, DWORD size, const char* funcName )
{
    if(hModule == 0 || size == 0)
        return 0;

    std::unique_ptr<uint8_t[]> buf(new uint8_t[size]());

    if(ReadProcessMemory64(hModule, buf.get(), size, 0) != STATUS_SUCCESS)
        return 0;

    IMAGE_NT_HEADERS64* inh   = (IMAGE_NT_HEADERS64*)(buf.get() + ((IMAGE_DOS_HEADER*)buf.get())->e_lfanew);
    IMAGE_DATA_DIRECTORY& idd = inh->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
    if (idd.VirtualAddress == 0)
        return 0;

    IMAGE_EXPORT_DIRECTORY* ied = (IMAGE_EXPORT_DIRECTORY*)(buf.get() + idd.VirtualAddress);

    DWORD* rvaTable  = (DWORD*)(buf.get() + ied->AddressOfFunctions);
    WORD*  ordTable  = (WORD*) (buf.get() + ied->AddressOfNameOrdinals);
    DWORD* nameTable = (DWORD*)(buf.get() + ied->AddressOfNames);

    for (DWORD i = 0; i < ied->NumberOfFunctions; i++)
    {
        WORD OrdIndex   = 0xFFFF;
        char *pName     = nullptr;

        // Find by index
        if((size_t)funcName <= 0xFFFF)
        {
            OrdIndex = (WORD)i;
        }
        // Find by name
        else if((size_t)funcName > 0xFFFF && i < ied->NumberOfNames)
        {
            pName    = (char*)(nameTable[i] + (size_t)buf.get());            
            OrdIndex = (WORD)ordTable[i];
        }
        else
            return 0;

        if(((size_t)funcName <= 0xFFFF && (WORD)funcName == (OrdIndex + ied->Base)) || ((size_t)funcName > 0xFFFF && strcmp(pName, funcName) == 0))
        {
            DWORD64 pFunc = (DWORD64)(rvaTable[OrdIndex] + hModule);

            // Check forwarded export
            if(pFunc >= hModule + idd.VirtualAddress && pFunc <= hModule + idd.VirtualAddress + idd.Size)
            {
                char forwardStr[255] = {0};
                DWORD size = 0;

                ReadProcessMemory64(pFunc, forwardStr, sizeof(forwardStr), 0);

                std::string  chainExp(forwardStr);
                std::wstring wchainExp(chainExp.begin(), chainExp.end());

                std::wstring strDll  = wchainExp.substr(0, wchainExp.find(L".")) + L".dll";
                std::string strName  = chainExp.substr(chainExp.find(".") + 1, strName.npos);

                DWORD64 hChainMod = GetModuleHandle64(strDll.c_str(), &size);

                // Import by ordinal
                if(strName.find("#") == 0)
                    return GetProcAddress64(hChainMod, size, (const char*)atoi(strName.c_str() + 1));
                // Import by name
                else
                    return GetProcAddress64(hChainMod, size, strName.c_str());
            }

            return pFunc;
        }
    }

    return 0;
}
示例#14
0
static INJECT_RESULT Win32Inject64(DWORD dwProcessID, const wchar_t* dllFilePath)
{
	int path_length = std::wcslen(dllFilePath);
	HANDLE hTargetProcess = ::OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, FALSE, dwProcessID);
	if (hTargetProcess == NULL) {
		return INJECT_FAIL_OPENPROCESS;
	}

	int alloc_size = sizeof(DWORD64);
	alloc_size += sizeof(_UNICODE_STRING_T<DWORD64>);
	alloc_size += (path_length + 1) * sizeof(wchar_t);

	DWORD64 lpVirtualMemExec = VirtualAllocEx64(hTargetProcess, NULL, sizeof(exec_code), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
	DWORD64 lpVirtualMemParameters = VirtualAllocEx64(hTargetProcess, NULL, alloc_size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
	if(lpVirtualMemExec == NULL || lpVirtualMemParameters == NULL) {
		if(lpVirtualMemExec != NULL) {
			VirtualFreeEx64(hTargetProcess, lpVirtualMemExec, sizeof(exec_code), MEM_RESERVE | MEM_COMMIT);
		}
		if(lpVirtualMemParameters != NULL) {
			VirtualFreeEx64(hTargetProcess, lpVirtualMemParameters, alloc_size, MEM_RESERVE | MEM_COMMIT);
		}
		::CloseHandle(hTargetProcess);
		return INJECT_FAIL_VIRTUALALLOC;
	}
	DWORD64 ntdll64 = GetModuleHandle64(L"ntdll.dll");
	DWORD64 ntdll_LdrLoadDll = GetProcAddress64(ntdll64, "LdrLoadDll");
	DWORD64 ntdll_RtlExitUserThread = GetProcAddress64(ntdll64, "RtlExitUserThread");
	DWORD64 ntdll_RtlCreateUserThread = GetProcAddress64(ntdll64, "RtlCreateUserThread");
	if(ntdll_LdrLoadDll == 0 || ntdll_RtlExitUserThread == 0 || ntdll_RtlCreateUserThread == 0) {
		VirtualFreeEx64(hTargetProcess, lpVirtualMemExec, sizeof(exec_code), MEM_RESERVE | MEM_COMMIT);
		VirtualFreeEx64(hTargetProcess, lpVirtualMemParameters, alloc_size, MEM_RESERVE | MEM_COMMIT);
		::CloseHandle(hTargetProcess);
		return INJECT_FAIL_GETPROCADDRESS;
	}

	unsigned char* parameters = new unsigned char[alloc_size];
	std::memset(parameters, 0, alloc_size);
	_UNICODE_STRING_T<DWORD64>* upath = reinterpret_cast<_UNICODE_STRING_T<DWORD64>*>(parameters + sizeof(DWORD64));
	upath->Length = (path_length) * sizeof(wchar_t);
	upath->MaximumLength = (path_length + 1) * sizeof(wchar_t);
	wchar_t* path = reinterpret_cast<wchar_t*>(parameters + sizeof(DWORD64) + sizeof(_UNICODE_STRING_T<DWORD64>));
	std::wcscpy(path, dllFilePath);
	upath->Buffer = lpVirtualMemParameters + sizeof(DWORD64) + sizeof(_UNICODE_STRING_T<DWORD64>);

	unsigned char exec_code_copy[sizeof(exec_code)];
	std::memcpy(exec_code_copy, exec_code, sizeof(exec_code_copy));
	union {
		DWORD64 dw64;
		unsigned char bytes[8];
	} cvt;
	// arg4
	cvt.dw64 = lpVirtualMemParameters;
	std::memcpy(exec_code_copy + 2 + PrefixCodeLength, cvt.bytes, sizeof(cvt.bytes));
	// arg3
	cvt.dw64 = lpVirtualMemParameters + sizeof(DWORD64);
	std::memcpy(exec_code_copy + 12 + PrefixCodeLength, cvt.bytes, sizeof(cvt.bytes));

	// rax = LdrLoadDll
	cvt.dw64 = ntdll_LdrLoadDll;
	std::memcpy(exec_code_copy + 42 + PrefixCodeLength, cvt.bytes, sizeof(cvt.bytes));

	// rax = RtlExitUserThread
	cvt.dw64 = ntdll_RtlExitUserThread;
	std::memcpy(exec_code_copy + 64 + PrefixCodeLength, cvt.bytes, sizeof(cvt.bytes));
	if(FALSE == WriteProcessMemory64(hTargetProcess, lpVirtualMemExec, exec_code_copy, sizeof(exec_code), NULL)
		|| FALSE == WriteProcessMemory64(hTargetProcess, lpVirtualMemParameters, parameters, alloc_size, NULL)) {
		VirtualFreeEx64(hTargetProcess, lpVirtualMemExec, sizeof(exec_code), MEM_RESERVE | MEM_COMMIT);
		VirtualFreeEx64(hTargetProcess, lpVirtualMemParameters, alloc_size, MEM_RESERVE | MEM_COMMIT);
		::CloseHandle(hTargetProcess);
		delete[] parameters;
		return INJECT_FAIL_WRITEPROCESSMEMERY;
	}
	DWORD64 hRemoteThread = 0;
	struct {
	  DWORD64 UniqueProcess;
	  DWORD64 UniqueThread;
	} client_id;

	X64Call(ntdll_RtlCreateUserThread, 10, 
		(DWORD64)hTargetProcess, // ProcessHandle
		(DWORD64)NULL, // SecurityDescriptor
		(DWORD64)FALSE, // CreateSuspended
		(DWORD64)0, // StackZeroBits
		(DWORD64)NULL, // StackReserved
		(DWORD64)NULL, // StackCommit
		lpVirtualMemExec, // StartAddress
		(DWORD64)NULL, // StartParameter
		(DWORD64)&hRemoteThread, // ThreadHandle
		(DWORD64)&client_id // ClientID
		);
	INJECT_RESULT result = INJECT_OK;
	if(hRemoteThread == 0) {
		result = INJECT_FAIL_CREATEREMOTETHREAD;
	}
	else {
		::WaitForSingleObject((HANDLE)hRemoteThread, 3000);
	}
	VirtualFreeEx64(hTargetProcess, lpVirtualMemExec, sizeof(exec_code), MEM_RESERVE | MEM_COMMIT);
	VirtualFreeEx64(hTargetProcess, lpVirtualMemParameters, alloc_size, MEM_RESERVE | MEM_COMMIT);
	::CloseHandle(hTargetProcess);
	delete[] parameters;
	return result;
}
示例#15
0
#include "WoW64Utils.h"

/*
   @28
*/
NTSTATUS
NTAPI
NtWow64ReadVirtualMemory64(
	_In_      HANDLE ProcessHandle,
	_In_      DWORD64 BaseAddress,
	_Out_     PVOID Buffer,
	_In_      DWORD64 NumberOfBytesToRead,
	_Out_opt_ DWORD64 *NumberOfBytesRead OPTIONAL
    )
{
	DWORD64 Proc64 = IsWoW64() ? GetProcAddress64(GetNtdll64(), "NtReadVirtualMemory") : 0;
	if (Proc64)
		return (NTSTATUS)x64Call(Proc64, 5, (DWORD64)ProcessHandle, (DWORD64)BaseAddress, (DWORD64)Buffer, (DWORD64)NumberOfBytesToRead, (DWORD64)NumberOfBytesRead);
	else
		return STATUS_NOT_IMPLEMENTED;
}

/*
   @28
*/
NTSTATUS
NTAPI
NtWow64WriteVirtualMemory64(
	_In_      HANDLE ProcessHandle,
	_In_      DWORD64 BaseAddress,
	_In_      PVOID Buffer,