亚洲免费人人妻人人,cao78在线视频,福建一级毛片,91精品视频免费观看,高清另类图片操逼,日本特黄特色大片免费看,超碰欧美人人澡曰曰澡夜夜泛

斷點(diǎn)為何失效的簡(jiǎn)單分析 -電腦資料

電腦資料 時(shí)間:2019-01-01 我要投稿
【www.msguai.com - 電腦資料】

    標(biāo) 題:關(guān)于Delphi/BCB程序中GetWindowTextA/GetDlgItemTextA斷點(diǎn)為何失效的簡(jiǎn)單分析 (7千字)

    發(fā)信人:blowfish

    時(shí) 間:2001-12-28 17:02:39

    詳細(xì)信息:

    VCL中標(biāo)準(zhǔn)的單行編輯控件TEdit和多行編輯控件TMemo在類樹(shù)中的派生關(guān)系如下:

    TObject -> TPersistent -> TComponent -> TControl -> TWinControl -> TCustomEdit -> TEdit

    TObject -> TPersistent -> TComponent -> TControl -> TWinControl -> TCustomEdit -> TCustomMemo -> TMemo

    以TEdit為例,來(lái)看一下它是如何獲取控件中的字符串的,把這個(gè)過(guò)程(也就是VCL內(nèi)部處理消息的過(guò)程)搞清楚了,就能夠知道該設(shè)什么樣的斷點(diǎn)來(lái)監(jiān)視這個(gè)獲得字符串的過(guò)程,從而找到我們輸入的注冊(cè)碼在內(nèi)存中的存放位置,進(jìn)而可以通過(guò)BPM/BPR斷點(diǎn)來(lái)跟蹤對(duì)注冊(cè)碼的處理過(guò)程,

斷點(diǎn)為何失效的簡(jiǎn)單分析

。

    TEdit用來(lái)存放字符串的屬性是Text,該屬性繼承自TControl。讀取該屬性的函數(shù)是私有函數(shù)GetText( )。

    (以下代碼來(lái)自VCL的源碼stdctrls.pas、control.pas、system.pas、sysutils.pas)

    //----------------------------------------------------------------------------------------------------

    TWndMethod = procedure(var Message: TMessage) of object;

    TControl = class(TComponent)

    private

    FWindowProc: TWndMethod;

    FText: PChar;

    function GetText: TCaption;

    procedure SetText(const Value: TCaption);

    ......

    protected

    property Text: TCaption read GetText write SetText;

    procedure WndProc(var Message: TMessage); virtual;

    ......

    public

    function GetTextBuf(Buffer: PChar; BufSize: Integer): Integer;

    function GetTextLen: Integer;

    procedure SetTextBuf(Buffer: PChar);

    function Perform(Msg: Cardinal; WParam LParam: Longint): Longint;

    property WindowProc: TWndMethod read FWindowProc write FWindowProc;

    ......

    end;

    //----------------------------------------------------------------------------------------------------

    GetText( )函數(shù)及相關(guān)函數(shù)的定義如下?梢(jiàn),TControl最終是以WM_GETTEXTLENGTH和WM_GETTEXT消息為參數(shù)直接調(diào)WndProc( )的。

    //----------------------------------------------------------------------------------------------------

    function TControl.GetText: TCaption;

    var

    Len: Integer;

    begin

    Len := GetTextLen;

    SetString(Result PChar(nil) Len);

    if Len <> 0 then GetTextBuf(Pointer(Result) Len + 1);

    end;

    function TControl.GetTextLen: Integer;

    begin

    Result := Perform(WM_GETTEXTLENGTH 0 0);

    end;

    function TControl.GetTextBuf(Buffer: PChar; BufSize: Integer): Integer;

    begin

    Result := Perform(WM_GETTEXT BufSize Longint(Buffer));

    end;

    procedure TControl.SetTextBuf(Buffer: PChar);

    begin

    Perform(WM_SETTEXT 0 Longint(Buffer));

    Perform(CM_TEXTCHANGED 0 0);

    end;

    procedure TControl.SetText(const Value: TCaption);

    begin

    if GetText <> Value then SetTextBuf(PChar(Value));

    end;

    function TControl.Perform(Msg: Cardinal; WParam LParam: Longint): Longint;

    var

    Message: TMessage;

    begin

    Message.Msg := Msg;

    Message.WParam := WParam;

    Message.LParam := LParam;

    Message.Result := 0;

    if Self <> nil then WindowProc(Message);

    Result := Message.Result;

    end;

    constructor TControl.Create(AOwner: TComponent);

    begin

    inherited Create(AOwner);

    FWindowProc := WndProc;

    ......

    end;

    //----------------------------------------------------------------------------------------------------

    WndProc( )是個(gè)virtual函數(shù)。TEdit和TCustomEdit未重載這個(gè)函數(shù),而TWinControl重載了這個(gè)函數(shù),但它并未處理WM_GETTEXT消息,而是直接把該消息傳遞給了父類的函數(shù)TControl.WndProc( )。

    //----------------------------------------------------------------------------------------------------

    procedure TWinControl.WndProc(var Message: TMessage);

    var

    Form. TCustomForm;

    KeyState: TKeyboardState;

    WheelMsg: TCMMouseWheel;

    begin

    ......

    inherited WndProc(Message);

    end;

    //----------------------------------------------------------------------------------------------------

    TControl.WndProc( )直接用Dispatch( )來(lái)分發(fā)該消息,

