C++新手一枚,最近在学习远程dll注入,经过摸索,dll成功注入,但是卸载出现问题,求指教。以下是卸载dll代码
DWORD dwHandle;
HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)GetModuleHandleA,
                                                                                 lpParameter, 0, &dwTid);
WaitForSingleObject(hThread, INFINITE);
GetExitCodeThread(hThread, &dwHandle); //线程的结束码即为Dll模块儿的句柄, 详见MSDN https://msdn.microsoft.com/en-us/library/windows/desktop/ms683190(v=vs.85).aspx 用Process Hacker 查到 注入dll 地址是:0x7ffc6bce0000
GetExitCodeThread(hThread, &dwHandle);执行完成后 dwHandle的值是:6bce0000,前面的高位7ffc丢掉了,我查了下0x7ffc6bce0000已经超出DWORD的范围了,所以前面的高位丢掉了。但是GetExitCodeThread方法的参数就是LPDWORD,如何破?
我是WIN10 64位系统 4G内存2.还想到另一种办法获取注入dll地址,就是用MODULEENTRY32 遍历被注入dll的进程,但是调用Module32First时就出错了,debug发现MODULEENTRY32 的modBaseAddr出现“读写字符串字符错误”,结构体其他字段正常,CreateToolhelp32Snapshot 调用的时候TH32CS_SNAPMODULE 和TH32CS_SNAPMODULE32试过,同样的错误,跪求指教

解决方案 »

  1.   

    参考WinAPIOverride32源代码片断。
      

  2.   

    EXPORT BOOL EnablePrivilege (PCTSTR szDebugName) {
    HANDLE hToken = NULL ;
    __try {
    if (szDebugName == NULL)
    __leave ;
    TOKEN_PRIVILEGES priv = {1 ,{{{0 ,0} ,SE_PRIVILEGE_ENABLED}}} ;
    LookupPrivilegeValue (0 ,szDebugName ,&priv.Privileges[0].Luid) ;
    OpenProcessToken (GetCurrentProcess () ,TOKEN_ADJUST_PRIVILEGES ,&hToken) ;
    if (hToken == NULL)
    __leave ;
    if (!AdjustTokenPrivileges (hToken ,FALSE ,&priv ,sizeof (priv) ,0 ,0))
    __leave ;
    return TRUE ;
    } __finally {
    if (hToken != NULL)
    CloseHandle (hToken) ;
    }
    return FALSE ;
    }EXPORT DWORD GetProcessIdByName (PCTSTR szProcessName) {
    HANDLE hSnapshot = NULL ;
    __try {
    if (szProcessName == NULL)
    __leave ;
    if ((hSnapshot = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS ,0)) == NULL)
    __leave ;
    PROCESSENTRY32 ps = {sizeof (ps)} ;
    if (Process32First (hSnapshot ,&ps)) {
    do {
    if (lstrcmp (ps.szExeFile ,szProcessName) == 0)
    return ps.th32ProcessID ;
    } while (Process32Next (hSnapshot ,&ps)) ;
    }
    } __finally {
    if (hSnapshot != NULL)
    CloseHandle (hSnapshot) ;
    }
    return 0 ;
    }EXPORT HMODULE GetModuleHandleByName (DWORD dwPID ,PCTSTR szDllName) {
    HANDLE hSnapshot = NULL ;
    __try {
    if (szDllName == NULL)
    __leave ;
    if ((hSnapshot = CreateToolhelp32Snapshot (TH32CS_SNAPMODULE ,dwPID)) == NULL)
    __leave ;
    MODULEENTRY32 md = {sizeof (md)} ;
    if (Module32First (hSnapshot ,&md)) {
    do {
    if (lstrcmp (md.szModule ,szDllName) == 0 || lstrcmp (md.szExePath ,szDllName) == 0)
    return md.hModule ;
    } while (Module32Next (hSnapshot ,&md)) ;
    }
    } __finally {
    if (hSnapshot != NULL)
    CloseHandle (hSnapshot) ;
    }
    return NULL ;
    }EXPORT BOOL LoadRemoteDll (DWORD dwPID ,PCTSTR szDllName) {
    HANDLE hProcess = NULL ;
    PVOID szRemoteDllName = NULL ;
    HANDLE hThread = NULL ;
    __try {
    if (szDllName == NULL)
    __leave ;
    if ((hProcess = OpenProcess (PROCESS_ALL_ACCESS ,FALSE ,dwPID)) == NULL)
    __leave ;
    const SIZE_T ch = (lstrlen (szDllName) + 1) * sizeof (TCHAR) ;
    if ((szRemoteDllName = VirtualAllocEx (hProcess ,NULL ,ch ,MEM_COMMIT ,PAGE_READWRITE)) == NULL)
    __leave ;
    if (!WriteProcessMemory (hProcess ,szRemoteDllName ,szDllName ,ch ,NULL))
    __leave ;
    const PTHREAD_START_ROUTINE pfnLoadLibrary = PTHREAD_START_ROUTINE (GetProcAddress (GetModuleHandle (TEXT ("Kernel32")) ,_STR_ (LoadLibrary))) ;
    if (pfnLoadLibrary == NULL)
    __leave ;
    if ((hThread = CreateRemoteThread (hProcess ,NULL ,0 ,pfnLoadLibrary ,szRemoteDllName ,0 ,NULL)) = NULL)
    __leave ;
    WaitForSingleObject (hThread ,INFINITE) ;
    return TRUE ;
    } __finally {
    if (hThread != NULL)
    CloseHandle (hThread) ;
    if (szRemoteDllName != NULL)
    VirtualFreeEx (hProcess ,szRemoteDllName ,0 ,MEM_RELEASE) ;
    if (hProcess != NULL)
    CloseHandle (hProcess) ;
    }
    return FALSE ;
    }EXPORT BOOL FreeRemoteDll (DWORD dwPID ,PCTSTR szDllName) {
    HANDLE hProcess = NULL ;
    HANDLE hThread = NULL ;
    __try {
    if (szDllName == NULL)
    __leave ;
    if ((hProcess = OpenProcess (PROCESS_ALL_ACCESS ,FALSE ,dwPID)) == NULL)
    __leave ;
    const PTHREAD_START_ROUTINE pfnFreeLibrary = PTHREAD_START_ROUTINE (GetProcAddress (GetModuleHandle (TEXT ("Kernel32")) ,"FreeLibrary")) ;
    if (pfnFreeLibrary == NULL)
    __leave ;
    if ((hThread = CreateRemoteThread (hProcess ,NULL ,0 ,pfnFreeLibrary ,GetModuleHandleByName (dwPID ,szDllName) ,0 ,NULL)) = NULL)
    __leave ;
    WaitForSingleObject (hThread ,INFINITE) ;
    return TRUE ;
    } __finally {
    if (hThread != NULL)
    CloseHandle (hThread) ;
    if (hProcess != NULL)
    CloseHandle (hProcess) ;
    }
    return FALSE ;
    }GetExitCodeThread不是必须的,而且没什么用
    如果你的dll打开了线程,把FreeLibrary换成FreeLibraryAndExitThread没用,FreeLibraryAndExitThread只对自身线程有效
    64位和32位差不多,只是不能用GetModuleHandle取得以加载dll的句柄
      

  3.   

    共享内存。dll注入后自己在注入进程中取自己的地址,然后写入共享内存,主进程取即可。
      

  4.   

    The exit value specified in the ExitThread or TerminateThread function. 
    The return value from the thread function. 
    The exit value of the thread's process.