Jump to content

pudnivec

Members
  • Content Count

    13
  • Joined

  • Last visited

Posts posted by pudnivec


  1. Finally, I used your code from GitHub (https://github.com/Fr0sT-Brutal/Delphi_StackTraces), in which I took the liberty to make a few changes to account for dynamic address changes when using e.g. ASLR.

     

    Added MapAddrOffset: Pointer to variables

    var
      MapFileAvailable: Boolean;
      LineAddrs: TArray<TMapFileLineAddrInfo>;
      PublicAddrs: TArray<TMapFilePublicAddrInfo>;
      MapAddrOffset: Pointer;

     

    Added the output for MapAddrOffest: Pointer to the ReadMapFile procedure.

    procedure ReadMapFile(const MapFile: string; out LineAddrs: TArray<TMapFileLineAddrInfo>;
      out PublicAddrs: TArray<TMapFilePublicAddrInfo>; out MapAddrOffset: Pointer);
    var
      arr: TStrArray;
      CurrIdx, HighArr: Integer;
      UnitName: string;
      SegmentInfo: TMapFileSegmentStartAddrs;
    begin
      LineAddrs:= nil;
      PublicAddrs:= nil;
    
      arr:= Split(MapFile, NL);
      CurrIdx:= Low(arr);
    
      ReadSegments(arr, CurrIdx, SegmentInfo);
      ReadPublics(arr, CurrIdx, SegmentInfo, PublicAddrs);
    
      //Get MAP address offset
      MapAddrOffset:= SegmentInfo[1];
      .
      .
      .
      .
      end;

     

    Added new function GetOrigMapProcAddress(AName: string): Pointer.

    function GetOrigMapProcAddress(AName: string): Pointer;
    var
      i: Integer;
      uRes: UInt64;
    begin
      Result:= Pointer(0);
    
      for i:= Low(PublicAddrs) to High(PublicAddrs) do
        begin
          if PublicAddrs[i].Name.Equals(AName) then
            begin
              uRes:= UInt64(PublicAddrs[i].Addr) - UInt64(MapAddrOffset);
    
              if uRes > High(NativeUInt) then
                uRes:= 0;
    
              Result:= Pointer(uRes);
    
              Break;
            end;
        end;
    end;


    Added new overloaded function GetAddrInfo(Addr, RealAddrOffset: Pointer; out AddrInfo: TMapFileAddrInfo): Boolean.

    function GetAddrInfo(Addr, RealAddrOffset: Pointer; out AddrInfo: TMapFileAddrInfo): Boolean; overload;
    var
      uRes: UInt64;
    begin
      uRes:= UInt64(Addr) - UInt64(RealAddrOffset) + UInt64(MapAddrOffset);
    
      if uRes > High(NativeUInt) then
        uRes:= 0;
    
      if not MapFileAvailable
        then Result:= False
        else Result:= GetAddrInfo(Pointer(uRes), LineAddrs, PublicAddrs, AddrInfo);
    end;

     

    Now it is enough to use this code in any application (including service app), which uses dynamic address change e.g. ASLR.

     

    To demonstrate the functionality I used the code from the service app:

    var
      RealAddressOffset: Pointer;
    
    function TMainService.GetRealAddressOffset: Pointer;
    var
      uRes: UInt64;
    begin
      uRes:= UInt64(MethodAddress('ServiceStart')) - UInt64(GetOrigMapProcAddress(UnitName + '.' + ClassName + '.ServiceStart'));
    
      if uRes > High(NativeUInt) then
        uRes:= 0;
    	  
      Result:= Pointer(uRes);	
    end;
    
    function TMainService.GetAddressInfo(AAddress: Pointer): string;
    var
      tmpAddrInfo: TMapFileAddrInfo;
    begin
      GetAddrInfo(AAddr, RealAddressOffset, tmpAddrInfo);
      Result:= AddrInfoToString(tmpAddrInfo);
    end;

    Then just call this function e.g. as follows:

    GetAddressInfo(GetCurrentAddress);

     

    • Thanks 1

  2. Interestingly, if I use your function

    function GetMethodName(AClass: TClass; Address: Pointer): string;

    which does not read data from the MAP file, with the same generated address pointer by MethodAddress, the correct method name is returned from the service app (but only for main class, not for private and public section).


    This indicates that most likely a bad MAP file is generated for the service app.


  3. I may have misspoken in my last post. 

    The address of the method (procedure) does not change for the compiled service. It is still the same.

    What does change is the difference in subtraction for different procedures - see the following examples:
     

     0001:003561A0       Unit1.TMainService.ServiceStart  (MAP file address: 003561A0, service address (used with MethodAddress('ServiceStart') function): 004C71A0, 004C71A0 - 003561A0 =  171000 HEX (1.511,424 DEC)
     0001:003576E0       Unit1.TMainService.ServiceStop   (MAP file address: 003576C0, service address (used with MethodAddress('ServiceStop') function):  004C86E0, 004C86E0 - 003576C0 =  171020 HEX (1.511.456 DEC)

    * I used the MethodAddress function only for the purpose of this post, because it refers to the address of the beginning of the method (procedure).

    Interestingly, for procedure Unit1.TMainService.ServiceStart the difference between MAP file and service is 171000 HEX (1.511.424 DEC), but for procedure Unit1.TMainService.ServiceStop the difference is 171020 HEX (1.511.456 DEC).
    The difference in both cases should be 401000 HEX (4.198.400 DEC) as indicated in the service MAP file.
     

     Start	       Length    Name   Class
     0001:00401000 0036EB7CH .text  CODE
     0002:00770000 0004E840H .data  DATA
     0003:007BF000 0000D4CCH .bss   BSS
     0004:00000000 00000280H .tls   TLS
     0005:00804000 00031710H .pdata PDATA

    For the classic application on the same machine the difference is 401000 HEX (4.198.400 DEC) for all mathods (procedures) as shown in the MAP file.


  4. The generated method address does not match (after or without 401000 HEX subtraction) adress of method in MAP file. Interestingly, the difference is different for each method (procedure).

     

    The MAP file service contains the same offset as the classic 401000 HEX application.

     Start	       Length    Name   Class
     0001:00401000 0036EB7CH .text  CODE
     0002:00770000 0004E840H .data  DATA
     0003:007BF000 0000D4CCH .bss   BSS
     0004:00000000 00000280H .tls   TLS
     0005:00804000 00031710H .pdata PDATA

    Could it be that the MAP file is generated incorrectly?

     

    PS: The settings for both applications are exactly the same, including the compilation settings


  5. Thank you for your answers.

    The problem is that when I use the MAP file (detailed mode), different method addresses are listed: in APP the address is [007B6B90: frmMain->Button9Click] (own generated string with IntToHex(NativeInt(Address: Pointer - generated with ReturnAddress), 8)) and in MAP [003B5B90 frmMain.TFormMain.Button9Click] - 007B6B90 vs 003B5B90   :-(

×