電腦資料

斷點(diǎn)為何失效的簡(jiǎn)單分析》(http://www.msguai.com)。

    //----------------------------------------------------------------------------------------------------

    procedure TControl.WndProc(var Message: TMessage);

    var

    Form. TCustomForm;

    begin

    ......

    Dispatch(Message);

    end;

    //----------------------------------------------------------------------------------------------------------

    由于WM_GETTEXT在TEdit中沒(méi)有對(duì)應(yīng)的專門的處理函數(shù),所以Dispatch( )最終會(huì)調(diào)用TEdit.DefaultHandler( ),這個(gè)方法是從TCustomEdit繼承來(lái)的,如此層層向上往父類分發(fā),直到TControl.DefaultHandler( )對(duì)WM_GETTEXT消息進(jìn)行了處理,它只是簡(jiǎn)單地把TControl的私有變量FText拷貝到軟件提供的緩沖區(qū)中,所用到的函數(shù)只有StrLen( )、StrLCopy( )。

    //----------------------------------------------------------------------------------------------------------

    procedure TControl.DefaultHandler(var Message);

    var

    P: PChar;

    begin

    with TMessage(Message) do

    case Msg of

    WM_GETTEXT:

    begin

    if FText <> nil then P := FText else P := '';

    Result := StrLen(StrLCopy(PChar(LParam) P WParam - 1));

    end;

    WM_GETTEXTLENGTH:

    if FText = nil then Result := 0 else Result := StrLen(FText);

    WM_SETTEXT:

    begin

    P := StrNew(PChar(LParam));

    StrDispose(FText);

    FText := P;

    SendDockNotification(Msg WParam LParam);

    end;

    end;

    end;

    //----------------------------------------------------------------------------------------------------------

    看一下sysutils.pas中的StrLen( )、StrLCopy( )函數(shù)的實(shí)現(xiàn),是用匯編寫的,沒(méi)有調(diào)用任何API函數(shù)。這就說(shuō)明從進(jìn)入TControl.GetText( )開(kāi)始,一直到WM_GETTEXT成功返回為止,沒(méi)有調(diào)用過(guò)任何Win32 API函數(shù)。所以常用的GetDlgItemTextA、GetWindowTextA斷點(diǎn)不生效是當(dāng)然的。

    //----------------------------------------------------------------------------------------------------------

    function StrLen(const Str: PChar): Cardinal; assembler;

    asm

    MOV EDXEDI

    MOV EDIEAX

    MOV ECX0FFFFFFFFH

    XOR ALAL

    REPNE SCASB

    MOV EAX0FFFFFFFEH

    SUB EAXECX

    MOV EDIEDX

    end;

    function StrLCopy(Dest: PChar; const Source: PChar; MaxLen: Cardinal): PChar; assembler;

    asm

    PUSH EDI

    PUSH ESI

    PUSH EBX

    MOV ESIEAX

    MOV EDIEDX

    MOV EBXECX

    XOR ALAL

    TEST ECXECX

    JZ @@1

    REPNE SCASB

    JNE @@1

    INC ECX

    @@1: SUB EBXECX

    MOV EDIESI

    MOV ESIEDX

    MOV EDXEDI

    MOV ECXEBX

    SHR ECX2

    REP MOVSD

    MOV ECXEBX

    AND ECX3

    REP MOVSB

    STOSB

    MOV EAXEDX

    POP EBX

    POP ESI

    POP EDI

    end;

    //-------------------------------------------------------------------------------------------------------

    那么如何才能在VCL將用戶輸入的字符串拷貝到軟件的緩沖區(qū)中時(shí)使SoftICE彈出來(lái)呢?一種辦法是先在軟件的內(nèi)存中搜索StrLCopy( )這個(gè)函數(shù)的機(jī)器碼(即其Signature),找到之后在其入口處設(shè)個(gè)斷點(diǎn)即可。實(shí)際上,你也可以在TControl.DefaultHandler( )、TControl.GetText( )等函數(shù)的入口處設(shè)斷點(diǎn),只要VCL在獲取TEdit.Text的過(guò)程中調(diào)用了該函數(shù),當(dāng)然調(diào)用的次數(shù)越少越好。

    另外一種方法就是跟蹤FText何時(shí)被賦值,實(shí)際上就在上面的WM_SETTEXT處。

    blowfish

    --------------------------------------------------------------------------------

最新文章