首页
社区
课程
招聘
[旧帖] [求助][求助]Win8 x64 dll注入DllMain里的代码不执行 0.00雪花
发表于: 2013-1-7 21:46 4304

[旧帖] [求助][求助]Win8 x64 dll注入DllMain里的代码不执行 0.00雪花

2013-1-7 21:46
4304
远程线程注入Dll时,有时DllMain里的代码没有执行。用procexp看目标进程,dll的确被加载了。
注入和dll的代码看起来都没问题。不知有没deadlock的可能性。请大家指点。
可以确定的是,目标进程没有保护。。拿notepad来动手也是一样的结果。也不是杀软的原因,裸奔的。UAC也没开。不是权限问题。
注入程序和dll和目标进程都是x64。。编译成32的。到32位系统上测试也时同样的问题。
dll代码:
/*******************************************************************************
 * File:        dllmain.cpp
 * Author:      HwangBae
 * Created:     1/5/2013
 * Blog:        http://hwangbae.cnblogs.com/
 * Email:       hwangbae@live.cn
 * Description: dll entry point and subproc
********************************************************************************/
#include "stdafx.h"

#pragma once
// Key atcion define
enum KEY_ACTION
{
    ACTION_NONE,
    ACTION_OPEN_COMPUTER,
    ACTION_OPEN_LIBRARIES,
    ACTION_OPEN_DOCUMENTS,
    ACTION_OPEN_CALCULATOR,
    ACTION_OPEN_NOTEPAD,
    ACTION_OPEN_TASKMANAGER,
    ACTION_OPEN_CMD,
    ACTION_OPEN_MUSICPLAYER,
    ACTION_OPEN_VIDEOPLAYER,
    ACTION_OPEN_BROWSER,
    ACTION_OPEN_EMAIL,
    ACTION_OPEN_APPLICATION
};


// key setting struct
typedef struct tagKEYSETTING
{
    KEY_ACTION action;
    TCHAR pszAtcionParameter[MAX_PATH];
}KEYSETTING, *PKEYSETTING;


// Forward declarations of functions included in this code module:

WNDPROC g_pfnOldWndProc;                        // The original window procedure
TCHAR   g_szCfgPath[MAX_PATH];                    // The config file path

/* The action string array as ShellExecute parameter,
   some elements is initialized to zero,
   it will be assigned values in the window message handler*/
TCHAR   g_szAction[][MAX_PATH]    
= {
    {0},                                                // ACTION_OPEN_NONE
    {TEXT("::{20D04FE0-3AEA-1069-A2D8-08002B30309D}")}, // ACTION_OPEN_COMPUTER
    {TEXT("::{031E4825-7B94-4dc3-B131-E946B44C8DD5}")}, // ACTION_OPEN_LIBRARIES
    {TEXT("::{450D8FBA-AD25-11D0-98A8-0800361B1103}")}, // ACTION_OPEN_DOCUMENTS
    {TEXT("calc.exe")},                                 // ACTION_OPEN_CALCULATOR
    {TEXT("notepad.exe")},                              // ACTION_OPEN_NOTEPAD
    {TEXT("taskmgr.exe")},                              // ACTION_OPEN_TASKMANAGER
    {TEXT("cmd.exe")},                                  // ACTION_OPEN_CMD
    {0},                                                // ACTION_OPEN_MUSICPLAYER
    {0},                                                // ACTION_OPEN_VIDEOPLAYER
    {TEXT("::{871C5380-42A0-1069-A2EA-08002B30309D}")}, // ACTION_OPEN_BROWSER
    {TEXT("mailto:")},                                  // ACTION_OPEN_EMAIL
    {0}                                                 // ACTION_OPEN_APPLICATION
  };


BOOL    DoAction(KEYSETTING& ks);
BOOL    GetAssociatedApp(LPCTSTR pszExt, LPTSTR pszPath);
LRESULT CALLBACK NewWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
BOOL    SubWindowClass(void);
BOOL    UnSubWindowClass(void);

