2015-02-06 14 views
3

Delphi 5에서 프로젝트를 빌드하여 생성 된 "Detailed"맵 파일에서 유닛 이름과 함수 이름을 조회하려고합니다. 코드를 온라인으로 작성하지만이 작업을 수행 할 수는 없습니다.어셈블리 언어 및 델파이 맵 파일을 사용하여 함수의 주소를 가져옵니다.

코드 요구 사항 :

  • 델파이 5
  • 한 TForm을
  • 한이 TButton
  • 한은 TEdit
  • 한 TLabel

목표 : 함수 : 'Log'는 호출하는 프로 시저의 주소를 반환합니다. 주소가 결정되면지도 파일에서 단위 및 함수 이름과 줄 번호를 조회 할 수 있습니다.

목적 : 함수의 이름이 어디서든 프로그램에서 '로그인'을 호출하여 바로 얻을 수 있다면 그것이 ... 좋지 않을까.

현실 : 내가 '로그인'기능에서 무슨 일이 일어나고 있는지 학습에 정말 관심이, 그리고이 작동하지 왜 또는 왜,이에 대한 보조가 기기와 기능의 이름을 반환하는 alternitave의 방법이 될 것입니다 호출 프로 시저의 줄 번호뿐 아니라

문제점 : 내가 TForm1.Button1Click에서 얻을 주소> TForm1.Log> TForm1.LogAddress> TForm1.ShowInfo 내가 즉, M = Unit1을 찾고 있어요 맵 파일에서 해당 항목과 일치하지 않습니다, TForm1.Button1Click은, 등등 ...

웹 사이트는 : http://www.haydenr.com/delphi/articles/article002.htm, http://www.experts-exchange.com/Programming/Languages/Pascal/Delphi/Q_22596248.html은 마지막으로 웹 사이트의 링크를 액세스 할 수 없습니다 - 나는 '로그인'기능에 구글 검색 문자열을 넣어.

델파이 코드 :

unit Unit1; 

interface 

uses 
    Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, 
    StdCtrls; 

type 
    TForm1 = class(TForm) 
    Button1: TButton; 
    Label1: TLabel; 
    Edit1: TEdit; 
    procedure Button1Click(Sender: TObject); 
    Procedure Log; 
    Procedure ShowInfo(hexAddress : Integer); 
    Procedure LogAddress(ptr: pointer); 
    private 
    { Private declarations } 
    public 
    { Public declarations } 
    end; 

var 
    Form1: TForm1; 

Implementation 

{$R *.DFM} 

    Procedure TForm1.Log; 
    // Google Search: capturing a procedure or function's name for logging purposes 
    // http://www.experts-exchange.com/Programming/Languages/Pascal/Delphi/Q_22596248.html 
    Begin 
     ASM 
      pop EAX 
      push EAX 
      Call LogAddress 
     End;//ASM 
    End; 

    Procedure TForm1.ShowInfo(hexAddress: Integer); 
    // http://www.haydenr.com/delphi/articles/article002.htm 
    Var 
     iMapFileAddress : Integer; 
     sMapFileAddress : String; 
     ImageBase  : Integer; 
     SubOffset  : Integer; 
     Offset   : Integer; 
    Begin 
     ImageBase := $00400000; // Project > Options... > Linker Tab > Memory sizes group box > Image Base 
     SubOffset := $1000; 
     Offset := ImageBase + SubOffset; 

     iMapFileAddress := hexAddress - Offset; 
     sMapFileAddress := IntToHex(iMapFileAddress,8); 
     Edit1.Text := sMapFileAddress; //This is the value I get: sMapFileAddress = 00542214 
     { 
     Here are some excerpts from: Project1.map 
     |Detailed map of segments 
     | 0001:00040498 000002D4 C=CODE  S=.text G=(none) M=Unit1 ACBP=A9 
     | 0001:0004076C 000001A5 C=CODE  S=.text G=(none) M=Project1 ACBP=A9 
     | : 
     | : 
     | : 
     | Address   Publics by Name 
     | 
     | 0001:0004071C  TForm1.Button1Click 
     | 0001:00040668  TForm1.Log 
     | 0001:00040700  TForm1.LogAddress 
     | 0001:0004067C  TForm1.ShowInfo 
     } 
    End; 

    procedure TForm1.LogAddress(ptr: pointer); 
    begin 
     ShowInfo(Integer(ptr)); 
    end; 

    procedure TForm1.Button1Click(Sender: TObject); 
    begin 
     Log; 
    end; 

end. 

답변

2

당신은 제대로 LogAddress를 호출 아닙니다. TForm1의 방법으로, 이것은 실제로 두 개의 인수를 갖는 함수입니다. 두 인수는 Selfptr이며이 순서대로 EAX는 Self이고 EDX는 ptr입니다. 그러나 EAX에서 address 매개 변수를 전달하면 EDX에 대해 아무 것도하지 않습니다. 즉, 프로그램에서 코드 섹션의 주소가 아닌 사람의 이름을 찾는 것입니다. 그 위에는 Self 값이 더 이상 유효하지 않으므로 멤버 변수에 대한 참조 (예 : Edit1)가 작동하지 않습니다. 액세스 위반이나 어떤 형태의 메모리 손상이 발생합니다.

변경이에 Log 방법 :

procedure TForm1.Log; 
asm 
    // fetch return address from top of stack 
    mov edx, [esp+4] 
    call LogAddress 
end; 

