Skip to content

Commit

Permalink
1.0.0 a11
Browse files Browse the repository at this point in the history
Добавил поддержку отладочных МАР файлов от Delphi 2010 и выше +
небольшие улучшения по GUI для удобства работы.
  • Loading branch information
AlexanderBagel committed Mar 2, 2017
1 parent 1111af0 commit 23e03a9
Show file tree
Hide file tree
Showing 24 changed files with 1,511 additions and 441 deletions.
19 changes: 15 additions & 4 deletions MemoryMap/MemoryMap.Core.pas
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
// * Unit Name : MemoryMap.Core.pas
// * Purpose : Áàçîâûé êëàññ ñîáèðàþùèé èíôîðìàöèþ î êàðòå ïàìÿòè ïðîöåññà
// * Author : Àëåêñàíäð (Rouse_) Áàãåëü
// * Copyright : © Fangorn Wizards Lab 1998 - 2016.
// * Version : 1.0.2
// * Copyright : © Fangorn Wizards Lab 1998 - 2017.
// * Version : 1.0.3
// * Home Page : http://rouse.drkb.ru
// * Home Blog : http://alexander-bagel.blogspot.ru
// ****************************************************************************
Expand All @@ -32,7 +32,8 @@ interface
MemoryMap.Threads,
MemoryMap.NtDll,
MemoryMap.PEImage,
MemoryMap.Symbols;
MemoryMap.Symbols,
MemoryMap.DebugMapData;

type
// Òèïû ôèëüòðîâ
Expand Down Expand Up @@ -104,6 +105,7 @@ TFriendlyRegionData = class(TRegionData);
FDetailedHeapData: Boolean;
FSuspendProcess: Boolean;
FGetWow64Heaps: TOnGetWow64HeapsEvent;
FDebugMapData: TDebugMap;
function GetItem(Index: Integer): TRegionData;
procedure SetShowEmpty(const Value: Boolean);
procedure SetFilter(const Value: TFilters);
Expand Down Expand Up @@ -138,6 +140,7 @@ TFriendlyRegionData = class(TRegionData);
procedure SaveToStream(AStream: TStream);
procedure LoadFromStream(AStream: TStream);
function Count: Integer;
property DebugMapData: TDebugMap read FDebugMapData;
function InitFromProcess(PID: Cardinal; const ProcessName: string): Boolean;
function GetHiddenRegion(RootIndex, SubIndex: Integer): TRegionData;
function GetRegionAtUnfilteredIndex(Index: Integer): TRegionData;
Expand Down Expand Up @@ -287,13 +290,15 @@ constructor TMemoryMap.Create;
FRegions := TObjectList<TRegionData>.Create(True);
FRegionFilters := TList<Integer>.Create;
FModules := TList<TModule>.Create;
FDebugMapData := TDebugMap.Create;
end;

//
// Ñòàíäàðòíûé äåñòðóêòîð
// =============================================================================
destructor TMemoryMap.Destroy;
begin
FDebugMapData.Free;
FModules.Free;
FRegionFilters.Free;
FRegions.Free;
Expand All @@ -312,6 +317,7 @@ procedure TMemoryMap.GetAllRegions;
Shared: Boolean;
SharedCount: Byte;
Module: TModule;
OriginalImageBase: ULONG_PTR;
begin
FRegions.Clear;
FRegionFilters.Clear;
Expand Down Expand Up @@ -362,7 +368,7 @@ procedure TMemoryMap.GetAllRegions;
// Åñëè äà, çàïîìèíàåì åãî ïóòü
RegionData.SetDetails(Module.Path);
// Ïðîâåðÿåì, ÿâëÿåòñÿ ëè ôàéë èñïîëíÿåìûì?
if CheckPEImage(FProcess, MBI.BaseAddress) then
if CheckPEImage(FProcess, MBI.BaseAddress, OriginalImageBase) then
begin
// Åñëè ÿâëÿåòñÿ - çàïîìèíàåì åãî â ñïèñêå ìîäóëåé
Module.BaseAddr := ULONG_PTR(MBI.BaseAddress);
Expand All @@ -371,6 +377,10 @@ procedure TMemoryMap.GetAllRegions;
RegionData.SetRegionType(rtExecutableImage);
// äî êó÷è ïîëó÷àåì èíôîðìàèþ ïî ñàìîìó PE ôàéëó
PEImage.GetInfoFromImage(Module.Path, MBI.BaseAddress, MBI.RegionSize);
// è ïðîáóåì ïîäòÿíóòü åãî îòëàäî÷íóþ èíôîìàöèþ, åñëè åñòü MAP ôàéë
if FileExists(ChangeFileExt(Module.Path, '.map')) then
DebugMapData.Init(ULONG_PTR(MBI.BaseAddress),
OriginalImageBase, Module.Path);
end;
end;

