mirror of
https://github.com/github/codeql.git
synced 2026-04-12 02:24:00 +02:00
943 lines
24 KiB
C++
943 lines
24 KiB
C++
void sink(char);
|
|
void sink(char*);
|
|
void sink(char**);
|
|
|
|
using HANDLE = void*;
|
|
using DWORD = unsigned long;
|
|
using LPCH = char*;
|
|
using LPSTR = char*;
|
|
using LPCSTR = const char*;
|
|
using LPVOID = void*;
|
|
using LPDWORD = unsigned long*;
|
|
using PVOID = void*;
|
|
using ULONG_PTR = unsigned long*;
|
|
using SIZE_T = decltype(sizeof(0));
|
|
|
|
LPSTR GetCommandLineA();
|
|
LPSTR* CommandLineToArgvA(LPSTR, int*);
|
|
LPCH GetEnvironmentStringsA();
|
|
DWORD GetEnvironmentVariableA(LPCSTR, LPSTR, DWORD);
|
|
|
|
void getCommandLine() {
|
|
char* cmd = GetCommandLineA();
|
|
sink(cmd);
|
|
sink(*cmd); // $ ir
|
|
|
|
int argc;
|
|
char** argv = CommandLineToArgvA(cmd, &argc);
|
|
sink(argv);
|
|
sink(argv[1]);
|
|
sink(*argv[1]); // $ ir
|
|
}
|
|
|
|
void getEnvironment() {
|
|
char* env = GetEnvironmentStringsA();
|
|
sink(env);
|
|
sink(*env); // $ ir
|
|
|
|
char buf[1024];
|
|
GetEnvironmentVariableA("FOO", buf, sizeof(buf));
|
|
sink(buf);
|
|
sink(*buf); // $ ir
|
|
}
|
|
|
|
typedef struct _OVERLAPPED {
|
|
ULONG_PTR Internal;
|
|
ULONG_PTR InternalHigh;
|
|
union {
|
|
struct {
|
|
DWORD Offset;
|
|
DWORD OffsetHigh;
|
|
} DUMMYSTRUCTNAME;
|
|
PVOID Pointer;
|
|
} DUMMYUNIONNAME;
|
|
HANDLE hEvent;
|
|
} OVERLAPPED, *LPOVERLAPPED;
|
|
|
|
using BOOL = int;
|
|
#define FILE_MAP_READ 0x0004
|
|
|
|
using ULONG64 = unsigned long long;
|
|
using ULONG = unsigned long;
|
|
|
|
using DWORD64 = unsigned long long;
|
|
#define MEM_EXTENDED_PARAMETER_TYPE_BITS 8
|
|
|
|
typedef struct MEM_EXTENDED_PARAMETER {
|
|
struct {
|
|
DWORD64 Type : MEM_EXTENDED_PARAMETER_TYPE_BITS;
|
|
DWORD64 Reserved : 64 - MEM_EXTENDED_PARAMETER_TYPE_BITS;
|
|
} DUMMYSTRUCTNAME;
|
|
union {
|
|
DWORD64 ULong64;
|
|
PVOID Pointer;
|
|
SIZE_T Size;
|
|
HANDLE Handle;
|
|
DWORD ULong;
|
|
} DUMMYUNIONNAME;
|
|
} MEM_EXTENDED_PARAMETER, *PMEM_EXTENDED_PARAMETER;
|
|
|
|
BOOL ReadFile(
|
|
HANDLE hFile,
|
|
LPVOID lpBuffer,
|
|
DWORD nNumberOfBytesToRead,
|
|
LPDWORD lpNumberOfBytesRead,
|
|
LPOVERLAPPED lpOverlapped
|
|
);
|
|
|
|
using LPOVERLAPPED_COMPLETION_ROUTINE = void (*)(DWORD, DWORD, LPOVERLAPPED);
|
|
|
|
BOOL ReadFileEx(
|
|
HANDLE hFile,
|
|
LPVOID lpBuffer,
|
|
DWORD nNumberOfBytesToRead,
|
|
LPOVERLAPPED lpOverlapped,
|
|
LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
|
|
);
|
|
|
|
using NTSTATUS = long;
|
|
using PIO_APC_ROUTINE = void (*)(struct _DEVICE_OBJECT*, struct _IRP*, PVOID);
|
|
typedef struct _IO_STATUS_BLOCK {
|
|
union {
|
|
NTSTATUS Status;
|
|
PVOID Pointer;
|
|
} DUMMYUNIONNAME;
|
|
ULONG_PTR Information;
|
|
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
|
|
using LONGLONG = long long;
|
|
using LONG = long;
|
|
typedef struct _LARGE_INTEGER {
|
|
union {
|
|
struct {
|
|
ULONG LowPart;
|
|
LONG HighPart;
|
|
} DUMMYSTRUCTNAME;
|
|
LONGLONG QuadPart;
|
|
} DUMMYUNIONNAME;
|
|
} LARGE_INTEGER, *PLARGE_INTEGER;
|
|
|
|
using PULONG = unsigned long*;
|
|
|
|
NTSTATUS NtReadFile(
|
|
HANDLE FileHandle,
|
|
HANDLE Event,
|
|
PIO_APC_ROUTINE ApcRoutine,
|
|
PVOID ApcContext,
|
|
PIO_STATUS_BLOCK IoStatusBlock,
|
|
PVOID Buffer,
|
|
ULONG Length,
|
|
PLARGE_INTEGER ByteOffset,
|
|
PULONG Key
|
|
);
|
|
|
|
|
|
void FileIOCompletionRoutine(
|
|
DWORD dwErrorCode,
|
|
DWORD dwNumberOfBytesTransfered,
|
|
LPOVERLAPPED lpOverlapped
|
|
) {
|
|
char* buffer = reinterpret_cast<char*>(lpOverlapped->hEvent);
|
|
sink(buffer);
|
|
sink(*buffer); // $ MISSING: ir
|
|
}
|
|
|
|
void FileIOCompletionRoutine2(
|
|
DWORD dwErrorCode,
|
|
DWORD dwNumberOfBytesTransfered,
|
|
LPOVERLAPPED lpOverlapped
|
|
) {
|
|
char* buffer = reinterpret_cast<char*>(lpOverlapped->hEvent);
|
|
sink(buffer);
|
|
sink(*buffer); // $ ir
|
|
}
|
|
|
|
void FileIOCompletionRoutine3(
|
|
DWORD dwErrorCode,
|
|
DWORD dwNumberOfBytesTransfered,
|
|
LPOVERLAPPED lpOverlapped
|
|
) {
|
|
char c = reinterpret_cast<char>(lpOverlapped->hEvent);
|
|
sink(c); // $ ir
|
|
}
|
|
|
|
void readFile(HANDLE hFile) {
|
|
{
|
|
char buffer[1024];
|
|
DWORD bytesRead;
|
|
OVERLAPPED overlapped;
|
|
BOOL result = ReadFile(hFile, buffer, sizeof(buffer), &bytesRead, &overlapped);
|
|
sink(buffer);
|
|
sink(*buffer); // $ ir
|
|
}
|
|
|
|
{
|
|
char buffer[1024];
|
|
OVERLAPPED overlapped;
|
|
overlapped.hEvent = reinterpret_cast<HANDLE>(buffer);
|
|
ReadFileEx(hFile, buffer, sizeof(buffer) - 1, &overlapped, FileIOCompletionRoutine);
|
|
sink(buffer);
|
|
sink(*buffer); // $ ir
|
|
|
|
char* p = reinterpret_cast<char*>(overlapped.hEvent);
|
|
sink(p);
|
|
sink(*p); // $ MISSING: ir
|
|
}
|
|
|
|
{
|
|
char buffer[1024];
|
|
OVERLAPPED overlapped;
|
|
ReadFile(hFile, buffer, sizeof(buffer), nullptr, nullptr);
|
|
overlapped.hEvent = reinterpret_cast<HANDLE>(buffer);
|
|
char buffer2[1024];
|
|
ReadFileEx(hFile, buffer2, sizeof(buffer2) - 1, &overlapped, FileIOCompletionRoutine2);
|
|
}
|
|
|
|
{
|
|
char buffer[1024];
|
|
OVERLAPPED overlapped;
|
|
ReadFile(hFile, buffer, sizeof(buffer), nullptr, nullptr);
|
|
overlapped.hEvent = reinterpret_cast<HANDLE>(*buffer);
|
|
char buffer2[1024];
|
|
ReadFileEx(hFile, buffer2, sizeof(buffer2) - 1, &overlapped, FileIOCompletionRoutine3);
|
|
}
|
|
|
|
{
|
|
char buffer[1024];
|
|
IO_STATUS_BLOCK ioStatusBlock;
|
|
LARGE_INTEGER byteOffset;
|
|
ULONG key;
|
|
NTSTATUS status = NtReadFile(hFile, nullptr, nullptr, nullptr, &ioStatusBlock, buffer, sizeof(buffer), &byteOffset, &key);
|
|
sink(buffer);
|
|
sink(*buffer); // $ ir
|
|
}
|
|
}
|
|
|
|
LPVOID MapViewOfFile(
|
|
HANDLE hFileMappingObject,
|
|
DWORD dwDesiredAccess,
|
|
DWORD dwFileOffsetHigh,
|
|
DWORD dwFileOffsetLow,
|
|
SIZE_T dwNumberOfBytesToMap
|
|
);
|
|
|
|
PVOID MapViewOfFile2(
|
|
HANDLE FileMappingHandle,
|
|
HANDLE ProcessHandle,
|
|
ULONG64 Offset,
|
|
PVOID BaseAddress,
|
|
SIZE_T ViewSize,
|
|
ULONG AllocationType,
|
|
ULONG PageProtection
|
|
);
|
|
|
|
PVOID MapViewOfFile3(
|
|
HANDLE FileMapping,
|
|
HANDLE Process,
|
|
PVOID BaseAddress,
|
|
ULONG64 Offset,
|
|
SIZE_T ViewSize,
|
|
ULONG AllocationType,
|
|
ULONG PageProtection,
|
|
MEM_EXTENDED_PARAMETER *ExtendedParameters,
|
|
ULONG ParameterCount
|
|
);
|
|
|
|
PVOID MapViewOfFile3FromApp(
|
|
HANDLE FileMapping,
|
|
HANDLE Process,
|
|
PVOID BaseAddress,
|
|
ULONG64 Offset,
|
|
SIZE_T ViewSize,
|
|
ULONG AllocationType,
|
|
ULONG PageProtection,
|
|
MEM_EXTENDED_PARAMETER *ExtendedParameters,
|
|
ULONG ParameterCount
|
|
);
|
|
|
|
LPVOID MapViewOfFileEx(
|
|
HANDLE hFileMappingObject,
|
|
DWORD dwDesiredAccess,
|
|
DWORD dwFileOffsetHigh,
|
|
DWORD dwFileOffsetLow,
|
|
SIZE_T dwNumberOfBytesToMap,
|
|
LPVOID lpBaseAddress
|
|
);
|
|
|
|
PVOID MapViewOfFileFromApp(
|
|
HANDLE hFileMappingObject,
|
|
ULONG DesiredAccess,
|
|
ULONG64 FileOffset,
|
|
SIZE_T NumberOfBytesToMap
|
|
);
|
|
|
|
PVOID MapViewOfFileNuma2(
|
|
HANDLE FileMappingHandle,
|
|
HANDLE ProcessHandle,
|
|
ULONG64 Offset,
|
|
PVOID BaseAddress,
|
|
SIZE_T ViewSize,
|
|
ULONG AllocationType,
|
|
ULONG PageProtection,
|
|
ULONG PreferredNode
|
|
);
|
|
|
|
void mapViewOfFile(HANDLE hMapFile) {
|
|
{
|
|
LPVOID pMapView = MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, 0);
|
|
char* buffer = reinterpret_cast<char*>(pMapView);
|
|
sink(buffer);
|
|
sink(*buffer); // $ ir
|
|
}
|
|
|
|
{
|
|
LPVOID pMapView = MapViewOfFile2(hMapFile, nullptr, 0, nullptr, 0, 0, 0);
|
|
char* buffer = reinterpret_cast<char*>(pMapView);
|
|
sink(buffer);
|
|
sink(*buffer); // $ ir
|
|
}
|
|
|
|
{
|
|
MEM_EXTENDED_PARAMETER extendedParams;
|
|
|
|
LPVOID pMapView = MapViewOfFile3(hMapFile, nullptr, 0, 0, 0, 0, 0, &extendedParams, 1);
|
|
char* buffer = reinterpret_cast<char*>(pMapView);
|
|
sink(buffer);
|
|
sink(*buffer); // $ ir
|
|
}
|
|
|
|
{
|
|
MEM_EXTENDED_PARAMETER extendedParams;
|
|
|
|
LPVOID pMapView = MapViewOfFile3FromApp(hMapFile, nullptr, 0, 0, 0, 0, 0, &extendedParams, 1);
|
|
char* buffer = reinterpret_cast<char*>(pMapView);
|
|
sink(buffer);
|
|
sink(*buffer); // $ ir
|
|
}
|
|
|
|
{
|
|
LPVOID pMapView = MapViewOfFileEx(hMapFile, FILE_MAP_READ, 0, 0, 0, nullptr);
|
|
char* buffer = reinterpret_cast<char*>(pMapView);
|
|
sink(buffer);
|
|
sink(*buffer); // $ ir
|
|
}
|
|
|
|
{
|
|
LPVOID pMapView = MapViewOfFileFromApp(hMapFile, FILE_MAP_READ, 0, 0);
|
|
char* buffer = reinterpret_cast<char*>(pMapView);
|
|
sink(buffer);
|
|
sink(*buffer); // $ ir
|
|
}
|
|
|
|
{
|
|
LPVOID pMapView = MapViewOfFileNuma2(hMapFile, nullptr, 0, nullptr, 0, 0, 0, 0);
|
|
char* buffer = reinterpret_cast<char*>(pMapView);
|
|
sink(buffer);
|
|
sink(*buffer); // $ ir
|
|
}
|
|
}
|
|
|
|
typedef struct _SECURITY_ATTRIBUTES
|
|
{
|
|
DWORD nLength;
|
|
LPVOID lpSecurityDescriptor;
|
|
BOOL bInheritHandle;
|
|
} SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES;
|
|
|
|
typedef DWORD (*LPTHREAD_START_ROUTINE)(
|
|
LPVOID lpThreadParameter);
|
|
|
|
HANDLE CreateThread(
|
|
LPSECURITY_ATTRIBUTES lpThreadAttributes,
|
|
SIZE_T dwStackSize,
|
|
LPTHREAD_START_ROUTINE lpStartAddress,
|
|
LPVOID lpParameter,
|
|
DWORD dwCreationFlags,
|
|
LPDWORD lpThreadId);
|
|
|
|
HANDLE CreateRemoteThread(
|
|
HANDLE hProcess,
|
|
LPSECURITY_ATTRIBUTES lpThreadAttributes,
|
|
SIZE_T dwStackSize,
|
|
LPTHREAD_START_ROUTINE lpStartAddress,
|
|
LPVOID lpParameter,
|
|
DWORD dwCreationFlags,
|
|
LPDWORD lpThreadId
|
|
);
|
|
|
|
typedef ULONG_PTR DWORD_PTR;
|
|
|
|
typedef struct _PROC_THREAD_ATTRIBUTE_ENTRY
|
|
{
|
|
DWORD_PTR Attribute;
|
|
SIZE_T cbSize;
|
|
PVOID lpValue;
|
|
} PROC_THREAD_ATTRIBUTE_ENTRY, *LPPROC_THREAD_ATTRIBUTE_ENTRY;
|
|
|
|
// This structure contains a list of attributes that have been added using UpdateProcThreadAttribute
|
|
typedef struct _PROC_THREAD_ATTRIBUTE_LIST
|
|
{
|
|
DWORD dwFlags;
|
|
ULONG Size;
|
|
ULONG Count;
|
|
ULONG Reserved;
|
|
PULONG Unknown;
|
|
PROC_THREAD_ATTRIBUTE_ENTRY Entries[1];
|
|
} PROC_THREAD_ATTRIBUTE_LIST, *LPPROC_THREAD_ATTRIBUTE_LIST;
|
|
|
|
HANDLE CreateRemoteThreadEx(
|
|
HANDLE hProcess,
|
|
LPSECURITY_ATTRIBUTES lpThreadAttributes,
|
|
SIZE_T dwStackSize,
|
|
LPTHREAD_START_ROUTINE lpStartAddress,
|
|
LPVOID lpParameter,
|
|
DWORD dwCreationFlags,
|
|
LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList,
|
|
LPDWORD lpThreadId
|
|
);
|
|
|
|
struct S
|
|
{
|
|
int x;
|
|
};
|
|
|
|
DWORD ThreadProc1(LPVOID lpParameter)
|
|
{
|
|
S *s = (S *)lpParameter;
|
|
sink(s->x); // $ ir
|
|
return 0;
|
|
}
|
|
|
|
DWORD ThreadProc2(LPVOID lpParameter)
|
|
{
|
|
S *s = (S *)lpParameter;
|
|
sink(s->x); // $ ir
|
|
return 0;
|
|
}
|
|
|
|
DWORD ThreadProc3(LPVOID lpParameter)
|
|
{
|
|
S *s = (S *)lpParameter;
|
|
sink(s->x); // $ ir
|
|
return 0;
|
|
}
|
|
|
|
int source();
|
|
|
|
void test_create_thread()
|
|
{
|
|
SECURITY_ATTRIBUTES sa;
|
|
|
|
S s;
|
|
s.x = source();
|
|
|
|
{
|
|
DWORD threadId;
|
|
HANDLE threadHandle = CreateThread(
|
|
&sa,
|
|
0,
|
|
ThreadProc1,
|
|
&s,
|
|
0,
|
|
&threadId);
|
|
}
|
|
|
|
{
|
|
DWORD threadId;
|
|
HANDLE threadHandle = CreateRemoteThread(
|
|
nullptr,
|
|
&sa,
|
|
0,
|
|
ThreadProc2,
|
|
&s,
|
|
0,
|
|
&threadId);
|
|
}
|
|
|
|
{
|
|
DWORD threadId;
|
|
PROC_THREAD_ATTRIBUTE_LIST attrList;
|
|
HANDLE threadHandle = CreateRemoteThreadEx(
|
|
nullptr,
|
|
&sa,
|
|
0,
|
|
ThreadProc3,
|
|
&s,
|
|
0,
|
|
&attrList,
|
|
&threadId);
|
|
}
|
|
}
|
|
|
|
using size_t = decltype(sizeof(0));
|
|
|
|
volatile void * RtlCopyVolatileMemory(
|
|
volatile void *Destination,
|
|
volatile const void *Source,
|
|
size_t Length
|
|
);
|
|
|
|
volatile void * RtlCopyDeviceMemory(
|
|
volatile void *Destination,
|
|
volatile const void *Source,
|
|
size_t Length
|
|
);
|
|
|
|
void RtlCopyMemory(
|
|
void* Destination,
|
|
const void* Source,
|
|
size_t Length
|
|
);
|
|
|
|
using VOID = void;
|
|
|
|
VOID RtlCopyMemoryNonTemporal(
|
|
VOID *Destination,
|
|
const VOID *Source,
|
|
SIZE_T Length
|
|
);
|
|
|
|
using USHORT = unsigned short;
|
|
using PWSTR = wchar_t*;
|
|
using PCWSTR = const wchar_t*;
|
|
using PCUNICODE_STRING = const struct _UNICODE_STRING*;
|
|
|
|
typedef struct _UNICODE_STRING {
|
|
USHORT Length;
|
|
USHORT MaximumLength;
|
|
PWSTR Buffer;
|
|
} UNICODE_STRING, *PUNICODE_STRING;
|
|
|
|
VOID RtlCopyUnicodeString(
|
|
PUNICODE_STRING DestinationString,
|
|
PCUNICODE_STRING SourceString
|
|
);
|
|
|
|
void RtlMoveMemory(
|
|
void* Destination,
|
|
const void* Source,
|
|
size_t Length
|
|
);
|
|
|
|
volatile void * RtlMoveVolatileMemory(
|
|
volatile void *Destination,
|
|
volatile const void *Source,
|
|
size_t Length
|
|
);
|
|
|
|
void RtlInitUnicodeString(
|
|
PUNICODE_STRING DestinationString,
|
|
PCWSTR SourceString
|
|
);
|
|
|
|
void test_copy_and_move_memory() {
|
|
int x = source();
|
|
|
|
{
|
|
char dest_buffer[1024];
|
|
RtlCopyVolatileMemory(dest_buffer, &x, sizeof(x));
|
|
sink(dest_buffer[0]); // $ ir
|
|
}
|
|
{
|
|
char dest_buffer[1024];
|
|
RtlCopyDeviceMemory(dest_buffer, &x, sizeof(x));
|
|
sink(dest_buffer[0]); // $ ir
|
|
}
|
|
{
|
|
char dest_buffer[1024];
|
|
RtlCopyMemory(dest_buffer, &x, sizeof(x));
|
|
sink(dest_buffer[0]); // $ ir
|
|
}
|
|
{
|
|
char dest_buffer[1024];
|
|
RtlCopyMemoryNonTemporal(dest_buffer, &x, sizeof(x));
|
|
sink(dest_buffer[0]); // $ ir
|
|
}
|
|
{
|
|
UNICODE_STRING dest_string;
|
|
UNICODE_STRING src_string;
|
|
wchar_t buffer[1024];
|
|
buffer[0] = source();
|
|
|
|
RtlInitUnicodeString(&src_string, buffer);
|
|
sink(src_string.Buffer[0]); // $ ir
|
|
RtlCopyUnicodeString(&dest_string, &src_string);
|
|
sink(dest_string.Buffer[0]); // $ ir
|
|
}
|
|
{
|
|
char dest_buffer[1024];
|
|
RtlMoveMemory(dest_buffer, &x, sizeof(x));
|
|
sink(dest_buffer[0]); // $ ir
|
|
}
|
|
{
|
|
volatile char dest_buffer[1024];
|
|
RtlMoveVolatileMemory(dest_buffer, &x, sizeof(x));
|
|
sink(dest_buffer[0]); // $ ir
|
|
}
|
|
}
|
|
|
|
using HINTERNET = void*;
|
|
using ULONGLONG = unsigned long long;
|
|
using UINT = unsigned int;
|
|
using PDWORD = DWORD*;
|
|
using PCSTR = const char*;
|
|
typedef union _WINHTTP_HEADER_NAME {
|
|
PCWSTR pwszName;
|
|
PCSTR pszName;
|
|
} WINHTTP_HEADER_NAME, *PWINHTTP_HEADER_NAME;
|
|
typedef struct _WINHTTP_EXTENDED_HEADER {
|
|
union {
|
|
PCWSTR pwszName;
|
|
PCSTR pszName;
|
|
};
|
|
union {
|
|
PCWSTR pwszValue;
|
|
PCSTR pszValue;
|
|
};
|
|
} WINHTTP_EXTENDED_HEADER, *PWINHTTP_EXTENDED_HEADER;
|
|
|
|
BOOL WinHttpReadData(
|
|
HINTERNET hRequest,
|
|
LPVOID lpBuffer,
|
|
DWORD dwNumberOfBytesToRead,
|
|
LPDWORD lpdwNumberOfBytesRead
|
|
);
|
|
|
|
DWORD WinHttpReadDataEx(
|
|
HINTERNET hRequest,
|
|
LPVOID lpBuffer,
|
|
DWORD dwNumberOfBytesToRead,
|
|
LPDWORD lpdwNumberOfBytesRead,
|
|
ULONGLONG ullFlags,
|
|
DWORD cbProperty,
|
|
PVOID pvProperty
|
|
);
|
|
|
|
using LPCWSTR = const wchar_t*;
|
|
|
|
BOOL WinHttpQueryHeaders(
|
|
HINTERNET hRequest,
|
|
DWORD dwInfoLevel,
|
|
LPCWSTR pwszName,
|
|
LPVOID lpBuffer,
|
|
LPDWORD lpdwBufferLength,
|
|
LPDWORD lpdwIndex
|
|
);
|
|
|
|
DWORD WinHttpQueryHeadersEx(
|
|
HINTERNET hRequest,
|
|
DWORD dwInfoLevel,
|
|
ULONGLONG ullFlags,
|
|
UINT uiCodePage,
|
|
PDWORD pdwIndex,
|
|
PWINHTTP_HEADER_NAME pHeaderName,
|
|
PVOID pBuffer,
|
|
PDWORD pdwBufferLength,
|
|
PWINHTTP_EXTENDED_HEADER *ppHeaders,
|
|
PDWORD pdwHeadersCount
|
|
);
|
|
|
|
void sink(PCSTR);
|
|
|
|
void test_winhttp(HINTERNET hRequest) {
|
|
{
|
|
char buffer[1024];
|
|
DWORD bytesRead;
|
|
BOOL result = WinHttpReadData(hRequest, buffer, sizeof(buffer), &bytesRead);
|
|
sink(buffer);
|
|
sink(*buffer); // $ ir
|
|
}
|
|
{
|
|
char buffer[1024];
|
|
DWORD bytesRead;
|
|
DWORD result = WinHttpReadDataEx(hRequest, buffer, sizeof(buffer), &bytesRead, 0, 0, nullptr);
|
|
sink(buffer);
|
|
sink(*buffer); // $ ir
|
|
}
|
|
{
|
|
char buffer[1024];
|
|
DWORD bufferLength = sizeof(buffer);
|
|
WinHttpQueryHeaders(hRequest, 0, nullptr, buffer, &bufferLength, nullptr);
|
|
sink(buffer);
|
|
sink(*buffer); // $ ir
|
|
}
|
|
{
|
|
char buffer[1024];
|
|
DWORD bufferLength = sizeof(buffer);
|
|
PWINHTTP_EXTENDED_HEADER headers;
|
|
DWORD headersCount;
|
|
PWINHTTP_HEADER_NAME headerName;
|
|
DWORD result = WinHttpQueryHeadersEx(hRequest, 0, 0, 0, nullptr, headerName, buffer, &bufferLength, &headers, &headersCount);
|
|
sink(buffer);
|
|
sink(*buffer); // $ ir
|
|
sink(headerName->pszName);
|
|
sink(*headerName->pszName); // $ ir
|
|
sink(headers->pszValue);
|
|
sink(*headers->pszValue); // $ ir
|
|
}
|
|
}
|
|
|
|
using LPWSTR = wchar_t*;
|
|
using INTERNET_SCHEME = enum {
|
|
INTERNET_SCHEME_INVALID = -1,
|
|
INTERNET_SCHEME_UNKNOWN = 0,
|
|
INTERNET_SCHEME_HTTP = 1,
|
|
INTERNET_SCHEME_HTTPS = 2,
|
|
INTERNET_SCHEME_FTP = 3,
|
|
INTERNET_SCHEME_FILE = 4,
|
|
INTERNET_SCHEME_NEWS = 5,
|
|
INTERNET_SCHEME_MAILTO = 6,
|
|
INTERNET_SCHEME_SNEWS = 7,
|
|
INTERNET_SCHEME_SOCKS = 8,
|
|
INTERNET_SCHEME_WAIS = 9,
|
|
INTERNET_SCHEME_LAST = 10
|
|
};
|
|
using INTERNET_PORT = unsigned short;
|
|
|
|
typedef struct _WINHTTP_URL_COMPONENTS {
|
|
DWORD dwStructSize;
|
|
LPWSTR lpszScheme;
|
|
DWORD dwSchemeLength;
|
|
INTERNET_SCHEME nScheme;
|
|
LPWSTR lpszHostName;
|
|
DWORD dwHostNameLength;
|
|
INTERNET_PORT nPort;
|
|
LPWSTR lpszUserName;
|
|
DWORD dwUserNameLength;
|
|
LPWSTR lpszPassword;
|
|
DWORD dwPasswordLength;
|
|
LPWSTR lpszUrlPath;
|
|
DWORD dwUrlPathLength;
|
|
LPWSTR lpszExtraInfo;
|
|
DWORD dwExtraInfoLength;
|
|
} URL_COMPONENTS, *LPURL_COMPONENTS;
|
|
|
|
BOOL WinHttpCrackUrl(
|
|
LPCWSTR pwszUrl,
|
|
DWORD dwUrlLength,
|
|
DWORD dwFlags,
|
|
LPURL_COMPONENTS lpUrlComponents
|
|
);
|
|
|
|
void sink(LPWSTR);
|
|
|
|
void test_winhttp_crack_url() {
|
|
{
|
|
URL_COMPONENTS urlComponents;
|
|
urlComponents.dwStructSize = sizeof(URL_COMPONENTS);
|
|
wchar_t x[256];
|
|
x[0] = (wchar_t)source();
|
|
BOOL result = WinHttpCrackUrl(x, 0, 0, &urlComponents);
|
|
sink(urlComponents.lpszHostName);
|
|
sink(*urlComponents.lpszHostName); // $ ir
|
|
sink(urlComponents.lpszUrlPath);
|
|
sink(*urlComponents.lpszUrlPath); // $ ir
|
|
sink(urlComponents.lpszExtraInfo);
|
|
sink(*urlComponents.lpszExtraInfo); // $ ir
|
|
}
|
|
}
|
|
|
|
using HTTP_REQUEST_ID = ULONGLONG;
|
|
using HTTP_CONNECTION_ID = ULONGLONG;
|
|
using HTTP_URL_CONTEXT = ULONGLONG;
|
|
using HTTP_RAW_CONNECTION_ID = ULONGLONG;
|
|
|
|
typedef struct _HTTP_VERSION {
|
|
USHORT MajorVersion;
|
|
USHORT MinorVersion;
|
|
} HTTP_VERSION, *PHTTP_VERSION;
|
|
|
|
typedef enum _HTTP_VERB {
|
|
HttpVerbUnparsed = 0
|
|
} HTTP_VERB, *PHTTP_VERB;
|
|
|
|
typedef struct _HTTP_COOKED_URL {
|
|
USHORT FullUrlLength;
|
|
USHORT HostLength;
|
|
USHORT AbsPathLength;
|
|
USHORT QueryStringLength;
|
|
PCWSTR pFullUrl;
|
|
PCWSTR pHost;
|
|
PCWSTR pAbsPath;
|
|
PCWSTR pQueryString;
|
|
} HTTP_COOKED_URL, *PHTTP_COOKED_URL;
|
|
|
|
typedef struct _HTTP_TRANSPORT_ADDRESS {
|
|
struct sockaddr* pRemoteAddress;
|
|
struct sockaddr* pLocalAddress;
|
|
} HTTP_TRANSPORT_ADDRESS, *PHTTP_TRANSPORT_ADDRESS;
|
|
|
|
typedef struct _HTTP_KNOWN_HEADER {
|
|
USHORT RawValueLength;
|
|
PCSTR pRawValue;
|
|
} HTTP_KNOWN_HEADER, *PHTTP_KNOWN_HEADER;
|
|
|
|
typedef struct _HTTP_UNKNOWN_HEADER {
|
|
USHORT NameLength;
|
|
USHORT RawValueLength;
|
|
PCSTR pName;
|
|
PCSTR pRawValue;
|
|
} HTTP_UNKNOWN_HEADER, *PHTTP_UNKNOWN_HEADER;
|
|
|
|
typedef struct _HTTP_REQUEST_HEADERS {
|
|
USHORT UnknownHeaderCount;
|
|
PHTTP_UNKNOWN_HEADER pUnknownHeaders;
|
|
USHORT TrailerCount;
|
|
PHTTP_UNKNOWN_HEADER pTrailers;
|
|
HTTP_KNOWN_HEADER KnownHeaders[41];
|
|
} HTTP_REQUEST_HEADERS, *PHTTP_REQUEST_HEADERS;
|
|
|
|
typedef struct _HTTP_BYTE_RANGE {
|
|
ULONGLONG StartingOffset;
|
|
ULONGLONG Length;
|
|
} HTTP_BYTE_RANGE, *PHTTP_BYTE_RANGE;
|
|
|
|
typedef struct _HTTP_DATA_CHUNK {
|
|
int DataChunkType;
|
|
union {
|
|
struct {
|
|
PVOID pBuffer;
|
|
ULONG BufferLength;
|
|
} FromMemory;
|
|
struct {
|
|
HTTP_BYTE_RANGE ByteRange;
|
|
HANDLE FileHandle;
|
|
} FromFileHandle;
|
|
struct {
|
|
USHORT FragmentNameLength;
|
|
PCWSTR pFragmentName;
|
|
} FromFragmentCache;
|
|
struct {
|
|
HTTP_BYTE_RANGE ByteRange;
|
|
PCWSTR pFragmentName;
|
|
} FromFragmentCacheEx;
|
|
struct {
|
|
USHORT TrailerCount;
|
|
PHTTP_UNKNOWN_HEADER pTrailers;
|
|
} Trailers;
|
|
};
|
|
} HTTP_DATA_CHUNK, *PHTTP_DATA_CHUNK;
|
|
|
|
typedef struct _HTTP_SSL_CLIENT_CERT_INFO {
|
|
ULONG CertFlags;
|
|
ULONG CertEncodedSize;
|
|
char* pCertEncoded;
|
|
HANDLE Token;
|
|
BOOL CertDeniedByMapper;
|
|
} HTTP_SSL_CLIENT_CERT_INFO, *PHTTP_SSL_CLIENT_CERT_INFO;
|
|
|
|
typedef struct _HTTP_SSL_INFO {
|
|
USHORT ServerCertKeySize;
|
|
USHORT ConnectionKeySize;
|
|
ULONG ServerCertIssuerSize;
|
|
ULONG ServerCertSubjectSize;
|
|
PCSTR pServerCertIssuer;
|
|
PCSTR pServerCertSubject;
|
|
PHTTP_SSL_CLIENT_CERT_INFO pClientCertInfo;
|
|
ULONG SslClientCertNegotiated;
|
|
} HTTP_SSL_INFO, *PHTTP_SSL_INFO;
|
|
|
|
typedef struct _HTTP_REQUEST_V1 {
|
|
ULONG Flags;
|
|
HTTP_CONNECTION_ID ConnectionId;
|
|
HTTP_REQUEST_ID RequestId;
|
|
HTTP_URL_CONTEXT UrlContext;
|
|
HTTP_VERSION Version;
|
|
HTTP_VERB Verb;
|
|
USHORT UnknownVerbLength;
|
|
USHORT RawUrlLength;
|
|
PCSTR pUnknownVerb;
|
|
PCSTR pRawUrl;
|
|
HTTP_COOKED_URL CookedUrl;
|
|
HTTP_TRANSPORT_ADDRESS Address;
|
|
HTTP_REQUEST_HEADERS Headers;
|
|
ULONGLONG BytesReceived;
|
|
USHORT EntityChunkCount;
|
|
PHTTP_DATA_CHUNK pEntityChunks;
|
|
HTTP_RAW_CONNECTION_ID RawConnectionId;
|
|
PHTTP_SSL_INFO pSslInfo;
|
|
} HTTP_REQUEST_V1, *PHTTP_REQUEST_V1;
|
|
|
|
using HTTP_REQUEST = HTTP_REQUEST_V1;
|
|
using PHTTP_REQUEST = PHTTP_REQUEST_V1;
|
|
|
|
ULONG HttpReceiveHttpRequest(
|
|
HANDLE RequestQueueHandle,
|
|
HTTP_REQUEST_ID RequestId,
|
|
ULONG Flags,
|
|
PHTTP_REQUEST RequestBuffer,
|
|
ULONG RequestBufferLength,
|
|
PULONG BytesReturned,
|
|
LPOVERLAPPED Overlapped
|
|
);
|
|
|
|
ULONG HttpReceiveRequestEntityBody(
|
|
HANDLE RequestQueueHandle,
|
|
HTTP_REQUEST_ID RequestId,
|
|
ULONG Flags,
|
|
PVOID EntityBuffer,
|
|
ULONG EntityBufferLength,
|
|
PULONG BytesReturned,
|
|
LPOVERLAPPED Overlapped
|
|
);
|
|
|
|
ULONG HttpReceiveClientCertificate(
|
|
HANDLE RequestQueueHandle,
|
|
HTTP_CONNECTION_ID ConnectionId,
|
|
ULONG Flags,
|
|
PHTTP_SSL_CLIENT_CERT_INFO SslClientCertInfo,
|
|
ULONG SslClientCertInfoSize,
|
|
PULONG BytesReceived,
|
|
LPOVERLAPPED Overlapped
|
|
);
|
|
|
|
void sink(PCWSTR);
|
|
void sink(HANDLE);
|
|
|
|
void test_http_server_api(HANDLE hRequestQueue) {
|
|
{
|
|
HTTP_REQUEST requestBuffer;
|
|
ULONG bytesReturned;
|
|
ULONG result = HttpReceiveHttpRequest(hRequestQueue, 0, 0, &requestBuffer, sizeof(requestBuffer), &bytesReturned, nullptr);
|
|
char* p = reinterpret_cast<char*>(&requestBuffer);
|
|
sink(p);
|
|
sink(*p); // $ ir
|
|
sink(requestBuffer.pRawUrl);
|
|
sink(*requestBuffer.pRawUrl); // $ ir
|
|
sink(requestBuffer.CookedUrl.pFullUrl);
|
|
sink(*requestBuffer.CookedUrl.pFullUrl); // $ ir
|
|
sink(requestBuffer.Headers.KnownHeaders[0].pRawValue);
|
|
sink(*requestBuffer.Headers.KnownHeaders[0].pRawValue); // $ ir
|
|
sink(requestBuffer.Headers.pUnknownHeaders[0].pRawValue);
|
|
sink(*requestBuffer.Headers.pUnknownHeaders[0].pRawValue); // $ ir
|
|
sink(requestBuffer.pEntityChunks->FromFileHandle.FileHandle); // $ ir
|
|
sink(requestBuffer.pEntityChunks->FromFragmentCache.pFragmentName);
|
|
sink(*requestBuffer.pEntityChunks->FromFragmentCache.pFragmentName); // $ ir
|
|
sink(requestBuffer.pEntityChunks->FromFragmentCacheEx.pFragmentName);
|
|
sink(*requestBuffer.pEntityChunks->FromFragmentCacheEx.pFragmentName); // $ ir
|
|
sink(requestBuffer.pEntityChunks->FromMemory.pBuffer);
|
|
sink(*(char*)requestBuffer.pEntityChunks->FromMemory.pBuffer); // $ ir
|
|
sink(requestBuffer.pSslInfo->pServerCertIssuer);
|
|
sink(*requestBuffer.pSslInfo->pServerCertIssuer); // $ ir
|
|
sink(requestBuffer.pSslInfo->pServerCertSubject);
|
|
sink(*requestBuffer.pSslInfo->pServerCertSubject); // $ ir
|
|
sink(requestBuffer.pSslInfo->pClientCertInfo->pCertEncoded);
|
|
sink(*requestBuffer.pSslInfo->pClientCertInfo->pCertEncoded); // $ ir
|
|
}
|
|
{
|
|
char buffer[1024];
|
|
ULONG bytesReturned;
|
|
ULONG result = HttpReceiveRequestEntityBody(hRequestQueue, 0, 0, buffer, sizeof(buffer), &bytesReturned, nullptr);
|
|
sink(buffer);
|
|
sink(*buffer); // $ ir
|
|
}
|
|
{
|
|
HTTP_SSL_CLIENT_CERT_INFO certInfo;
|
|
ULONG bytesReceived;
|
|
ULONG result = HttpReceiveClientCertificate(hRequestQueue, 0, 0, &certInfo, sizeof(certInfo), &bytesReceived, nullptr);
|
|
char* p = reinterpret_cast<char*>(&certInfo);
|
|
sink(p);
|
|
sink(*p); // $ ir
|
|
sink(certInfo.pCertEncoded);
|
|
sink(*certInfo.pCertEncoded); // $ ir
|
|
}
|
|
} |