simplify thread safety code

This commit is contained in:
Akash Mozumdar 2018-06-12 17:31:24 -04:00
parent 30f95423f1
commit 32bcee8f50
5 changed files with 27 additions and 168 deletions

View File

@ -43,7 +43,7 @@ target_compile_options(vnrhost PRIVATE
target_link_libraries(vnrhost
#ithsys
profile
${WDK_HOME}/lib/wxp/i386/ntdll.lib
#${WDK_HOME}/lib/wxp/i386/ntdll.lib
)
target_compile_definitions(vnrhost

View File

@ -25,7 +25,7 @@
namespace { // unnamed
//enum { MAX_ENTRY = 0x40 };
#define HM_LOCK win_mutex_lock<HookManager::mutex_type> d_locker(hmcs) // Synchronized scope for accessing private data
#define HM_LOCK CriticalSectionLocker d_locker(hmcs) // Synchronized scope for accessing private data
} // unnamed namespace
@ -59,14 +59,14 @@ DWORD GetHookName(LPSTR str, DWORD pid, DWORD hook_addr, DWORD max)
ProcessRecord *pr = ::man->GetProcessRecord(pid);
if (!pr)
return 0;
NtWaitForSingleObject(pr->hookman_mutex, 0, 0);
WaitForSingleObject(pr->hookman_mutex, 0);
const Hook *hks = (const Hook *)pr->hookman_map;
for (int i = 0; i < MAX_HOOK; i++)
if (hks[i].Address() == hook_addr) {
len = hks[i].NameLength();
if (len >= max)
len = max;
NtReadVirtualMemory(pr->process_handle, hks[i].Name(), str, len, &len);
ReadProcessMemory(pr->process_handle, hks[i].Name(), str, len, &len);
if (str[len - 1] == 0)
len--;
else
@ -74,18 +74,11 @@ DWORD GetHookName(LPSTR str, DWORD pid, DWORD hook_addr, DWORD max)
break;
}
NtReleaseMutant(pr->hookman_mutex, 0);
ReleaseMutex(pr->hookman_mutex);
//::man->UnlockProcessHookman(pid);
return len;
}
// Artikash 5/31/2018: required for unordered_map to work with struct key
bool operator==(const ThreadParameter& one, const ThreadParameter& two)
{
return one.pid == two.pid && one.hook == two.hook && one.retn == two.retn && one.spl == two.spl;
}
#define NAMED_PIPE_DISCONNECT 1
//Class member of HookManger
HookManager::HookManager() :
// jichi 9/21/2013: Zero memory
@ -105,11 +98,14 @@ HookManager::HookManager() :
TextThread* consoleTextThread = threadTable[{0, -1UL, -1UL, -1UL}] = new TextThread({ 0, -1UL, -1UL, -1UL }, new_thread_number++);
consoleTextThread->Status() |= USING_UNICODE;
SetCurrent(consoleTextThread);
InitializeCriticalSection(&hmcs);
}
HookManager::~HookManager()
{
// Artikash 5/31/2018: This is called when the program terminates, so Windows should automatically free all these resources.....right?
//LeaveCriticalSection(&hmcs);
//LARGE_INTEGER timeout={-1000*1000,-1};
//IthBreak();
//NtWaitForSingleObject(destroy_event, 0, 0);
@ -364,88 +360,6 @@ HANDLE HookManager::GetHostPipeByPID(DWORD pid)
MK_BASIC_TYPE(DWORD)
MK_BASIC_TYPE(LPVOID)
//DWORD Hash(LPCWSTR module, int length)
//{
// bool flag = (length==-1);
// DWORD hash = 0;
// for (;*module && (flag || length--); module++)
// hash = ((hash>>7)|(hash<<25)) + *module;
// return hash;
//}
//void AddLink(WORD from, WORD to) { ::man->AddLink(from, to); }
// jichi 9/27/2013: Unparse to hook parameters /H code
void GetCode(const HookParam &hp, LPWSTR buffer, DWORD pid)
{
WCHAR c;
LPWSTR ptr = buffer;
// jichi 12/7/2014: disabled
//if (hp.type&PRINT_DWORD)
// c = L'H';
if (hp.type&USING_UNICODE) {
if (hp.type&USING_STRING)
c = L'Q';
else if (hp.type&STRING_LAST_CHAR)
c = L'L';
else
c = L'W';
} else {
if (hp.type&USING_STRING)
c = L'S';
else if (hp.type&BIG_ENDIAN)
c = L'A';
else if (hp.type&STRING_LAST_CHAR)
c = L'E';
else
c = L'B';
}
ptr += swprintf(ptr, L"/H%c",c);
if (hp.type & NO_CONTEXT)
*ptr++ = L'N';
if (hp.offset>>31)
ptr += swprintf(ptr, L"-%X",-(hp.offset+4));
else
ptr += swprintf(ptr, L"%X",hp.offset);
if (hp.type & DATA_INDIRECT) {
if (hp.index>>31)
ptr += swprintf(ptr, L"*-%X",-hp.index);
else
ptr += swprintf(ptr,L"*%X",hp.index);
}
if (hp.type & USING_SPLIT) {
if (hp.split >> 31)
ptr += swprintf(ptr, L":-%X", -(4 + hp.split));
else
ptr += swprintf(ptr, L":%X", hp.split);
}
if (hp.type & SPLIT_INDIRECT) {
if (hp.split_index >> 31)
ptr += swprintf(ptr, L"*-%X", -hp.split_index);
else
ptr += swprintf(ptr, L"*%X", hp.split_index);
}
if (hp.module) {
if (pid) {
WCHAR path[MAX_PATH];
MEMORY_BASIC_INFORMATION info;
ProcessRecord* pr = ::man->GetProcessRecord(pid);
if (pr) {
HANDLE hProc = pr->process_handle;
if (NT_SUCCESS(NtQueryVirtualMemory(hProc,(PVOID)hp.address, MemorySectionName, path, MAX_PATH*2, 0)) &&
NT_SUCCESS(NtQueryVirtualMemory(hProc,(PVOID)hp.address, MemoryBasicInformation, &info, sizeof(info), 0)))
ptr += swprintf(ptr, L"@%X:%s", hp.address - (DWORD)info. AllocationBase, wcsrchr(path,L'\\') + 1);
}
} else {
ptr += swprintf(ptr, L"@%X!%X", hp.address, hp.module);
if (hp.function)
ptr += swprintf(ptr, L"!%X", hp.function);
}
}
else
ptr += swprintf(ptr, L"@%X", hp.address);
}
void AddHooksToProfile(Profile& pf, const ProcessRecord& pr);
DWORD AddThreadToProfile(Profile& pf, const ProcessRecord& pr, TextThread* thread);
void MakeHookRelative(const ProcessRecord& pr, HookParam& hp);

View File

@ -95,8 +95,7 @@ private:
std::unordered_map<ThreadParameter, TextThread*, ThreadParameterHasher> threadTable;
std::unordered_map<DWORD, ProcessRecord*> processRecordsByIds;
typedef win_mutex<CRITICAL_SECTION> mutex_type;
mutex_type hmcs;
CRITICAL_SECTION hmcs;
TextThread *current;
ConsoleCallback console; // jichi 12/25/2013: add console output callback

View File

@ -19,7 +19,13 @@ struct ThreadParameter {
DWORD pid; // jichi: 5/11/2014: The process ID
DWORD hook; // Artikash 6/6/2018: The start address of the hook
DWORD retn; // jichi 5/11/2014: The return address of the hook
DWORD spl; // jichi 5/11/2014: the processed split value of the hook parameter
DWORD spl; // jichi 5/11/2014: the processed split value of the hook paramete
// Artikash 5/31/2018: required for unordered_map to work with struct key
friend bool operator==(const ThreadParameter& one, const ThreadParameter& two)
{
return one.pid == two.pid && one.hook == two.hook && one.retn == two.retn && one.spl == two.spl;
}
};
#define CURRENT_SELECT 0x1000

View File

@ -8,77 +8,6 @@
# 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 try_lock() { return _M_locked = _M_mutex.try_lock(); }
};
// 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); }
};
class MutexLocker
{
HANDLE m;
@ -90,4 +19,15 @@ template <>
~MutexLocker() { if (m != INVALID_HANDLE_VALUE && m != nullptr) ReleaseMutex(m); }
};
class CriticalSectionLocker
{
CRITICAL_SECTION cs;
public:
explicit CriticalSectionLocker(CRITICAL_SECTION cs) : cs(cs)
{
EnterCriticalSection(&cs);
}
~CriticalSectionLocker() { LeaveCriticalSection(&cs); }
};
// EOF