首页
社区
课程
招聘
奇怪的远程线程dll注入问题
发表于: 2009-2-25 10:45 6173

奇怪的远程线程dll注入问题

2009-2-25 10:45
6173
被注入的dll代码:

// Library.cpp
#include "stdafx.h"

void StartOurCode();

LRESULT WINAPI MouseProc(
  int nCode,      // hook code
  WPARAM wParam,  // message  identifier
  LPARAM lParam   // mouPrse coordinates
);

#pragma data_seg("ShareSec")
HWND g_hWnd=NULL;

HINSTANCE hInstance;
HHOOK hOurHook;      

#pragma data_seg()

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                                         )
{
        switch (ul_reason_for_call)
        {
        case DLL_PROCESS_ATTACH:
                {
                        hInstance = (HMODULE)hModule;
                        StartOurCode();

                        TCHAR szAppName[256];
                        GetModuleFileName(hModule, szAppName, 256);
                        MessageBox(NULL, _T("dll Load OK!"), szAppName, MB_ICONINFORMATION);

                        break;
                }
        case DLL_PROCESS_DETACH:
                {
                        UnhookWindowsHookEx(hOurHook);

                        TCHAR szAppName[256];
                        GetModuleFileName(hModule, szAppName, 256);
                        MessageBox(NULL, _T("dll unload OK!"), szAppName, MB_ICONINFORMATION);
                        break;
                }
        }

    return TRUE;
}

void StartOurCode()
{
        hOurHook = SetWindowsHookEx(WH_MOUSE, MouseProc, hInstance, 0);
}

LRESULT WINAPI MouseProc(
  int nCode,      // hook code
  WPARAM wParam,  // message  identifier
  LPARAM lParam   // mouPrse coordinates
)
{
        BOOL bChecked = FALSE;
        MOUSEHOOKSTRUCT* mouse;

        mouse = reinterpret_cast<MOUSEHOOKSTRUCT *>(lParam);
        if (mouse == NULL)
        {
                return CallNextHookEx(hOurHook, nCode, wParam, lParam);
        }

        if (nCode >= 0)
        {
                if(wParam == WM_RBUTTONUP)
                {
                        WORD nState = GetKeyState(VK_CONTROL);
                        if (nState & 0x8000)
                        {
                                TCHAR buffer[256] = { 0 };

                                GetWindowText(mouse->hwnd, buffer, 256);
                                MessageBox(mouse->hwnd, buffer, _T("tip"), MB_ICONINFORMATION);
                                bChecked = TRUE;
                        }
                }
        }

        return bChecked ? TRUE : CallNextHookEx(hOurHook, nCode, wParam, lParam);
}

这里是一个全局的鼠标钩子, 当按CTRL+鼠标右键的时候, 弹出一个提示框,就这么简单。

下面的代码在一个远程进程中注入这个dll:

#include "resource.h"
#include <windows.h>
#include <tlhelp32.h>
#include <tchar.h>

#pragma comment(lib, "comctl32.lib")
#pragma warning(disable: 4312)

LRESULT CALLBACK RemoteProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

int APIENTRY _tWinMain(HINSTANCE hInstance,
                                        HINSTANCE hPrevInstance,
                                        LPTSTR     lpCmdLine,
                                        int       nCmdShow)
{
        return (int)DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_REMOTE_DIALOG), NULL,

(DLGPROC)RemoteProc, NULL);
}

DWORD FindTarget( LPCTSTR lpszProcess )
{
    PROCESSENTRY32 pe32;
        HANDLE hSnapshot;
    DWORD dwRet = 0;

        hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
    pe32.dwSize = sizeof( PROCESSENTRY32 );
    Process32First( hSnapshot, &pe32 );
    do
    {
        if ( lstrcmpi( pe32.szExeFile, lpszProcess ) == 0 )
        {
            dwRet = pe32.th32ProcessID;
            break;
        }
    } while ( Process32Next( hSnapshot, &pe32 ) );
    CloseHandle( hSnapshot );

    return dwRet;
}