// Dll entry point
BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                    )
{
    OutputDebugString(TEXT("DllMain\n"));
    switch (ul_reason_for_call)
    {
        case DLL_PROCESS_ATTACH:
        {
            ::GetModuleFileName(hModule, g_szCfgPath, MAX_PATH);
            ::lstrcpy(PathFindExtension(g_szCfgPath) - 3, TEXT(".cfg"));
            ::SubWindowClass();
            break;
        }
        case DLL_THREAD_ATTACH:
        case DLL_THREAD_DETACH:
            break;
        case DLL_PROCESS_DETACH:
        {
            ::UnSubWindowClass();
            break;
        }
    }
    return TRUE;
}

//************************************
// Method:      DoAction
// Returns:     BOOL
// Parameter:   KEYSETTING & ks
// Description: process the key action
//************************************
BOOL DoAction(KEYSETTING& ks) 
{
    switch (ks.action)
    {
        case ACTION_OPEN_MUSICPLAYER:
        {
            ::OutputDebugString(TEXT("case ACTION_OPEN_MUSICPLAYER\n"));
            ::GetAssociatedApp(TEXT(".mp3"), g_szAction[ACTION_OPEN_MUSICPLAYER]);
            break;
        }
        case ACTION_OPEN_VIDEOPLAYER:
        {
            ::OutputDebugString(TEXT("case ACTION_OPEN_VIDEOPLAYER\n"));
            ::GetAssociatedApp(TEXT(".mp4"), g_szAction[ACTION_OPEN_VIDEOPLAYER]);
            break;
        }
        case ACTION_OPEN_APPLICATION:
        {
            ::OutputDebugString(TEXT("case ACTION_OPEN_APPLICATION\n"));
            ::lstrcpy(g_szAction[ACTION_OPEN_APPLICATION], ks.pszAtcionParameter);
            break;
        }
    }
    return 32 < reinterpret_cast<int>(::ShellExecute(NULL, NULL, g_szAction[ks.action], NULL, NULL, SW_NORMAL));
}

//************************************
// Method:      GetAssociatedApp
// Returns:     BOOL
// Parameter:   LPCTSTR pszExt
// Parameter:   LPTSTR pszPath
// Description: Get the associated app by file extension
//************************************
BOOL GetAssociatedApp( LPCTSTR pszExt, LPTSTR pszPath )
{
    HKEY hKey;
    LONG lRet;
    lRet = ::RegOpenKeyEx(HKEY_CLASSES_ROOT, pszExt, 0, KEY_QUERY_VALUE, &hKey);
    if (ERROR_SUCCESS != lRet) return FALSE;

    DWORD dwData = MAX_PATH;
    lRet = ::RegQueryValueEx(hKey, NULL, 0, NULL, reinterpret_cast<LPBYTE>(pszPath), &dwData);
    if (ERROR_SUCCESS != lRet) return FALSE;

    lRet = ::RegCloseKey(hKey);
    if (ERROR_SUCCESS != lRet) return FALSE;

    TCHAR szSubKey[MAX_PATH];
    ::wsprintf(szSubKey, TEXT("%s\\Shell\\Open\\Command"), pszPath);

    lRet = ::RegOpenKeyEx(HKEY_CLASSES_ROOT, szSubKey, 0, KEY_QUERY_VALUE, &hKey);
    if (ERROR_SUCCESS != lRet) return FALSE;

    dwData = MAX_PATH;
    lRet = ::RegQueryValueEx(hKey, NULL, 0, NULL, reinterpret_cast<LPBYTE>(pszPath), &dwData);
    if (ERROR_SUCCESS != lRet) return FALSE;

    lRet = ::RegCloseKey(hKey);
    if (ERROR_SUCCESS != lRet) return FALSE;

    ::PathRemoveArgs(pszPath);
    return TRUE;
}

