?? unit2.pas
字號:
unit unit2;
interface
uses
SysUtils, WinTypes,WINPROCS, Messages, Classes, Graphics, Controls,
StdCtrls, Dialogs;
const
MAXBUF=100;
MAXFUN=2;
function TextHookCreate:boolean;export;
function TextHookFree:boolean;export;
function checkbuf(buf:pchar):boolean;export;
procedure HookTextOut;
procedure unHookTextOut;
procedure HookExTextOut;
procedure unHookExTextOut;
var
OldAddr,NewAddr:array[0..MAXFUN-1,0..4] of byte;
already:array[0..MAXFUN-1]of boolean;
s:array[0..MAXBUF] of char;
implementation
function min(a,b:integer):integer;
begin
if a>=b then result:=a
else result:=b;
end;
function max(a,b:integer):integer;
begin
if a<=b then result:=a
else result:=b;
end;
function checkbuf(buf:pchar):boolean;
var
A:array[0..50] of char;
r:boolean;
begin
asm
{保存段、寄存器的值}
push es
push ds
pusha
push ax
mov ax,seg oldaddr[0]
mov ds,ax
mov es,ax
pop ax
end;
{拷貝緩沖區數據到輸出緩沖區中}
strlcopy(buf,@s[0],MAXBUF);
{非空數據}
r:=s[0]<>#0;
asm
popa
pop ds
pop es
end;
result:=r;
end;
function MyTextOut( hdc:HDC; x:integer; y:integer; Str:PChar; count:integer):boolean;far;
var
poOri:longint;
size:TSize;
poDC, poText, poMouse: TPoint;
begin
asm
{保存段、寄存器}
push es
push ds
pusha
push ax
mov ax,seg oldaddr[0]
mov ds,ax
mov es,ax
pop ax
end;
{設置文件顏色}
{ SetTextColor(hDC,RGB(255,0,0)); }
{恢復函數入口}
unHookTextOut;
{調用默認的顯示函數}
Result := TextOut(hDC, X, Y,Str,count);
{修改函數入口}
HookTextOut;
{取HDC坐標}
poOri:=GetDCOrg(hDC);
poDC.x := X;
poDC.y := Y;
{局部邏輯坐標轉化為設備相關坐標}
LPToDP(hDC, poDC, 1);
{獲取當前鼠標的坐標}
GetCursorPos(poMouse);
poText.x := poDC.x + LoWord(poOri);
poText.y := poDC.y + HiWord(poOri);
{獲取對齊屬性}
if (GetTextAlign(hDC) and TA_UPDATECP) <> 0 then
begin
GetCurrentPositionEx(hDC, @poOri);
poText.x := poText.x + LoWord(poOri);
poText.y := poText.y + HiWord(poOri);
end;
{取得要輸出的字符串的實際顯示大小}
GetTextExtentPoint(hDC, Str, Count, Size);
{鼠標是否在文本的范圍內}
if (count<>0)and (poMouse.x >= poText.x) and (poMouse.x <= poText.x + Size.cx) and
(poMouse.y >= poText.y) and (poMouse.y <= poText.y + Size.cy) then
begin
strlcopy(@s[0],str,count);
end;
asm
popa
pop ds
pop es
end;
end;
function MyExtTextOut(hDC: HDC; X, Y: Integer; Options: Word; Rect: PRect; Str: PChar; Count: Word; Dx: PInteger):
Boolean;far;
var
poOri:longint;
size:TSize;
poDC, poText, poMouse: TPoint;
begin
asm
push es
push ds
pusha
push ax
mov ax,seg oldaddr[1]
mov ds,ax
mov es,ax
pop ax
end;
{ SetTextColor(hDC,RGB(255,0,0)); }
{恢復函數入口}
UnHookExTextOut;
{調用默認的輸出顯示函數}
Result := ExtTextOut(hDC,x,y,Options,Rect,str,count,Dx);
HookExTextOut;
{取HDC坐標}
poOri:=GetDCOrg(hDC);
poDC.x := X;
poDC.y := Y;
{局部邏輯坐標轉化為設備相關坐標}
LPToDP(hDC, poDC, 1);
{獲取當前鼠標的坐標}
GetCursorPos(poMouse);
poText.x := poDC.x + LoWord(poOri);
poText.y := poDC.y + HiWord(poOri);
{獲取對齊屬性}
if (GetTextAlign(hDC) and TA_UPDATECP) <> 0 then
begin
GetCurrentPositionEx(hDC, @poOri);
poText.x := poText.x + LoWord(poOri);
poText.y := poText.y + HiWord(poOri);
end;
{取得要輸出的字符串的實際顯示大小}
GetTextExtentPoint(hDC, Str, Count, Size);
{鼠標是否在文本的范圍內}
if (count<>0)and (poMouse.x >= poText.x) and (poMouse.x <= poText.x + Size.cx) and
(poMouse.y >= poText.y) and (poMouse.y <= poText.y + Size.cy) then
begin
strlcopy(@s[0],str,count);
end;
asm
popa
pop ds
pop es
end;
end;
procedure HookTextOut;
var
segment,offset, DsSegment, NewSegment,NewOffset:Word;
begin
asm
push es
push ds
pusha
push ax
mov ax,seg oldaddr[0]
mov ds,ax
mov es,ax
pop ax
end;
if not already[0] then
begin
Segment:=Seg(TextOut);
Offset:=Ofs(TextOut);
DsSegment:=AllocCStoDSAlias(Segment);
OldAddr[0][0]:=PByte(Ptr(DsSegment,Offset+0))^;
OldAddr[0][1]:=PByte(Ptr(DsSegment,Offset+1))^;
OldAddr[0][2]:=PByte(Ptr(DsSegment,Offset+2))^;
OldAddr[0][3]:=PByte(Ptr(DsSegment,Offset+3))^;
OldAddr[0][4]:=PByte(Ptr(DsSegment,Offset+4))^;
NewSegment:=Seg(MyTextOut);
NewOffset:=Ofs(MyTextOut);
{修改入口為跳轉到新的函數入口}
NewAddr[0][0]:=$EA;
NewAddr[0][1]:=Lo(NewOffset);
NewAddr[0][2]:=Hi(NewOffset);
NewAddr[0][3]:=Lo(NewSegment);
NewAddr[0][4]:=Hi(NewSegment);
PByte(Ptr(DsSegment,Offset))^:=NewAddr[0][0];
PByte(Ptr(DsSegment,Offset+1))^:=NewAddr[0][1];
PByte(Ptr(DsSegment,Offset+2))^:=NewAddr[0][2];
PByte(Ptr(DsSegment,Offset+3))^:=NewAddr[0][3];
PByte(Ptr(DsSegment,Offset+4))^:=NewAddr[0][4];
already[0]:=true;
FreeSelector(DsSegment);
end;
end;
procedure HookExTextOut;
var
segment,Exoffset,ExDsSegment,ExNewSegment,ExNewOffset:Word;
begin
asm
push es
push ds
pusha
push ax
mov ax,seg oldaddr[1]
mov ds,ax
mov es,ax
pop ax
end;
if not already[1] then
begin
{獲取段基地址}
Segment:=Seg(EXTTextOut);
{段偏移量}
ExOffset:=Ofs(EXTTextOut);
{取與代碼段有相同基址的可寫數據段別名}
ExDsSegment:=AllocCStoDSAlias(Segment);
{保存原函數要替換的頭幾個字節}
OldAddr[1][0]:=PByte(Ptr(ExDsSegment,ExOffset+0))^;
OldAddr[1][1]:=PByte(Ptr(ExDsSegment,ExOffset+1))^;
OldAddr[1][2]:=PByte(Ptr(ExDsSegment,ExOffset+2))^;
OldAddr[1][3]:=PByte(Ptr(ExDsSegment,ExOffset+3))^;
OldAddr[1][4]:=PByte(Ptr(ExDsSegment,ExOffset+4))^;
{獲取段基地址}
ExNewSegment:=Seg(MyExtTextOut);
{段偏移量}
ExNewOffset:=Ofs(MyExtTextOut);
{取自定義函數的地址}
NewAddr[1][0]:=$EA;
NewAddr[1][1]:=Lo(ExNewOffset);
NewAddr[1][2]:=Hi(ExNewOffset);
NewAddr[1][3]:=Lo(ExNewSegment);
NewAddr[1][4]:=Hi(ExNewSegment);
{修改指定Windows函數的前幾個字節}
PByte(Ptr(ExDsSegment,ExOffset))^:=NewAddr[1][0];
PByte(Ptr(ExDsSegment,ExOffset+1))^:=NewAddr[1][1];
PByte(Ptr(ExDsSegment,ExOffset+2))^:=NewAddr[1][2];
PByte(Ptr(ExDsSegment,ExOffset+3))^:=NewAddr[1][3];
PByte(Ptr(ExDsSegment,ExOffset+4))^:=NewAddr[1][4];
already[1]:=true;
{釋放段}
FreeSelector(ExDsSegment);
end;
asm
popa
pop ds
pop es
end;
end;
procedure unHookTextOut;
var
segment,offset,Exoffset,DsSegment,ExDsSegment:word;
begin
asm
{保存段寄存器和段的內容}
push es
push ds
pusha
push ax
mov ax,seg oldaddr[0]
mov ds,ax
mov es,ax
pop ax
end;
{處于取詞狀態}
if already[0] then
begin
{函數的段基址}
Segment:=Seg(TextOut);
{函數的偏移}
Offset:=Ofs(TextOut);
{取與代碼段有相同基址的可寫數據段別名}
DsSegment:=AllocCStoDSAlias(Segment);
{改回原windows函數}
PByte(Ptr(DsSegment,Offset))^:=OldAddr[0][0];
PByte(Ptr(DsSegment,Offset+1))^:=OldAddr[0][1];
PByte(Ptr(DsSegment,Offset+2))^:=OldAddr[0][2];
PByte(Ptr(DsSegment,Offset+3))^:=OldAddr[0][3];
PByte(Ptr(DsSegment,Offset+4))^:=OldAddr[0][4];
FreeSelector(DsSegment);
already[0]:=false;
end;
asm
popa
pop ds
pop es
end;
end;
procedure unHookExTextOut;
var
segment,offset,Exoffset,
DsSegment,ExDsSegment:word;
begin
asm
push es
push ds
pusha
push ax
mov ax,seg oldaddr[1]
mov ds,ax
mov es,ax
pop ax
end;
if already[1] then
begin
{取函數段基址}
Segment:=Seg(EXTTextOut);
{取函數偏移}
ExOffset:=Ofs(EXTTextOut);
{取與代碼段有相同基址的可寫數據段別名}
ExDsSegment:=AllocCStoDSAlias(Segment);
{恢復原函數}
PByte(Ptr(ExDsSegment,ExOffset+0))^:=OldAddr[1][0];
PByte(Ptr(ExDsSegment,ExOffset+1))^:=OldAddr[1][1];
PByte(Ptr(ExDsSegment,ExOffset+2))^:=OldAddr[1][2];
PByte(Ptr(ExDsSegment,ExOffset+3))^:=OldAddr[1][3];
PByte(Ptr(ExDsSegment,ExOffset+4))^:=OldAddr[1][4];
FreeSelector(ExDsSegment);
already[1]:=false;
end;
asm
popa
pop ds
pop es
end;
end;
{修改Windows系統函數地址}
function TextHookCreate:boolean;
begin
s[0]:=#0;
HookTextOut;
HookExTextOut;
result:=true;
end;
{恢復Windows系統函數地址}
function TextHookFree:boolean;
begin
unHookTextOut;
unHookExTextOut;
result:=true;
end;
end.
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -