如果调用 RtlSetProcessIsCritical,将使用 lstrcmpW 将命令行与值进行比较将使程序崩溃
If RtlSetProcessIsCritical is called, comparing the commandline to a value using lstrcmpW will crash the programm
我现在正在做一个更大的项目,我遇到了一个奇怪的问题。 正如标题所述,如果命令行中的第二个参数与使用lstrcmpW
的预设值匹配,我将调用RtlSetProcessIsCritical
函数,然后尝试执行代码块。
从我的项目中重建的项目,投影结构器
主 CPP 文件:
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow) {
int nArgs;
LPWSTR* szArglist = CommandLineToArgvW(GetCommandLine(), &nArgs);
// Check if ArgumentList was Created, if not: Exit Malware
if (!szArglist) {
MessageBox(NULL, L"Couldn't parse Commandline", L"CommandLineToArgvW", MB_OK | MB_SYSTEMMODAL | MB_ICONERROR);
ExitProcess(EXIT_FAILURE);
}
if (nArgs > 1) {
if (!lstrcmp(szArglist[1], L"/exec") {
// Some Code here...
} else if (!lstrcmp(szArglist[1], L"/host")) {
// Some Code here...
if (NTImportDLLFUNC()) {
if (NTSetProcessIsCritical(TRUE)) {
// Debug Message
MessageBox(NULL, L"HostProcess is now Critical", L"N0T-iLLerka.X", MB_OK | MB_SYSTEMMODAL | MB_ICONWARNING);
}
}
if (nArgs > 2) {
if (!lstrcmp(szArglist[2], L"/init")) {
// Some Code here...
}
}
// Deadlock here
}
}
// Some Code here...
}
实用程序文件:
#define OPTION_SHUTDOWN_SYSTEM 6
#define SE_DEBUG_PRIVILEGE 20
typedef NTSTATUS(CALLBACK* pRTLADJUSTPRIVILEGE)(ULONG, BOOLEAN, BOOLEAN, PBOOLEAN);
pRTLADJUSTPRIVILEGE RtlAdjustPrivilege;
typedef NTSTATUS(CALLBACK* pRTLSETPROCESSISCRITICAL)(BOOLEAN, BOOLEAN*, BOOLEAN);
pRTLSETPROCESSISCRITICAL RtlSetProcessIsCritical;
bool NTImportDLLFUNC() {
HINSTANCE hNtdll = LoadLibrary(L"ntdll.dll");
if (hNtdll) {
RtlAdjustPrivilege = (pRTLADJUSTPRIVILEGE)GetProcAddress(hNtdll, "RtlAdjustPrivilege");
if (!RtlAdjustPrivilege) {
MessageBox(NULL, L""RtlAdjustPrivilege" is invalid", L"GetProcAddress", MB_OK | MB_SYSTEMMODAL | MB_ICONERROR);
FreeLibrary(hNtdll);
return FALSE;
}
RtlSetProcessIsCritical = (pRTLSETPROCESSISCRITICAL)GetProcAddress(hNtdll, "RtlSetProcessIsCritical");
if (!RtlSetProcessIsCritical) {
MessageBox(NULL, L""RtlSetProcessIsCritical" is invalid", L"GetProcAddress", MB_OK | MB_SYSTEMMODAL | MB_ICONERROR);
FreeLibrary(hNtdll);
return FALSE;
}
} else {
MessageBox(NULL, L"Couldn't load "ntdll.dll"", L"N0T-iLLerka.X", MB_OK | MB_SYSTEMMODAL | MB_ICONERROR);
return FALSE;
}
FreeLibrary(hNtdll);
return TRUE;
}
bool NTSetProcessIsCritical(BOOLEAN blIscritical) {
BOOLEAN bl;
if (!RtlAdjustPrivilege(SE_DEBUG_PRIVILEGE, TRUE, FALSE, &bl)) {
if (!RtlSetProcessIsCritical(blIscritical, NULL, FALSE)) {
return TRUE;
} else {
MessageBox(NULL, L"Couldn't set Process Critical", L"RtlSetProcessIsCritical", MB_OK | MB_SYSTEMMODAL | MB_ICONERROR);
return FALSE;
}
} else {
MessageBox(NULL, L"Couldn't set Debug Privileges", L"RtlAdjustPrivilege", MB_OK | MB_SYSTEMMODAL | MB_ICONERROR);
return FALSE;
}
return FALSE;
}
现在的问题是,当我调用RtlSetProcessIsCritical
(对它得到的设置并不重要(并且命令行参数得到比较时,应用程序崩溃,但是如果我不调用RtlSetProcessIsCritical
程序无论出于何种原因都可以完美运行。
我发现问题出在RtlSetProcessIsCritical
函数和这条行if (!lstrcmp(szArglist[2], L"/init")) {
我还尝试使用相同的代码结构器在另一个项目中重现这个"错误",但它在那里完美无缺,我现在没有想法了。
如果您需要其余的代码,您可以在我的Github上阅读它,链接到2个文件:
主要CPP
公用事业 CPP
(在我的 Github 上的主文件中,对RtlSetProcessIsCritical
的调用是在 if 语句之后。这是暂时的,这只是一个快速的解决方法,所以我至少可以测试软件的其余部分。在发布版本中,这应该按照前面描述的顺序!
声明
typedef NTSTATUS(CALLBACK* pRTLSETPROCESSISCRITICAL)(BOOLEAN, BOOLEAN*, BOOLEAN);
是错误的。正确的函数定义是
NTSYSAPI
NTSTATUS
STDAPIVCALLTYPE
RtlSetProcessIsCritical(
_In_ BOOLEAN NewValue,
_Out_opt_ PBOOLEAN OldValue,
_In_ BOOLEAN CheckFlag
);
这是STDAPIVCALLTYPE
- 与__cdecl
相同,而不是CALLBACK
(又名__stdcall
(。 对于 NTDLL API 来说,这是非常罕见的例外。 当然对于x64没有什么不同,所以我确定你的代码是x86。 因此,调用RtlSetProcessIsCritical
后的堆栈是错误的
作为旁注 - 你不需要LoadLibrary
和GetProcAddress
(有趣 - 如何在没有第一次呼叫和GetProcAddress(LoadLibrary("kernel32"), "GetProcAddress")
的情况下调用GetProcAddress
? 存在ntdll.lib和ntdllp.lib- 只需与它链接即可。
- 我的 c++ 程序似乎没有发现字符串和我拥有但输入使用 getline 的变量之间的比较
- 比较迭代器会使程序崩溃,而不会在自定义气泡排序实现中出现错误
- 用于比较基元类型的std::可选的有趣程序集
- 如果调用 RtlSetProcessIsCritical,将使用 lstrcmpW 将命令行与值进行比较将使程序崩溃
- 将正在运行的程序的用户名与登录到Windows的用户名进行比较
- 通过查看程序集来比较按值传递与按引用传递性能
- 简单的程序比较阵列运行但给出不正确的结果
- 比较两个字符串数组,我的控制台应用程序"stops responding"
- 从数组比较2个字符串时,程序崩溃
- 如何制作一个从文件中读取密码并与用户编写的密码进行比较的 c++ 程序
- 在比较特定输入中的程序的数组中出错
- C++中更快地执行两个程序的可能解释(使用 Python 比较)?
- 比较CPP和Python上的程序结果
- C++迭代程序访问下一个元素进行比较
- C++:比较可变参数无符号 int 模板参数的帮助程序
- 正在比较标头记录值和读取程序崩溃的行数.C++
- 检查并比较是否在C++控制台应用程序中按下了"down arrow"键?
- 在C++测验程序中使用数据文件处理比较答案
- 将STL容器内容与初始化程序列表进行比较
- c++ vs D的例子.前端程序RPN计算器从D主页比较