#include        <windows.h>
#include        <stdio.h>
#include        <Shellapi.h>
#include        <xed-interface.h>
#include        "list.h"
#include        "exapi.h"
#include        "wrappers.h"
#include        "decode.h"
#include        "pe64.h"
#include        "pestuff.h"
#include        "hook.h"
#include        "trace.h"
#include        "assemble.h"
#include        "emulate.h"
#include        "probe.h"
#include        "lock.h"
#include        "image.h"
#include        "vmmaps.h"
#include        "inject.h"
#include        "bitmap.h"
#include        "peutil.h"
#include        "util.h"
#include        "instrument.h"


#define REBASED_NTDLL_BASE      0x50000000

VOID    ntOutputDebugString(__in char *szMessage);

void    __cdecl ntDbgPrint(__in const char *format, ...);
#define DbgPrint(x) ntDbgPrint ##x

void* dlmalloc(size_t);
void  dlfree(void*);
void* dlcalloc(size_t, size_t);
void* dlrealloc(void*, size_t);

#undef GetCurrentProcess
#undef GetCurrentThread

#define CURRENT_PROCESS (HANDLE)(ULONG_PTR)-1
#define CURRENT_THREAD  (HANDLE)(ULONG_PTR)-2

PVOID WINAPI ExportTrampoline(__out DWORD *dwSize);

ULONG   get_currentthreadid();
ULONG   get_currentprocessid();
HANDLE  get_currentprocess();
HANDLE  get_getcurrentthread();
PVOID   get_imagebase();

#define TEB_THREAD_SAVE_EAX     0xFE8     //save eax...
#define TEB_THREAD_CONTEXT      0xFEC     //context with registers...
#define TEB_THREAD_JMP          0xFF0     //jmp address for next code block...
#define TEB_THREAD_EXCEPTION    0xFF4     //used by ProbeRead/ProbeWrite to detect exception...
#define TEB_EXCEPTION_SAVE_REG  0xFF8     //used to save EBP during exception handling...


#define THREAD_STACK_SIZE       0x100000
#define THREAD_STACK_TOP        0x100000

BOOL    TestBit(unsigned long bitmap, unsigned long bit);

VOID    InitThread(__in dwThreadId);

VOID __cdecl TerminateThreadAsm(PVOID dlfree, PVOID stack, DWORD exit_code, DWORD num_of_args, ...);

#define HOOK_LDRINITIALIZETHUNK         0x00
#define HOOK_KIUSEREXCEPTIONDISPATCHER  0x20
#define HOOK_KIUSERAPCDISPATCHER        0x40
#define HOOK_KIUSERCALLBACKDISPATCHER   0x60
#define HOOK_KIFASTSYSTEMCALLRET        0x80


extern ULONG_PTR       pLdrInitializeThunk;
extern ULONG_PTR       pKiUserExceptionDispatcher;
extern ULONG_PTR       pKiUserApcDispatcher;
extern ULONG_PTR       pKiUserCallbackDispatcher;
extern ULONG_PTR       pKiFastSystemCallRet;
extern ULONG_PTR       pRtlUserThreadStart;
extern ULONG_PTR       pEtwpNotificationThread;
extern ULONG_PTR       pLdrHotPatchRoutine;
extern ULONG_PTR       pKiRaiseUserExceptionDispatcher;
extern ULONG_PTR       pExpInterlockedPopEntrySListEnd;
extern ULONG_PTR       pExpInterlockedPopEntrySListFault;
extern ULONG_PTR       pExpInterlockedPopEntrySListResume;

extern ULONG_PTR       pLdrInitializeThunkShadow;
extern ULONG_PTR       pKiUserExceptionDispatcherShadow;
extern ULONG_PTR       pKiUserApcDispatcherShadow;
extern ULONG_PTR       pKiUserCallbackDispatcherShadow;
extern ULONG_PTR       pKiFastSystemCallRetShadow;
extern ULONG_PTR       pRtlUserThreadStartShadow; 
extern ULONG_PTR       pEtwpNotificationThreadShadow;
extern ULONG_PTR       pLdrHotPatchRoutineShadow;
extern ULONG_PTR       pKiRaiseUserExceptionDispatcherShadow;
extern ULONG_PTR       pExpInterlockedPopEntrySListEndShadow;
extern ULONG_PTR       pExpInterlockedPopEntrySListFaultShadow;
extern ULONG_PTR       pExpInterlockedPopEntrySListResumeShadow;

extern ULONG_PTR       pNtContinue;
extern ULONG_PTR       pNtTerminateThread;
extern ULONG_PTR       pNtMapViewOfSection;
extern ULONG_PTR       pNtUnmapViewOfSection;
extern ULONG_PTR       pNtAllocateVirtualMemory;
extern ULONG_PTR       pNtFreeVirtualMemory;
extern ULONG_PTR       pNtProtectVirtualMemory;
extern ULONG_PTR       pNtQueryVirtualMemory;
extern ULONG_PTR       pKiFastSystemCallRet;
extern ULONG_PTR       pNtCallbackReturn;
extern ULONG_PTR       pNtRaiseException;
extern ULONG_PTR       pNtTerminateProcess;
extern ULONG_PTR       pNtCreateProcess;
extern ULONG_PTR       pNtCreateProcessEx;
extern ULONG_PTR       pNtCreateUserProcess;
extern ULONG_PTR       pNtSuspendThread;


extern ULONG_PTR       NtContinue_sn;
extern ULONG_PTR       NtTerminateThread_sn;
extern ULONG_PTR       NtMapViewOfSection_sn;
extern ULONG_PTR       NtUnmapViewOfSection_sn;
extern ULONG_PTR       NtCallbackReturn_sn;
extern ULONG_PTR       NtRaiseException_sn;
extern ULONG_PTR       NtAllocateVirtualMemory_sn;
extern ULONG_PTR       NtFreeVirtualMemory_sn;
extern ULONG_PTR       NtProtectVirtualMemory_sn; 
extern ULONG_PTR       NtTerminateProcess_sn;
extern ULONG_PTR       NtCreateProcess_sn;
extern ULONG_PTR       NtCreateProcessEx_sn;
extern ULONG_PTR       NtCreateUserProcess_sn;
extern ULONG_PTR       NtSuspendThread_sn;


extern ULONG_PTR       g_vm_enter;
extern ULONG_PTR       g_vm_exit;
extern ULONG_PTR       g_traceInitThread;
extern ULONG_PTR       g_postSysenter;
extern ULONG_PTR       g_vm_sysenter_enter;
extern ULONG_PTR       g_vm_sysenter_buffer; 
extern ULONG_PTR       g_vm_int2e_vm_enter;


typedef VOID (WINAPI *FN_HANDLE_EXCEPTION)(PEXCEPTION_POINTERS pExceptionPointers);

extern  LIST image_list_head;
extern  LIST vmmap_list_head;

extern ULONG_PTR       trace_base;
extern ULONG_PTR       trace_end;

extern  WCHAR   g_wsTraceNtPath[];
extern  WCHAR   g_wsNtdllNtPath[];
extern  ULONG_PTR g_ntdllbase;
extern  ULONG_PTR g_ntdllend;
extern  ULONG     b_log_now;

VOID __fastcall DllMainInject(pinject_struct pinject);
void    ntdllFix(__in PVOID ntdllbase);

extern ULONG_PTR       LdrInitializeThunkHook;
extern ULONG_PTR       KiUserApcDispatcherHook;
extern ULONG_PTR       KiUserExceptionDispatcherHook;
extern ULONG_PTR       KiUserCallbackDispatcher;

