Skip to content

Instantly share code, notes, and snippets.

@sirpoot
Created March 5, 2015 05:01
Show Gist options
  • Save sirpoot/874d53d1f767aead3808 to your computer and use it in GitHub Desktop.
Save sirpoot/874d53d1f767aead3808 to your computer and use it in GitHub Desktop.
Disable Ctrl+Alt+Del in Windows 7 32-bit and Windows 8.1 32-bit
#include "stdafx.h"
#include "Windows.h"
#include "psapi.h"
#include <DbgHelp.h>
#include <TlHelp32.h>
#define MAX 10000
using namespace std;
IMAGE_DOS_HEADER ReadRemoteDosHeader(HANDLE hProcess, LPCVOID lpImageBaseAddress)
{
IMAGE_DOS_HEADER dosHeader;
BOOL bSuccess = ReadProcessMemory
(
hProcess,
lpImageBaseAddress,
&dosHeader,
sizeof(IMAGE_DOS_HEADER),
0
);
return dosHeader;
}
IMAGE_NT_HEADERS ReadRemoteNTHeaders(HANDLE hProcess, LPCVOID lpImageBaseAddress)
{
IMAGE_NT_HEADERS ntheaders;
BOOL bSuccess = ReadProcessMemory
(
hProcess,
lpImageBaseAddress,
&ntheaders,
sizeof(IMAGE_NT_HEADERS),
0
);
return ntheaders;
}
IMAGE_SECTION_HEADER ReadRemoteSectionHeader(HANDLE hProcess, LPCVOID lpImageBaseAddress)
{
IMAGE_SECTION_HEADER sectionHeader;
BOOL bSuccess = ReadProcessMemory
(
hProcess,
lpImageBaseAddress,
&sectionHeader,
sizeof(IMAGE_SECTION_HEADER),
0
);
return sectionHeader;
}
BOOL ReadRemoteSection(BYTE* section, HANDLE hProcess, LPCVOID lpImageBaseAddress, DWORD size)
{
BOOL bSuccess = ReadProcessMemory
(
hProcess,
lpImageBaseAddress,
section,
size,
0
);
return bSuccess;
}
int GetWinlogonPid()
{
HANDLE hProcessSnap;
HANDLE hProcess;
PROCESSENTRY32 pe32;
DWORD dwPriorityClass;
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcessSnap == INVALID_HANDLE_VALUE)
return 0;
pe32.dwSize = sizeof(PROCESSENTRY32);
if (!Process32First(hProcessSnap, &pe32))
{
CloseHandle(hProcessSnap);
return 0;
}
do
{
if (!strcmp(pe32.szExeFile, "winlogon.exe"))
{
CloseHandle(hProcessSnap);
return pe32.th32ProcessID;
}
} while (Process32Next(hProcessSnap, &pe32));
CloseHandle(hProcessSnap);
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
unsigned char toFind[] = {
0x8B, 0xFF, // mov edi, edi
0x55, // push ebp
0x8B, 0xEC, // mov ebp, esp
0xA1, 0xCC, 0xCC, 0xCC, 0xCC, // mov eax, _WPP_GLOBAL_Control
0x3D, 0xCC, 0xCC, 0xCC, 0xCC, // cmp eax, offset _WPP_GLOBAL_Control
0x74, 0x24, // jz short loc_1028F61
0xF7, 0x40, 0x1C, 0x00, 0x01, 0x00, 0x00, // test dword ptr[eax + 1Ch], 100h
};
unsigned char byteToSkip = 0xCC; // this means the byte can be an arbituary value, do not check for this particular byte
unsigned char toPatch[] = { 0xC2, 0x04, 0x00 }; // retn 4
DWORD dwSize = 0;
DWORD dwModuleSize = 0;
HMODULE hModules[MAX] = { 0 };
HANDLE hProcModule =
OpenProcess(PROCESS_ALL_ACCESS,
FALSE,
GetWinlogonPid());
if (!hProcModule)
{
printf("Cannot open winlogon.exe process. Are you running as nt authority\\system?\nYou must run as nt authority\\system to work! Even running as administrator can't cut it!\n");
return 1;
}
EnumProcessModules(hProcModule,
hModules,
sizeof(hModules),
&dwModuleSize);
dwModuleSize /= sizeof(HMODULE);
if (!dwModuleSize)
return 1;
for (DWORD dwModIndex = 0; dwModIndex < dwModuleSize; ++dwModIndex)
{
// get name of module
char szName[MAX];
GetModuleFileNameEx(hProcModule,
hModules[dwModIndex],
szName,
MAX_PATH);
// get address of module
MODULEINFO ModInfo;
GetModuleInformation(hProcModule,
hModules[dwModIndex],
&ModInfo,
sizeof(MODULEINFO));
if (strstr(szName, "winlogon.exe") != NULL) {
IMAGE_DOS_HEADER dosHeader = ReadRemoteDosHeader(hProcModule, ModInfo.lpBaseOfDll);
if (dosHeader.e_magic == 0x5a4d)
{
DWORD ntHeaderBase = (DWORD)ModInfo.lpBaseOfDll + dosHeader.e_lfanew;
IMAGE_NT_HEADERS ntheader = ReadRemoteNTHeaders(hProcModule, (LPCVOID)ntHeaderBase);
for (int i = 0; i<ntheader.FileHeader.NumberOfSections; i++)
{
IMAGE_SECTION_HEADER sectionHeader = ReadRemoteSectionHeader(hProcModule, (LPCVOID)(ntHeaderBase + sizeof(IMAGE_NT_HEADERS)+sizeof(IMAGE_SECTION_HEADER)* i));
if (strcmp((char*)sectionHeader.Name, ".text") == 0)
{
DWORD offsetToPatch = 0;
DWORD numFunctionsFound = 0;
BYTE* textSection = new BYTE[sectionHeader.Misc.VirtualSize];
printf("Found winlogon.exe .text section\nVirtual Address: %x\tVirtual Size: %x\n", (DWORD)ModInfo.lpBaseOfDll + sectionHeader.VirtualAddress, sectionHeader.Misc.VirtualSize);
ReadRemoteSection(textSection, hProcModule, (LPCVOID)((DWORD)ModInfo.lpBaseOfDll + sectionHeader.VirtualAddress), sectionHeader.Misc.VirtualSize);
// find the offset in the text section for bytes to patch
for (DWORD offset = 0; offset <= sectionHeader.Misc.VirtualSize - sizeof(toFind); offset++)
{
BOOL found = true;
for (int j = 0; j < sizeof(toFind); j++)
{
if (toFind[j] != byteToSkip && textSection[offset + j] != toFind[j])
{
found = false;
break;
}
}
if (found)
{
// WLGeneric_CAD_Execute is the first function to be found via these bytes, the other 2 functions are
// WLGeneric_CAD_Exit and WLGeneric_Return_Enter
printf("Bytes to patch found at offset 0x%x, virtual address 0x%x\n", offset, (DWORD)ModInfo.lpBaseOfDll + sectionHeader.VirtualAddress + offset);
// Only use the first offset found, because that corresponds to WLGeneric_CAD_Execute
if (offsetToPatch == 0)
offsetToPatch = offset;
numFunctionsFound++;
}
}
if (numFunctionsFound == 3)
{
if (offsetToPatch > 0)
{
if (WriteProcessMemory(hProcModule, (LPVOID)((DWORD)ModInfo.lpBaseOfDll + sectionHeader.VirtualAddress + offsetToPatch), toPatch, sizeof(toPatch), 0))
{
printf("WLGeneric_CAD_Execute patched! Your Ctrl Alt Del should be disabled now =)\n");
}
else {
printf("WriteProcessMemory error!");
}
}
}
else {
printf("WLGeneric_CAD_Execute already patched!\n");
}
delete textSection;
}
}
}
}
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment