我有一个应用程序,用于在单击“确定”按钮后显示一条消息“正在处理”,然后显示另一条消息“完成”,但现在没有了。所以我把它倒过来看看发生了什么,但结果是搜索字符串的方式不起作用,所以我搜索了messageboxAPI,但我发现了messageboxA两次,MessageboxW一次,它们似乎都没有用于那个。
所以,我想知道是否有可能在不使用MessageBoxAPI 的情况下显示消息,或者甚至 DLL 可以在没有 API 的情况下显示消息?请帮忙
我有一个应用程序,用于在单击“确定”按钮后显示一条消息“正在处理”,然后显示另一条消息“完成”,但现在没有了。所以我把它倒过来看看发生了什么,但结果是搜索字符串的方式不起作用,所以我搜索了messageboxAPI,但我发现了messageboxA两次,MessageboxW一次,它们似乎都没有用于那个。
所以,我想知道是否有可能在不使用MessageBoxAPI 的情况下显示消息,或者甚至 DLL 可以在没有 API 的情况下显示消息?请帮忙
首先你需要确定它是否是windows消息框。
消息框(自定义/标准win32 /系统字符串编译)中是什么类型的消息?如果可能的话,屏幕截图也会很好(所以我们可以看到更多......)如果你可以让它在一些测试机器上工作然后检查消息框的CLASS_ID它可以显示它是 Windows 消息框还是自定义VCL形式,只是看起来像它...你可以获得类标识码与
但它被删除了,你在 SO 上没有足够的代表来查看它,所以这里复制了源代码(VCL C++,所以如果你没有Borland C++,你只需要移植到Pascal):
//---------------------------------------------------------------------------
//--- 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,因此您需要将其转换为您的语言。实际上它只AnsiString从VCL使用,所以只需将其更改为您拥有的任何字符串。它基于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
这里有几行未过滤的输出:
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
正如你所看到的,会有很多句柄(所有的视觉组件都像窗口一样,所以你需要过滤掉很多东西......例如找到hnd你的消息框应用程序的 。然后只显示具有相同 parrent 的句柄hnd0。
例如,我刚刚创建了一个消息框来获取Class_ID:
int ret=MessageDlg("Test message",mtCustom,TMsgDlgButtons(mrOk),-1); // cls = "TMessageForm"
要获得父句柄,您需要在未过滤的列表中搜索 class 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可以被压缩或加密,从而它是不容易看到。尝试在文件名中搜索带有语言的文件。
如果您有更多信息,请告诉我,希望对您有所帮助。
MessageBox API 只是创建一个窗口对话框并在消息循环中旋转直到它关闭。
程序可以在不使用 MessageBox 的情况下自行完成此操作,您可以查找对CreateDialog或CreateWindow 的调用。
尝试在 CFF Explorer 的十六进制编辑器中打开可执行文件并搜索这些字符串,如果找不到它们,那么我建议您寻找有关在可执行文件中查找隐藏代码的帮助。我认为程序员有时可以隐藏代码部分,也可以加密或隐藏字符串。找到隐藏的代码部分,然后再次查找 API。