请教如何截获刚运行程序的名称(进程)(200分)

  • 主题发起人 chinazyk
  • 开始时间
C

chinazyk

Unregistered / Unconfirmed
GUEST, unregistred user!
请教如何截获刚运行程序的名称(进程),即实时获取运行程序的名称,不要用timer控件
 
呵呵, 你可以拦截CreateProcess 和 CreateProcessEx两个API[:D][:D], 最可靠的办法
 
请教tseug:<br>具体如何实现,能否给个实例,谢谢!
 
有很多拦截API的范例, 你搜索一下能有一大堆
 
我感觉不好办,拦截createProcess的确是个好主意.<br>具体实现起来就不知道了.<br>我来听课.<br>
 
请教tseug:<br>具体如何实现,能否给个实例,谢谢!<br>
 
tseug兄:<br>拜托,拜托,具体如何实现,帮忙小弟,不胜感激!
 
参考下面代码吧<br>http://www.csdn.net/dev/C&amp;C++/Source%20Code/
 
拦截CreateProcess 和 CreateProcessEx两个API
 
怎么拦截呀?学习.....
 
哪位前辈能抽空答复呢?发扬一下雷峰精神嘛!
 
library PigLatinDll;<br><br>uses<br>&nbsp; Windows,<br>&nbsp; SysUtils,<br>&nbsp; Classes,<br>&nbsp; HookTextUnit in 'HookTextUnit.pas';<br><br>function PigLatinWord(s: String): String;<br>Var start: String; Capitalize, AllCapitals: Boolean; i: Integer; begin<br>&nbsp; Result:=s;<br>&nbsp; if length(s)&lt;=1 then exit;<br>&nbsp; Capitalize:=IsCharUpper(s[1]);<br>&nbsp; AllCapitals:=True;<br>&nbsp; for i:=1 to length(s) do begin<br>&nbsp; &nbsp; if IsCharLower(s) then begin<br>&nbsp; &nbsp; &nbsp; AllCapitals:=False; break;<br>&nbsp; &nbsp; end;<br>&nbsp; end;<br>&nbsp; start:=lowercase(copy(s,1,2));<br>&nbsp; if (start[1]&lt;'a') or (start[1]&gt;'z') then exit;<br>&nbsp; if (start[1] in ['a','e','i','o','u']) then start:='';<br>&nbsp; if (start&lt;&gt;'ch') and (start&lt;&gt;'th') and (start&lt;&gt;'sh') and (start&lt;&gt;'wh') <br><br>&nbsp; and (start&lt;&gt;'qu') and (start&lt;&gt;'kn') and (start&lt;&gt;'wr') then &nbsp; &nbsp;delete(start,2,1);<br>&nbsp; Result:=copy(s,length(start)+1,length(s))+start;<br>&nbsp; if start='' then Result:=Result+'yay' else Result:=Result+'ay'; &nbsp;if AllCapitals then result:=Uppercase(Result) else<br>&nbsp; if Capitalize then result[1]:=Upcase(result[1]);<br>end;<br><br>function IntToRoman(n: Integer): String;<br>Var i, units, tens, hundreds, thousands: Integer;<br>begin<br>&nbsp; If (n&gt;=5000) or (n&lt;=0) then Result:=IntToStr(n) else begin &nbsp; &nbsp;thousands:=n div 1000; n:=n mod 1000;<br>&nbsp; &nbsp; hundreds:=n div 100; n:=n mod 100;<br>&nbsp; &nbsp; tens:=n div 10; n:=n mod 10;<br>&nbsp; &nbsp; units:=n;<br>&nbsp; &nbsp; Result:='';<br>&nbsp; &nbsp; for i:=1 to Thousands do begin<br>&nbsp; &nbsp; &nbsp; Result:=Result+'M';<br>&nbsp; &nbsp; end;<br>&nbsp; &nbsp; Case Hundreds of<br>&nbsp; &nbsp; &nbsp; 1: Result:=Result+'C';<br>&nbsp; &nbsp; &nbsp; 2: Result:=Result+'CC';<br>&nbsp; &nbsp; &nbsp; 3: Result:=Result+'CCC';<br>&nbsp; &nbsp; &nbsp; 4: Result:=Result+'CD';<br>&nbsp; &nbsp; &nbsp; 5: Result:=Result+'D';<br>&nbsp; &nbsp; &nbsp; 6: Result:=Result+'DC';<br>&nbsp; &nbsp; &nbsp; 7: Result:=Result+'DCC';<br>&nbsp; &nbsp; &nbsp; 8: Result:=Result+'DCCC';<br>&nbsp; &nbsp; &nbsp; 9: Result:=Result+'CM';<br>&nbsp; &nbsp; end;<br>&nbsp; &nbsp; Case Tens of<br>&nbsp; &nbsp; &nbsp; 1: Result:=Result+'X';<br>&nbsp; &nbsp; &nbsp; 2: Result:=Result+'XX';<br>&nbsp; &nbsp; &nbsp; 3: Result:=Result+'XXX';<br>&nbsp; &nbsp; &nbsp; 4: Result:=Result+'XL';<br>&nbsp; &nbsp; &nbsp; 5: Result:=Result+'L';<br>&nbsp; &nbsp; &nbsp; 6: Result:=Result+'LX';<br>&nbsp; &nbsp; &nbsp; 7: Result:=Result+'LXX';<br>&nbsp; &nbsp; &nbsp; 8: Result:=Result+'LXXX';<br>&nbsp; &nbsp; &nbsp; 9: Result:=Result+'XC';<br>&nbsp; &nbsp; end;<br>&nbsp; &nbsp; Case Units of<br>&nbsp; &nbsp; &nbsp; 1: Result:=Result+'I';<br>&nbsp; &nbsp; &nbsp; 2: Result:=Result+'II';<br>&nbsp; &nbsp; &nbsp; 3: Result:=Result+'III';<br>&nbsp; &nbsp; &nbsp; 4: Result:=Result+'IV';<br>&nbsp; &nbsp; &nbsp; 5: Result:=Result+'V';<br>&nbsp; &nbsp; &nbsp; 6: Result:=Result+'VI';<br>&nbsp; &nbsp; &nbsp; 7: Result:=Result+'VII';<br>&nbsp; &nbsp; &nbsp; 8: Result:=Result+'VIII';<br>&nbsp; &nbsp; &nbsp; 9: Result:=Result+'IX';<br>&nbsp; &nbsp; end;<br>&nbsp; end;<br>end;<br><br>function LatinNumber(s: String): String;<br>Var n: Integer;<br>begin<br>&nbsp; try<br>&nbsp; &nbsp; n:=StrToInt(s);<br>&nbsp; &nbsp; Result:=IntToRoman(n);<br>&nbsp; except<br>&nbsp; &nbsp; Result:=s;<br>&nbsp; end;<br>end;<br><br>function Conv(s: String): String;<br>Var i: Integer; w: String;<br>begin<br>&nbsp; Result:='';<br>&nbsp; try<br>&nbsp; &nbsp; if s='' then exit;<br>&nbsp; &nbsp; i:=1;<br>&nbsp; &nbsp; while (i&lt;=length(s)) do begin<br>&nbsp; &nbsp; &nbsp; while (i&lt;=length(s)) and (s&lt;=' ') do begin<br>&nbsp; &nbsp; &nbsp; &nbsp; Result:=Result+s;<br>&nbsp; &nbsp; &nbsp; &nbsp; Inc(i);<br>&nbsp; &nbsp; &nbsp; end;<br><br>&nbsp; &nbsp; &nbsp; // convert any numbers into latin numbers<br>&nbsp; &nbsp; &nbsp; w:='';<br>&nbsp; &nbsp; &nbsp; while (i&lt;=length(s)) and (s&gt;='0') and (s&lt;='9') do begin &nbsp; &nbsp; &nbsp; &nbsp;w:=w+s;<br>&nbsp; &nbsp; &nbsp; &nbsp; Inc(i);<br>&nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; &nbsp; Result:=Result+LatinNumber(w);<br><br>&nbsp; &nbsp; &nbsp; // add any other symbols unchanged (for now)<br>&nbsp; &nbsp; &nbsp; w:='';<br>&nbsp; &nbsp; &nbsp; while (i&lt;=length(s)) and not IsCharAlphaNumeric(s) do begin &nbsp; &nbsp; &nbsp; &nbsp;w:=w+s;<br>&nbsp; &nbsp; &nbsp; &nbsp; Inc(i);<br>&nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; &nbsp; Result:=Result+w;<br><br>&nbsp; &nbsp; &nbsp; // convert whole words into pig latin<br>&nbsp; &nbsp; &nbsp; w:='';<br>&nbsp; &nbsp; &nbsp; while (i&lt;=length(s)) and IsCharAlpha(s) do begin<br>&nbsp; &nbsp; &nbsp; &nbsp; w:=w+s;<br>&nbsp; &nbsp; &nbsp; &nbsp; Inc(i);<br>&nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; &nbsp; Result:=Result+PigLatinWord(w);<br>&nbsp; &nbsp; end;<br>&nbsp; except<br>&nbsp; end;<br>end;<br><br>function GetMsgProc(code: integer; removal: integer; msg: Pointer): Integer; stdcall;<br>begin<br>&nbsp; Result:=0;<br>end;<br><br>Var HookHandle: THandle;<br><br>procedure StartHook; stdcall;<br>begin<br>&nbsp; HookHandle:=SetWindowsHookEx(WH_GETMESSAGE, @GetMsgProc, HInstance, 0);<br>end;<br><br>procedure StopHook; stdcall;<br>begin<br>&nbsp; UnhookWindowsHookEx(HookHandle);<br>end;<br><br>exports StartHook, StopHook;<br><br>begin<br>&nbsp; HookTextOut(Conv);<br>end.<br><br>====================================================<br><br>unit HookTextUnit;<br><br>interface<br>uses Windows, SysUtils, Classes, PEStuff;<br><br>type<br>&nbsp; TConvertTextFunction = function(text: String): String;<br>&nbsp; TTextOutA = function(hdc: HDC; x,y: Integer; text: PAnsiChar; len: Integer): BOOL; stdcall;<br>&nbsp; TTextOutW = function(hdc: HDC; x,y: Integer; text: PWideChar; len: Integer): BOOL; stdcall;<br>&nbsp; TExtTextOutA = function(hdc: HDC; x,y: Integer; Options: DWORD; Clip: PRect;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; text: PAnsiChar; len: Integer; dx: PInteger): BOOL; stdcall;<br>&nbsp; TExtTextOutW = function(hdc: HDC; x,y: Integer; Options: DWORD; Clip: PRect;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; text: PWideChar; len: Integer; dx: PInteger): BOOL; stdcall;<br>&nbsp; TDrawTextA = function(hdc: HDC; text: PAnsiChar; len: Integer; rect: PRect;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Format: DWORD): Integer; stdcall;<br>&nbsp; TDrawTextW = function(hdc: HDC; text: PWideChar; len: Integer; rect: PRect;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Format: DWORD): Integer; stdcall;<br>&nbsp; TDrawTextExA = function(hdc: HDC; text: PAnsiChar; len: Integer; rect: PRect;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Format: DWORD; DTParams: PDrawTextParams): Integer; stdcall;<br>&nbsp; TDrawTextExW = function(hdc: HDC; text: PWideChar; len: Integer; rect: PRect;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Format: DWORD; DTParams: PDrawTextParams): Integer; stdcall;<br><br>&nbsp; TTabbedTextOutA = function(hdc: HDC; x,y: Integer; text: PAnsiChar; len: Integer;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; TabCount: Integer; TabPositions: PInteger; TabOrigin: Integer): Integer; stdcall;<br>&nbsp; TTabbedTextOutW = function(hdc: HDC; x,y: Integer; text: PWideChar; len: Integer;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; TabCount: Integer; TabPositions: PInteger; TabOrigin: Integer): Integer; stdcall;<br>&nbsp; TPolyTextOutA = function(hdc: HDC; pptxt: PPOLYTEXTA; count: Integer): BOOL; stdcall;<br>&nbsp; TPolyTextOutW = function(hdc: HDC; pptxt: PPOLYTEXTW; count: Integer): BOOL; stdcall;<br><br>&nbsp; TGetTextExtentExPointA = function(hdc: HDC; text: PAnsiChar; len: Integer;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; maxExtent: Integer; Fit: PInteger; Dx: PInteger; Size: Pointer): BOOL; stdcall;<br>&nbsp; TGetTextExtentExPointW = function(hdc: HDC; text: PWideChar; len: Integer;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; maxExtent: Integer; Fit: PInteger; Dx: PInteger; Size: Pointer): BOOL; stdcall;<br>&nbsp; TGetTextExtentPoint32A = function(hdc: HDC; text: PAnsiChar; len: Integer; Size: Pointer): BOOL; stdcall;<br>&nbsp; TGetTextExtentPoint32W = function(hdc: HDC; text: PWideChar; len: Integer; Size: Pointer): BOOL; stdcall;<br>&nbsp; TGetTextExtentPointA = function(hdc: HDC; text: PAnsiChar; len: Integer; Size: Pointer): BOOL; stdcall;<br>&nbsp; TGetTextExtentPointW = function(hdc: HDC; text: PWideChar; len: Integer; Size: Pointer): BOOL; stdcall;<br><br>&nbsp; PPointer = ^Pointer;<br><br>&nbsp; TImportCode = packed record<br>&nbsp; &nbsp; JumpInstruction: Word; // should be $25FF<br>&nbsp; &nbsp; AddressOfPointerToFunction: PPointer;<br>&nbsp; end;<br>&nbsp; PImportCode = ^TImportCode;<br><br>procedure HookTextOut(ConvertFunction: TConvertTextFunction);<br>procedure UnhookTextOut;<br><br>implementation<br><br>Var<br>&nbsp; ConvertTextFunction: TConvertTextFunction = nil;<br>&nbsp; OldTextOutA: TTextOutA = nil;<br>&nbsp; OldTextOutW: TTextOutW = nil;<br>&nbsp; OldExtTextOutA: TExtTextOutA = nil;<br>&nbsp; OldExtTextOutW: TExtTextOutW = nil;<br>&nbsp; OldDrawTextA: TDrawTextA = nil;<br>&nbsp; OldDrawTextW: TDrawTextW = nil;<br>&nbsp; OldDrawTextExA: TDrawTextExA = nil;<br>&nbsp; OldDrawTextExW: TDrawTextExW = nil;<br>&nbsp; OldTabbedTextOutA: TTabbedTextOutA = nil;<br>&nbsp; OldTabbedTextOutW: TTabbedTextOutW = nil;<br>&nbsp; OldPolyTextOutA: TPolyTextOutA = nil;<br>&nbsp; OldPolyTextOutW: TPolyTextOutW = nil;<br>&nbsp; OldGetTextExtentExPointA: TGetTextExtentExPointA = nil;<br>&nbsp; OldGetTextExtentExPointW: TGetTextExtentExPointW = nil;<br>&nbsp; OldGetTextExtentPoint32A: TGetTextExtentPoint32A = nil;<br>&nbsp; OldGetTextExtentPoint32W: TGetTextExtentPoint32W = nil;<br>&nbsp; OldGetTextExtentPointA: TGetTextExtentPointA = nil;<br>&nbsp; OldGetTextExtentPointW: TGetTextExtentPointW = nil;<br><br>function StrLenW(s: PWideChar): Integer;<br>Var i: Integer;<br>begin<br>&nbsp; if s=nil then begin<br>&nbsp; &nbsp; Result:=0; exit;<br>&nbsp; end;<br>&nbsp; i:=0;<br>&nbsp; try<br>&nbsp; &nbsp; while (s&lt;&gt;#0) do inc(i);<br>&nbsp; except<br>&nbsp; end;<br>&nbsp; Result:=i;<br>end;<br><br>function NewTextOutA(hdc: HDC; x,y: Integer; text: PAnsiChar; len: Integer): BOOL; stdcall;<br>Var s: String;<br>begin<br>&nbsp; try<br>&nbsp; if Len&lt;0 then Len:=strlen(text);<br>&nbsp; &nbsp; If Len&gt;0 then begin<br>&nbsp; &nbsp; &nbsp; SetLength(s,len);<br>&nbsp; &nbsp; &nbsp; FillChar(s[1],len+1,0);<br>&nbsp; &nbsp; &nbsp; Move(text^,s[1],len);<br>&nbsp; &nbsp; &nbsp; if @ConvertTextFunction&lt;&gt;nil then<br>&nbsp; &nbsp; &nbsp; &nbsp; s:=ConvertTextFunction(s);<br>&nbsp; &nbsp; &nbsp; if @OldTextOutA&lt;&gt;nil then<br>&nbsp; &nbsp; &nbsp; &nbsp; Result:=OldTextOutA(hdc,x,y,PAnsiChar(s),length(s))<br>&nbsp; &nbsp; &nbsp; else<br>&nbsp; &nbsp; &nbsp; &nbsp; Result:=False;<br>&nbsp; &nbsp; end else Result:=OldTextOutA(hdc,x,y,PAnsiChar(s),0);<br>&nbsp; except<br>&nbsp; &nbsp; Result:=False;<br>&nbsp; end;<br>end;<br><br>function NewTextOutW(hdc: HDC; x,y: Integer; text: PWideChar; len: Integer): BOOL; stdcall;<br>Var s: WideString;<br>begin<br>&nbsp; try<br>&nbsp; if Len&lt;0 then Len:=strlenW(text);<br>&nbsp; &nbsp; If Len&gt;0 then begin<br>&nbsp; &nbsp; &nbsp; SetLength(s,len);<br>&nbsp; &nbsp; &nbsp; FillChar(s[1],len*2+2,0);<br>&nbsp; &nbsp; &nbsp; Move(text^,s[1],len*2);<br>&nbsp; &nbsp; &nbsp; if @ConvertTextFunction&lt;&gt;nil then<br>&nbsp; &nbsp; &nbsp; &nbsp; s:=ConvertTextFunction(s);<br>&nbsp; &nbsp; &nbsp; if @OldTextOutW&lt;&gt;nil then<br>&nbsp; &nbsp; &nbsp; &nbsp; Result:=OldTextOutW(hdc,x,y,PWideChar(s),length(s))<br>&nbsp; &nbsp; &nbsp; else<br>&nbsp; &nbsp; &nbsp; &nbsp; Result:=False;<br>&nbsp; &nbsp; end else Result:=OldTextOutW(hdc,x,y,PWideChar(s),0);<br>&nbsp; except<br>&nbsp; &nbsp; Result:=False;<br>&nbsp; end;<br>end;<br>function NewExtTextOutA(hdc: HDC; x,y: Integer; Options: DWORD; Clip: PRect;<br>&nbsp; text: PAnsiChar; len: Integer; dx: PInteger): BOOL; stdcall;<br>Var s: String;<br>begin<br>&nbsp; try<br>&nbsp; &nbsp; if Len&lt;0 then Len:=strlen(text); // ???<br>&nbsp; &nbsp; if Len&gt;0 then begin<br>&nbsp; &nbsp; &nbsp; SetLength(s,len);<br>&nbsp; &nbsp; &nbsp; FillChar(s[1],len+1,0);<br>&nbsp; &nbsp; &nbsp; Move(text^,s[1],len);<br>&nbsp; &nbsp; &nbsp; if @ConvertTextFunction&lt;&gt;nil then s:=ConvertTextFunction(s); &nbsp; &nbsp; &nbsp;if @OldExtTextOutA&lt;&gt;nil then<br><br>Result:=OldExtTextOutA(hdc,x,y,Options,Clip,PAnsiChar(s),length(s),dx) &nbsp; &nbsp; &nbsp;else Result:=False;<br>&nbsp; &nbsp; end else Result:=OldExtTextOutA(hdc,x,y,Options,Clip,text,0,dx); &nbsp;except<br>&nbsp; &nbsp; Result:=False;<br>&nbsp; end;<br>end;<br><br>function NewExtTextOutW(hdc: HDC; x,y: Integer; Options: DWORD; Clip: PRect;<br>&nbsp; text: PWideChar; len: Integer; dx: PInteger): BOOL; stdcall;<br>Var s: WideString;<br>begin<br>&nbsp; try<br>&nbsp; &nbsp; if Len&lt;0 then Len:=strlenW(text);<br>&nbsp; &nbsp; If Len&gt;0 then begin<br>&nbsp; &nbsp; &nbsp; SetLength(s,len);<br>&nbsp; &nbsp; &nbsp; FillChar(s[1],len*2+2,0);<br>&nbsp; &nbsp; &nbsp; Move(text^,s[1],len*2);<br>&nbsp; &nbsp; &nbsp; if @ConvertTextFunction&lt;&gt;nil then<br>&nbsp; &nbsp; &nbsp; &nbsp; s:=ConvertTextFunction(s);<br>&nbsp; &nbsp; &nbsp; if @OldExtTextOutW&lt;&gt;nil then<br><br>Result:=OldExtTextOutW(hdc,x,y,Options,Clip,PWideChar(s),length(s),dx) &nbsp; &nbsp; &nbsp;else Result:=False;<br>&nbsp; &nbsp; end else Result:=OldExtTextOutW(hdc,x,y,Options,Clip,text,0,dx); &nbsp;except<br>&nbsp; &nbsp; Result:=False;<br>&nbsp; end;<br>end;<br><br>function NewDrawTextA(hdc: HDC; text: PAnsiChar; len: Integer; rect: PRect;<br>&nbsp; Format: DWORD): Integer; stdcall;<br>Var s: String;<br>begin<br>&nbsp; try<br>&nbsp; &nbsp; if Len&lt;0 then Len:=strlen(text); // ???<br>&nbsp; &nbsp; if Len&gt;0 then begin<br>&nbsp; &nbsp; &nbsp; SetLength(s,len);<br>&nbsp; &nbsp; &nbsp; FillChar(s[1],len+1,0);<br>&nbsp; &nbsp; &nbsp; Move(text^,s[1],len);<br>&nbsp; &nbsp; &nbsp; if @ConvertTextFunction&lt;&gt;nil then<br>&nbsp; &nbsp; &nbsp; &nbsp; s:=ConvertTextFunction(s);<br>&nbsp; &nbsp; &nbsp; if @OldDrawTextA&lt;&gt;nil then<br>&nbsp; &nbsp; &nbsp; &nbsp; Result:=OldDrawTextA(hdc,PAnsiChar(s),length(s),rect,Format) &nbsp; &nbsp; &nbsp;else Result:=0;<br>&nbsp; &nbsp; end else Result:=OldDrawTextA(hdc,text,0,rect,Format);<br>&nbsp; except<br>&nbsp; &nbsp; Result:=0;<br>&nbsp; end;<br>end;<br><br>function NewDrawTextW(hdc: HDC; text: PWideChar; len: Integer; rect: PRect;<br>&nbsp; Format: DWORD): Integer; stdcall;<br>Var s: WideString;<br>begin<br>&nbsp; try<br>&nbsp; &nbsp; if Len&lt;0 then Len:=strlenW(text);<br>&nbsp; &nbsp; if len&gt;0 then begin<br>&nbsp; &nbsp; &nbsp; SetLength(s,len);<br>&nbsp; &nbsp; &nbsp; FillChar(s[1],len*2+2,0);<br>&nbsp; &nbsp; &nbsp; Move(text^,s[1],len*2);<br>&nbsp; &nbsp; &nbsp; if @ConvertTextFunction&lt;&gt;nil then<br>&nbsp; &nbsp; &nbsp; &nbsp; s:=ConvertTextFunction(s);<br>&nbsp; &nbsp; &nbsp; if @OldDrawTextW&lt;&gt;nil then<br>&nbsp; &nbsp; &nbsp; &nbsp; Result:=OldDrawTextW(hdc,PWideChar(s),length(s),rect,Format) &nbsp; &nbsp; &nbsp;else Result:=0;<br>&nbsp; &nbsp; end else Result:=OldDrawTextW(hdc,text,0,rect,Format);<br>&nbsp; except<br>&nbsp; &nbsp; Result:=0;<br>&nbsp; end;<br>end;<br><br>function NewDrawTextExA(hdc: HDC; text: PAnsiChar; len: Integer; rect: PRect;<br>&nbsp; Format: DWORD; DTParams: PDrawTextParams): Integer; stdcall;<br>Var s: String;<br>begin<br>&nbsp; try<br>&nbsp; &nbsp; if Len&lt;0 then Len:=strlen(text);<br>&nbsp; &nbsp; if len&gt;0 then begin<br>&nbsp; &nbsp; &nbsp; SetLength(s,len);<br>&nbsp; &nbsp; &nbsp; FillChar(s[1],len+1,0);<br>&nbsp; &nbsp; &nbsp; Move(text^,s[1],len);<br>&nbsp; &nbsp; &nbsp; if @ConvertTextFunction&lt;&gt;nil then<br>&nbsp; &nbsp; &nbsp; &nbsp; s:=ConvertTextFunction(s);<br>&nbsp; &nbsp; &nbsp; if @OldDrawTextExA&lt;&gt;nil then<br><br>Result:=OldDrawTextExA(hdc,PAnsiChar(s),length(s),rect,Format,DTParams) &nbsp; &nbsp; &nbsp;else Result:=0;<br>&nbsp; &nbsp; end else Result:=OldDrawTextExA(hdc,text,0,rect,Format,DTParams); &nbsp;except<br>&nbsp; &nbsp; Result:=0;<br>&nbsp; end;<br>end;<br><br>function NewDrawTextExW(hdc: HDC; text: PWideChar; len: Integer; rect: PRect;<br>&nbsp; Format: DWORD; DTParams: PDrawTextParams): Integer; stdcall;<br>Var s: WideString;<br>begin<br>&nbsp; try<br>&nbsp; &nbsp; if Len&lt;0 then Len:=strlenW(text);<br>&nbsp; &nbsp; if Len&gt;0 then begin<br>&nbsp; &nbsp; &nbsp; SetLength(s,len);<br>&nbsp; &nbsp; &nbsp; FillChar(s[1],len*2+2,0);<br>&nbsp; &nbsp; &nbsp; Move(text^,s[1],len*2);<br>&nbsp; &nbsp; &nbsp; if @ConvertTextFunction&lt;&gt;nil then<br>&nbsp; &nbsp; &nbsp; &nbsp; s:=ConvertTextFunction(s);<br>&nbsp; &nbsp; &nbsp; if @OldDrawTextExW&lt;&gt;nil then<br><br>Result:=OldDrawTextExW(hdc,PWideChar(s),length(s),rect,Format,DTParams) &nbsp; &nbsp; &nbsp;else Result:=0;<br>&nbsp; &nbsp; end else Result:=OldDrawTextExW(hdc,text,0,rect,Format,DTParams); &nbsp;except<br>&nbsp; &nbsp; Result:=0;<br>&nbsp; end;<br>end;<br><br>function NewTabbedTextOutA(hdc: HDC; x,y: Integer; text: PAnsiChar; len: Integer;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; TabCount: Integer; TabPositions: PInteger; TabOrigin: Integer): Integer; stdcall;<br>Var s: AnsiString;<br>begin<br>&nbsp; try<br>&nbsp; &nbsp; if Len&lt;0 then Len:=strlen(text);<br>&nbsp; &nbsp; if Len&gt;0 then begin<br>&nbsp; &nbsp; &nbsp; SetLength(s,len);<br>&nbsp; &nbsp; &nbsp; FillChar(s[1],len+1,0);<br>&nbsp; &nbsp; &nbsp; Move(text^,s[1],len);<br>&nbsp; &nbsp; &nbsp; if @ConvertTextFunction&lt;&gt;nil then<br>&nbsp; &nbsp; &nbsp; &nbsp; s:=ConvertTextFunction(s);<br>&nbsp; &nbsp; &nbsp; if @OldTabbedTextOutA&lt;&gt;nil then<br><br>Result:=OldTabbedTextOutA(hdc,x,y,PAnsiChar(s),length(s),TabCount,TabPositions,TabOrigin) <br><br>&nbsp; &nbsp; &nbsp; else Result:=0;<br>&nbsp; &nbsp; end else<br>Result:=OldTabbedTextOutA(hdc,x,y,text,0,TabCount,TabPositions,TabOrigin); <br><br>&nbsp; except<br>&nbsp; &nbsp; Result:=0;<br>&nbsp; end;<br>end;<br><br>function NewTabbedTextOutW(hdc: HDC; x,y: Integer; text: PWideChar; len: Integer;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; TabCount: Integer; TabPositions: PInteger; TabOrigin: Integer): Integer; stdcall;<br>Var s: WideString;<br>begin<br>&nbsp; try<br>&nbsp; &nbsp; if Len&lt;0 then Len:=strlenW(text);<br>&nbsp; &nbsp; if Len&gt;0 then begin<br>&nbsp; &nbsp; &nbsp; SetLength(s,len);<br>&nbsp; &nbsp; &nbsp; FillChar(s[1],len*2+2,0);<br>&nbsp; &nbsp; &nbsp; Move(text^,s[1],len*2);<br>&nbsp; &nbsp; &nbsp; if @ConvertTextFunction&lt;&gt;nil then<br>&nbsp; &nbsp; &nbsp; &nbsp; s:=ConvertTextFunction(s);<br>&nbsp; &nbsp; &nbsp; if @OldTabbedTextOutW&lt;&gt;nil then<br>Result:=OldTabbedTextOutW(hdc,x,y,PWideChar(s),length(s),TabCount,TabPositions,TabOrigin) <br><br>&nbsp; &nbsp; &nbsp; else Result:=0;<br>&nbsp; &nbsp; end else<br>Result:=OldTabbedTextOutW(hdc,x,y,text,0,TabCount,TabPositions,TabOrigin); <br><br>&nbsp; except<br>&nbsp; &nbsp; Result:=0;<br>&nbsp; end;<br>end;<br><br>function NewPolyTextOutA(hdc: HDC; pptxt: PPOLYTEXTA; count: Integer): BOOL; stdcall;<br>Var s: String; i: Integer; ppnew: PPOLYTEXTA;<br>begin<br>&nbsp; ppnew:=nil;<br>&nbsp; try<br>&nbsp; &nbsp; Result:=False;<br>&nbsp; &nbsp; if Count&lt;0 then exit;<br>&nbsp; &nbsp; if Count=0 then begin Result:=True; exit; end;<br>&nbsp; &nbsp; GetMem(ppnew,count*sizeof(TPOLYTEXTA));<br>&nbsp; &nbsp; For i:=1 to count do begin<br>&nbsp; &nbsp; &nbsp; ppnew^:=pptxt^;<br>&nbsp; &nbsp; &nbsp; if ppnew^.n&lt;0 then ppnew^.n:=strlen(ppnew^.PAnsiChar);<br>&nbsp; &nbsp; &nbsp; if ppnew^.n&gt;0 then begin<br>&nbsp; &nbsp; &nbsp; &nbsp; SetLength(s,ppnew^.n);<br>&nbsp; &nbsp; &nbsp; &nbsp; FillChar(s[1],ppnew^.n+1,0);<br>&nbsp; &nbsp; &nbsp; &nbsp; Move(ppnew^.PAnsiChar,s[1],ppnew^.n);<br>&nbsp; &nbsp; &nbsp; &nbsp; if @ConvertTextFunction&lt;&gt;nil then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; s:=ConvertTextFunction(s);<br>&nbsp; &nbsp; &nbsp; &nbsp; ppnew^.PAnsiChar:=PAnsiChar(s);<br>&nbsp; &nbsp; &nbsp; &nbsp; ppnew^.n:=length(s);<br>&nbsp; &nbsp; &nbsp; &nbsp; if @OldPolyTextOutA&lt;&gt;nil then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Result:=OldPolyTextOutA(hdc,ppnew,1);<br>&nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; &nbsp; Inc(pptxt);<br>&nbsp; &nbsp; end;<br>&nbsp; except<br>&nbsp; &nbsp; Result:=False;<br>&nbsp; end;<br>&nbsp; if ppnew&lt;&gt;nil then FreeMem(ppnew);<br>end;<br><br>function NewPolyTextOutW(hdc: HDC; pptxt: PPOLYTEXTW; count: Integer): BOOL; stdcall;<br>begin<br>&nbsp; Result:=OldPolyTextOutW(hdc,pptxt,count);<br>end;<br><br>function NewGetTextExtentExPointA(hdc: HDC; text: PAnsiChar; len: Integer;<br>&nbsp; &nbsp; &nbsp; &nbsp; maxExtent: Integer; Fit: PInteger; Dx: PInteger; Size: Pointer): BOOL; stdcall;<br>Var s: AnsiString;<br>begin<br>&nbsp; try<br>&nbsp; &nbsp; if Len&lt;0 then Len:=strlen(text);<br>&nbsp; &nbsp; if Len&gt;0 then begin<br>&nbsp; &nbsp; &nbsp; SetLength(s,len);<br>&nbsp; &nbsp; &nbsp; FillChar(s[1],len+1,0);<br>&nbsp; &nbsp; &nbsp; Move(text^,s[1],len);<br>&nbsp; &nbsp; &nbsp; if @ConvertTextFunction&lt;&gt;nil then<br>&nbsp; &nbsp; &nbsp; &nbsp; s:=ConvertTextFunction(s);<br>&nbsp; &nbsp; &nbsp; if @OldGetTextExtentExPointA&lt;&gt;nil then<br><br>Result:=OldGetTextExtentExPointA(hdc,PAnsiChar(s),length(s),maxExtent,Fit,Dx,Size) <br><br>&nbsp; &nbsp; &nbsp; else Result:=False;<br>&nbsp; &nbsp; end else<br>Result:=OldGetTextExtentExPointA(hdc,text,0,maxExtent,Fit,Dx,Size); &nbsp;except<br>&nbsp; &nbsp; Result:=False;<br>&nbsp; end;<br>end;<br><br>Function NewGetTextExtentExPointW(hdc: HDC; text: PWideChar; len: Integer;<br>&nbsp; maxExtent: Integer; Fit: PInteger; Dx: PInteger; Size: Pointer): BOOL; stdcall;<br>Var s: WideString;<br>begin<br>&nbsp; try<br>&nbsp; &nbsp; if Len&lt;0 then Len:=strlenW(text);<br>&nbsp; &nbsp; if Len&gt;0 then begin<br>&nbsp; &nbsp; &nbsp; SetLength(s,len);<br>&nbsp; &nbsp; &nbsp; FillChar(s[1],len*2+2,0);<br>&nbsp; &nbsp; &nbsp; Move(text^,s[1],len);<br>&nbsp; &nbsp; &nbsp; if @ConvertTextFunction&lt;&gt;nil then<br>&nbsp; &nbsp; &nbsp; &nbsp; s:=ConvertTextFunction(s);<br>&nbsp; &nbsp; &nbsp; if @OldGetTextExtentExPointW&lt;&gt;nil then<br><br>Result:=OldGetTextExtentExPointW(hdc,PWideChar(s),length(s),maxExtent,Fit,Dx,Size) <br><br>&nbsp; &nbsp; &nbsp; else Result:=False;<br>&nbsp; &nbsp; end else<br>Result:=OldGetTextExtentExPointW(hdc,text,0,maxExtent,Fit,Dx,Size); &nbsp;except<br>&nbsp; &nbsp; Result:=False;<br>&nbsp; end;<br>end;<br><br>function NewGetTextExtentPoint32A(hdc: HDC; text: PAnsiChar; len: Integer; Size: Pointer): BOOL; stdcall;<br>Var s: AnsiString;<br>begin<br>&nbsp; try<br>&nbsp; &nbsp; if Len&lt;0 then Len:=strlen(text);<br>&nbsp; &nbsp; if Len&gt;0 then begin<br>&nbsp; &nbsp; &nbsp; SetLength(s,len);<br>&nbsp; &nbsp; &nbsp; FillChar(s[1],len+1,0);<br>&nbsp; &nbsp; &nbsp; Move(text^,s[1],len);<br>&nbsp; &nbsp; &nbsp; if @ConvertTextFunction&lt;&gt;nil then<br>&nbsp; &nbsp; &nbsp; &nbsp; s:=ConvertTextFunction(s);<br>&nbsp; &nbsp; &nbsp; if @OldGetTextExtentPoint32A&lt;&gt;nil then<br><br>Result:=OldGetTextExtentPoint32A(hdc,PAnsiChar(s),length(s),Size) &nbsp; &nbsp; &nbsp;else Result:=False;<br>&nbsp; &nbsp; end else Result:=OldGetTextExtentPoint32A(hdc,text,0,Size);<br>&nbsp; except<br>&nbsp; &nbsp; Result:=False;<br>&nbsp; end;<br>end;<br><br>function NewGetTextExtentPoint32W(hdc: HDC; text: PWideChar; len: Integer; Size: Pointer): BOOL; stdcall;<br>Var s: WideString;<br>begin<br>&nbsp; try<br>&nbsp; &nbsp; if Len&lt;0 then Len:=strlenW(text);<br>&nbsp; &nbsp; if Len&gt;0 then begin<br>&nbsp; &nbsp; &nbsp; SetLength(s,len);<br>&nbsp; &nbsp; &nbsp; FillChar(s[1],len*2+2,0);<br>&nbsp; &nbsp; &nbsp; Move(text^,s[1],len);<br>&nbsp; &nbsp; &nbsp; if @ConvertTextFunction&lt;&gt;nil then<br>&nbsp; &nbsp; &nbsp; &nbsp; s:=ConvertTextFunction(s);<br>&nbsp; &nbsp; &nbsp; if @OldGetTextExtentPoint32W&lt;&gt;nil then<br><br>Result:=OldGetTextExtentPoint32W(hdc,PWideChar(s),length(s),Size) &nbsp; &nbsp; &nbsp;else Result:=False;<br>&nbsp; &nbsp; end else Result:=OldGetTextExtentPoint32W(hdc,text,0,Size);<br>&nbsp; except<br>&nbsp; &nbsp; Result:=False;<br>&nbsp; end;<br>end;<br>function NewGetTextExtentPointA(hdc: HDC; text: PAnsiChar; len: Integer; Size: Pointer): BOOL; stdcall;<br>Var s: AnsiString;<br>begin<br>&nbsp; try<br>&nbsp; &nbsp; if Len&lt;0 then Len:=strlen(text);<br>&nbsp; &nbsp; if Len&gt;0 then begin<br>&nbsp; &nbsp; &nbsp; SetLength(s,len);<br>&nbsp; &nbsp; &nbsp; FillChar(s[1],len+1,0);<br>&nbsp; &nbsp; &nbsp; Move(text^,s[1],len);<br>&nbsp; &nbsp; &nbsp; if @ConvertTextFunction&lt;&gt;nil then<br>&nbsp; &nbsp; &nbsp; &nbsp; s:=ConvertTextFunction(s);<br>&nbsp; &nbsp; &nbsp; if @OldGetTextExtentPointA&lt;&gt;nil then<br>&nbsp; &nbsp; &nbsp; &nbsp; Result:=OldGetTextExtentPointA(hdc,PAnsiChar(s),length(s),Size) &nbsp; &nbsp; &nbsp;else Result:=False;<br>&nbsp; &nbsp; end else Result:=OldGetTextExtentPointA(hdc,text,0,Size);<br>&nbsp; except<br>&nbsp; &nbsp; Result:=False;<br>&nbsp; end;<br>end;<br><br><br>function NewGetTextExtentPointW(hdc: HDC; text: PWideChar; len: Integer; Size: Pointer): BOOL; stdcall;<br>Var s: WideString;<br>begin<br>&nbsp; try<br>&nbsp; &nbsp; if Len&lt;0 then Len:=strlenW(text);<br>&nbsp; &nbsp; if Len&gt;0 then begin<br>&nbsp; &nbsp; &nbsp; SetLength(s,len);<br>&nbsp; &nbsp; &nbsp; FillChar(s[1],len*2+2,0);<br>&nbsp; &nbsp; &nbsp; Move(text^,s[1],len);<br>&nbsp; &nbsp; &nbsp; if @ConvertTextFunction&lt;&gt;nil then<br>&nbsp; &nbsp; &nbsp; &nbsp; s:=ConvertTextFunction(s);<br>&nbsp; &nbsp; &nbsp; if @OldGetTextExtentPoint32W&lt;&gt;nil then<br>&nbsp; &nbsp; &nbsp; &nbsp; Result:=OldGetTextExtentPointW(hdc,PWideChar(s),length(s),Size) &nbsp; &nbsp; &nbsp;else Result:=False;<br>&nbsp; &nbsp; end else Result:=OldGetTextExtentPointW(hdc,text,0,Size);<br>&nbsp; except<br>&nbsp; &nbsp; Result:=False;<br>&nbsp; end;<br>end;<br><br>function PointerToFunctionAddress(Code: Pointer): PPointer;<br>Var func: PImportCode;<br>begin<br>&nbsp; Result:=nil;<br>&nbsp; if Code=nil then exit;<br>&nbsp; try<br>&nbsp; &nbsp; func:=code;<br>&nbsp; &nbsp; if (func.JumpInstruction=$25FF) then begin<br>&nbsp; &nbsp; &nbsp; Result:=func.AddressOfPointerToFunction;<br>&nbsp; &nbsp; end;<br>&nbsp; except<br>&nbsp; &nbsp; Result:=nil;<br>&nbsp; end;<br>end;<br><br>function FinalFunctionAddress(Code: Pointer): Pointer;<br>Var func: PImportCode;<br>begin<br>&nbsp; Result:=Code;<br>&nbsp; if Code=nil then exit;<br>&nbsp; try<br>&nbsp; &nbsp; func:=code;<br>&nbsp; &nbsp; if (func.JumpInstruction=$25FF) then begin<br>&nbsp; &nbsp; &nbsp; Result:=func.AddressOfPointerToFunction^;<br>&nbsp; &nbsp; end;<br>&nbsp; except<br>&nbsp; &nbsp; Result:=nil;<br>&nbsp; end;<br>end;<br><br><br>Function PatchAddress(OldFunc, NewFunc: Pointer): Integer;<br>Var BeenDone: TList;<br><br>Function PatchAddressInModule(hModule: THandle; OldFunc, NewFunc: Pointer): Integer;<br>Var Dos: PImageDosHeader; NT: PImageNTHeaders;<br>ImportDesc: PImage_Import_Entry; rva: DWORD;<br>Func: PPointer; DLL: String; f: Pointer; written: DWORD;<br>begin<br>&nbsp; Result:=0;<br>&nbsp; Dos:=Pointer(hModule);<br>&nbsp; if BeenDone.IndexOf(Dos)&gt;=0 then exit;<br>&nbsp; BeenDone.Add(Dos);<br>&nbsp; OldFunc:=FinalFunctionAddress(OldFunc);<br>&nbsp; if IsBadReadPtr(Dos,SizeOf(TImageDosHeader)) then exit;<br>&nbsp; if Dos.e_magic&lt;&gt;IMAGE_DOS_SIGNATURE then exit;<br>&nbsp; NT :=Pointer(Integer(Dos) + dos._lfanew);<br>// &nbsp;if IsBadReadPtr(NT,SizeOf(TImageNtHeaders)) then exit;<br><br>RVA:=NT^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress; <br><br>&nbsp; if RVA=0 then exit;<br>&nbsp; ImportDesc := pointer(integer(Dos)+RVA);<br>&nbsp; While (ImportDesc^.Name&lt;&gt;0) do begin<br>&nbsp; &nbsp; DLL:=PChar(Integer(Dos)+ImportDesc^.Name);<br>&nbsp; &nbsp; PatchAddressInModule(GetModuleHandle(PChar(DLL)),OldFunc,NewFunc); &nbsp; &nbsp;Func:=Pointer(Integer(DOS)+ImportDesc.LookupTable);<br>&nbsp; &nbsp; While Func^&lt;&gt;nil do begin<br>&nbsp; &nbsp; &nbsp; f:=FinalFunctionAddress(Func^);<br>&nbsp; &nbsp; &nbsp; if f=OldFunc then begin<br>&nbsp; &nbsp; &nbsp; &nbsp; WriteProcessMemory(GetCurrentProcess,Func,@NewFunc,4,written); &nbsp; &nbsp; &nbsp; &nbsp;If Written&gt;0 then Inc(Result);<br>&nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; &nbsp; Inc(Func);<br>&nbsp; &nbsp; end;<br>&nbsp; &nbsp; Inc(ImportDesc);<br>&nbsp; end;<br>end;<br><br><br>begin<br>&nbsp; BeenDone:=TList.Create;<br>&nbsp; try<br>&nbsp; &nbsp; Result:=PatchAddressInModule(GetModuleHandle(nil),OldFunc,NewFunc); &nbsp;finally<br>&nbsp; &nbsp; BeenDone.Free;<br>&nbsp; end;<br>end;<br><br>procedure HookTextOut(ConvertFunction: TConvertTextFunction);<br>begin<br>&nbsp; if @OldTextOutA=nil then<br>&nbsp; &nbsp; @OldTextOutA:=FinalFunctionAddress(@TextOutA);<br>&nbsp; if @OldTextOutW=nil then<br>&nbsp; &nbsp; @OldTextOutW:=FinalFunctionAddress(@TextOutW);<br><br>&nbsp; if @OldExtTextOutA=nil then<br>&nbsp; &nbsp; @OldExtTextOutA:=FinalFunctionAddress(@ExtTextOutA);<br>&nbsp; if @OldExtTextOutW=nil then<br>&nbsp; &nbsp; @OldExtTextOutW:=FinalFunctionAddress(@ExtTextOutW);<br><br>&nbsp; if @OldDrawTextA=nil then<br>&nbsp; &nbsp; @OldDrawTextA:=FinalFunctionAddress(@DrawTextA);<br>&nbsp; if @OldDrawTextW=nil then<br>&nbsp; &nbsp; @OldDrawTextW:=FinalFunctionAddress(@DrawTextW);<br><br>&nbsp; if @OldDrawTextExA=nil then<br>&nbsp; &nbsp; @OldDrawTextExA:=FinalFunctionAddress(@DrawTextExA);<br>&nbsp; if @OldDrawTextExW=nil then<br>&nbsp; &nbsp; @OldDrawTextExW:=FinalFunctionAddress(@DrawTextExW);<br><br>&nbsp; if @OldTabbedTextOutA=nil then<br>&nbsp; &nbsp; @OldTabbedTextOutA:=FinalFunctionAddress(@TabbedTextOutA);<br>&nbsp; if @OldTabbedTextOutW=nil then<br>&nbsp; &nbsp; @OldTabbedTextOutW:=FinalFunctionAddress(@TabbedTextOutW);<br><br>&nbsp; if @OldPolyTextOutA=nil then<br>&nbsp; &nbsp; @OldPolyTextOutA:=FinalFunctionAddress(@PolyTextOutA);<br>&nbsp; if @OldPolyTextOutW=nil then<br>&nbsp; &nbsp; @OldPolyTextOutW:=FinalFunctionAddress(@PolyTextOutW);<br><br>&nbsp; if @OldGetTextExtentExPointA=nil then<br><br>@OldGetTextExtentExPointA:=FinalFunctionAddress(@GetTextExtentExPointA); <br><br>&nbsp; if @OldGetTextExtentExPointW=nil then<br><br>@OldGetTextExtentExPointW:=FinalFunctionAddress(@GetTextExtentExPointW); <br><br>&nbsp; if @OldGetTextExtentPoint32A=nil then<br><br>@OldGetTextExtentPoint32A:=FinalFunctionAddress(@GetTextExtentPoint32A); <br><br>&nbsp; if @OldGetTextExtentPoint32W=nil then<br><br>@OldGetTextExtentPoint32W:=FinalFunctionAddress(@GetTextExtentPoint32W); <br><br><br>&nbsp; if @OldGetTextExtentPointA=nil then<br>&nbsp; &nbsp; @OldGetTextExtentPointA:=FinalFunctionAddress(@GetTextExtentPointA); <br><br>&nbsp; if @OldGetTextExtentPointW=nil then<br>&nbsp; &nbsp; @OldGetTextExtentPointW:=FinalFunctionAddress(@GetTextExtentPointW); <br><br><br><br>&nbsp; @ConvertTextFunction:=@ConvertFunction;<br><br>&nbsp; PatchAddress(@OldTextOutA, @NewTextOutA);<br>&nbsp; PatchAddress(@OldTextOutW, @NewTextOutW);<br>&nbsp; PatchAddress(@OldExtTextOutA, @NewExtTextOutA);<br>&nbsp; PatchAddress(@OldExtTextOutW, @NewExtTextOutW);<br>&nbsp; PatchAddress(@OldDrawTextA, @NewDrawTextA);<br>&nbsp; PatchAddress(@OldDrawTextW, @NewDrawTextW);<br>&nbsp; PatchAddress(@OldDrawTextExA, @NewDrawTextExA);<br>&nbsp; PatchAddress(@OldDrawTextExW, @NewDrawTextExW);<br>&nbsp; PatchAddress(@OldTabbedTextOutA, @NewTabbedTextOutA);<br>&nbsp; PatchAddress(@OldTabbedTextOutW, @NewTabbedTextOutW);<br>&nbsp; PatchAddress(@OldPolyTextOutA, @NewPolyTextOutA);<br>&nbsp; PatchAddress(@OldPolyTextOutW, @NewPolyTextOutW);<br>&nbsp; PatchAddress(@OldGetTextExtentExPointA, @NewGetTextExtentExPointA); &nbsp;PatchAddress(@OldGetTextExtentExPointW, @NewGetTextExtentExPointW); &nbsp;PatchAddress(@OldGetTextExtentPoint32A, @NewGetTextExtentPoint32A); &nbsp;PatchAddress(@OldGetTextExtentPoint32W, @NewGetTextExtentPoint32W); &nbsp;PatchAddress(@OldGetTextExtentPointA, @NewGetTextExtentPointA); &nbsp;PatchAddress(@OldGetTextExtentPointW, @NewGetTextExtentPointW); end;<br><br>procedure UnhookTextOut;<br>begin<br>&nbsp; If @OldTextOutA&lt;&gt;nil then begin<br>&nbsp; &nbsp; PatchAddress(@NewTextOutA, @OldTextOutA);<br>&nbsp; &nbsp; PatchAddress(@NewTextOutW, @OldTextOutW);<br>&nbsp; &nbsp; PatchAddress(@NewExtTextOutA, @OldExtTextOutA);<br>&nbsp; &nbsp; PatchAddress(@NewExtTextOutW, @OldExtTextOutW);<br>&nbsp; &nbsp; PatchAddress(@NewDrawTextA, @OldDrawTextA);<br>&nbsp; &nbsp; PatchAddress(@NewDrawTextW, @OldDrawTextW);<br>&nbsp; &nbsp; PatchAddress(@NewDrawTextExA, @OldDrawTextExA);<br>&nbsp; &nbsp; PatchAddress(@NewDrawTextExW, @OldDrawTextExW);<br>&nbsp; &nbsp; PatchAddress(@NewTabbedTextOutA, @OldTabbedTextOutA);<br>&nbsp; &nbsp; PatchAddress(@NewTabbedTextOutW, @OldTabbedTextOutW);<br>&nbsp; &nbsp; PatchAddress(@NewPolyTextOutA, @OldPolyTextOutA);<br>&nbsp; &nbsp; PatchAddress(@NewPolyTextOutW, @OldPolyTextOutW);<br>&nbsp; &nbsp; PatchAddress(@NewGetTextExtentExPointA, @OldGetTextExtentExPointA); &nbsp; &nbsp;PatchAddress(@NewGetTextExtentExPointW, @OldGetTextExtentExPointW); &nbsp; &nbsp;PatchAddress(@NewGetTextExtentPoint32A, @OldGetTextExtentPoint32A); &nbsp; &nbsp;PatchAddress(@NewGetTextExtentPoint32W, @OldGetTextExtentPoint32W); &nbsp; &nbsp;PatchAddress(@NewGetTextExtentPointA, @OldGetTextExtentPointA); &nbsp; &nbsp;PatchAddress(@NewGetTextExtentPointW, @OldGetTextExtentPointW); &nbsp;end;<br>end;<br><br>initialization<br>finalization<br>&nbsp; UnhookTextOut;<br>end.<br><br>===================================================<br>unit PEStuff;<br><br>interface<br>uses Windows;<br><br>type<br>&nbsp; PImageDosHeader = ^TImageDosHeader;<br>&nbsp; _IMAGE_DOS_HEADER = packed record &nbsp; &nbsp; &nbsp;{ DOS .EXE<br>header &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br>&nbsp; &nbsp; &nbsp; e_magic: Word; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{ Magic<br>number &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br>&nbsp; &nbsp; &nbsp; e_cblp: Word; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{ Bytes on last page of file &nbsp; &nbsp; &nbsp;}<br>&nbsp; &nbsp; &nbsp; e_cp: Word; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{ Pages in<br>file &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br>&nbsp; &nbsp; &nbsp; e_crlc: Word; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{<br>Relocations &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br>&nbsp; &nbsp; &nbsp; e_cparhdr: Word; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{ Size of header in<br>paragraphs &nbsp; &nbsp;}<br>&nbsp; &nbsp; &nbsp; e_minalloc: Word; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{ Minimum extra paragraphs needed &nbsp;}<br>&nbsp; &nbsp; &nbsp; e_maxalloc: Word; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{ Maximum extra paragraphs needed &nbsp;}<br>&nbsp; &nbsp; &nbsp; e_ss: Word; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{ Initial (relative) SS value &nbsp; &nbsp; &nbsp;}<br>&nbsp; &nbsp; &nbsp; e_sp: Word; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{ Initial SP<br>value &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br>&nbsp; &nbsp; &nbsp; e_csum: Word; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{<br>Checksum &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br>&nbsp; &nbsp; &nbsp; e_ip: Word; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{ Initial IP<br>value &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br>&nbsp; &nbsp; &nbsp; e_cs: Word; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{ Initial (relative) CS value &nbsp; &nbsp; &nbsp;}<br>&nbsp; &nbsp; &nbsp; e_lfarlc: Word; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{ File address of relocation table }<br>&nbsp; &nbsp; &nbsp; e_ovno: Word; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{ Overlay<br>number &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br>&nbsp; &nbsp; &nbsp; e_res: array [0..3] of Word; &nbsp; &nbsp; &nbsp;{ Reserved<br>words &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br>&nbsp; &nbsp; &nbsp; e_oemid: Word; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{ OEM identifier (for<br>e_oeminfo) &nbsp;}<br>&nbsp; &nbsp; &nbsp; e_oeminfo: Word; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{ OEM information; e_oemid specific}<br>&nbsp; &nbsp; &nbsp; e_res2: array [0..9] of Word; &nbsp; &nbsp; &nbsp;{ Reserved<br>words &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br>&nbsp; &nbsp; &nbsp; _lfanew: LongInt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{ File address of new exe header &nbsp;}<br>&nbsp; end;<br>&nbsp; TImageDosHeader = _IMAGE_DOS_HEADER;<br><br>&nbsp; PIMAGE_FILE_HEADER = ^IMAGE_FILE_HEADER;<br>&nbsp; IMAGE_FILE_HEADER = packed record<br>&nbsp; &nbsp; Machine &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;: WORD;<br>&nbsp; &nbsp; NumberOfSections &nbsp; &nbsp;: WORD;<br>&nbsp; &nbsp; TimeDateStamp &nbsp; &nbsp; &nbsp; &nbsp;: DWORD;<br>&nbsp; &nbsp; PointerToSymbolTable : DWORD;<br>&nbsp; &nbsp; NumberOfSymbols &nbsp; &nbsp; &nbsp;: DWORD;<br>&nbsp; &nbsp; SizeOfOptionalHeader : WORD;<br>&nbsp; &nbsp; Characteristics &nbsp; &nbsp; &nbsp;: WORD;<br>&nbsp; end;<br><br>&nbsp; PIMAGE_DATA_DIRECTORY = ^IMAGE_DATA_DIRECTORY;<br>&nbsp; IMAGE_DATA_DIRECTORY = packed record<br>&nbsp; &nbsp; VirtualAddress &nbsp;: DWORD;<br>&nbsp; &nbsp; Size &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;: DWORD;<br>&nbsp; end;<br><br>&nbsp; PIMAGE_SECTION_HEADER = ^IMAGE_SECTION_HEADER;<br>&nbsp; IMAGE_SECTION_HEADER = packed record<br>&nbsp; &nbsp; Name &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;: packed array [0..IMAGE_SIZEOF_SHORT_NAME-1] of Char;<br>&nbsp; &nbsp; VirtualSize : DWORD; // or VirtualSize (union);<br>&nbsp; &nbsp; VirtualAddress &nbsp;: DWORD;<br>&nbsp; &nbsp; SizeOfRawData &nbsp;: DWORD;<br>&nbsp; &nbsp; PointerToRawData : DWORD;<br>&nbsp; &nbsp; PointerToRelocations : DWORD;<br>&nbsp; &nbsp; PointerToLinenumbers : DWORD;<br>&nbsp; &nbsp; NumberOfRelocations : WORD;<br>&nbsp; &nbsp; NumberOfLinenumbers : WORD;<br>&nbsp; &nbsp; Characteristics : DWORD;<br>&nbsp; end;<br><br>&nbsp; PIMAGE_OPTIONAL_HEADER = ^IMAGE_OPTIONAL_HEADER;<br>&nbsp; IMAGE_OPTIONAL_HEADER = packed record<br>&nbsp; { Standard fields. }<br>&nbsp; &nbsp; Magic &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;: WORD;<br>&nbsp; &nbsp; MajorLinkerVersion : Byte;<br>&nbsp; &nbsp; MinorLinkerVersion : Byte;<br>&nbsp; &nbsp; SizeOfCode &nbsp; &nbsp; &nbsp;: DWORD;<br>&nbsp; &nbsp; SizeOfInitializedData : DWORD;<br>&nbsp; &nbsp; SizeOfUninitializedData : DWORD;<br>&nbsp; &nbsp; AddressOfEntryPoint : DWORD;<br>&nbsp; &nbsp; BaseOfCode &nbsp; &nbsp; &nbsp;: DWORD;<br>&nbsp; &nbsp; BaseOfData &nbsp; &nbsp; &nbsp;: DWORD;<br>&nbsp; { NT additional fields. }<br>&nbsp; &nbsp; ImageBase &nbsp; &nbsp; &nbsp;: DWORD;<br>&nbsp; &nbsp; SectionAlignment : DWORD;<br>&nbsp; &nbsp; FileAlignment &nbsp;: DWORD;<br>&nbsp; &nbsp; MajorOperatingSystemVersion : WORD;<br>&nbsp; &nbsp; MinorOperatingSystemVersion : WORD;<br>&nbsp; &nbsp; MajorImageVersion : WORD;<br>&nbsp; &nbsp; MinorImageVersion : WORD;<br>&nbsp; &nbsp; MajorSubsystemVersion : WORD;<br>&nbsp; &nbsp; MinorSubsystemVersion : WORD;<br>&nbsp; &nbsp; Reserved1 &nbsp; &nbsp; &nbsp;: DWORD;<br>&nbsp; &nbsp; SizeOfImage &nbsp; &nbsp;: DWORD;<br>&nbsp; &nbsp; SizeOfHeaders &nbsp;: DWORD;<br>&nbsp; &nbsp; CheckSum &nbsp; &nbsp; &nbsp; &nbsp;: DWORD;<br>&nbsp; &nbsp; Subsystem &nbsp; &nbsp; &nbsp;: WORD;<br>&nbsp; &nbsp; DllCharacteristics : WORD;<br>&nbsp; &nbsp; SizeOfStackReserve : DWORD;<br>&nbsp; &nbsp; SizeOfStackCommit : DWORD;<br>&nbsp; &nbsp; SizeOfHeapReserve : DWORD;<br>&nbsp; &nbsp; SizeOfHeapCommit : DWORD;<br>&nbsp; &nbsp; LoaderFlags &nbsp; &nbsp;: DWORD;<br>&nbsp; &nbsp; NumberOfRvaAndSizes : DWORD;<br>&nbsp; &nbsp; DataDirectory &nbsp;: packed array<br>[0..IMAGE_NUMBEROF_DIRECTORY_ENTRIES-1] of IMAGE_DATA_DIRECTORY; &nbsp; &nbsp;Sections: packed array [0..9999] of IMAGE_SECTION_HEADER;<br>&nbsp; end;<br><br>&nbsp; PIMAGE_NT_HEADERS = ^IMAGE_NT_HEADERS;<br>&nbsp; IMAGE_NT_HEADERS = packed record<br>&nbsp; &nbsp; Signature &nbsp; &nbsp; &nbsp;: DWORD;<br>&nbsp; &nbsp; FileHeader &nbsp; &nbsp; &nbsp;: IMAGE_FILE_HEADER;<br>&nbsp; &nbsp; OptionalHeader &nbsp;: IMAGE_OPTIONAL_HEADER;<br>&nbsp; end;<br>&nbsp; PImageNtHeaders = PIMAGE_NT_HEADERS;<br>&nbsp; TImageNtHeaders = IMAGE_NT_HEADERS;<br><br>{ &nbsp;PIMAGE_IMPORT_DESCRIPTOR = ^IMAGE_IMPORT_DESCRIPTOR;<br>&nbsp; IMAGE_IMPORT_DESCRIPTOR = packed record<br>&nbsp; &nbsp; Characteristics: DWORD; // or original first thunk // 0 for<br>terminating null import descriptor // RVA to original unbound IAT &nbsp; &nbsp;TimeDateStamp: DWORD; // 0 if not bound,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // -1 if bound, and real date/time stamp &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// &nbsp; &nbsp;in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new BIND)<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // O.W. date/time stamp of DLL bound to (Old BIND)<br>&nbsp; &nbsp; Name: DWORD;<br>&nbsp; &nbsp; FirstThunk: DWORD; &nbsp;// PIMAGE_THUNK_DATA // RVA to IAT (if bound this IAT has actual addresses)<br>&nbsp; &nbsp; ForwarderChain: DWORD; // -1 if no forwarders<br>&nbsp; end;<br>&nbsp; TImageImportDescriptor = IMAGE_IMPORT_DESCRIPTOR;<br>&nbsp; PImageImportDescriptor = PIMAGE_IMPORT_DESCRIPTOR;}<br><br>&nbsp; PIMAGE_IMPORT_BY_NAME = ^IMAGE_IMPORT_BY_NAME;<br>&nbsp; IMAGE_IMPORT_BY_NAME = record<br>&nbsp; &nbsp; Hint: Word;<br>&nbsp; &nbsp; Name: Array[0..0] of Char;<br>&nbsp; end;<br><br>&nbsp; PIMAGE_THUNK_DATA = ^IMAGE_THUNK_DATA;<br>&nbsp; IMAGE_THUNK_DATA = record<br>&nbsp; &nbsp; Whatever: DWORD;<br>&nbsp; end;<br><br>&nbsp; PImage_Import_Entry = ^Image_Import_Entry;<br>&nbsp; Image_Import_Entry = record<br>&nbsp; &nbsp; Characteristics: DWORD;<br>&nbsp; &nbsp; TimeDateStamp: DWORD;<br>&nbsp; &nbsp; MajorVersion: Word;<br>&nbsp; &nbsp; MinorVersion: Word;<br>&nbsp; &nbsp; Name: DWORD;<br>&nbsp; &nbsp; LookupTable: DWORD;<br>&nbsp; end;<br><br><br>const<br>IMAGE_DOS_SIGNATURE &nbsp; &nbsp;= &nbsp;$5A4D; &nbsp; &nbsp; &nbsp;// MZ<br>IMAGE_OS2_SIGNATURE &nbsp; &nbsp;= &nbsp;$454E; &nbsp; &nbsp; &nbsp;// NE<br>IMAGE_OS2_SIGNATURE_LE &nbsp;= &nbsp;$454C; &nbsp; &nbsp; &nbsp;// LE<br>IMAGE_VXD_SIGNATURE &nbsp; &nbsp;= &nbsp;$454C; &nbsp; &nbsp; &nbsp;// LE<br>IMAGE_NT_SIGNATURE &nbsp; &nbsp; &nbsp;= &nbsp;$00004550; &nbsp;// PE00<br><br>implementation<br><br>end.<br><br>=================================================<br>Create a new project with one form, with two buttons.<br>=================================================<br><br><br>unit PigLatinUnit;<br><br>interface<br><br>uses<br>&nbsp; Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,<br>&nbsp; StdCtrls;<br><br>type<br>&nbsp; TForm1 = class(TForm)<br>&nbsp; &nbsp; Button1: TButton;<br>&nbsp; &nbsp; Button2: TButton;<br>&nbsp; &nbsp; procedure Button1Click(Sender: TObject);<br>&nbsp; &nbsp; procedure Button2Click(Sender: TObject);<br>&nbsp; private<br>&nbsp; &nbsp; { Private declarations }<br>&nbsp; public<br>&nbsp; &nbsp; { Public declarations }<br>&nbsp; end;<br><br>var<br>&nbsp; Form1: TForm1;<br><br>implementation<br><br>{$R *.DFM}<br>procedure StartHook; stdcall; external 'PigLatinDll.DLL';<br>procedure StopHook; stdcall; external 'PigLatinDll.DLL';<br><br>procedure TForm1.Button1Click(Sender: TObject);<br>begin<br>&nbsp; WindowState:=wsMaximized;<br>&nbsp; StartHook;<br>&nbsp; Sleep(1000);<br>&nbsp; WindowState:=wsNormal;<br>end;<br><br>procedure TForm1.Button2Click(Sender: TObject);<br>begin<br>&nbsp; WindowState:=wsMaximized;<br>&nbsp; StopHook;<br>&nbsp; Sleep(1000);<br>&nbsp; WindowState:=wsNormal;<br>end;<br><br>initialization<br>finalization<br>&nbsp; StopHook;<br>end.
 
顶部