mirror of
https://github.com/Artikash/Textractor.git
synced 2024-12-24 01:14:12 +08:00
simplify thread safety code
This commit is contained in:
parent
30f95423f1
commit
32bcee8f50
@ -43,7 +43,7 @@ target_compile_options(vnrhost PRIVATE
|
|||||||
target_link_libraries(vnrhost
|
target_link_libraries(vnrhost
|
||||||
#ithsys
|
#ithsys
|
||||||
profile
|
profile
|
||||||
${WDK_HOME}/lib/wxp/i386/ntdll.lib
|
#${WDK_HOME}/lib/wxp/i386/ntdll.lib
|
||||||
)
|
)
|
||||||
|
|
||||||
target_compile_definitions(vnrhost
|
target_compile_definitions(vnrhost
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
namespace { // unnamed
|
namespace { // unnamed
|
||||||
//enum { MAX_ENTRY = 0x40 };
|
//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
|
} // unnamed namespace
|
||||||
@ -59,14 +59,14 @@ DWORD GetHookName(LPSTR str, DWORD pid, DWORD hook_addr, DWORD max)
|
|||||||
ProcessRecord *pr = ::man->GetProcessRecord(pid);
|
ProcessRecord *pr = ::man->GetProcessRecord(pid);
|
||||||
if (!pr)
|
if (!pr)
|
||||||
return 0;
|
return 0;
|
||||||
NtWaitForSingleObject(pr->hookman_mutex, 0, 0);
|
WaitForSingleObject(pr->hookman_mutex, 0);
|
||||||
const Hook *hks = (const Hook *)pr->hookman_map;
|
const Hook *hks = (const Hook *)pr->hookman_map;
|
||||||
for (int i = 0; i < MAX_HOOK; i++)
|
for (int i = 0; i < MAX_HOOK; i++)
|
||||||
if (hks[i].Address() == hook_addr) {
|
if (hks[i].Address() == hook_addr) {
|
||||||
len = hks[i].NameLength();
|
len = hks[i].NameLength();
|
||||||
if (len >= max)
|
if (len >= max)
|
||||||
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)
|
if (str[len - 1] == 0)
|
||||||
len--;
|
len--;
|
||||||
else
|
else
|
||||||
@ -74,18 +74,11 @@ DWORD GetHookName(LPSTR str, DWORD pid, DWORD hook_addr, DWORD max)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
NtReleaseMutant(pr->hookman_mutex, 0);
|
ReleaseMutex(pr->hookman_mutex);
|
||||||
//::man->UnlockProcessHookman(pid);
|
//::man->UnlockProcessHookman(pid);
|
||||||
return len;
|
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
|
//Class member of HookManger
|
||||||
HookManager::HookManager() :
|
HookManager::HookManager() :
|
||||||
// jichi 9/21/2013: Zero memory
|
// 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++);
|
TextThread* consoleTextThread = threadTable[{0, -1UL, -1UL, -1UL}] = new TextThread({ 0, -1UL, -1UL, -1UL }, new_thread_number++);
|
||||||
consoleTextThread->Status() |= USING_UNICODE;
|
consoleTextThread->Status() |= USING_UNICODE;
|
||||||
SetCurrent(consoleTextThread);
|
SetCurrent(consoleTextThread);
|
||||||
|
|
||||||
|
InitializeCriticalSection(&hmcs);
|
||||||
}
|
}
|
||||||
|
|
||||||
HookManager::~HookManager()
|
HookManager::~HookManager()
|
||||||
{
|
{
|
||||||
// Artikash 5/31/2018: This is called when the program terminates, so Windows should automatically free all these resources.....right?
|
// 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};
|
//LARGE_INTEGER timeout={-1000*1000,-1};
|
||||||
//IthBreak();
|
//IthBreak();
|
||||||
//NtWaitForSingleObject(destroy_event, 0, 0);
|
//NtWaitForSingleObject(destroy_event, 0, 0);
|
||||||
@ -364,88 +360,6 @@ HANDLE HookManager::GetHostPipeByPID(DWORD pid)
|
|||||||
MK_BASIC_TYPE(DWORD)
|
MK_BASIC_TYPE(DWORD)
|
||||||
MK_BASIC_TYPE(LPVOID)
|
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);
|
void AddHooksToProfile(Profile& pf, const ProcessRecord& pr);
|
||||||
DWORD AddThreadToProfile(Profile& pf, const ProcessRecord& pr, TextThread* thread);
|
DWORD AddThreadToProfile(Profile& pf, const ProcessRecord& pr, TextThread* thread);
|
||||||
void MakeHookRelative(const ProcessRecord& pr, HookParam& hp);
|
void MakeHookRelative(const ProcessRecord& pr, HookParam& hp);
|
||||||
|
@ -95,8 +95,7 @@ private:
|
|||||||
std::unordered_map<ThreadParameter, TextThread*, ThreadParameterHasher> threadTable;
|
std::unordered_map<ThreadParameter, TextThread*, ThreadParameterHasher> threadTable;
|
||||||
std::unordered_map<DWORD, ProcessRecord*> processRecordsByIds;
|
std::unordered_map<DWORD, ProcessRecord*> processRecordsByIds;
|
||||||
|
|
||||||
typedef win_mutex<CRITICAL_SECTION> mutex_type;
|
CRITICAL_SECTION hmcs;
|
||||||
mutex_type hmcs;
|
|
||||||
|
|
||||||
TextThread *current;
|
TextThread *current;
|
||||||
ConsoleCallback console; // jichi 12/25/2013: add console output callback
|
ConsoleCallback console; // jichi 12/25/2013: add console output callback
|
||||||
|
@ -19,7 +19,13 @@ struct ThreadParameter {
|
|||||||
DWORD pid; // jichi: 5/11/2014: The process ID
|
DWORD pid; // jichi: 5/11/2014: The process ID
|
||||||
DWORD hook; // Artikash 6/6/2018: The start address of the hook
|
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 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
|
#define CURRENT_SELECT 0x1000
|
||||||
|
@ -8,77 +8,6 @@
|
|||||||
# pragma warning(disable:4800) // C4800: forcing value to bool
|
# pragma warning(disable:4800) // C4800: forcing value to bool
|
||||||
#endif // _MSC_VER
|
#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
|
class MutexLocker
|
||||||
{
|
{
|
||||||
HANDLE m;
|
HANDLE m;
|
||||||
@ -90,4 +19,15 @@ template <>
|
|||||||
~MutexLocker() { if (m != INVALID_HANDLE_VALUE && m != nullptr) ReleaseMutex(m); }
|
~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
|
// EOF
|
||||||
|
Loading…
x
Reference in New Issue
Block a user