#include <scfw/runtime.h>
#include <scfw/platform/windows/kernelmode.h>
#include <vmi/shellcode.hpp>
#include <cstdint>
IMPORT_BEGIN();
IMPORT_MODULE("ntoskrnl.exe");
IMPORT_SYMBOL(ZwCreateFile);
IMPORT_SYMBOL(ZwWriteFile);
IMPORT_SYMBOL(ZwClose);
IMPORT_END();
namespace sc {
enum class stage : uint8_t {
none = 0x00,
create = 0x01,
write = 0x02,
};
enum class error : uint8_t {
empty_path = 0x01,
zw_create_file = 0x02,
zw_write_file = 0x03,
};
template <>
struct vmi::is_error_code<error> : std::true_type {};
using failure = vmi::failure<error>;
using status = vmi::status<stage>;
struct bridge_traits : vmi::default_bridge_traits {
static constexpr uint16_t request = 0x0002;
};
struct bridge : vmi::bridge<bridge_traits> {
static constexpr uint16_t method_exit = 0xffff;
static
void
exit(
_In_ status status
)
{
(void)send(
method_exit,
status.encode()
);
}
};
auto
WriteHelloWorld(
_In_ PCWSTR Path
) -> status
{
NTSTATUS Status;
SIZE_T PathLength = 0;
while (Path[PathLength] != L'\0')
{
PathLength++;
}
if (PathLength == 0)
{
return status::invalid_parameters(
stage::none,
failure{ error::empty_path, STATUS_INVALID_PARAMETER }
);
}
UNICODE_STRING FileName;
FileName.Length = (USHORT)(PathLength * sizeof(WCHAR));
FileName.MaximumLength = FileName.Length;
FileName.Buffer = (PWSTR)Path;
OBJECT_ATTRIBUTES ObjectAttributes;
InitializeObjectAttributes(&ObjectAttributes,
&FileName,
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
NULL,
NULL);
HANDLE FileHandle;
IO_STATUS_BLOCK IoStatusBlock;
Status = ZwCreateFile(&FileHandle,
FILE_GENERIC_WRITE,
&ObjectAttributes,
&IoStatusBlock,
NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ,
FILE_OVERWRITE_IF,
FILE_SYNCHRONOUS_IO_NONALERT
| FILE_NON_DIRECTORY_FILE,
NULL,
0);
if (!NT_SUCCESS(Status))
{
return status::operation_failed(
stage::create,
failure{ error::zw_create_file, Status }
);
}
const CHAR Content[] = "hello world";
Status = ZwWriteFile(FileHandle,
NULL,
NULL,
NULL,
&IoStatusBlock,
(PVOID)Content,
sizeof(Content) - 1,
NULL,
NULL);
ZwClose(FileHandle);
if (!NT_SUCCESS(Status))
{
return status::operation_failed(
stage::write,
failure{ error::zw_write_file, Status }
);
}
return status::success(stage::write);
}
extern "C"
void
__fastcall
entry(
_In_ void* argument1, _In_ void* argument2 )
{
(void)argument1;
vmi::parameter_reader reader{ argument2 };
bridge::exit(WriteHelloWorld(reader.read_wstring()));
}
}