mireado

starting commit

cmake_minimum_required(VERSION 2.8)
set(CMAKE_CONFIGURATION_TYPES Debug Release)
project(vnr)
set(WDK_HOME "C:\\WinDDK\\7600.16385.1" CACHE FILEPATH "path to the Windows DDK directory")
add_definitions(
-DUNICODE
-D_UNICODE
)
include_directories(${PROJECT_SOURCE_DIR})
set(common_src
${PROJECT_SOURCE_DIR}/ith/common/const.h
${PROJECT_SOURCE_DIR}/ith/common/defs.h
${PROJECT_SOURCE_DIR}/ith/common/except.h
${PROJECT_SOURCE_DIR}/ith/common/growl.h
${PROJECT_SOURCE_DIR}/ith/common/memory.h
${PROJECT_SOURCE_DIR}/ith/common/types.h
)
set(import_src
${PROJECT_SOURCE_DIR}/ith/import/mono/funcinfo.h
${PROJECT_SOURCE_DIR}/ith/import/mono/types.h
${PROJECT_SOURCE_DIR}/ith/import/ppsspp/funcinfo.h
)
add_subdirectory(ith/hook)
add_subdirectory(ith/host)
add_subdirectory(ith/sys)
#ifndef CCMACRO_H
#define CCMACRO_H
// ccmacro.h
// 12/9/2011 jichi
#define CC_UNUSED(_var) (void)(_var)
#define CC_NOP CC_UNUSED(0)
#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96)
# define CC_LIKELY(expr) __builtin_expect(!!(expr), true)
# define CC_UNLIKELY(expr) __builtin_expect(!!(expr), false)
#else
# define CC_LIKELY(x) (x)
# define CC_UNLIKELY(x) (x)
#endif
#define CC_MIN(x, y) ((x) < (y) ? (x) : (y))
#define CC_MAX(x, y) ((x) < (y) ? (y) : (x))
#endif // CCMACRO_H
# ccutil.pri
# 1/31/2012 jichi
DEFINES += WITH_LIB_CCUTIL
DEPENDPATH += $$PWD
HEADERS += \
$$PWD/ccmacro.h
# EOF
This diff is collapsed. Click to expand it.
@echo off
setlocal
if [%1] == [] (
echo usage: copy_vnr <path-to-Sakura-directory>
goto :EOF
)
xcopy %1\config.pri . /S /Y /I
xcopy %1\cpp\libs\ccutil ccutil /S /Y /I
xcopy %1\cpp\libs\cpputil cpputil /S /Y /I
xcopy %1\cpp\libs\disasm disasm /S /Y /I /EXCLUDE:exclude.txt
xcopy %1\cpp\plugins\ith ith /S /Y /I
xcopy %1\cpp\libs\memdbg memdbg /S /Y /I
xcopy %1\cpp\libs\ntdll ntdll /S /Y /I
xcopy %1\cpp\libs\ntinspect ntinspect /S /Y /I
xcopy %1\cpp\libs\winmaker winmaker /S /Y /I
xcopy %1\cpp\libs\winmutex winmutex /S /Y /I
xcopy %1\cpp\libs\winversion winversion /S /Y /I
xcopy %1\cpp\libs\winseh winseh /S /Y /I
endlocal
#pragma once
#include "winmutex/winmutex.h"
#pragma once
// winmutex.h
// 12/11/2011 jichi
#include <windows.h>
#ifdef _MSC_VER
# pragma warning(disable:4800) // C4800: forcing value to bool
#endif // _MSC_VER
// Mutex lock
// The interface of this class is consistent with the mutex class
template <typename _Mutex>
class win_mutex_lock
{
typedef win_mutex_lock<_Mutex> _Self;
win_mutex_lock(const _Self&);
_Self &operator=(const _Self&);
_Mutex &_M_mutex;
bool _M_locked;
public:
typedef _Mutex mutex_type;
typedef typename _Mutex::native_handle_type native_handle_type;
explicit win_mutex_lock(mutex_type &mutex)
: _M_mutex(mutex), _M_locked(false) { lock(); }
~win_mutex_lock() { if (_M_locked) _M_mutex.unlock(); }
mutex_type &mutex() { return _M_mutex; }
//bool isLock() const { return _M_locked; }
native_handle_type native_handle() { return _M_mutex.native_handle(); }
void unlock() { _M_mutex.unlock(); _M_locked = false; }
void lock() { _M_mutex.lock(); _M_locked = true; }
bool tryLock() { return _M_locked = _M_mutex.tryLock(); }
};
// Mutex
template <typename _Mutex, size_t _Irql = 0>
class win_mutex
{
typedef win_mutex<_Mutex> _Self;
typedef _Mutex __native_type;
enum { __minimal_irql = _Irql };
__native_type _M_mutex;
win_mutex(const _Self&);
_Self &operator=(const _Self&);
private:
win_mutex() {}
typedef __native_type *native_handle_type;
native_handle_type native_handle() { return &_M_mutex; }
static size_t minimal_irql() { return __minimal_irql; }
void unlock() {}
void lock() {}
bool try_lock() {}
};
template <>
class IHFSERVICE win_mutex<CRITICAL_SECTION>
{
typedef win_mutex<CRITICAL_SECTION> _Self;
typedef CRITICAL_SECTION __native_type;
enum { __minimal_irql = 0 };
win_mutex(const _Self&);
_Self &operator=(const _Self&);
__native_type _M_mutex;
public:
typedef __native_type *native_handle_type;
native_handle_type native_handle() { return &_M_mutex; }
static size_t minimal_irql() { return __minimal_irql; }
win_mutex() { ::InitializeCriticalSection(&_M_mutex); }
~win_mutex() { ::DeleteCriticalSection(&_M_mutex); }
void lock() { ::EnterCriticalSection(&_M_mutex); }
void unlock() { ::LeaveCriticalSection(&_M_mutex); }
bool try_lock() { return ::TryEnterCriticalSection(&_M_mutex); }
};
// Conditional variable
template <typename _Cond>
class win_mutex_cond
{
typedef win_mutex_cond<_Cond> _Self;
typedef _Cond __native_type;
win_mutex_cond(const _Self&);
_Self &operator=(const _Self&);
__native_type _M_cond;
public:
enum wait_status { no_timeout = 0, timeout };
typedef __native_type *native_handle_type;
win_mutex_cond() {}
native_handle_type native_handle() { return &_M_cond; }
void notify_one() {}
void notify_all() {}
template <typename _Mutex>
void wait(_Mutex &mutex) {}
template <typename _Mutex, typename _Pred>
void wait(_Mutex &mutex, _Pred pred) {}
template <typename _Mutex>
wait_status wait_for(_Mutex &mutex, int msecs) {}
template <typename _Mutex, typename _Pred>
wait_status wait_for(_Mutex &mutex, int msecs, _Pred pred) {}
};
// Note: Conditional variables are NOT availabe on Windows XP/2003
// See: http://en.cppreference.com/w/cpp/thread/condition_variable
// See: http://msdn.microsoft.com/en-us/library/windows/desktop/ms686903%28v=vs.85%29.aspx
template <>
class win_mutex_cond<CONDITION_VARIABLE>
{
typedef win_mutex_cond<CONDITION_VARIABLE> _Self;
typedef CONDITION_VARIABLE __native_type;
win_mutex_cond(const _Self&);
_Self &operator=(const _Self&);
__native_type _M_cond;
public:
enum wait_status { no_timeout = 0, timeout };
typedef __native_type *native_handle_type;
native_handle_type native_handle() { return &_M_cond; }
win_mutex_cond() { ::InitializeConditionVariable(&_M_cond); }
void notify_one() { ::WakeConditionVariable(&_M_cond); }
void notify_all() { ::WakeAllConditionVariable(&_M_cond); }
template <typename _Mutex>
void wait(_Mutex &mutex)
{ ::SleepConditionVariableCS(&_M_cond, mutex.native_handle(), INFINITE); }
template <typename _Mutex, typename _Pred>
void wait(_Mutex &mutex, _Pred pred)
{ while (!pred()) wait(mutex); }
template <typename _Mutex>
wait_status wait_for(_Mutex &mutex, int msecs)
{ return ::SleepConditionVariableCS(&_M_cond, mutex.native_handle(), msecs) ? no_timeout : timeout; }
template <typename _Mutex, typename _Pred>
wait_status wait_for(_Mutex &mutex, int msecs, _Pred pred)
{
auto start = ::GetTickCount();
while (!pred()) {
auto now = ::GetTickCount();
msecs -= now - start;
if (msecs <= 0)
return timeout;
start = now;
wait_for(mutex, msecs);
}
return no_timeout;
}
};
// EOF
# winmutex.pri
# 3/8/2013 jichi
DEFINES += WITH_LIB_WINMUTEX
DEPENDPATH += $$PWD
#LIBS += -lkernel32 -luser32
HEADERS += \
$$PWD/winmutex \
$$PWD/winmutex.h
# EOF
# Makefile
# 12/13/2013 jichi
# This file is for Windows only.
# Compile SAFESEH table from the ASM file.
# See: http://stackoverflow.com/questions/19722308/exception-handler-not-called-in-c
# See: ::http://stackoverflow.com/questions/12019689/custom-seh-handler-with-safeseh
# See: http://msdn.microsoft.com/en-us/library/16aexws6.aspx
BUILDDIR = ../../../build
OBJ = $(BUILDDIR)/safeseh.obj
ML = ml
CFLAGS =
.PHONY: all compile clean
all: compile
compile: $(OBJ)
$(OBJ): safeseh.asm
$(ML) $(CFLAGS) -Fo $@ -c -safeseh $^
clean:
# EOF
; safeseh.asm
; 12/13/2013 jichi
; see: http://stackoverflow.com/questions/12019689/custom-seh-handler-with-safeseh
; see: http://code.metager.de/source/xref/WebKit/Source/WebCore/platform/win/makesafeseh.asm
; see: http://jpassing.com/2008/05/20/fun-with-low-level-seh/
.386
.model flat, stdcall
option casemap :none
; The symbol name can be found out using: dumpbin /symbols winseh.obj
extern _seh_handler:near ; defined in winseh.cc
_seh_asm_handler proto
.safeseh _seh_asm_handler
.code
_seh_asm_handler proc
jmp _seh_handler
_seh_asm_handler endp
end
// winseh.cc
// 12/13/2013 jichi
#include "winseh/winseh.h"
#include "ntdll/ntdll.h"
//#include <cstdio>
// - Global variables -
seh_dword_t seh_esp[seh_capacity],
seh_eip[seh_capacity],
seh_eh[seh_capacity];
seh_dword_t seh_count;
// - Exception handlers -
// VC 2013: http://msdn.microsoft.com/en-us/library/b6sf5kbd.aspx
// typedef EXCEPTION_DISPOSITION (*PEXCEPTION_ROUTINE) (
// _In_ PEXCEPTION_RECORD ExceptionRecord,
// _In_ ULONG64 EstablisherFrame,
// _Inout_ PCONTEXT ContextRecord,
// _Inout_ PDISPATCHER_CONTEXT DispatcherContext
// );
//
// winnt.h: http://www.codemachine.com/downloads/win81/ntdef.h
// typedef
// __drv_sameIRQL
// __drv_functionClass(EXCEPTION_ROUTINE)
// EXCEPTION_DISPOSITION
// NTAPI
// EXCEPTION_ROUTINE (
// _Inout_ struct _EXCEPTION_RECORD *ExceptionRecord,
// _In_ PVOID EstablisherFrame,
// _In_ struct _CONTEXT *ContextRecord,
// _In_ PVOID DispatcherContext
// );
extern "C" EXCEPTION_DISPOSITION _seh_handler( // extern C is needed to avoid name hashing in C++
_In_ PEXCEPTION_RECORD ExceptionRecord,
_In_ PVOID EstablisherFrame, // does not work if I use ULONG64
_Inout_ PCONTEXT ContextRecord,
_In_ PVOID DispatcherContext) // PDISPATCHER_CONTEXT is not declared in windows.h
{
//assert(::seh_count > 0);
ContextRecord->Esp = ::seh_esp[::seh_count - 1];
ContextRecord->Eip = ::seh_eip[::seh_count - 1];
//printf("seh_handler:%i,%x,%x\n", ::seh_count, ContextRecord->Esp, ContextRecord->Eip);
return ::seh_eh[::seh_count - 1] ?
reinterpret_cast<PEXCEPTION_ROUTINE>(::seh_eh[::seh_count - 1])(ExceptionRecord, EstablisherFrame, ContextRecord, DispatcherContext) :
ExceptionContinueExecution;
}
// EOF
#pragma once
// winseh.h
// 12/13/2013 jichi
// See: http://code.metager.de/source/xref/WebKit/Source/WebCore/platform/win/makesafeseh.asm
// See: http://jpassing.com/2008/05/20/fun-with-low-level-seh/
#ifdef _MSC_VER
# pragma warning (disable:4733) // C4733: Inline asm assigning to 'FS:0' : handler not registered as safe handler
#endif // _MSC_VER
#define SEH_RAISE (*(int*)0 = 0) // raise C000005, for debugging only
// Maximum number of nested SEH
// Default nested function count is 100, see: http://stackoverflow.com/questions/8656089/solution-for-fatal-error-maximum-function-nesting-level-of-100-reached-abor
#ifndef SEH_CAPACITY
# define SEH_CAPACITY 100
#endif // SEH_CAPACITY
enum { seh_capacity = SEH_CAPACITY };
typedef unsigned long seh_dword_t; // DWORD in <windows.h>
// 12/13/2013 jichi
// The list implementation is not thread-safe
extern seh_dword_t seh_esp[seh_capacity], // LPVOID, current stack
seh_eip[seh_capacity], // LPVOID, current IP address
seh_eh[seh_capacity]; // EXCEPTION_ROUTINE, current exception handler function address
extern seh_dword_t seh_count; // current number of exception handlers
extern seh_dword_t seh_handler; //extern PEXCEPTION_ROUTINE seh_handler;
/**
* Push SEH handler
* @param _label exception recover label which should be the same as seh_pop_
* @param _eh EXCEPTION_ROUTINE or 0
* @param _r1 scalar register name, such as eax
* @param _r2 counter register name, such as ecx
*
* Note: __asm prefix is needed to allow inlining macro
* I didn't pushad and popad which seems to be not needed
*
* For SEH, see:
* http://www.codeproject.com/Articles/82701/Win32-Exceptions-OS-Level-Point-of-View
* http://sploitfun.blogspot.com/2012/08/seh-exploit-part1.html
* http://sploitfun.blogspot.com/2012/08/seh-exploit-part2.html
*
* fs:0x0 on Windows is the pointer to ExceptionList
* http://stackoverflow.com/questions/4657661/what-lies-at-fs0x0-on-windows
*
* EPB and ESP
* http://stackoverflow.com/questions/1395591/what-is-exactly-the-base-pointer-and-stack-pointer-to-what-do-they-point
*/
#define seh_push_(_label, _eh, _r1, _r2) \
{ \
__asm mov _r1, _eh /* move new handler address */ \
__asm mov _r2, seh_count /* get current seh counter */ \
__asm mov dword ptr seh_eh[_r2*4], _r1 /* set recover exception hander */ \
__asm mov _r1, _label /* move jump label address */ \
__asm mov dword ptr seh_eip[_r2*4], _r1 /* set recover eip as the jump label */ \
__asm push seh_handler /* push new safe seh handler */ \
__asm push fs:[0] /* push old fs:0 */ \
__asm mov dword ptr seh_esp[_r2*4], esp /* safe current stack address */ \
__asm mov fs:[0], esp /* change fs:0 to the current stack */ \
__asm inc seh_count /* increase number of seh */ \
}
//TODO: get sizeof dword instead of hardcode 4
/**
* Restore old SEH handler
* @param _label exception recover label which should be the same as seh_push_
*/
#define seh_pop_(_label) \
{ \
__asm _label: /* the exception recover label */ \
__asm pop dword ptr fs:[0] /* restore old fs:0 */ \
__asm add esp, 4 /* pop seh_handler */ \
__asm dec seh_count /* decrease number of seh */ \
}
#define seh_pop() seh_pop_(seh_exit)
#define seh_push() seh_push_(seh_exit, 0, eax, ecx) // use ecx as counter better than ebx
/**
* @param _eh EXCEPTION_ROUTINE or 0
*/
#define seh_push_eh(_eh) seh_push_(seh_exit, _eh, eax, ecx)
/**
* Wrap the code block with SEH handler
* @param* any code block. The colon for the last expression is optional.
*/
#define seh_with(...) \
{ \
seh_push() \
__VA_ARGS__ \
; \
seh_pop() \
}
/**
* Wrap the code block with SEH handler
* @param _eh EXCEPTION_ROUTINE or 0
* @param* any code block. The colon for the last expression is optional.
*/
#define seh_with_eh(_eh, ...) \
{ \
seh_push_eh(_eh) \
__VA_ARGS__ \
; \
seh_pop() \
}
// EOF
//#define seh_push_front() \
// { \
// __asm mov eax, seh_exit \
// __asm mov seh_eip, eax \
// __asm push seh_handler \
// __asm push fs:[0] \
// __asm mov seh_esp, esp \
// __asm mov fs:[0], esp \
// }
//
//#define seh_pop_front() \
// { \
// __asm seh_exit: \
// __asm mov eax, [esp] \
// __asm mov fs:[0], eax \
// __asm add esp, 8 \
// }
//
//#define seh_push_back() \
// { \
// __asm mov eax, seh_exit \
// __asm mov ecx, seh_capacity - 1 \
// __asm mov DWORD PTR seh_eip[ecx*4], eax \
// __asm push seh_handler \
// __asm push fs:[0] \
// __asm mov DWORD PTR seh_esp[ecx*4], esp \
// __asm mov fs:[0], esp \
// }
//
//#define seh_pop_back() \
// { \
// __asm seh_exit: \
// __asm mov eax, [esp] \
// __asm mov fs:[0], eax \
// __asm add esp, 8 \
// }
// winseh_safe.cc
// 12/13/2013 jichi
// See: http://stackoverflow.com/questions/12019689/custom-seh-handler-with-safeseh
#include "winseh/winseh.h"
extern "C" int __stdcall _seh_asm_handler();
seh_dword_t seh_handler = reinterpret_cast<seh_dword_t>(_seh_asm_handler);
// EOF
# winseh_safe.pri
# 12/13/2013 jichi
#
# Need link with with SEH assembly
# See: http://stackoverflow.com/questions/12019689/custom-seh-handler-with-safeseh
# See: http://stackoverflow.com/questions/19722308/exception-handler-not-called-in-c
win32 {
#include(../../../config.pri)
# Disable buffer security check: http://msdn.microsoft.com/en-us/library/8dbf701c.aspx
#QMAKE_CXXFLAGS += /GS-
LIBS += safeseh.obj # compiled from safeseh.asm using ml -safeseh
DEFINES += WITH_LIB_WINSEH
DEPENDPATH += $$PWD
HEADERS += $$PWD/winseh.h
SOURCES += \
$$PWD/winseh.cc \
$$PWD/winseh_safe.cc
OTHER_FILES += \
$$PWD/safeseh.asm \
$$PWD/Makefile
}
# EOF
// winseh_unsafe.cc
// 12/13/2013 jichi
// See: http://stackoverflow.com/questions/19722308/exception-handler-not-called-in-c
#include "winseh/winseh.h"
#include <windows.h>
extern "C" EXCEPTION_DISPOSITION _seh_handler(PEXCEPTION_RECORD, PVOID, PCONTEXT, PVOID);
seh_dword_t seh_handler = reinterpret_cast<seh_dword_t>(_seh_handler);
// EOF