BOOL RemoteLoadLibrary( DWORD dwProcessID, const char* lpszDll )
{
           HANDLE   hProc;
        void     *buff;
        LPTHREAD_START_ROUTINE pLLAddr;
        HANDLE _hThread;
       
       
        hProc=OpenProcess(PROCESS_CREATE_THREAD|PROCESS_VM_OPERATION|PROCESS_VM_WRITE,
                0,dwProcessID);

        if(hProc==NULL)
        {
                MessageBox(NULL,_T("Open Remote Process Failed"),_T("Error"),0);
                return 0;
        }

       
        if((buff=VirtualAllocEx(hProc,0,MAX_PATH,MEM_COMMIT,PAGE_READWRITE))==NULL)
        {
                MessageBox(NULL,_T("Allocate Memory Failed"),_T("Error"),0);
                return 0;
        }
       
       
        if(WriteProcessMemory(hProc,buff,(PVOID)lpszDll,MAX_PATH,0)==0)
        {
                return 0;
        }

       
        pLLAddr=(LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandleA

("Kernel32"),"LoadLibraryA");
        if(pLLAddr==NULL)
                return 0;

        _hThread=CreateRemoteThread(hProc, NULL, 0, pLLAddr, buff, 0, NULL);
        if(_hThread==NULL)
                return 0;

       
        WaitForSingleObject(_hThread,INFINITE);
        CloseHandle(_hThread);
       
       
        VirtualFreeEx( hProc, buff, MAX_PATH, MEM_DECOMMIT );
       
        MessageBox(NULL,_T("Dll start in remote process"),_T("info"),0);
        CloseHandle(hProc);
       
        return 1;
}

BOOL RemoteFreeLibrary( DWORD dwProcessID, const char* lpszDll )
{

    HANDLE hProcess = OpenProcess( PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION |

PROCESS_VM_WRITE, FALSE, dwProcessID );
   

    DWORD dwSize, dwWritten;
    dwSize = lstrlenA( lpszDll ) + 1;
    LPVOID lpBuf = VirtualAllocEx( hProcess, NULL, dwSize, MEM_COMMIT, PAGE_READWRITE );
    if ( NULL == lpBuf )
    {
        CloseHandle( hProcess );
        return FALSE;
    }
    if ( WriteProcessMemory( hProcess, lpBuf, (LPVOID)lpszDll, dwSize, &dwWritten ) )
    {
        if ( dwWritten != dwSize )
        {
            VirtualFreeEx( hProcess, lpBuf, dwSize, MEM_DECOMMIT );
            CloseHandle( hProcess );
            return FALSE;
        }
    }
    else
    {
        CloseHandle( hProcess );
        return FALSE;
    }
   

    DWORD dwHandle, dwID;
    LPVOID pFunc = GetModuleHandleA;
    HANDLE hThread = CreateRemoteThread( hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)

pFunc, lpBuf, 0, &dwID );

    WaitForSingleObject( hThread, INFINITE );

    GetExitCodeThread( hThread, &dwHandle );

    VirtualFreeEx( hProcess, lpBuf, dwSize, MEM_DECOMMIT );
    CloseHandle( hThread );

    pFunc = FreeLibrary;
    hThread = CreateRemoteThread( hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pFunc,

(LPVOID)dwHandle, 0, &dwID );

    WaitForSingleObject( hThread, INFINITE );
    CloseHandle( hThread );
    CloseHandle( hProcess );
    return TRUE;
}

int InitProcessList(HWND hWnd)
{
        PROCESSENTRY32 pe32;
        HANDLE hProcess;

        hProcess = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
        pe32.dwSize = sizeof(PROCESSENTRY32);
        Process32First(hProcess, &pe32);

        while (Process32Next(hProcess, &pe32))
        {
                ::SendMessage(hWnd, LB_ADDSTRING, 0, (LPARAM)pe32.szExeFile);
        }

        CloseHandle(hProcess);
    return 0;
}