당신이 ptr 매개 변수에 전달하는 주소가 Log 호출의 반환 주소 있음을 유의하십시오. 실제로 이것은 보통 의 주소 인 Log 방법을 사용하기 위해 CALL 명령어를 사용한 것입니다. 따라서 맵 파일의 함수 목록에서 정확한 주소를 찾을 필요는 없습니다. 대신, 당신은 가지고있는 주소를 초과하지 않고 주소가 가장 가까운 함수를 찾아야 할 것입니다. 또한 해당 주소를 회선 번호로 변환하면 실제 전화 사이트 인 뒤에 이 표시 될 수 있습니다.

JclDebug 단위는 the JCL에 이미이 작업을 수행하는 기능이 있습니다. ProcByLevel 함수를 사용하여 호출자의 이름을 가져오고 LiveByLevel을 사용하여 줄 번호를 가져올 수 있습니다.

+0

합니까 JclDebug 작업을 빌드? –

+0

델파이 5가 원격으로 최신 상태였던 때를 되돌아 보았습니다. @Ken. 요즘에는 트렁크를 사용하는 대신 오래된 버전을 체크 아웃해야 할 수도 있습니다. –

+0

그래, 나는 그것이 10 년 반 전 것을 알았다. 나는 아직도 그것을 지금 확실하지 않았다. (델파이 5를 원격으로 지원하는 것은 거의 없으며, 적어도 D7 이상을 필요로한다는 것을 알고 있습니다.) –

1

A는 "파일을지도"생산하기 위해

... 코드 교체를 제작하고, 작업 코드는 다음과 롭 케네디의 제안에 따라 "ESP 오프셋"조정 후, 델파이 IDE에서 다음 단계를 수행

  1. 프로젝트> 옵션 ...> 컴파일러 탭> 코드 생성 창 : 최적화 = FALSE
  2. 창> 링커 탭>지도 파일 창은 프로젝트 옵션 : 선택 "상세 "
  3. 프로젝트> 델파이 5와 함께 모든 프로젝트를

    unit Unit1; 
    
    interface 
    
    uses 
        Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, 
        StdCtrls; 
    
    type 
        TForm1 = class(TForm) 
        Button1: TButton; 
        Label1: TLabel; 
        Edit1: TEdit; 
        procedure Button1Click(Sender: TObject); 
        Procedure Log; 
        Procedure ShowInfo(hexAddress : Integer); 
        Procedure LogAddress(ptr: pointer); 
        private 
        { Private declarations } 
        public 
        { Public declarations } 
        end; 
    
    var 
        Form1: TForm1; 
    
    Implementation 
    
    {$R *.DFM} 
    
        Procedure TForm1.Log; 
        // Google Search: capturing a procedure or function's name for logging purposes 
        // http://www.experts-exchange.com/Programming/Languages/Pascal/Delphi/Q_22596248.html 
        Begin 
         ASM 
          // fetch return address from top of stack 
          mov edx,[esp+8] 
          call LogAddress 
         End;//ASM 
        End; 
    
        Procedure TForm1.ShowInfo(hexAddress: Integer); 
        // http://www.haydenr.com/delphi/articles/article002.htm 
        Var 
         iMapFileAddress : Integer; 
         sMapFileAddress : String; 
         ImageBase  : Integer; 
         SubOffset  : Integer; 
         Offset   : Integer; 
        Begin 
         ImageBase := $00400000; // Project > Options... > Linker Tab > Memory sizes group box > Image Base 
         SubOffset := $1000; 
         Offset := ImageBase + SubOffset; 
    
         iMapFileAddress := hexAddress - Offset; 
         sMapFileAddress := IntToHex(iMapFileAddress,8); 
         Edit1.Text := sMapFileAddress; //This is the value I get: sMapFileAddress = 00040730 
         { 
         |Here are some excerpts from: Project1.map 
         |******************************************************************************************************************* 
         |Detailed map of segments 
         | 0001:00040498 000002D4 C=CODE  S=.text G=(none) M=Unit1 ACBP=A9 
         | 0001:0004076C 000001A5 C=CODE  S=.text G=(none) M=Project1 ACBP=A9 
         | : 
         | : 
         | V 
         | Address   Publics by Name 
         | 
         | 0001:0004071C  TForm1.Button1Click 
         | 0001:00040668  TForm1.Log 
         | 0001:00040700  TForm1.LogAddress 
         | 0001:0004067C  TForm1.ShowInfo 
         | : 
         | : 
         | V 
         |Line numbers for Unit1(Unit1.pas) segment .text 
         | 
         | 82 0001:00040728 83 0001:00040730 85 0001:00040764 85 0001:0004076B 
         |******************************************************************************************************************* 
         | 
         |  Returned Hex (H) = 00040730 
         | Returned Integer (I) = 263984 
         |------------------------------------------------------------------------------------------------------------------- 
         |Address Of    Min Hex  Max Hex  Min Integer Max Integer |    Evaluation 
         |------------------------------------------------------------------------------|------------------------------------ 
         |Unit1      00040498 000406E5 263320   263909  | Hmin < H < Hmax AND Imin < I < Imax 
         |Function/Procedure     0004071C     263964  |  H < Hmax AND   I < Imax 
         |Line Number       00040730     263984  |  H = Hmax AND   I = Imax 
         |------------------------------------------------------------------------------------------------------------------- 
         | 
         |NOTE: The actual line number where 'Log' is called is: Returned Line Number - 1 (83 - 1 = 82) 
         } 
        End; 
    
        procedure TForm1.LogAddress(ptr: pointer); 
        begin 
         ShowInfo(Integer(ptr)); 
        end; 
    
        procedure TForm1.Button1Click(Sender: TObject); 
        begin 
         Log; 
        end; 
    
    end.