Skip to content

Commit

Permalink
1.0.0 a12
Browse files Browse the repository at this point in the history
Добавлена поддержка всех типов отладочных МАР файлов (Delphi 2 и выше,
MS VC++)
Добавлен вывод подсказок для CALL вызовов через таблицу импорта
  • Loading branch information
AlexanderBagel committed Mar 7, 2017
1 parent 85fd8e5 commit 2011df9
Show file tree
Hide file tree
Showing 13 changed files with 320 additions and 443 deletions.
8 changes: 3 additions & 5 deletions MemoryMap/MemoryMap.Core.pas
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
// * Purpose : Áàçîâûé êëàññ ñîáèðàþùèé èíôîðìàöèþ î êàðòå ïàìÿòè ïðîöåññà
// * Author : Àëåêñàíäð (Rouse_) Áàãåëü
// * Copyright : © Fangorn Wizards Lab 1998 - 2017.
// * Version : 1.0.3
// * Version : 1.0.4
// * Home Page : http://rouse.drkb.ru
// * Home Blog : http://alexander-bagel.blogspot.ru
// ****************************************************************************
Expand Down Expand Up @@ -317,7 +317,6 @@ procedure TMemoryMap.GetAllRegions;
Shared: Boolean;
SharedCount: Byte;
Module: TModule;
OriginalImageBase: ULONG_PTR;
begin
FRegions.Clear;
FRegionFilters.Clear;
Expand Down Expand Up @@ -368,7 +367,7 @@ procedure TMemoryMap.GetAllRegions;
// Åñëè äà, çàïîìèíàåì åãî ïóòü
RegionData.SetDetails(Module.Path);
// Ïðîâåðÿåì, ÿâëÿåòñÿ ëè ôàéë èñïîëíÿåìûì?
if CheckPEImage(FProcess, MBI.BaseAddress, OriginalImageBase) then
if CheckPEImage(FProcess, MBI.BaseAddress) then
begin
// Åñëè ÿâëÿåòñÿ - çàïîìèíàåì åãî â ñïèñêå ìîäóëåé
Module.BaseAddr := ULONG_PTR(MBI.BaseAddress);
Expand All @@ -379,8 +378,7 @@ procedure TMemoryMap.GetAllRegions;
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);
DebugMapData.Init(ULONG_PTR(MBI.BaseAddress), Module.Path);
end;
end;