LRESULT CALLBACK RemoteProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
        switch (uMsg)
        {
        case WM_INITDIALOG:
                {
                        HICON hIcon = LoadIcon(NULL, IDI_APPLICATION);
                        SendMessage(hWnd, WM_SETICON, ICON_BIG, (LPARAM)hIcon);

                        InitProcessList(GetDlgItem(hWnd, IDC_PROC_LIST));
                }
        case WM_COMMAND:
                {
                        if (LOWORD(wParam) == IDC_PROC_LIST &&
                                HIWORD(wParam) == LBN_SELCHANGE)
                        {
                                HWND hListWnd = GetDlgItem(hWnd, IDC_PROC_LIST);
                                HWND hSelWnd = GetDlgItem(hWnd, IDC_SELECT_EDIT);

                                int nCurSel = (int)SendMessage(hListWnd, LB_GETCURSEL, 0,

0);
                                if (nCurSel != LB_ERR)
                                {
                                        TCHAR buffer[_MAX_FNAME];
                                        SendMessage(hListWnd, LB_GETTEXT, nCurSel,

(LPARAM)buffer);
                                        SetWindowText(hSelWnd, buffer);
                                }

                                break;
                        }

                        switch (wParam)
                        {
                        case IDC_PROC_LIST:
                                {
                                        HWND hListWnd = GetDlgItem(hWnd, IDC_PROC_LIST);
                                        HWND hSelWnd = GetDlgItem(hWnd, IDC_SELECT_EDIT);

                                        int nCurSel = (int)SendMessage(hListWnd,

LB_GETCURSEL, 0, 0);
                                        if (nCurSel != LB_ERR)
                                        {
                                                TCHAR buffer[_MAX_FNAME];
                                                SendMessage(hListWnd, LB_GETTEXT,

nCurSel, (LPARAM)buffer);
                                                SetWindowText(hSelWnd, buffer);
                                        }

                                        break;
                                }
                        case IDOK:
                                {
                                        TCHAR szTarget[MAX_PATH];
                                        DWORD dwProcessID;

                                        GetDlgItemText(hWnd, IDC_SELECT_EDIT, szTarget,

MAX_PATH);
                                        dwProcessID = FindTarget(szTarget);

                                        TCHAR szCurDir[_MAX_PATH];
                                        char szDllPath[_MAX_PATH];
                                        GetCurrentDirectory(_MAX_PATH, szCurDir);
                                        wsprintfA(szDllPath, "%s\\Library.dll",

szCurDir);
                                        RemoteLoadLibrary(dwProcessID, szDllPath);
                                        break;
                                }
                        case IDCANCEL:
                                {
                                        TCHAR szTarget[MAX_PATH];
                                        DWORD dwProcessID;
                                        TCHAR szCurDir[_MAX_PATH];
                                        CHAR szDllPath[_MAX_PATH];

                                        GetDlgItemText(hWnd, IDC_SELECT_EDIT, szTarget,

MAX_PATH);
                                        dwProcessID = FindTarget(szTarget);

                                        GetCurrentDirectory(_MAX_PATH, szCurDir);
                                        wsprintfA(szDllPath, "%s\\Library.dll",

szCurDir);

                                        if (dwProcessID == 0)
                                        {
                                                MessageBox( hWnd, _T("Can NOT find target process"),

_T("error"), MB_ICONINFORMATION );
                                                break;
                                        }

                                        if (!RemoteFreeLibrary(dwProcessID, szDllPath))
                                        {
                                                MessageBox( hWnd, _T("Unload DLL failed"), _T("error"), MB_ICONINFORMATION );
                                        }
                                        break;
                                }
                        }

                        break;
                }

        case WM_CLOSE:
                {
                        EndDialog(hWnd, 0);
                        break;
                }
        }

        return 0;
}

当选中一个一般进程注入的时候, 成功了, 按ctrl+鼠标右键也能够显示提示信息。
现在的问题是, 当注入一个进程成功的时候, 我再打开一个新的程序,比如firefox,
或者是Visual Studio 6.0, dll也会被注入到新打开的程序,这个是为什么?

