mirror of
https://github.com/0xjbb/cet-spoofing-detection
synced 2026-06-21 13:41:03 +00:00
65 lines
2.0 KiB
C++
65 lines
2.0 KiB
C++
#include "util.h"
|
|
|
|
#pragma comment(lib, "dbghelp.lib")
|
|
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
try {
|
|
auto processes = util::GetCETProcesses();
|
|
|
|
if (processes.size() == 0)
|
|
return -2;
|
|
|
|
|
|
for (auto& [pid, process_] : processes) {
|
|
if (pid == GetCurrentProcessId())
|
|
continue;
|
|
|
|
auto hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, pid);
|
|
if (!hProcess) continue;
|
|
|
|
SymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS);
|
|
SymInitialize(hProcess, nullptr, true); // once per process
|
|
|
|
for (auto& t : process_.threads) {
|
|
auto thread_handle = OpenThread(THREAD_ALL_ACCESS, FALSE, t.threadId);
|
|
if (!thread_handle) continue;
|
|
|
|
SuspendThread(thread_handle);
|
|
auto SSP = util::GetShadowStackFrames(thread_handle, hProcess);
|
|
auto normalStack = util::GetNormalFrames(thread_handle, hProcess); // no SymInit inside
|
|
ResumeThread(thread_handle);
|
|
|
|
if (!SSP.HasShadowStack)
|
|
continue;
|
|
|
|
if (SSP.frames.empty() || normalStack.empty())
|
|
continue;
|
|
|
|
size_t si = 0;
|
|
|
|
for (size_t i = 0; i < normalStack.size() && si < SSP.frames.size(); ++i) {
|
|
if (normalStack[i] == SSP.frames[si])
|
|
++si;
|
|
}
|
|
|
|
if (si != SSP.frames.size()) {
|
|
std::cout << "[ALERT] Shadow stack frames missing or out of order\n";
|
|
std::cout << "Process: " << t.processId << '\n';
|
|
std::cout << "Thread: " << t.threadId << '\n';
|
|
}
|
|
|
|
CloseHandle(thread_handle);
|
|
}
|
|
|
|
SymCleanup(hProcess); // once per process
|
|
CloseHandle(hProcess);
|
|
}
|
|
}
|
|
catch (std::exception& e) {
|
|
std::cout << e.what() << std::endl;
|
|
}
|
|
return 0;
|
|
}
|