1

我正在尝试通过使用互操作将 .dll 注入另一个进程的内存。

这是我的 C# 代码:

class Program
{
        static void Main(string[] args)
        {
            var result = Inject(Process.GetProcessesByName("notepad")[0].Id);

            Console.WriteLine(result);

            if (result < 0)
                throw new Win32Exception(Marshal.GetLastWin32Error());

            Console.ReadLine();
        }

        [DllImport("Testing.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int Inject(int dwProcessId);
}

该函数的代码Inject是这样的(注意注释return -6):

//C++ .dll that does actually exists
const char* DLL_NAME = "C:\\Users\\Bruno\\Source\\Repos\\CourseGuidance\\InteropTesting\Debug\\Loader.dll";

TESTING_API DWORD Inject(DWORD dwProcessId)
{
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);

    if (hProcess == NULL)
        return -1;

    HMODULE hModule = GetModuleHandleW(L"kernel32.dll");

    if (hModule == NULL)
        return -2;

    FARPROC pLoadLibrary = GetProcAddress(hModule, "LoadLibraryA");

    if (pLoadLibrary == NULL)
        return -3;

    LPVOID pMemory = VirtualAllocEx(hProcess, NULL, strlen(DLL_NAME) + 1, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);

    if (pMemory == NULL)
        return -4;

    BOOL result = WriteProcessMemory(hProcess, pMemory, DLL_NAME, strlen(DLL_NAME) + 1, NULL);

    if (!result)
        return -5;

    HANDLE hThread = CreateRemoteThread(hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE) pLoadLibrary, pMemory, 0, NULL);

    if (hThread == NULL)
        return -6;

    WaitForSingleObject(hThread, INFINITE);

    VirtualFreeEx(hProcess, pMemory, strlen(DLL_NAME) + 1, MEM_RELEASE);

    CloseHandle(hThread);

    CloseHandle(hProcess);

    return 0;
}

我认为我得到的错误可能具有误导性,因为该文件确实存在于该文件夹中。我还认为错误可能是因为LoadLibraryAASCII 的,甚至尝试使用LoadLibraryW,但我仍然遇到同样的问题。

如果有人知道可能出了什么问题,你能给我提供正确的方向吗?

4

1 回答 1

2

您没有声明InjectSetLastError=true. 因此,您从中获得的价值Marshal.GetLastWin32Error是垃圾:

Marshal.GetLastWin32Error 方法

返回使用设置了 DllImportAttribute.SetLastError 标志的平台调用调用的最后一个非托管函数返回的错误代码。

仅当将 System.Runtime.InteropServices.DllImportAttribute 应用于方法签名并将 SetLastError 字段设置为 true 时,才能使用此方法获取错误代码。此过程因使用的源语言而异:C# 和 C++ 默认为 false,但 Visual Basic 中的 Declare 语句为 true。

于 2014-06-21T17:18:59.357 回答