比如我把这个dll注入到explorer.exe,程序提示我“dll加载成功“,然后打开一个firefox, 程序也提示我”dll加载成功“, 接着再卸载掉explorer.exe中的dll, 但是这个全局的钩子仍然起作用, 按Ctrl+鼠标右键还是有提示信息, 不知道这是为什么?哪位能帮看看

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (11)
雪    币: 635
活跃值: (101)
能力值: ( LV12,RANK:420 )
在线值:
发帖
回帖
粉丝
2
SetWindowsHookEx的thread id 参数不要写0就可以了
2009-2-25 10:58
0
雪    币: 387
活跃值: (25)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
3
这个不是关键, 关键问题是:
MessageBox(NULL, _T("dll Load OK!"), szAppName, MB_ICONINFORMATION);
这个提示信息会出现多次, 没当我打开新的程序的时候, 就会出现这个提示, 也就是dll被加载了多次
2009-2-25 12:08
0
雪    币: 387
活跃值: (25)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
4
而且我要安装的是一个全局的钩子, thread id 必须为0
2009-2-25 12:13
0
雪    币: 387
活跃值: (25)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
5
附件中library就是这个dll
remote就是加载创建远程线程, 注入dll的。
是用VC6编译的, 哪位能帮看看, 找出问题所在。
上传的附件:
2009-2-25 12:16
0
雪    币: 635
活跃值: (101)
能力值: ( LV12,RANK:420 )
在线值:
发帖
回帖
粉丝
6
看过MSDN再用函数吧,全局钩子就是会注入所有的有窗口进程~你可以在弹框前判断是不是你想要的进程~
2009-2-25 12:37
0
雪    币: 387
活跃值: (25)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
7
我说的意思你没有理解,
我说的是下面这段代码会被执行多次:
case DLL_PROCESS_ATTACH:
    {
      hInstance = (HMODULE)hModule;
      StartOurCode();

      TCHAR szAppName[256];
      GetModuleFileName(hModule, szAppName, 256);
      MessageBox(NULL, _T("dll Load OK!"), szAppName, MB_ICONINFORMATION);

      break;
    }

也就是dll会被加载多次, 可是我在远程进程注入中,只在一个进程中用LoadLibrary加载了dll, 按道理讲, dll只会被加载一次, dll运行之后, 是个全局的钩子, 能捕捉所有的鼠标消息。

难道说,用了全局钩子, 只要启动一个新的窗口进程, 这个dll会被自动加载?
就算是这样, 我没有在其他的进程中开辟空间,保留dll的路径,那么其它的进程
要加载这个dll, 是怎么知道这个dll的路径的?
2009-2-25 12:57
0
雪    币: 462
活跃值: (53)
能力值: ( LV9,RANK:460 )
在线值:
发帖
回帖
粉丝
8
关于这个问题,你看一下上面那段话中的粗体部分,然后再想一想:Windows为什么要求你全局钩子必须在一个动态链接库中?
2009-2-25 13:24
0
雪    币: 387
活跃值: (25)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
9
谢谢,我再好好看看
2009-2-25 13:30
0
雪    币: 387
活跃值: (25)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
10
是不是说, 因为是个全局的钩子, 系统要把这个dll映射到每个进程中去, 而这个映射实际上就是在每个进程中加载这个dll?
而且只有当进程窗口被激活的时候才加载?
因为我发现, 如果有已经存在的窗口进程, 当我点击窗口的时候, 也就是窗口被激活的时候, 才出现那个dll被加载的信息, 新打开的窗口进程也会出现这个提示信息
2009-2-25 13:38
0
雪    币: 7651
活跃值: (523)
能力值: ( LV9,RANK:610 )
在线值:
发帖
回帖
粉丝
11
还是多看看MSDN好啊~
2009-2-25 14:01
0
雪    币: 26
活跃值: (28)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
threadid为0就是全局钩子啊,
安装了全局钩子,
新启动的进程都会被钩住。
2009-2-25 15:16
0
游客
登录 | 注册 方可回帖
返回
//