//************************************
// Method:      NewWndProc
// Returns:     LRESULT CALLBACK
// Parameter:   HWND hwnd
// Parameter:   UINT uMsg
// Parameter:   WPARAM wParam
// Parameter:   LPARAM lParam
// Description: the custom window proc, then u can rider oughshod over it, ahh.
//************************************
LRESULT CALLBACK NewWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    BOOL bHandled = FALSE; // msg is handled?
    switch (uMsg)
    {
    case WM_USER + 1002:
        {
            ::OutputDebugString(TEXT("case WM_USER + 1002\n"));
            if (wParam == 0x05u)
            {
                ::OutputDebugString(TEXT("wParam == 0x05u\n"));

                KEYSETTING ks;
                ::GetPrivateProfileStruct(TEXT("KeyConfig"), TEXT("TheaterKey"),
                    &ks, sizeof(KEYSETTING), g_szCfgPath);

                if (ks.action == ACTION_NONE) break;

                bHandled = ::DoAction(ks);
            }
            else if (wParam == 0x0bu)
            {
                ::OutputDebugString(TEXT("wParam == 0x0bu\n"));

                KEYSETTING ks;
                ::GetPrivateProfileStruct(TEXT("KeyConfig"), TEXT("RecoveryKey"),
                    &ks, sizeof(KEYSETTING), g_szCfgPath);

                if (ks.action == ACTION_NONE) break;

                bHandled = ::DoAction(ks);
            }
        }
    }
    return bHandled || ::CallWindowProc(g_pfnOldWndProc, hwnd, uMsg, wParam, lParam);
}

//************************************
// Method:      SubWindowClass
// Returns:     BOOL
// Parameter:   void
// Description: Call this function to change the window proc
//************************************
BOOL SubWindowClass(void)
{
    HWND hWnd = ::FindWindow(TEXT("Utility_Window"), NULL);
    if (hWnd != NULL)
    {
        g_pfnOldWndProc = reinterpret_cast<WNDPROC>(
            ::SetWindowLongPtr(hWnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(NewWndProc)));
        if (g_pfnOldWndProc == 0)
        {
            MessageBox(hWnd, TEXT("SetWindowSubclass Faild\n"), TEXT("Error"), MB_OK | MB_ICONERROR);
        }
    }
    return g_pfnOldWndProc != 0;
}

//************************************
// Method:      UnSubWindowClass
// Returns:     BOOL
// Parameter:   void
// Description: Call this function to restore the default window proc
//************************************
BOOL UnSubWindowClass(void)
{
    HWND hWnd = ::FindWindow(TEXT("Utility_Window"), NULL);
    if (hWnd != NULL)
    {
        return ::SetWindowLongPtr(hWnd, GWLP_WNDPROC , reinterpret_cast<LONG_PTR>(g_pfnOldWndProc));
    }
    return FALSE;
}