Expand Down
84 changes: 60 additions & 24 deletions MemoryMap/MemoryMap.DebugMapData.pas
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
// * Purpose : Êëàññ äëÿ ðàáîòû ñ îòëàäî÷íûì MAP ôàéëîì.
// * Author : Àëåêñàíäð (Rouse_) Áàãåëü
// * Copyright : © Fangorn Wizards Lab 1998 - 2017.
// * Version : 1.0.0
// * Version : 1.0.1
// * Home Page : http://rouse.drkb.ru
// * Home Blog : http://alexander-bagel.blogspot.ru
// ****************************************************************************
Expand Down Expand Up @@ -46,14 +46,17 @@ TSectionData = record
constructor Create;
destructor Destroy; override;
procedure Clear;
procedure Init(BaseAddress, InstanceAddress: ULONG_PTR; const ModulePath: string);
procedure Init(BaseAddress: 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

uses
MemoryMap.PEImage;

{ TDebugMap }

procedure TDebugMap.Clear;
Expand Down Expand Up @@ -117,12 +120,13 @@ procedure TDebugMap.GetExportFuncList(const ModuleName: string;
Value.AddObject(FItems[I].FunctionName, Pointer(FItems[I].Address));
end;

procedure TDebugMap.Init(BaseAddress, InstanceAddress: ULONG_PTR; const ModulePath: string);
procedure TDebugMap.Init(BaseAddress: ULONG_PTR; const ModulePath: string);
var
PEImage: TPEImage;
MapFile: TStringList;
SectionDataList: TList<TSectionData>;
I, A, Count, StartPosition, SpacePos, SectionIndex: Integer;
Line: string;
Line, SectionName, SectionClass: string;
Section: TSectionData;
FoundTable: Boolean;
SectionAddress: DWORD;
Expand All @@ -136,31 +140,63 @@ procedure TDebugMap.Init(BaseAddress, InstanceAddress: ULONG_PTR; const ModulePa
DebugMapItem.ModuleName := ExtractFileName(ModulePath);
SectionDataList := TList<TSectionData>.Create;
try
I := 0;
Count := MapFile.Count;
PEImage := TPEImage.Create(0, False);
try
PEImage.GetInfoFromImage(ModulePath, nil, 0);

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

// çàïîëíÿåì òàáëèöó ñåêöèé
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);
// èùåì íà÷àëî òàáëèöû ñåêöèé
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, 24);
Line := TrimLeft(Line);
SpacePos := Pos(' ', Line);
if SpacePos = 0 then Continue;
SectionName := Copy(Line, 1, SpacePos - 1);
Delete(Line, 1, SpacePos);

// â ñòàðûõ âåðñèÿõ äåëüôè â ÐÅ ôàéëå èìÿ ñåêöèè íàçûâàëîñü ïî èìåíè åå êëàññà
// ïîýòîìó áóäåì èñêàòü ïðàâèëüíóþ ñåêöèþ îïèðàÿñü íà ýòîò ìîìåíò
SectionClass := TrimLeft(Line);

// óáèðàåì äåêîðèðîâàíèå (MS VC++ Debug MAP)
SpacePos := Pos('$', SectionName);
if SpacePos > 0 then
SectionName := Copy(SectionName, 1, SpacePos - 1);

// åñëè ñåêöèÿ ñîäåðæèò êîä, çàíîñèì åå â ñïèñîê
for A := 0 to PEImage.Sections.Count - 1 do
if (PEImage.Sections[A].Caption = ShortString(SectionName)) or
(PEImage.Sections[A].Caption = ShortString(SectionClass)) then
begin
if PEImage.Sections[A].IsCode then
begin
Section.StartAddr := PEImage.Sections[A].Address + BaseAddress;
Section.Length := PEImage.Sections[A].Size;
SectionDataList.Add(Section);
end;
Break;
end;

Inc(I);
if I = Count then Exit;
Line := Trim(MapFile[I]);
end;
finally
PEImage.Free;
end;

// èùåì íà÷àëî òàáëèöû "Publics by Value"
Expand Down
5 changes: 3 additions & 2 deletions MemoryMap/MemoryMap.PEImage.pas
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
// * Purpose : Êëàññ ñîáèðàåò äàííûå ïî ñåêöèÿì è äèðåêòîðèÿì PE ôàéëà
// * Author : Àëåêñàíäð (Rouse_) Áàãåëü
// * Copyright : © Fangorn Wizards Lab 1998 - 2017.
// * Version : 1.0.4
// * Version : 1.0.5
// * Home Page : http://rouse.drkb.ru
// * Home Blog : http://alexander-bagel.blogspot.ru
// ****************************************************************************
Expand Down Expand Up @@ -242,7 +242,8 @@ procedure TPEImage.GetInfoFromImage(const FileName: string; ImageBase: Pointer;
FEntryPoints.Add(Pointer(NativeUInt(ImageBase) +
FImageInfo.FileHeader.OptionalHeader.AddressOfEntryPoint));
EnumSections;
EnumDirectoryes;
if FProcessHandle <> 0 then
EnumDirectoryes;
finally
UnMapAndLoad(@FImageInfo);
end;
Expand Down
64 changes: 62 additions & 2 deletions MemoryMap/MemoryMap.Symbols.pas
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ TSymbols = class
function GetDescriptionAtAddr(Address, BaseAddress: ULONG_PTR;
const ModuleName: string): string; overload;
function GetDescriptionAtAddr(Address: ULONG_PTR): string; overload;
function GetDescriptionAtAddr2(Address, BaseAddress: ULONG_PTR;
const ModuleName: string): string;
procedure GetExportFuncList(const ModuleName: string;
BaseAddress: ULONG_PTR; Value: TStringList);
end;
Expand Down Expand Up @@ -160,7 +162,7 @@ function TSymbols.GetDescriptionAtAddr(Address: ULONG_PTR): string;
Result := ExtractFileName(FModuleName) + '!' + Result;
end;

function TSymbols.GetDescriptionAtAddr(Address, BaseAddress: ULONG_PTR;
function TSymbols.GetDescriptionAtAddr2(Address, BaseAddress: ULONG_PTR;
const ModuleName: string): string;
const
{$IFDEF WIN64}
Expand Down Expand Up @@ -188,13 +190,71 @@ function TSymbols.GetDescriptionAtAddr(Address, BaseAddress: ULONG_PTR;
nil, BaseAddress, 0);
try
if SymGetSymFromAddr(FProcess, Address, @Displacement, Symbol) then
Result := string(PAnsiChar(@(Symbol^).Name[0])) + ' + 0x' + IntToHex(Displacement, 4)
begin
if Displacement = 0 then
Result := string(PAnsiChar(@(Symbol^).Name[0]));
end
else
begin
// ñ ïåðâîé ïîïûòêè ìîæåò è íå ïîëó÷èòüñÿ
SymLoadModule(FProcess, 0, PAnsiChar(AnsiString(ModuleName)), nil, BaseAddress, 0);
if SymGetSymFromAddr(FProcess, Address, @Displacement, Symbol) then
if Displacement = 0 then
Result := string(PAnsiChar(@(Symbol^).Name[0]));
end;
finally
SymUnloadModule(FProcess, BaseAddress);
end;
finally
FreeMem(Symbol);
end;
if Result <> '' then
Result := ExtractFileName(ModuleName) + '!' + Result;
end;

function TSymbols.GetDescriptionAtAddr(Address, BaseAddress: ULONG_PTR;
const ModuleName: string): string;
const
{$IFDEF WIN64}
SizeOfStruct = SizeOf(TImagehlpSymbol64);
MaxNameLength = BuffSize - SizeOfStruct;
var
Symbol: PImagehlpSymbol64;
Displacement: DWORD64;
{$ELSE}
SizeOfStruct = SizeOf(TImagehlpSymbol);
MaxNameLength = BuffSize - SizeOfStruct;
var
Symbol: PImagehlpSymbol;
Displacement: DWORD;
{$ENDIF}
begin
Result := '';
if not FInited then Exit;
GetMem(Symbol, BuffSize);
try
Symbol^.SizeOfStruct := SizeOfStruct;
Symbol^.MaxNameLength := MaxNameLength;
Symbol^.Size := 0;
SymLoadModule(FProcess, 0, PAnsiChar(AnsiString(ModuleName)),
nil, BaseAddress, 0);
try
if SymGetSymFromAddr(FProcess, Address, @Displacement, Symbol) then
begin
if Displacement = 0 then
Result := string(PAnsiChar(@(Symbol^).Name[0]))
else
Result := string(PAnsiChar(@(Symbol^).Name[0])) + ' + 0x' + IntToHex(Displacement, 4);
end
else
begin
// ñ ïåðâîé ïîïûòêè ìîæåò è íå ïîëó÷èòüñÿ
SymLoadModule(FProcess, 0, PAnsiChar(AnsiString(ModuleName)), nil, BaseAddress, 0);
if SymGetSymFromAddr(FProcess, Address, @Displacement, Symbol) then
if Displacement = 0 then
Result := string(PAnsiChar(@(Symbol^).Name[0]))
else
Result := string(PAnsiChar(@(Symbol^).Name[0])) + ' + 0x' + IntToHex(Displacement, 4);
end;
finally
SymUnloadModule(FProcess, BaseAddress);
Expand Down
32 changes: 2 additions & 30 deletions MemoryMap/MemoryMap.Utils.pas
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
// * Purpose : Ðàçëè÷íûå âñïîìîãàòåëüíûå ïðîöåäóðû è ôóíêöèè
// * Author : Àëåêñàíäð (Rouse_) Áàãåëü
// * Copyright : © Fangorn Wizards Lab 1998 - 2017.
// * Version : 1.01
// * Version : 1.02
// * Home Page : http://rouse.drkb.ru
// * Home Blog : http://alexander-bagel.blogspot.ru
// ****************************************************************************
Expand Down Expand Up @@ -35,9 +35,7 @@ interface
function CheckAddr(Value: Pointer): Boolean; overload;
function IsExecute(const Value: DWORD): Boolean;
function IsWrite(const Value: DWORD): Boolean;
function CheckPEImage(hProcess: THandle; ImageBase: Pointer): Boolean; overload;
function CheckPEImage(hProcess: THandle; ImageBase: Pointer;
out RealImageBase: ULONG_PTR): Boolean; overload;
function CheckPEImage(hProcess: THandle; ImageBase: Pointer): Boolean;

type
TProcessLockHandleList = TList<THandle>;
Expand Down Expand Up @@ -216,45 +214,19 @@ function IsWrite(const Value: DWORD): Boolean;
end;

function CheckPEImage(hProcess: THandle; ImageBase: Pointer): Boolean;
var
RealImageBase: ULONG_PTR;
begin
Result := CheckPEImage(hProcess, ImageBase, RealImageBase);
end;

function CheckPEImage(hProcess: THandle; ImageBase: Pointer;
out RealImageBase: ULONG_PTR): Boolean;
var
ReturnLength: NativeUInt;
IDH: TImageDosHeader;
NT: TImageNtHeaders;
Header32: TImageNtHeaders32;
Header64: TImageNtHeaders64;
begin
Result := False;
RealImageBase := 0;
if not ReadProcessMemory(hProcess, ImageBase,
@IDH, SizeOf(TImageDosHeader), ReturnLength) then Exit;
if IDH.e_magic <> IMAGE_DOS_SIGNATURE then Exit;
ImageBase := Pointer(NativeInt(ImageBase) + IDH._lfanew);
if not ReadProcessMemory(hProcess, ImageBase,
@NT, SizeOf(TImageNtHeaders), ReturnLength) then Exit;
Result := NT.Signature = IMAGE_NT_SIGNATURE;
if Result then
begin
if NT.FileHeader.Machine = IMAGE_FILE_MACHINE_I386 then
begin
if not ReadProcessMemory(hProcess, ImageBase,
@Header32, SizeOf(TImageNtHeaders32), ReturnLength) then Exit;
RealImageBase := Header32.OptionalHeader.ImageBase;
end
else
begin
if not ReadProcessMemory(hProcess, ImageBase,
@Header64, SizeOf(TImageNtHeaders64), ReturnLength) then Exit;
RealImageBase := Header64.OptionalHeader.ImageBase;
end;
end;
end;

function SuspendProcess(PID: DWORD): TProcessLockHandleList;
Expand Down
Loading

0 comments on commit 2011df9

Please sign in to comment.