📄 fastmm4bcb.cpp.svn-base
字号:
test eax, eax
jz Exit2 //Exit1
#if __BORLANDC__ >= 0x564
jmp InvalidGetMemPtr
nop
#else
call InvalidGetMemPtr
ret
#endif
nop
//Exit1:
//ret
Realloc:
mov edx, [esp + 8] //size
test edx, edx
jnz DoRealloc
call InvalidFreeMemPtr
ReturnNULL:
xor eax, eax
Exit2:
ret
nop
nop
nop
DoRealloc:
#if __BORLANDC__ >= 0x564
jmp InvalidReallocMemPtr
//ret
#else
call InvalidReallocMemPtr
ret
#endif
}
}
#endif //DetectMMOperationsAfterUninstall
#pragma option push -b -a8
typedef void (_RTLENTRY *HeapRedirect_free) (void *);
typedef void * (_RTLENTRY *HeapRedirect_malloc) (size_t);
typedef void * (_RTLENTRY *HeapRedirect_realloc) (void *, size_t);
typedef void (_RTLENTRY *HeapRedirect_terminate) (void);
typedef enum
{
hrfVirgin,
hrfInternal,
hrfBorlndmm,
hrfOldBorlndmm,
hrfVCLSystem,
hrfDgbAlloc,
hrfOther
} HeapRedirectFlag;
typedef struct
{
size_t size;
unsigned int allocated;
HeapRedirectFlag flags;
HeapRedirect_free free;
HeapRedirect_malloc malloc;
HeapRedirect_realloc realloc;
HeapRedirect_terminate terminate;
} HeapRedirector;
typedef struct HeapRedirectorStoreStruct
{
HeapRedirector Data;
HMODULE Module;
void * PatchAddress;
TRelativeJmp32 PatchBackup;
struct HeapRedirectorStoreStruct *Next;
} HeapRedirectorStore, *HeapRedirectorStorePtr;
extern HeapRedirector * _RTLENTRY _EXPFUNC _get_heap_redirector_info(void);
typedef HeapRedirector * _RTLENTRY _EXPFUNC (* rtl_get_heap_redirector_info_func)(void);
#pragma option pop
HeapRedirector * pHRDir = NULL;
HeapRedirector Old_heap_redirector;
HeapRedirectorStorePtr HeapRedirectorStoreListHeader = NULL;
//#endif //!_RTLDLL
#define UseHeap
#ifdef UseHeap
HANDLE ProcessHeapHandle = NULL;
#endif
void __fastcall InitFinalMemMgr(void)
{
#ifdef UseHeap
if (!ProcessHeapHandle)
{
ProcessHeapHandle = GetProcessHeap();
}
#endif
}
void * __fastcall FinalGetMem(unsigned ASize)
{
#ifdef UseHeap
return HeapAlloc(ProcessHeapHandle, HEAP_GENERATE_EXCEPTIONS, ASize);
#else
return malloc(ASize);
#endif
}
void __fastcall FinalFreeMem(void * ABlock)
{
#ifdef UseHeap
HeapFree(ProcessHeapHandle, 0, ABlock);
#else
free(ABlock);
#endif
}
void * __fastcall FinalReallocMem(void * ABlock, unsigned ANewSize)
{
#ifdef UseHeap
return HeapReAlloc(ProcessHeapHandle, HEAP_GENERATE_EXCEPTIONS, ABlock, ANewSize);
#else
return realloc(ABlock, ANewSize);
#endif
}
void __fastcall FinalizeHeapRedirectorStoreList(void)
{
if (HeapRedirectorStoreListHeader)
{
HeapRedirectorStorePtr next, ptr = HeapRedirectorStoreListHeader;
HeapRedirectorStoreListHeader = NULL;
while (ptr)
{
next = ptr->Next;
FinalFreeMem(ptr);
ptr = next;
}
}
}
typedef bool __fastcall (* EnumModuleCallback)(HMODULE AModule, void *AParam);
#define PSAPI "psapi"
bool __fastcall EnumModulesWinNT(EnumModuleCallback ACallback, void *AParam)
{
typedef BOOL (__stdcall * EnumProcessModulesType)(HANDLE hProcess,
HMODULE* lphModule,
DWORD cb,
LPDWORD lpcbNeeded
);
if (!ACallback)
{
return false;
}
EnumProcessModulesType EnumProcessModules;
bool DynamicLoaded;
HMODULE PsapiLib = GetModuleHandle(PSAPI);
if (!PsapiLib)
{
PsapiLib = LoadLibrary(PSAPI);
if (!PsapiLib)
{
return false;
}
DynamicLoaded = true;
}
else {
DynamicLoaded = false;
}
InitFinalMemMgr();
bool ret = false;
try
{
EnumProcessModules = (EnumProcessModulesType)GetProcAddress(PsapiLib,
"EnumProcessModules");
if (EnumProcessModules)
{
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
FALSE, GetCurrentProcessId());
if (hProcess)
{
try
{
DWORD cbNeeded = 0;
if (EnumProcessModules(hProcess, NULL, 0, &cbNeeded))
{
HMODULE * hMod = (HMODULE *)FinalGetMem(cbNeeded);
try
{
if (EnumProcessModules(hProcess, hMod, cbNeeded, &cbNeeded))
{
for (unsigned int i = 0; i < (cbNeeded / sizeof(HMODULE)); i++)
{
if (!ACallback(hMod[i], AParam))
{
break;
}
}
ret = true;
}
}
__finally
{
FinalFreeMem(hMod);
}
}
}
__finally
{
CloseHandle(hProcess);
}
}
}
}
__finally
{
if (DynamicLoaded)
{
FreeLibrary(PsapiLib);
}
}
return ret;
}
#define KERNEL32 "kernel32"
bool __fastcall EnumModulesWin9x(EnumModuleCallback ACallback, void *AParam)
{
#define MAX_MODULE_NAME32 255
#define TH32CS_SNAPMODULE 0x00000008
typedef struct tagMODULEENTRY32
{
DWORD dwSize;
DWORD th32ModuleID;
DWORD th32ProcessID;
DWORD GlblcntUsage;
DWORD ProccntUsage;
BYTE * modBaseAddr;
DWORD modBaseSize;
HMODULE hModule;
char szModule[MAX_MODULE_NAME32 + 1];
char szExePath[MAX_PATH];
} MODULEENTRY32;
typedef MODULEENTRY32 * PMODULEENTRY32;
typedef MODULEENTRY32 * LPMODULEENTRY32;
typedef HANDLE (__stdcall * CreateToolhelp32SnapshotType)(DWORD dwFlags,
DWORD th32ProcessID);
typedef BOOL (__stdcall * Module32FirstType)(HANDLE hSnapshot, LPMODULEENTRY32 lpme);
typedef BOOL (__stdcall * Module32NextType)(HANDLE hSnapshot, LPMODULEENTRY32 lpme);
if (!ACallback)
{
return false;
}
HANDLE Kernel32Lib, hSnapshot;
CreateToolhelp32SnapshotType CreateToolhelp32Snapshot;
Module32FirstType Module32First;
Module32NextType Module32Next;
bool ret = false;
Kernel32Lib = GetModuleHandle(KERNEL32);
if (Kernel32Lib)
{
CreateToolhelp32Snapshot = (CreateToolhelp32SnapshotType)GetProcAddress(Kernel32Lib,
"CreateToolhelp32Snapshot");
Module32First = (Module32FirstType)GetProcAddress(Kernel32Lib, "Module32First");
Module32Next = (Module32NextType)GetProcAddress(Kernel32Lib, "Module32Next");
if ((CreateToolhelp32Snapshot) && (Module32First) && (Module32Next))
{
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId());
if (hSnapshot != INVALID_HANDLE_VALUE)
{
try
{
MODULEENTRY32 ModuleInfo = {0};
ModuleInfo.dwSize = sizeof(ModuleInfo);
while (Module32First(hSnapshot, &ModuleInfo))
{
if (!ACallback(ModuleInfo.hModule, AParam))
break;
}
ret = true;
}
__finally
{
CloseHandle(hSnapshot);
}
}
}
}
return ret;
}
bool __fastcall EnumModules(EnumModuleCallback ACallback, void *AParam)
{
if (ACallback)
{
OSVERSIONINFO OSVersionInfo;
OSVersionInfo.dwOSVersionInfoSize = sizeof(OSVersionInfo);
if (GetVersionEx(&OSVersionInfo))
{
if (OSVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT)
{
return EnumModulesWinNT(ACallback, AParam);
}
else {
return EnumModulesWin9x(ACallback, AParam);
}
}
}
return false;
}
#ifdef CheckCppObjectTypeEnabled
typedef struct {
DWORD CodeSecStart;
DWORD DataSecStart;
DWORD DataSecEnd;
} ModuleCodeDataRanges, * PModuleCodeDataRanges;
int ModuleCodeDataRangesCount = 0;
int ModuleCodeDataRangesCapacity = 0;
PModuleCodeDataRanges gpModuleCodeDataRanges = NULL;
unsigned LowestDataAddr = NULL;
unsigned HighestDataAddr = NULL;
bool __fastcall FindCodeDataRangeByDataAddr(DWORD ADataAddr, int * Index,
PModuleCodeDataRanges * ARange)
{
bool ret = false;
int L, H, I;
L = 0;
H = ModuleCodeDataRangesCount - 1;
while (L <= H)
{
I = (L + H) / 2;
DWORD AStart = gpModuleCodeDataRanges[I].DataSecStart;
DWORD AEnd = gpModuleCodeDataRanges[I].DataSecEnd;
if (ADataAddr < AStart)
{
H = I - 1;
}
else if (ADataAddr >= AEnd)
{
L = I + 1;
}
else {
if (ARange)
{
*ARange = &(gpModuleCodeDataRanges[I]);
}
L = I;
ret = true;
break;
}
}
if (Index)
{
*Index = L;
}
return ret;
}
bool __fastcall FindCodeDataRangeByCodeAddr(DWORD ACodeAddr, int * Index,
PModuleCodeDataRanges * ARange)
{
bool ret = false;
int L, H, I;
L = 0;
H = ModuleCodeDataRangesCount - 1;
while (L <= H)
{
I = (L + H) / 2;
DWORD AStart = gpModuleCodeDataRanges[I].CodeSecStart;
DWORD AEnd = gpModuleCodeDataRanges[I].DataSecStart;
if (ACodeAddr < AStart)
{
H = I - 1;
}
else if (ACodeAddr >= AEnd)
{
L = I + 1;
}
else {
if (ARange)
{
*ARange = &(gpModuleCodeDataRanges[I]);
}
L = I;
ret = true;
break;
}
}
if (Index)
{
*Index = L;
}
return ret;
}
PIMAGE_SECTION_HEADER __fastcall GetImageFirstSection(PIMAGE_NT_HEADERS ntheader)
{
return (PIMAGE_SECTION_HEADER)((unsigned)&(ntheader->OptionalHeader)
+ ntheader->FileHeader.SizeOfOptionalHeader);
}
#define DefaultCodeSectionName ".text"
#define DefaultDataSectionName ".data"
bool __fastcall AddModuleCodeDataRange(HMODULE AModule, void *AParam)
{
if ((FindResource(AModule, DVCLALResName, RT_RCDATA))
/*&& (GetProcAddress(AModule, CPPdebugHookExport))*/)
{
PIMAGE_NT_HEADERS ntheader = (PIMAGE_NT_HEADERS)((unsigned)AModule
+ ((PIMAGE_DOS_HEADER)AModule)->e_lfanew);
PIMAGE_SECTION_HEADER CodeSecHeader = GetImageFirstSection(ntheader);
//= IMAGE_FIRST_SECTION(ntheader);
PIMAGE_SECTION_HEADER DataSecHeader = CodeSecHeader + 1;
if (((memcmp(DefaultCodeSectionName, CodeSecHeader->Name, 5)) == 0)
&& (CodeSecHeader->Characteristics == (IMAGE_SCN_MEM_EXECUTE
| IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_CODE))
&& ((memcmp(DefaultDataSectionName, DataSecHeader->Name, 5)) == 0)
&& (DataSecHeader->Characteristics == (IMAGE_SCN_MEM_WRITE
| IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA)))
{
int Index;
if (!FindCodeDataRangeByDataAddr((unsigned)AModule
+ DataSecHeader->VirtualAddress, &Index, NULL))
{
int NewCount = ModuleCodeDataRangesCount + 1;
if (NewCount >= ModuleCodeDataRangesCapacity)
{
//Realloc
int NewCapacity = ModuleCodeDataRangesCapacity
+ (ModuleCodeDataRangesCapacity / 4);
gpModuleCodeDataRanges =
(PModuleCodeDataRanges)FinalReallocMem(gpModuleCodeDataRanges,
sizeof(ModuleCodeDataRanges) * NewCapacity);
ModuleCodeDataRangesCapacity = NewCapacity;
}
ModuleCodeDataRangesCount = NewCount;
gpModuleCodeDataRanges[Index].CodeSecStart = (unsigned)AModule
+ CodeSecHeader->VirtualAddress;
gpModuleCodeDataRanges[Index].DataSecStart = (unsigned)AModule
+ DataSecHeader->VirtualAddress;
gpModuleCodeDataRanges[Index].DataSecEnd = (unsigned)AModule
+ DataSecHeader->VirtualAddress + DataSecHeader->Misc.VirtualSize;
}
}
}
return true;
}
void __fastcall FinalizeModuleCodeDataRanges(void)
{
if ((unsigned)gpModuleCodeDataRanges > 1)
{
FinalFreeMem(gpModuleCodeDataRanges);
gpModuleCodeDataRanges = NULL;
ModuleCodeDataRangesCount = 0;
ModuleCodeDataRangesCapacity = NULL;
}
}
#define InitialCodeDataRangeCount 256
bool __fastcall FillModuleCodeDataRanges(void)
{
if (!gpModuleCodeDataRanges)
{
InitFinalMemMgr();
gpModuleCodeDataRanges =
(PModuleCodeDataRanges)FinalGetMem(sizeof(ModuleCodeDataRanges)
* InitialCodeDataRangeCount);
ModuleCodeDataRangesCapacity = InitialCodeDataRangeCount;
bool ret = EnumModules(AddModuleCodeDataRange, NULL);
if ((!ret) || (!ModuleCodeDataRangesCount))
{
FinalizeModuleCodeDataRanges();
gpModuleCodeDataRanges = (PModuleCodeDataRanges)1;
return false;
}
if (ret)
{
LowestDataAddr = gpModuleCodeDataRanges->DataSecStart;
HighestDataAddr =
gpModuleCodeDataRanges[ModuleCodeDataRangesCount - 1].DataSecEnd
- sizeof(void *);
}
return ret;
}
else {
return false;
}
}
#pragma option push -a1
struct TypeDescriptor;
typedef TypeDescriptor * TypeDescriptorPtr;
struct TypeDescriptor
{
unsigned Size;
unsigned short Mask;
unsigned short Name;
union
{
struct
{
unsigned VTablePtrOffset;
unsigned Flags;
}
Class;
};
};
//TypeDescriptor.Mask flags
#define TYPE_MASK_IS_STRUCT 0x0001
#define TYPE_MASK_IS_CLASS 0x0002
#define CLASS_FLAG_HAS_VTABPTR 0x00000010
#define CLASS_FLAG_HAS_RTTI 0x00000040
#pragma option pop
TypeDescriptorPtr __fastcall GetCppVirtualObjectTypeIdPtrByVTablePtr(void * AVTablePtr,
unsigned AVTablePtrOffset)
{
if (AVTablePtr)
{
if ((!((unsigned)AVTablePtr & (sizeof(void *) - 1)))
&& (!((unsigned)AVTablePtrOffset & (sizeof(void *) - 1))))
{
if (!gpModuleCodeDataRanges)
{
if (!FillModuleCodeDataRanges())
{
return NULL;
}
}
if (((unsigned)AVTablePtr >= LowestDataAddr) && ((unsigned)AVTablePtr <= HighestDataAddr))
{
PModuleCodeDataRanges ADataRange, ACodeRange;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -