101 lines
2.5 KiB
C++
101 lines
2.5 KiB
C++
|
// ntinspect.cc
|
||
|
// 4/20/2014 jichi
|
||
|
#include "ntdll/ntdll.h"
|
||
|
#include "ntinspect/ntinspect.h"
|
||
|
|
||
|
//#ifdef _MSC_VER
|
||
|
//# pragma warning(disable:4018) // C4018: signed/unsigned mismatch
|
||
|
//#endif // _MSC_VER
|
||
|
|
||
|
namespace { // unnamed
|
||
|
// Replacement of wcscpy_s which is not available on Windows XP's msvcrt
|
||
|
// http://sakuradite.com/topic/247
|
||
|
errno_t wcscpy_safe(wchar_t *buffer, size_t bufferSize, const wchar_t *source)
|
||
|
{
|
||
|
size_t len = min(bufferSize - 1, wcslen(source));
|
||
|
buffer[len] = 0;
|
||
|
if (len)
|
||
|
memcpy(buffer, source, len * 2);
|
||
|
return 0;
|
||
|
}
|
||
|
} // unnamed namespace
|
||
|
|
||
|
NTINSPECT_BEGIN_NAMESPACE
|
||
|
|
||
|
BOOL getCurrentProcessName(LPWSTR buffer, int bufferSize)
|
||
|
{
|
||
|
//assert(name);
|
||
|
PLDR_DATA_TABLE_ENTRY it;
|
||
|
__asm
|
||
|
{
|
||
|
mov eax,fs:[0x30]
|
||
|
mov eax,[eax+0xc]
|
||
|
mov eax,[eax+0xc]
|
||
|
mov it,eax
|
||
|
}
|
||
|
// jichi 6/4/2014: _s functions are not supported on Windows XP's msvcrt.dll
|
||
|
//return 0 == wcscpy_s(buffer, bufferSize, it->BaseDllName.Buffer);
|
||
|
return 0 == wcscpy_safe(buffer, bufferSize, it->BaseDllName.Buffer);
|
||
|
}
|
||
|
|
||
|
BOOL getModuleMemoryRange(LPCWSTR moduleName, DWORD *lowerBound, DWORD *upperBound)
|
||
|
{
|
||
|
//assert(lower);
|
||
|
//assert(upper);
|
||
|
PLDR_DATA_TABLE_ENTRY it;
|
||
|
LIST_ENTRY *begin;
|
||
|
__asm
|
||
|
{
|
||
|
mov eax,fs:[0x30]
|
||
|
mov eax,[eax+0xc]
|
||
|
mov eax,[eax+0xc]
|
||
|
mov it,eax
|
||
|
mov begin,eax
|
||
|
}
|
||
|
|
||
|
while (it->SizeOfImage) {
|
||
|
if (_wcsicmp(it->BaseDllName.Buffer, moduleName) == 0) {
|
||
|
DWORD lower = (DWORD)it->DllBase;
|
||
|
if (lowerBound)
|
||
|
*lowerBound = lower;
|
||
|
|
||
|
if (upperBound) {
|
||
|
DWORD upper = lower;
|
||
|
MEMORY_BASIC_INFORMATION mbi = {};
|
||
|
DWORD size = 0;
|
||
|
do {
|
||
|
DWORD len;
|
||
|
// Nt function is needed instead of VirtualQuery, which only works for the current process
|
||
|
::NtQueryVirtualMemory(NtCurrentProcess(), (LPVOID)upper, MemoryBasicInformation, &mbi, sizeof(mbi), &len);
|
||
|
if (mbi.Protect & PAGE_NOACCESS) {
|
||
|
it->SizeOfImage = size;
|
||
|
break;
|
||
|
}
|
||
|
size += mbi.RegionSize;
|
||
|
upper += mbi.RegionSize;
|
||
|
} while (size < it->SizeOfImage);
|
||
|
|
||
|
*upperBound = upper;
|
||
|
}
|
||
|
return TRUE;
|
||
|
}
|
||
|
it = (PLDR_DATA_TABLE_ENTRY)it->InLoadOrderModuleList.Flink;
|
||
|
if (it->InLoadOrderModuleList.Flink == begin)
|
||
|
break;
|
||
|
}
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
BOOL getCurrentMemoryRange(DWORD *lowerBound, DWORD *upperBound)
|
||
|
{
|
||
|
WCHAR procName[MAX_PATH]; // cached
|
||
|
*lowerBound = 0;
|
||
|
*upperBound = 0;
|
||
|
return getCurrentProcessName(procName, MAX_PATH)
|
||
|
&& getModuleMemoryRange(procName, lowerBound, upperBound);
|
||
|
}
|
||
|
|
||
|
NTINSPECT_END_NAMESPACE
|
||
|
|
||
|
// EOF
|