控制台下输出DLL的调试信息

幻影技术综合区 看到这个帖子,备忘下

问:

在cmd.exe下运行rundll32.exe mydll.dll,MyFunc ,本想直接在当前cmd窗口输出调试信息.
可因rundll32是Win32 GUI程序而非Win32 console,所以cmd.exe标准输入输出句柄无法被mydll.dll继承用来向父进程cmd.exe输出数据.
这时, 如果用强行用GetStdHandle获得句柄,然后用WriteConsole来进行输出,则会发生无效句柄错误.
但是如果在这之前先AllocConsole,则可正常WriteConsole,但是会新建个控制台窗口来输出数据,很不爽 :-P

有没有什么办法向当前cmd.exe窗口输出数据呢?

我想通过给进程拍照和遍历,
可以获得rundll32的父进程cmd.exe的PID和Handle,但如何进一步下去(建立管道, 写数据)就没辙了?

不知道有没有描述清楚 还是太罗嗦了,麻烦大家看看,谢谢~

 

答:

如果只是要输出数据的话 可以向父窗口 发送键盘消息 WM_CHAR 输出你的数据

 

 

代码

Code:


BOOL APIENTRY DllMain
( HANDLE hModule,
                       
DWORD  ul_reason_for_call
,
                       
LPVOID lpReserved
)
{
    switch (
ul_reason_for_call
)
    {
        case
DLL_PROCESS_ATTACH
:
            
ShowMe
();
            
        case
DLL_THREAD_ATTACH
:
        case
DLL_THREAD_DETACH
:
        case
DLL_PROCESS_DETACH
:
            break;

    }
    return
TRUE
;
}


void ShowMe
()
{
    
DWORD    dwProcID
;
    
HWND    hWnd
;
    
dwProcID = FindParentProcID(GetCurrentProcessId
());
        
sprintf(buf, "dwProcID:%d/nProcessId:%d ",  dwProcID, GetCurrentProcessId
());
        
MessageBox (NULL, buf, "提示", MB_ICONERROR
);
    if(
dwProcID == -1
)
        return;

    
hWnd = GetProcessMainWnd(dwProcID
);
    if(
hWnd ==NULL
)
        return;

    
SendMessage(hWnd, WM_CHAR, WPARAM('Z'), NULL
);
}


Code:

DWORD FindParentProcID
(DWORD dwChildProcID)        //找到返回父进程PID, 找不到返回-1
{
    
PROCESSENTRY32     pr32 = {0
};
    
pr32.dwSize = sizeof(PROCESSENTRY32);   
// 不要漏了这句

    // 提权先
    
DebugPrivilege(SE_DEBUG_NAME, TRUE
);    
    
// 给进程照相
    
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0
);
    
// 拍照失败, 返回-1
    
if (hSnap == (HANDLE)-1) return (DWORD)-1
;
    
    
// 开始枚举...
    
if (Process32First(hSnap,&pr32) == FALSE
)  
    {
        
CloseHandle( hSnap
);
        return (
DWORD)-1
;
    }

    do
    {
        if(
pr32.th32ProcessID == dwChildProcID
)  
        {            
// 如果被枚举到的进程ID等于所给的ID, 则返回父进程ID
            
CloseHandle( hSnap
);
            return
pr32.th32ParentProcessID
;
        }
    }
    while(
Process32Next(hSnap, &pr32
));

    
// 找不到父进程ID, 返回-1
    
CloseHandle(hSnap
);
    return -
1
;
}


Code:

typedef struct tagWNDINFO
{
    
DWORD dwProcessId
;
    
HWND hWnd
;
}
WNDINFO, *LPWNDINFO
;

BOOL CALLBACK YourEnumProc(HWND hWnd,LPARAM lParam
)
{
    
DWORD dwProcessId
;
    
GetWindowThreadProcessId(hWnd, &dwProcessId
);
    
LPWNDINFO pInfo = (LPWNDINFO)lParam
;
    if(
dwProcessId == pInfo->dwProcessId
)
    {
        
pInfo->hWnd = hWnd
;
        return
FALSE
;
    }
    return
TRUE
;
}

HWND GetProcessMainWnd(DWORD dwProcessId)        
// 找到返回进程主窗口的hWnd, 如果没有,返回NULL
{
    
WNDINFO wi
;
    
wi.dwProcessId = dwProcessId
;
    
wi.hWnd = NULL
;
    
EnumWindows(YourEnumProc,(LPARAM)&wi
);
    return
wi.hWnd
;
}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值