Reputation: 15
Im working on a bigger project right now and I've run into a weird problem.
As the title states, im calling the RtlSetProcessIsCritical
function and I than try to exectute a codeblock if the second argument from the commandline matches with a preset value using lstrcmpW
.
Reconstructed code from my project that projects the structer
Main Cpp File:
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...
}
The Utilities File:
#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;
}
The problem now is that when I have called the RtlSetProcessIsCritical
(unimportant to what it get's set) and the commandlineargument get's compared the application crashes, however if I don't make a call to RtlSetProcessIsCritical
the programm works flawlessly for whatever reason.
I've found out that the problem is between the RtlSetProcessIsCritical
function and this line if (!lstrcmp(szArglist[2], L"/init")) {
I've also tried to reproduce this "bug" in a other project with the same structer of code but it worked flawlessly there and I'm now out of ideas.
If you need the rest of the code you can read it at my Github, links to the 2 files:
(In the main file on my Github the call to RtlSetProcessIsCritical
is after the if statement. This is temporery, it was just a quick workaround so I can atleast test the rest of the Software. In the release version this should be in the previously described order!)
Upvotes: 0
Views: 1246
Reputation: 33754
declaration
typedef NTSTATUS(CALLBACK* pRTLSETPROCESSISCRITICAL)(BOOLEAN, BOOLEAN*, BOOLEAN);
is wrong. correct function definition is
NTSYSAPI
NTSTATUS
STDAPIVCALLTYPE
RtlSetProcessIsCritical(
_In_ BOOLEAN NewValue,
_Out_opt_ PBOOLEAN OldValue,
_In_ BOOLEAN CheckFlag
);
this is STDAPIVCALLTYPE
- same as __cdecl
, not CALLBACK
(aka __stdcall
). this is very rare exception for ntdll api. of course for x64 no different, so i sure your code is x86. as result your stack after call to RtlSetProcessIsCritical
is wrong
as side note - you not need LoadLibrary
and GetProcAddress
(interesting - how you can call GetProcAddress
without first call and GetProcAddress(LoadLibrary("kernel32"), "GetProcAddress")
?) . exist ntdll.lib and ntdllp.lib - simply link with it.
Upvotes: 1