Expand Down Expand Up @@ -513,6 +523,7 @@ function TMemoryMap.InitFromProcess(PID: Cardinal;
Result := False;
FRegions.Clear;
FModules.Clear;
FDebugMapData.Clear;
FFilter := fiNone;
ProcessLock := nil;
// Îòêðûâàåì ïðîöåññ íà ÷òåíèå
Expand Down
240 changes: 240 additions & 0 deletions MemoryMap/MemoryMap.DebugMapData.pas
Original file line number Diff line number Diff line change
@@ -0,0 +1,240 @@
////////////////////////////////////////////////////////////////////////////////
//
// ****************************************************************************
// * Project : MemoryMap
// * Unit Name : MemoryMap.DebugMapData.pas
// * Purpose : Êëàññ äëÿ ðàáîòû ñ îòëàäî÷íûì MAP ôàéëîì.
// * Author : Àëåêñàíäð (Rouse_) Áàãåëü
// * Copyright : © Fangorn Wizards Lab 1998 - 2017.
// * Version : 1.0.0
// * Home Page : http://rouse.drkb.ru
// * Home Blog : http://alexander-bagel.blogspot.ru
// ****************************************************************************
// * Stable Release : http://rouse.drkb.ru/winapi.php#pmm2
// * Latest Source : https://github.com/AlexanderBagel/ProcessMemoryMap
// ****************************************************************************
//

unit MemoryMap.DebugMapData;

interface

uses
Winapi.Windows,
System.Classes,
Generics.Collections,
Generics.Defaults,
System.SysUtils;

type
TDebugMapItem = record
Address, EndAddress: NativeUInt;
ModuleName,
FunctionName: string;
end;

TDebugMap = class
private type
TSectionData = record
Index: Integer;
StartAddr: DWORD;
Length: DWORD;
end;
private
FItems: TList<TDebugMapItem>;
public
constructor Create;
destructor Destroy; override;
procedure Clear;
procedure Init(BaseAddress, InstanceAddress: ULONG_PTR; const ModulePath: string);
function GetDescriptionAtAddr(Address: ULONG_PTR): string;
function GetDescriptionAtAddrWithOffset(Address: ULONG_PTR): string;
procedure GetExportFuncList(const ModuleName: string; Value: TStringList);
end;

implementation

{ TDebugMap }

procedure TDebugMap.Clear;
begin
FItems.Clear;
end;

constructor TDebugMap.Create;
begin
FItems := TList<TDebugMapItem>.Create(
TComparer<TDebugMapItem>.Construct(
function (const A, B: TDebugMapItem): Integer
begin
Result := Integer(A.Address) - Integer(B.Address);
end)
);
end;

destructor TDebugMap.Destroy;
begin
FItems.Free;
inherited;
end;

function TDebugMap.GetDescriptionAtAddr(Address: ULONG_PTR): string;
var
I: Integer;
Item: TDebugMapItem;
begin
Result := '';
Item.Address := Address;
if FItems.BinarySearch(Item, I) then
if I >= 0 then
Result := FItems.List[I].ModuleName + '!' + FItems.List[I].FunctionName;
end;

function TDebugMap.GetDescriptionAtAddrWithOffset(Address: ULONG_PTR): string;
var
I: Integer;
begin
Result := '';
for I := 0 to FItems.Count - 1 do
if FItems.List[I].Address <= Address then
if FItems.List[I].EndAddress > Address then
begin
if FItems.List[I].Address = Address then
Result := FItems.List[I].ModuleName + '!' + FItems.List[I].FunctionName
else
Result := FItems.List[I].ModuleName + '!' + FItems.List[I].FunctionName +
' + 0x' + IntToHex(Address - FItems.List[I].Address, 1);
end;
end;

procedure TDebugMap.GetExportFuncList(const ModuleName: string;
Value: TStringList);
var
I: Integer;
begin
for I := 0 to FItems.Count - 1 do
if FItems[I].ModuleName = ModuleName then
Value.AddObject(FItems[I].FunctionName, Pointer(FItems[I].Address));
end;

procedure TDebugMap.Init(BaseAddress, InstanceAddress: ULONG_PTR; const ModulePath: string);
var
MapFile: TStringList;
SectionDataList: TList<TSectionData>;
I, A, Count, StartPosition, SpacePos, SectionIndex: Integer;
Line: string;
Section: TSectionData;
FoundTable: Boolean;
SectionAddress: DWORD;
DebugMapItem: TDebugMapItem;
begin
StartPosition := FItems.Count;
try
MapFile := TStringList.Create;
try
MapFile.LoadFromFile(ChangeFileExt(ModulePath, '.map'));
DebugMapItem.ModuleName := ExtractFileName(ModulePath);
SectionDataList := TList<TSectionData>.Create;
try
I := 0;
Count := MapFile.Count;

// èùåì íà÷àëî òàáëèöû ñåêöèé
while Copy(Trim(MapFile[I]), 1, 5) <> 'Start' do
begin
Inc(I);
if I = Count then Exit;
end;

// çàïîëíÿåì òàáëèöó ñåêöèé
Inc(I);
if I = Count then Exit;
Line := Trim(MapFile[I]);
while Line <> '' do
begin
Section.Index := StrToInt(Copy(Line, 1, 4));
Delete(Line, 1, 5);
Section.StartAddr := ULONG_PTR(StrToInt('$' + Copy(Line, 1, 8))) - InstanceAddress + BaseAddress;
Delete(Line, 1, 9);
Section.Length := StrToInt('$' + Copy(Line, 1, 8));
SectionDataList.Add(Section);
Inc(I);
if I = Count then Exit;
Line := Trim(MapFile[I]);
end;

// èùåì íà÷àëî òàáëèöû "Publics by Value"
FoundTable := False;
while not FoundTable do
begin
Inc(I);
if I = Count then Exit;
Line := Trim(MapFile[I]);
while Copy(Line, 1, 7) <> 'Address' do
begin
Inc(I);
if I = Count then Exit;
Line := Trim(MapFile[I]);
end;
Delete(Line, 1, 8);
FoundTable := Copy(TrimLeft(Line), 1, 16) = 'Publics by Value';
end;

// ïàðñèì òàáëèöó "Publics by Value"
Inc(I, 2);
if I >= Count then Exit;
Line := Trim(MapFile[I]);
while Line <> '' do
begin
SectionIndex := StrToInt(Copy(Line, 1, 4));
if SectionIndex <> 1 then
begin
Inc(I);
if I = Count then Exit;
Line := Trim(MapFile[I]);
Continue;
end;
SectionAddress := $FFFFFFFF;
for A := 0 to SectionDataList.Count - 1 do
if SectionDataList[A].Index = SectionIndex then
begin
SectionAddress := SectionDataList[A].StartAddr;
DebugMapItem.EndAddress := SectionAddress + SectionDataList[A].Length;
Break;
end;
if SectionAddress = $FFFFFFFF then Continue;
Delete(Line, 1, 5);
DebugMapItem.Address := SectionAddress + NativeUInt(StrToInt('$' + Copy(Line, 1, 8)));
Delete(Line, 1, 9);
Line := TrimLeft(Line);
SpacePos := Pos(' ', Line);
if SpacePos = 0 then
DebugMapItem.FunctionName := Line
else
DebugMapItem.FunctionName := Copy(Line, 1, SpacePos - 1);
FItems.Add(DebugMapItem);
Inc(I);
if I = Count then Exit;
Line := Trim(MapFile[I]);
end;

finally
SectionDataList.Free;
end;
finally
MapFile.Free;
end;

// âûñòàâëÿì ïðàâèëüíûå äëèíû ôóíêöèé
for I := FItems.Count - 1 downto StartPosition + 1 do
FItems.List[I - 1].EndAddress := FItems.List[I].Address;

FItems.Sort;
except
// åñëè íå ñìîãëè ðàñïàðñèòü - âûêèäûâàåì âñå èç ìàññèâà äàííûõ
for I := FItems.Count - 1 downto StartPosition do
FItems.Delete(I);
end;
end;

end.
4 changes: 2 additions & 2 deletions MemoryMap/MemoryMap.PEImage.pas
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
// * Unit Name : MemoryMap.PEImage.pas
// * Purpose : Êëàññ ñîáèðàåò äàííûå ïî ñåêöèÿì è äèðåêòîðèÿì PE ôàéëà
// * Author : Àëåêñàíäð (Rouse_) Áàãåëü
// * Copyright : © Fangorn Wizards Lab 1998 - 2016.
// * Version : 1.0.3
// * Copyright : © Fangorn Wizards Lab 1998 - 2017.
// * Version : 1.0.4
// * Home Page : http://rouse.drkb.ru
// * Home Blog : http://alexander-bagel.blogspot.ru
// ****************************************************************************
Expand Down
Loading

0 comments on commit 23e03a9

Please sign in to comment.