#Include "windows.bi"

Function InjectDLL(hProcess As HANDLE, dllpath As String) As HMODULE
        ' get module handle of kernel32.dll
        Var kernel32 = GetModuleHandle("Kernel32") 

        ' allocate space for dll name in victim's address space
        Var addr = VirtualAllocEx(hProcess, NULL, Len(dllpath) + 1, MEM_COMMIT, PAGE_READWRITE)
        If addr = NULL Then Return NULL

        ' write dll name into newly allocated memory
        WriteProcessMemory(hProcess, addr, StrPtr(dllpath), Len(dllpath) + 1, NULL)

        ' call LoadLibrary in victim's address space in order to load our dll
        Var hThread = CreateRemoteThread(hProcess, NULL, 0, GetProcAddress(kernel32, "LoadLibraryA"), addr, NULL, NULL)

        ' free memory used for dll name
        VirtualFreeEx(hProcess, addr, Len(dllpath) + 1, MEM_RELEASE)
        
        ' check if CreateRemoteThread failed
        If hThread = NULL Then Return NULL
        WaitForSingleObject(hThread, INFINITE)

        ' get hModule of our dll
        Dim hDllModule As HMODULE
        GetExitCodeThread(hThread, @hDllModule)
        If hDllModule = NULL Then Return NULL
        CloseHandle(hThread)

        Return hDllModule
End Function

' *** TEST: Inject some dll into notepad ***

' check if WinNT/2000/XP/Vista is used
Var shlwapi = LoadLibrary("shlwapi")
Dim IsOS As Function(As Dword) As BOOL = GetProcAddress(shlwapi, 437)
#Define OS_NT 1
If IsOS = NULL OrElse IsOS(OS_NT) = FALSE Then
        Print "operating system not supported"
        Sleep
        FreeLibrary(shlwapi)
        End
EndIf
FreeLibrary(shlwapi)

' start notepad
Dim pi As PROCESS_INFORMATION
Dim si As STARTUPINFO
Var AppName = Environ("windir") & "\system32\calc.exe"
If CreateProcess(StrPtr(AppName), StrPtr(AppName), NULL, NULL, FALSE, NULL, NULL, NULL, @si, @pi) = FALSE Then
        Print "starting calculator failed"
        Sleep
        End
EndIf

' wait for app to be ready
WaitForInputIdle(pi.hProcess, INFINITE)

' inject the dll
Var hDllModule = InjectDLL(pi.hProcess, "some_dll.dll")
If hDllModule = NULL Then
        Print "injecting dll failed"
        Sleep
        End
EndIf
Print "successful! hModule of dll: 0x" & Hex(hDllModule)
Sleep

' close handles
CloseHandle(pi.hProcess)
CloseHandle(pi.hThread)