messagebox
API,但是我发现两次messageboxA
和一次MessageboxW
,它们似乎都没有被用于此目的。 。因此,我想知道是否有可能在不使用
MessageBox
API的情况下显示消息,甚至DLL在没有API的情况下也可以显示消息?请帮助
#1 楼
首先,您需要确定它是否是Windows消息框。
消息框中包含哪种消息(自定义/标准win32 /系统字符串的编译) ?另外,如果可能的话,屏幕截图也会很好(因此我们可以看到更多...)如果您可以使其在某些测试机上工作,则还检查消息框的CLASS_ID,可以显示它是Windows消息框还是自定义看起来像这样的VCL表单...您可以使用
如何从第3个App的运行时中找到MDI的活动子表单
但已将其删除,并且您在SO上没有足够的代表可以看到它,因此在此复制了源(VCL C ++,因此如果没有Borland C ++,则只需移植到Pascal)即可: br />
//---------------------------------------------------------------------------
//--- Windows ver: 1.1 ------------------------------------------------------
//---------------------------------------------------------------------------
HWND getwindow(HWND hnd0,AnsiString nam,AnsiString cls="")
{
int i,l,ln=nam.Length(),lc=cls.Length(),e;
char txt[256];
HWND hnd1;
if (hnd0==NULL) hnd1=GetTopWindow(hnd0);
else hnd1=GetWindow(hnd0,GW_HWNDNEXT);
for (;;)
{
e=1;
if (hnd1==hnd0) break;
if (hnd1==NULL) break;
l=GetWindowText(hnd1,txt,256);
if (e) { if (l>ln) l=ln; if (l<ln) e=0; else for (i=0;i<l;i++) if (txt[i]!=nam[i+1]) { e=0; break; } }
l=RealGetWindowClass(hnd1,txt,256);
if (e) { if (l>lc) l=lc; if (l<lc) e=0; else for (i=0;i<l;i++) if (txt[i]!=cls[i+1]) { e=0; break; } }
if (e) return hnd1;
hnd0=hnd1;
hnd1=GetWindow(hnd0,GW_HWNDNEXT);
}
return NULL;
};
//---------------------------------------------------------------------------
HWND getsubwindow(HWND hndp,HWND hnd0,AnsiString nam,AnsiString cls="")
{
int i,l,ln=nam.Length(),lc=cls.Length(),e;
char txt[256];
HWND hnd1;
if (hnd0==NULL) hnd1=GetTopWindow(hnd0);
else hnd1=GetWindow(hnd0,GW_HWNDNEXT);
for (;;)
{
e=1;
if (hnd1==hnd0) break;
if (hnd1==NULL) break;
if (GetParent(hnd1)!=hndp) e=0;
l=GetWindowText(hnd1,txt,256);
if (e) { if (l>ln) l=ln; if (l<ln) e=0; else for (i=0;i<l;i++) if (txt[i]!=nam[i+1]) { e=0; break; } }
l=RealGetWindowClass(hnd1,txt,256);
if (e) { if (l>lc) l=lc; if (l<lc) e=0; else for (i=0;i<l;i++) if (txt[i]!=cls[i+1]) { e=0; break; } }
if (e) return hnd1;
hnd0=hnd1;
hnd1=GetWindow(hnd0,GW_HWNDNEXT);
}
return NULL;
};
//---------------------------------------------------------------------------
bool getwindows(HWND &hnd,AnsiString &nam,AnsiString &cls)
{
int i,l;
char txt[256];
HWND hnd0=hnd;
nam=""; cls="";
if (hnd0==NULL) hnd=GetTopWindow(hnd0);
else hnd=GetWindow(hnd0,GW_HWNDNEXT);
if (hnd==hnd0) { hnd=NULL; return false; }
if (hnd==NULL) { hnd=NULL; return false; }
l=GetWindowText(hnd,txt,256); for (i=0;i<l;i++) nam+=txt[i];
l=RealGetWindowClass(hnd,txt,256); for (i=0;i<l;i++) cls+=txt[i];
return true;
};
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
它是用BDS2006 Turbo C ++编写的,并且使用VCL,因此您需要将其转换为您的语言。实际上,它仅使用VCL中的
AnsiString
,因此只需将其更改为您拥有的任何字符串即可。它是基于WinAPI的,因此包含“ Windows.h”。这里是一些用法示例: HANDLE hnd,hnd0;
AnsiString nam,cls;
AnsiString s,t="";
for (hnd=NULL;;)
{
if (!getwindows(hnd,nam,cls)) break; // get hnd,name and class
hnd0=GetParent(hnd); // get parent hnd
if (hnd0!=Application->Handle) continue;// filter out unwanted windows
// here process found window or add it to list or what ever
// for example add to memo->Lines->Add(...) so you obtain a list of all windows ...
s=AnsiString().sprintf("%X",hnd); while (s.Length()< 8) s="0"+s; t+=s+"h ";
s=cls; while (s.Length()<32) s=s+" "; t+=s+" ";
s=nam; while (s.Length()<32) s=s+" "; t+=s+"\r\n";
}
mm_log->Text=t; // just my memo
未过滤的输出的以下几行:事物...例如找到您的消息框App的
hnd
,然后仅显示具有相同的hnd0
的句柄。例如,我刚刚创建了一个消息框来获取Class_ID: /> Handle: Class_ID: Name
0003060Ch TTokenWindow CodeParamWindow
00030374h ComboLBox
000100F8h tooltips_class32
000100FAh TaskListThumbnailWnd
000100E6h tooltips_class32
000100E8h tooltips_class32
000100ECh tooltips_class32
000100EEh tooltips_class32
000100D0h tooltips_class32
000100E4h tooltips_class32
000100C8h Button Start
00030118h tooltips_class32
0003013Eh tooltips_class32
00040122h tooltips_class32
00090102h tooltips_class32
000100C2h Shell_TrayWnd
000303ECh TaskSwitcherOverlayWnd
00010240h IME Default IME
0001023Eh TaskSwitcherWnd Task Switching
00030376h ComboLBox
000403A0h Auto-Suggest Dropdown
00010108h CiceroUIWndFrame CiceroUIWndFrame
000100C6h MSCTFIME UI MSCTFIME UI
000100C0h IME Default IME
00010158h tooltips_class32
00010246h ATL:000007FEF0EF52C0 Network Flyout
00010180h CDA Server Class Administrator : CDA Server
00010182h IME Default IME
0001008Ch CiceroUIWndFrame CiceroUIWndFrame
0001008Ah CiceroUIWndFrame TF_FloatingLangBar_WndTitle
000303CEh tooltips_class32
0003061Eh TForm1 Project Euler
00090566h TApplication Project1
0003061Ah TPUtilWindow
00050610h IME Default IME
00090386h MSCTFIME UI MSCTFIME UI
00210408h IME Default IME
000B0416h TEditWindow Unit1.cpp
0007057Ch TWatchWindow Watch List
000105B2h TTabDockHostForm Project1.bdsproj - Project Manager
要获取父句柄,您需要在未过滤列表中搜索类
TApplication
。我使用Application->Handle
代替,因为我直接在同一应用程序中对此进行了测试。如果消息框是本机win32
这并不一定意味着该应用程序直接调用winapi。最有可能的是,它使用了一些VCL封装。因此,请为Delphi IDE帮助中的所有消息框函数名称添加褐色...测试它们,看看Class_ID是否与您的应用程序匹配...
如果消息框不是本机win32
那很可能是正常的VCL窗口。然后,类名是Delphi窗口类的名称,如
TForm1
。窗口名称通常是它的Caption
,对于App来说是exe文件名。在这种情况下,显示对话框不同:设置位置
Left,Top,Width,Height
或调用SetBounds()
设置消息可以是
TLabel,TEdit
,... Text
或Caption
属性或直接在Canvas
上呈现。设置
Visible=true
或使用ShowWindow,ShowModal
... 所以您知道要查找的内容... />
对于多语言应用程序,文本通常在某些
*.ini
或*.dll
文件中。如果是DLL,则DLL可以压缩或加密,因此不容易看到。尝试用文件名中的语言搜索文件。希望有更多信息让我知道。
#2 楼
MessageBox API只会创建一个Windows对话框,并在消息循环中旋转直到关闭为止。程序可以自己执行此操作而无需使用MessageBox,您可以查找对CreateDialog或CreateWindow的调用。 br />
评论
我只找到了CreateWindowExW,它也不用于消息显示
– D.Trap
16年1月23日在13:39
#3 楼
尝试在CFF Explorer的十六进制编辑器中打开可执行文件并搜索那些字符串,如果找不到它们,那么我建议您寻求有关在可执行文件中查找隐藏代码的帮助。我认为程序员有时可以隐藏部分代码并同时加密或隐藏字符串。
找到隐藏的代码部分,然后再次查找API。
评论
是的,好像它隐藏在某个地方,如何在可执行文件中找到隐藏的代码?
– D.Trap
16年1月23日在13:40
评论
消息框中显示哪种消息?习俗?标准的win32?系统字符串的编译? ...如果可能的话,屏幕截图也会很不错(所以我们可以看到更多...)如果您可以使其在某些测试机上运行,则还要检查消息框的CLASS_ID,它可以显示是Windows消息框还是看起来像这样的自定义公式...