⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fastmm4bcb.cpp.svn-base

📁 Memory Manager for delphi 5-2007. Usefully to find the memory leaks and help for optimalize your mem
💻 SVN-BASE
📖 第 1 页 / 共 3 页
字号:
    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 + -