LOAD_DLL_DEBUG_EVENT取DLL名称

来源:互联网 发布:淘宝怎样才能分期付款 编辑:程序博客网 时间:2024/06/04 19:07

前言

msdn上说, 当(dbgEvent.dwDebugEventCode == LOAD_DLL_DEBUG_EVENT)时, 如果要取DLL名称.
要 判断 以下条件
pInfo = &dbgEvent.u.LoadDll;
if ((NULL != pInfo) && (NULL != pInfo->lpImageName) && (NULL != (DWORD)(pInfo->lpImageName))) {
/// 才可以取Dll名字
/// 判断pInfo->fUnicode, 决定是unicode串,还是ansi串
}

(DWORD)(pInfo->lpImageName) 说的是去对方进程中取.
开始实验没作足, 从DLL中取导出表中标明的DLL原始名称.
后来,按照msdn说明,去对方进程中去取名字,也是可以的. 看来msdn还是靠谱的, 如果有错,一定是自己看文档看的不够细,实验做的不够细致.

UI

从对方进程的导出表位置拿DLL原始名称
这里写图片描述
按照msdn说明, 去直接取(DWORD)(pInfo->lpImageName)字符串缓冲区.
这里写图片描述
对比效果,可以看出,使用LOAD_DLL_DEBUG_EVENT时,给出的信息,直接拿,可以拿到DLL全路径, 比自己从DLL导出表中拿DLL原始名称信息多.

代码片段

// MyDebugger.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include <Windows.h>#include <process.h>#include "stdlib.h"#include "stdio.h"#define OBJ_PROG_NAME "winmine.exe"void fnDebuggerStart();DWORD OnDebugEvent_EXCEPTION_DEBUG_EVENT(PROCESS_INFORMATION& pi, DEBUG_EVENT& dbgEvent, DWORD& dwContinueStatus);DWORD OnDebugEvent_CREATE_THREAD_DEBUG_EVENT(PROCESS_INFORMATION& pi, DEBUG_EVENT& dbgEvent, DWORD& dwContinueStatus);DWORD OnDebugEvent_CREATE_PROCESS_DEBUG_EVENT(PROCESS_INFORMATION& pi, DEBUG_EVENT& dbgEvent, DWORD& dwContinueStatus);DWORD OnDebugEvent_EXIT_THREAD_DEBUG_EVENT(PROCESS_INFORMATION& pi, DEBUG_EVENT& dbgEvent, DWORD& dwContinueStatus);DWORD OnDebugEvent_EXIT_PROCESS_DEBUG_EVENT(PROCESS_INFORMATION& pi, DEBUG_EVENT& dbgEvent, DWORD& dwContinueStatus);DWORD OnDebugEvent_LOAD_DLL_DEBUG_EVENT(PROCESS_INFORMATION& pi, DEBUG_EVENT& dbgEvent, DWORD& dwContinueStatus);DWORD OnDebugEvent_LOAD_DLL_DEBUG_EVENT_m1(PROCESS_INFORMATION& pi, DEBUG_EVENT& dbgEvent, DWORD& dwContinueStatus);DWORD OnDebugEvent_LOAD_DLL_DEBUG_EVENT_m2(PROCESS_INFORMATION& pi, DEBUG_EVENT& dbgEvent, DWORD& dwContinueStatus);DWORD OnDebugEvent_UNLOAD_DLL_DEBUG_EVENT(PROCESS_INFORMATION& pi, DEBUG_EVENT& dbgEvent, DWORD& dwContinueStatus);DWORD OnDebugEvent_OUTPUT_DEBUG_STRING_EVENT(PROCESS_INFORMATION& pi, DEBUG_EVENT& dbgEvent, DWORD& dwContinueStatus);DWORD OnDebugEvent_RIP_EVENT(PROCESS_INFORMATION& pi, DEBUG_EVENT& dbgEvent, DWORD& dwContinueStatus);int main(int argc, char* argv[]){    fnDebuggerStart();    printf("END, press any key to quit\n");    system("pause");    return 0;}void fnDebuggerStart() {    BOOL bRc = FALSE;    BOOL bNeedDebug = TRUE;    STARTUPINFO si;     PROCESS_INFORMATION pi;    DEBUG_EVENT dbgEvent;    DWORD dwContinueStatus = DBG_EXCEPTION_NOT_HANDLED;    do {        ZeroMemory(&si, sizeof(si));        si.cb = sizeof(si);        ZeroMemory(&pi, sizeof(pi));        ZeroMemory(&dbgEvent, sizeof(dbgEvent));        bRc = CreateProcess(OBJ_PROG_NAME, NULL, NULL, NULL, FALSE, DEBUG_ONLY_THIS_PROCESS, NULL, NULL, &si, &pi);        if (!bRc) {            printf("CreateProcesss failed [%s]\n", OBJ_PROG_NAME);        }        do {            if (!WaitForDebugEvent(&dbgEvent, INFINITE)) {                break;            }            switch (dbgEvent.dwDebugEventCode) {                case EXCEPTION_DEBUG_EVENT:                    bNeedDebug = (S_OK == OnDebugEvent_EXCEPTION_DEBUG_EVENT(pi, dbgEvent, dwContinueStatus));                    break;                case CREATE_THREAD_DEBUG_EVENT:                    bNeedDebug = (S_OK == OnDebugEvent_CREATE_THREAD_DEBUG_EVENT(pi, dbgEvent, dwContinueStatus));                    break;                case CREATE_PROCESS_DEBUG_EVENT:                    bNeedDebug = (S_OK == OnDebugEvent_CREATE_PROCESS_DEBUG_EVENT(pi, dbgEvent, dwContinueStatus));                    break;                case EXIT_THREAD_DEBUG_EVENT:                    bNeedDebug = (S_OK == OnDebugEvent_EXIT_THREAD_DEBUG_EVENT(pi, dbgEvent, dwContinueStatus));                    break;                case EXIT_PROCESS_DEBUG_EVENT:                    bNeedDebug = (S_OK == OnDebugEvent_EXIT_PROCESS_DEBUG_EVENT(pi, dbgEvent, dwContinueStatus));                    break;                case LOAD_DLL_DEBUG_EVENT:                    bNeedDebug = (S_OK == OnDebugEvent_LOAD_DLL_DEBUG_EVENT(pi, dbgEvent, dwContinueStatus));                    break;                case UNLOAD_DLL_DEBUG_EVENT:                    bNeedDebug = (S_OK == OnDebugEvent_UNLOAD_DLL_DEBUG_EVENT(pi, dbgEvent, dwContinueStatus));                    break;                case OUTPUT_DEBUG_STRING_EVENT:                    bNeedDebug = (S_OK == OnDebugEvent_OUTPUT_DEBUG_STRING_EVENT(pi, dbgEvent, dwContinueStatus));                    break;                case RIP_EVENT:                    bNeedDebug = (S_OK == OnDebugEvent_RIP_EVENT(pi, dbgEvent, dwContinueStatus));                    break;                default:                    printf("dbgEvent.dwDebugEventCode = %d\n", dbgEvent.dwDebugEventCode);                    break;            }            ContinueDebugEvent(dbgEvent.dwProcessId, dbgEvent.dwThreadId, dwContinueStatus);         } while (bNeedDebug);        WaitForSingleObject(pi.hProcess, INFINITE);        CloseHandle(pi.hProcess);        CloseHandle(pi.hThread);    } while (0);}DWORD OnDebugEvent_EXCEPTION_DEBUG_EVENT(PROCESS_INFORMATION& pi, DEBUG_EVENT& dbgEvent, DWORD& dwContinueStatus) {    dwContinueStatus = DBG_CONTINUE; ///< ! 必须处理, 否则报错    return S_OK;}DWORD OnDebugEvent_CREATE_THREAD_DEBUG_EVENT(PROCESS_INFORMATION& pi, DEBUG_EVENT& dbgEvent, DWORD& dwContinueStatus) {    dwContinueStatus = DBG_EXCEPTION_NOT_HANDLED;    return S_OK;}DWORD OnDebugEvent_CREATE_PROCESS_DEBUG_EVENT(PROCESS_INFORMATION& pi, DEBUG_EVENT& dbgEvent, DWORD& dwContinueStatus) {    dwContinueStatus = DBG_EXCEPTION_NOT_HANDLED;    return S_OK;}DWORD OnDebugEvent_EXIT_THREAD_DEBUG_EVENT(PROCESS_INFORMATION& pi, DEBUG_EVENT& dbgEvent, DWORD& dwContinueStatus) {    dwContinueStatus = DBG_EXCEPTION_NOT_HANDLED;    return S_OK;}DWORD OnDebugEvent_EXIT_PROCESS_DEBUG_EVENT(PROCESS_INFORMATION& pi, DEBUG_EVENT& dbgEvent, DWORD& dwContinueStatus) {    dwContinueStatus = DBG_CONTINUE;    return S_FALSE; ///< 必须处理(退出调试等待), 否则目标程序退出后, 死在 WaitForDebugEvent} DWORD OnDebugEvent_LOAD_DLL_DEBUG_EVENT(PROCESS_INFORMATION& pi, DEBUG_EVENT& dbgEvent, DWORD& dwContinueStatus) {    return OnDebugEvent_LOAD_DLL_DEBUG_EVENT_m2(pi, dbgEvent, dwContinueStatus);}DWORD OnDebugEvent_LOAD_DLL_DEBUG_EVENT_m1(PROCESS_INFORMATION& pi, DEBUG_EVENT& dbgEvent, DWORD& dwContinueStatus) {    LOAD_DLL_DEBUG_INFO* pInfo = NULL;    dwContinueStatus = DBG_EXCEPTION_NOT_HANDLED;    char szBuf[MAX_PATH] = {'\0'};    SIZE_T nNumberOfBytesRead = 0;    IMAGE_DOS_HEADER dosHeader;    IMAGE_NT_HEADERS ntHeader;    IMAGE_DATA_DIRECTORY* pDataDir = NULL;    IMAGE_EXPORT_DIRECTORY* pExportDir = NULL;    IMAGE_EXPORT_DIRECTORY ExportDir;    DWORD dwAddrDllName = 0;    WORD wLenDllName = 0;    pInfo = &dbgEvent.u.LoadDll;    // *(DWORD*)(pInfo->lpImageName) 里面总是0, 不能按照msdn上来判断    // if ((NULL != pInfo) && (NULL != pInfo->lpImageName) && (NULL != *(DWORD*)(pInfo->lpImageName))) {    // 看到载入不同DLL时, pInfo->lpBaseOfDll 总是不同的    if ((NULL != pInfo) && (NULL != pInfo->lpBaseOfDll)) {        // 读目标DLL导出表中的dll名称吧        do {            if (!ReadProcessMemory(pi.hProcess, pInfo->lpBaseOfDll, &dosHeader, sizeof(dosHeader), &nNumberOfBytesRead)) {                break;            }            if (!ReadProcessMemory(pi.hProcess, (void*)((DWORD)pInfo->lpBaseOfDll + dosHeader.e_lfanew), &ntHeader, sizeof(ntHeader), &nNumberOfBytesRead)) {                break;            }            pDataDir = &ntHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];            pExportDir = (IMAGE_EXPORT_DIRECTORY*)((DWORD)pInfo->lpBaseOfDll + pDataDir->VirtualAddress);            if (!ReadProcessMemory(pi.hProcess, pExportDir, &ExportDir, sizeof(ExportDir), &nNumberOfBytesRead)) {                break;            }            dwAddrDllName = (DWORD)pInfo->lpBaseOfDll + ExportDir.Name;            if (!ReadProcessMemory(pi.hProcess, (void*)dwAddrDllName, &szBuf, sizeof(szBuf), &nNumberOfBytesRead)) {                break;            }            // Name都是Ascii串            printf("OnDebugEvent_LOAD_DLL_DEBUG_EVENT dllName=[%s]\n", szBuf);        } while (0);    }    return S_OK;}DWORD OnDebugEvent_LOAD_DLL_DEBUG_EVENT_m2(PROCESS_INFORMATION& pi, DEBUG_EVENT& dbgEvent, DWORD& dwContinueStatus) {    LOAD_DLL_DEBUG_INFO* pInfo = NULL;    dwContinueStatus = DBG_EXCEPTION_NOT_HANDLED;    char szBuf[MAX_PATH] = {'\0'};    SIZE_T nNumberOfBytesRead = 0;    DWORD dwAddrImageName = 0;    pInfo = &dbgEvent.u.LoadDll;    if ((NULL != pInfo) && (NULL != pInfo->lpImageName)) {        // 读目标DLL导出表中的dll名称吧        do {            if (!ReadProcessMemory(pi.hProcess, pInfo->lpImageName, &dwAddrImageName, sizeof(dwAddrImageName), &nNumberOfBytesRead)) {                break;            }            if (0 == dwAddrImageName) {                break;            }            if (!ReadProcessMemory(pi.hProcess, (void*)dwAddrImageName, &szBuf, sizeof(szBuf), &nNumberOfBytesRead)) {                break;            }            if (0 == pInfo->fUnicode) {                // ansi                printf("Load dll : %s\n", szBuf);            } else {                // unicode                wprintf(L"Load dll : %s\n", szBuf);            }        } while (0);    }    return S_OK;}DWORD OnDebugEvent_UNLOAD_DLL_DEBUG_EVENT(PROCESS_INFORMATION& pi, DEBUG_EVENT& dbgEvent, DWORD& dwContinueStatus) {    dwContinueStatus = DBG_EXCEPTION_NOT_HANDLED;    return S_OK;}DWORD OnDebugEvent_OUTPUT_DEBUG_STRING_EVENT(PROCESS_INFORMATION& pi, DEBUG_EVENT& dbgEvent, DWORD& dwContinueStatus) {    dwContinueStatus = DBG_EXCEPTION_NOT_HANDLED;    return S_OK;}DWORD OnDebugEvent_RIP_EVENT(PROCESS_INFORMATION& pi, DEBUG_EVENT& dbgEvent, DWORD& dwContinueStatus) {    dwContinueStatus = DBG_EXCEPTION_NOT_HANDLED;    return S_OK;}
0 0