注入的代码摘自windows核心编程一书
//************************************
// Method:      InjectLib 
// Returns:     BOOL
// Parameter:   DWORD dwProcessId
// Parameter:   LPCTSTR pszLibFileName
// Description: Inject dll to target process
//************************************
BOOL InjectLib( DWORD dwProcessId, LPCTSTR pszLibFileName )
{
    // TODO: Inject dll to process
    BOOL bOk = FALSE;  // Assume that the function fails
    HANDLE hProcess = NULL;
    HANDLE hThread = NULL;
    LPVOID pszLibFileRemote = NULL;
    __try
    {
        // Get a handle for the target process.
        hProcess = ::OpenProcess(
            PROCESS_QUERY_INFORMATION |   // Required by Alpha
            PROCESS_CREATE_THREAD     |   // For CreateRemoteThread
            PROCESS_VM_OPERATION      |   // For VirtualAllocEx/VirtualFreeEx
            PROCESS_VM_WRITE,             // For WriteProcessMemory
            FALSE, dwProcessId);
        if (hProcess == NULL) __leave;

        // Calculate the number of bytes needed for the DLL's pathname
        int cb  = (::lstrlen(pszLibFileName) + 1) * sizeof(TCHAR);

        // Allocate space in the remote process for the pathname
        pszLibFileRemote = ::VirtualAllocEx(hProcess, NULL, cb, MEM_COMMIT, PAGE_READWRITE);
        if (pszLibFileRemote == NULL) __leave;

        // Copy the DLL's pathname to the remote process' address space
        if (!::WriteProcessMemory(hProcess, pszLibFileRemote, 
            pszLibFileName, cb, NULL)) __leave;

        // Get the real address of LoadLibraryW in Kernel32.dll
        PTHREAD_START_ROUTINE pfnThreadRtn = reinterpret_cast<PTHREAD_START_ROUTINE>(
            ::GetProcAddress(::GetModuleHandle(_T("Kernel32")), "LoadLibraryW"));
        if (pfnThreadRtn == NULL) __leave;

        // Create a remote thread that calls LoadLibraryW(DLLPathname)
        hThread = ::CreateRemoteThread(hProcess, NULL, 0, pfnThreadRtn, pszLibFileRemote, 0, NULL);
        if (hThread == NULL) __leave;

        // Wait for the remote thread to terminate
        ::WaitForSingleObject(hThread, INFINITE);
        bOk = TRUE; // Everything executed successfully
    }
    __finally
    { // Now, we can clean everything up

        // Free the remote memory that contained the DLL's pathname
        if (pszLibFileRemote != NULL) ::VirtualFreeEx(hProcess, pszLibFileRemote, 0, MEM_RELEASE);

        CLOSE_HANDLE(hThread);
        CLOSE_HANDLE(hProcess);
    }
    return bOk;
}

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (10)
雪    币: 652
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
注入不了的话,原因比较多。比如被某些杀软底层拦截,或者你的程序不兼容win8 x86

还有可能就是你的程序执行过程中有失败的返回值,你自己没有检查。

比较进程权限,读取文件,分配内存等。建议楼主还是慢慢跟踪调试吧。

将错误的地方和错误状态码找出来,查查就知道了。
2013-1-8 13:10
0
雪    币: 44
活跃值: (26)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
64位下 ,如果被注入的进程是32位,那么注入器和dll都得是32位  
如果被注入进程是64位的,那么注入器和dll都得是64位的
2013-1-8 14:18
0
雪    币: 1462
活跃值: (379)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
不是注入不了。。。是注入后DllMain里的代码没执行。。。没有杀软拦截。。。我是 win8 x64,注入和被注入和dll都是x64.。。。也不需要提权。。DllMain里代码没执行。。怎么检查?
2013-1-8 14:32
0
雪    币: 1462
活跃值: (379)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
这当然知道。。。都是x64。。没32.。。用32来注入64也是可以实现的。。只不过这里不需要这么干。求解问题所在?
2013-1-8 14:34
0
雪    币: 44
活跃值: (26)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
OutputDebugString(TEXT("DllMain\n"));
这行代码前加一行MessageBoxA(NULL, "DllMain", NULL, NULL);
看一下可否弹出。
2013-1-9 19:57
0
雪    币: 1462
活跃值: (379)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
没效果。。。。。
2013-1-9 19:58
0
雪    币: 44
活跃值: (26)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
这太奇怪了...其他语言写的程序试过没?
2013-1-10 09:23
0
雪    币: 215
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
试试ddk自带的lib库,不要用系统自带的试试
2013-1-10 10:07
0
雪    币: 465
活跃值: (191)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
注入是为了过UAC提示以FULL权限执行程序,但过了UAC才能注入FULL权限的目标进程,死循环绕不出去了,望大神指点。
2016-3-8 14:49
0
雪    币: 2
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
新手来学习了.
2016-3-9 09:07
0
游客
登录 | 注册 方可回帖
返回
//