library PigLatinDll; uses Windows, SysUtils, Classes, HookTextUnit in 'HookTextUnit.pas'; function PigLatinWord (s: String): String; Var start: String; Capitalize, AllCapitals: Boolean; i: Integer; begin Result: = s; if Length (s) <= 1 THEN EXIT; Capitalize: = Ischarupper (s [1]); allcapitals: = true; for i: = 1 to length (s) do begin if ischarlower (s [i]) THEN BEGIN AllCapitals: = False; Break; end; end; start: = Lowercase (COPY (S, 1, 2)); if (start [1] <'a') or (start [1]> 'Z') THEN EXIT; IF (Start [1] in ['A', 'E', 'I', 'O', 'U']) THEN START: = '; IF (Start <>') And (Start <> " TH ') AND (Start <> ") and (start <>' qu ') AND (Start <>' qn ') and (start <>' wr ') Then Delete (Start, 2, 1); Result: = Copy (S, Length 1, Length (s)) start; if start = '' Then Result: = Result 'Yay' Else Result: = Result 'AY '; If allCapitals the result: = Uppercase (Result) Else if capitalize the result [1]: = Upcase (Result [1]); end; function INTORMAN (N: Integer): String; Var i, units, Tens, Hundreds Thousands: Integer; begin if (n> = 5000) OR (n <= 0) Then Result: = INTOSTR (N) Else Begin Thousands: = N Div 1000; N: = N MOD 1000; Hundreds: = N Div 100; N: = N mod 100; TENS: = N DIV 10; N: = n MOD 10; Units: = N; Result: = '; for i: = 1 to Thousands do beg, result: = Result ' m '; end; case; Hundreds of 1: Result: = Result 'C'; 2: Result: = Result 'CC';
3: Result: = Result 'CCC'; 4: Result: = Result 'CD'; 5: Result: = Result 'D'; 6: Result: = Result 'DC'; 7: Result: = Result 'DCC'; 8: Result: = Result 'DCCC'; 9: Result: = Result 'cm'; End; Case Tens of 1: Result: = Result 'X'; 2: Result: = Result 'XX'; 3: Result: = Result 'xxx'; 4: Result: = Result 'XL'; 5: Result: = Result 'L'; 6: Result: = Result 'lx'; 7: Result: = Result 'Lxx'; 8: Result: = Result 'Lxxx'; 9: Result: = Result 'XC'; END; CASE Units of 1: Result: = Result 'I'; 2: Result: = Result 'Ii'; 3: Result: = Result 'III'; 4: Result: = Result 'IV'; 5: Result: = Result 'V'; 6: Result: = Result 'vi'; 7: Result: = Result 'VII'; 8: Result: = Result 'VIII' 9: Result: = Result 'ix'; end; end; end; function latinnumber (s: string): string; var N: integer; begin try n: = start (s); result: = INTOROMAN (N); ExcePT Result: = S; end; end; function conv (s: string): string; var i: integer; w: string; begin Result: = '; try if s =' '' TEN EXIT; I: = 1; while (i <= length (s)) DO Begin While (i <= length (s)) AND (S [i] <= '') Do Begin Result: = Result S [I]; Inc (i); end; // convert any number = ';
While (I <= Length (s)) and (s [i]> = '0') AND (S [i] <= '9') DO Begin W: = W S [I]; Inc (i) End; result: = result latinnumber (w); // add any other symbols unchanged (for now) W: = ''; while (i <= length (s)) and not ischaralphanumeric (s [i]) DO Begin W: = W S [I]; INC (I); End; Result: = Result W; // Convert Whole Words INTO PIG LATIN W: = '; while (i <= length (s)) and Ischaralpha (s [i]) DO Begin W: = W S [I]; INC (I); End; Result: = Result PiglatinWord (W); END; ExcePt End; End; Function GetMsgProc (Code: integer; removal: integer; msg: Pointer): Integer; stdcall; begin Result: = 0; end; Var HookHandle: THandle; procedure StartHook; stdcall; begin HookHandle: = SetWindowsHookEx (WH_GETMESSAGE, @GetMsgProc, hInstance, 0); end; procedure Stophook; hook unhookwindowshookex (hook "; end; eXports starthook, stophook; begin hooktextout (conv); end. =========================== ===========================1 hooktextunit; Interfa ceuses Windows, SysUtils, Classes, PEStuff; type TConvertTextFunction = function (text: String): String; TTextOutA = function (hdc: HDC; x, y: Integer; text: PAnsiChar; len: Integer): BOOL; stdcall; TTextOutW = Function (hdc: hdc; x, y: integer; text: bool; stdcall; texttextouta = function (hdc: hdc; x, y: integer; options: dword; clip: prect;
TEXT: PANSICHAR; LEN: INTEGER; DX: PINTEGER: BOOL; stdcall; texttextoutw = function (hdc: hdc; x, y: integer; option; type; clip: prect; text: pwidechar; len: integer; dx: pinteger : Bool; stdcall; tdrawtexta = function (HDC: HDC; Text: Pansichar; LEN: Integer; Rect: prect; Format: DWORD): Integer; stdcall; tdrawtextw = function (hdc: hdc; text: pWideChar; len: integer ; rect: pRect; Format: DWORD): Integer; stdcall; TDrawTextExA = function (hdc: HDC; text: PAnsiChar; len: Integer; rect: pRect; Format: DWORD; DTParams: PDrawTextParams): Integer; stdcall; TDrawTextExW = function (hdc: HDC; text: PWideChar; len: Integer; rect: pRect; Format: DWORD; DTParams: PDrawTextParams): Integer; stdcall; TTabbedTextOutA = function (hdc: HDC; x, y: Integer; text: PAnsiChar; len: Integer; TabCounts: Pinteger; Taborigin: Integer: Integer; STDC all; TTabbedTextOutW = function (hdc: HDC; x, y: Integer; text: PWideChar; len: Integer; TabCount: Integer; TabPositions: PInteger; TabOrigin: Integer): Integer; stdcall; TPolyTextOutA = function (hdc: HDC; pptxt : PPOLYTEXTA; count: Integer): BOOL; stdcall; TPolyTextOutW = function (hdc: HDC; pptxt: PPOLYTEXTW; count: Integer): BOOL; stdcall; TGetTextExtentExPointA = function (hdc: HDC; text: PAnsiChar; len: Integer; maxExtent : Integer; Fit: Pinteger; DX: PINTEGER; SIZE: POINTER: BOOL; stdcall; tgettextextentexpointw = function (hdc: hdc; text: pWideChar; len: integer; maxextent: integer; fit: pinteger;
Dx: PInteger; Size: Pointer): BOOL; stdcall; TGetTextExtentPoint32A = function (hdc: HDC; text: PAnsiChar; len: Integer; Size: Pointer): BOOL; stdcall; TGetTextExtentPoint32W = function (hdc: HDC; text: PWideChar; len: Integer; Size: Pointer): BOOL; stdcall; TGetTextExtentPointA = function (hdc: HDC; text: PAnsiChar; len: Integer; Size: Pointer): BOOL; stdcall; TGetTextExtentPointW = function (hdc: HDC; text: PWideChar; len: Integer; Size: Pointer): BOOL; stdcall; PPointer = ^ Pointer; TImportCode = packed record JumpInstruction: Word; // should be $ 25FF AddressOfPointerToFunction: PPointer; end; PImportCode = ^ TImportCode; procedure HookTextOut (ConvertFunction: TConvertTextFunction) ; procedure UnhookTextOut; implementationVar ConvertTextFunction: TConvertTextFunction = nil; OldTextOutA: TTextOutA = nil; OldTextOutW: TTextOutW = nil; OldExtTextOutA: TExtTextOutA = nil; OldExtTextOutW: TExtTextOutW = nil; OldDrawTextA: TDrawTextA = nil; OldDrawTextW: TDrawTextW = nil; OldD rawTextExA: TDrawTextExA = nil; OldDrawTextExW: TDrawTextExW = nil; OldTabbedTextOutA: TTabbedTextOutA = nil; OldTabbedTextOutW: TTabbedTextOutW = nil; OldPolyTextOutA: TPolyTextOutA = nil; OldPolyTextOutW: TPolyTextOutW = nil; OldGetTextExtentExPointA: TGetTextExtentExPointA = nil; OldGetTextExtentExPointW: TGetTextExtentExPointW = nil; OldGetTextExtentPoint32A: TGetTextExtentPoint32A = nil; OldGetTextExtentPoint32W: TGetTextExtentPoint32W = nil; OldGetTextExtentPointA: TGetTextExtentPointA = nil; OldGetTextExtentPointW: TGetTextExtentPointW = nil; function StrLenW (s: PWideChar): Integer; Var i: Integer; begin if s =
NIL THEN Begin Result: = 0; End; End; I: = 0; Try While (S [i] <> # 0) DO INC (I); ExcePt End; Result: = I; End; Function NewTextouta (HDC: HDC; X, Y: INTEGER; TEXT: PANSICHAR; LEN: INTEGER: BOOL; stdcall; var s: string; begin tryness; if len: = strlen (text); if len> 0 Then Begin SetLENGTH (S , LEN); Fillchar (S [1], LEN 1, 0); Move (Text ^, S [1], LEN); if @converttextFunction <> nil the s: = convertTextFunction (s); if @oldtextouta < > NIL THEN RESULT: = OldTextOuta (HDC, X, Y, Pansichar (s), Length (s)) Else Result: = false; Else Result: = Oldtextouta (HDC, X, Y, Pansichar (s), 0) EXCEPT Result: = false; end; end; function newtextoutw (HDC: HDC; x, y: integer; text: pwidechar; len: integer: bool; stdcall; var s: wideString; begin try if len <0 Then Len : = Strlenw (Text); if Len> 0 Then Begin SetLENGTH (S, LEN); FillChar (S [1], Len * 2 2, 0); Move (Text ^, S [1], Len * 2) ; If @ConvertTextFunction <> nil the s: = convertTextFunction (s); if @oldte Xtoutw <> nil dam: = OldTextOutw (HDC, X, Y, PWIDECHAR (S), Length (s)) Else Result: = false; end else result: = OldTextOutw (HDC, X, Y, PWIDECHAR (S), 0); EXCEPT RESULT: = false; end; end; function newextTextouta (HDC: HDC; X, Y: Integer; options: dword; clip: prect; text: pansichar; len: integer; dx: pinteger: bool; stdcall): Bool; stdcall Var s: string; begin tryness; be: = strlen (text); // ??? if len> 0 Then Begin setlength (s, len); Fillchar (s [1], len 1, 0); Move (Text ^, s [1], len); if @converttextFunction <> nil the s: = convertTextFunction (s); if @
OldextTextOuta <> nil lifext: = OldextTextOuta (HDC, X, Y, Options, Clip, Pansichar (s), Length (s), dx) else result: = false; end else result: = OldextTextouta (HDC, X, Y, Options, Clip, Text, 0, DX); Except Result: = false; end; end; function newExtTextoutw (HDC: HDC; X, Y: integer; options: dword; clip: prect; text: pWideChar; len: integer; DX: PINTEGER): Bool; stdcall; var s: widestring; begin tryness; need; = strlenw (text); if len> 0 dam (s, len); Fillchar (s, len); Fillchar (s, LEN); * 2 2, 0); Move (Text ^, S [1], Len * 2); if @converttextFunction <> nil the s: = convertTextFunction (s); if @eldextTextOutw <> nil lifeResult: = OldExtTextoutw (HDC) , PWIDECHAR (S), Length (s), dx) Else Result: = false; Else Result: = OldextTextOutw (HDC, X, Y, Options, Clip, Text, 0, DX) EXCEPT RESULT: = false; end; end; function newdrawtexta (HDC: HDC; Text: Pansichar; LEN: Integer; Rect: prect; Format: DWORD): Integer; stdcall; var s: string; begin try if len <0 Then Len: = strle n (text); // ??? if Len> 0 Then Begin setLength (S, LEN); Fillchar (S [1], LEN 1, 0); Move (Text ^, S [1], LEN); IF @ConvertTextFunction <> NIL THEN S: = ConvertTextFunction (s); if @elddrawtexta <> nil dam = OlddrawTexta (HDC, Pansichar (s), Length (s), Rect, Format) Else Result: = 0; END Else Result: = OlddrawTexta (HDC, Text, 0, Rect, Format); EXCEPT Result: = 0; End; End; Function NewDrawTextw (HDC: HDC; Text: PWIDECHAR; LEN: Integer; Rect: prect; Format: DWORD) : Integer; stdcall; var s: widestring; begin tryness; need = strlenw (text); if len>
0 dam (s, len); Fillchar (s [1], len * 2 2, 0); Move (Text ^, s [1], len * 2); if @converttextFunction <> nil the S: = ConvertTextFunction (s); if @OldDrawTextW <> nil then Result: = OldDrawTextW (hdc, PWideChar (s), length (s), rect, Format) else Result: = 0; end else Result: = OldDrawTextW (hdc, text , 0, RECT, FORMAT; End; End; Function NewDrawTextexa (HDC: HDC; Text: Pansichar; LEN: Integer; Rect: prect; Format: DWORD; DTPARAMS: PDRAWTEXTPARAMS: Integer; stdcall; Var s: string; begin try if len <0 dam: = strlen (text); if len> 0 THEN BEGIN SETLENGTH (S, LEN); Fillchar (S [1], LEN 1, 0); MOVE (Text ^, s [1], len); if @convertTextFunction <> nil the s: = convertTextFunction (s); if @olddrawtextexa <> nil thetenx: = OlddrawTextexa (HDC, Pansichar (s), Length (s), RECT, Format, dtparams) Else Result: = 0; end else result: = OlddrawTextexa (HDC, Text, 0, Rect, Format, Dtparams); Except Result: = 0; end; end; function newdrawtext EXW (HDC: HDC; Text: PWIDECHAR; LEN: INTEGER; Rect: prect; Format: DWORD; DTPARAMS: PDRAWTEXTPARAMS: PDRAWTEXTPARAMS: Integer; stdcall; var s: widestring; begin tryness; var s: wideString; begin tryness; If LEN> 0 dam (S, LEN); FillChar (S [1], Len * 2 2, 0); Move (Text ^, S [1], Len * 2); if @converttextFunction <> nil then s: = ConvertTextFunction (s); if @OldDrawTextExW <> nil thenResult: = OldDrawTextExW (hdc, PWideChar (s), length (s), rect, Format, DTParams) else Result: = 0; end else Result: = Olddrawtextexw (HDC, Text, 0, Rect, Format, Dtparams); Except Result: = 0; end;
function NewTabbedTextOutA (hdc: HDC; x, y: Integer; text: PAnsiChar; len: Integer; TabCount: Integer; TabPositions: PInteger; TabOrigin: Integer): Integer; stdcall; Var s: AnsiString; begin try if Len <0 then LEN: = Strlen (Text); if Len> 0 Then Begin SetLENGTH (S, LEN); Fillchar (S [1], LEN 1, 0); Move (Text ^, S [1], LEN); if @ ConvertTextFunction <> nil then s: = ConvertTextFunction (s); if @OldTabbedTextOutA <> nil thenResult: = OldTabbedTextOutA (hdc, x, y, PAnsiChar (s), length (s), TabCount, TabPositions, TabOrigin) else Result: = 0; END ELSERESUT: = OldTabbedTextOuta (HDC, X, Y, Text, 0, TabCount, TabPositions, Taborigin); Except Result: = 0; End; End; Function NEWTABEDTEXTOUTW (HDC: HDC; X, Y: Integer; Text: PWIDECHAR; TabCount: Integer; TabPositions: Pinteger; Taborigin: Integer: Integer; stdcall; var s: wideString; begin tryness; need = strlenw (text); if len> 0 THEN Begin setlength (S, LEN); Fillc HAR (s [1], len * 2 2, 0); Move (Text ^, s [1], len * 2); if @converttextFunction <> nil the s: = convertTextFunction (s); if @oldtabbedtextoutw < > NIL TENRESULT: = OldTabbedTextOutw (HDC, X, Y, PWIDECHAR (S), Length (s), TabCount, TabPositions, Taborigin Else Result: = 0; Elseresult: = OldTabbedTextOutw (HDC, X, Y, Text, 0 , TabCount, TabPositions, TabOrigin); except Result: = 0; end; end; function NewPolyTextOutA (hdc: HDC; pptxt: PPOLYTEXTA; count: Integer): BOOL; stdcall; Var s: String; i: Integer; ppnew: PPOLYTEXTA Begin PPNew: = NIL; Try Result: = false; if count <0 THEN EXIT; if count = 0 THEN Begin Result: = true;
EXIT; END; PPNEW, Count * SizeOf (TPOLYTEXTA)); for i: = 1 to count do beg ppnew ^: = pptxt ^; if ppnew ^ .n <0 THEN PPNEW ^ .n: = Strlen (PPNew ^ .Pansichar); if ppnew ^ .n> 0 Then Begin setlength (s, ppnew ^ .n); FillChar (s [1], ppnew ^ .n 1, 0); Move (Ppnew ^ .pansichar, s [1 ], PPNEW ^ .n); if @ConvertTextFunction <> NIL THEN S: = ConvertTextFunction (s); ppnew ^ .pansichar: = Pansichar (s); PPNEW ^ .n: = Length (s); if @oldpolytextouta <> NIL THEN Result: = OldPolyTextOuta (HDC, PPNEW, 1); End; INC (PPTXT); END; EXCEPT Result: = false; end; if PPNEW <> nil dam (ppnew); end; function newpolytextoutw (HDC: HDC) ; pptxt: PPOLYTEXTW; count: Integer): BOOL; stdcall; begin Result: = OldPolyTextOutW (hdc, pptxt, count); end; function NewGetTextExtentExPointA (hdc: HDC; text: PAnsiChar; len: Integer; maxExtent: Integer; Fit: PINTEGER; DX: PINTEGER; SIZE: POINTER): Bool; stdcall; var s: ansistring; begin tryness; = strlen (text ); If len> 0 dam (s, len); Fillchar (S [1], LEN 1, 0); Move (Text ^, S [1], LEN); if @converttextFunction <> nil dam : = ConvertTextFunction (s); if @OldGetTextExtentExPointA <> nil thenResult: = OldGetTextExtentExPointA (hdc, PAnsiChar (s), length (s), maxExtent, Fit, Dx, Size) else Result: = False; end elseResult: = OldGetTextExtentExPointA ( HDC, TEXT, 0, MAXEXTENT, FIT, DX, SIZE); Except Result: = false; end; end; function newgettextExtentExpointw (HDC: hdc; text: pwidechar; len: integer; maxextent: integer; fits: pinteger; dx: Pinteger; Size: Pointer: Bool; stdcall; var s: wideString;
Begin Try if len <0; if len> 0 THEN BEGIN SETLENGTH (S, LEN); FillChar (S [1], Len * 2 2, 0); Move (Text ^, S [1], len); if @ConvertTextFunction <> nil then s: = ConvertTextFunction (s); if @OldGetTextExtentExPointW <> nil thenResult: = OldGetTextExtentExPointW (hdc, PWideChar (s), length (s), maxExtent, Fit, Dx , Size) else Result: = False; end elseResult: = OldGetTextExtentExPointW (hdc, text, 0, maxExtent, Fit, Dx, Size); except Result: = False; end; end; function NewGetTextExtentPoint32A (hdc: HDC; text: PAnsiChar LEN: INTEGER; SIZE: POINTER: BOOL; stdcall; var s: ansistring; begin tryness; if len: = strlen (text); if len> 0 dam (s, len); Fillchar (s); [1], LEN 1, 0); Move (Text ^, S [1], LEN); if @converttextFunction <> nil the: = convertTextFunction (s); if @ OldgetTextExtentPoint32a <> nil tellte: = OldgetTexTextentPoint32a ( HDC, Pansichar (s), Length (s), size) Else Result: = false; end else result: = OldgetText ExtentPoint32A (hdc, text, 0, Size); except Result: = False; end; end; function NewGetTextExtentPoint32W (hdc: HDC; text: PWideChar; len: Integer; Size: Pointer): BOOL; stdcall; Var s: WideString; Begin Try if len <0; if len> 0 THEN BEGIN SETLENGTH (S, LEN); FillChar (S [1], Len * 2 2, 0); Move (Text ^, S [1], len); if @ConvertTextFunction <> nil then s: = ConvertTextFunction (s); if @ OldGetTextExtentPoint32W <> nil thenResult: = OldGetTextExtentPoint32W (hdc, PWideChar (s), length (s), Size) else Result: = False; Else Result: =
OldGetTextExtentPoint32W (hdc, text, 0, Size); except Result: = False; end; end; function NewGetTextExtentPointA (hdc: HDC; text: PAnsiChar; len: Integer; Size: Pointer): BOOL; stdcall; Var s: AnsiString; Begin try if len <0; if len> 0 THEN BEGIN SETLENGTH (S, LEN); FillChar (s [1], LEN 1, 0); Move (Text ^, S [1 ], len); if @ConvertTextFunction <> nil then s: = ConvertTextFunction (s); if @OldGetTextExtentPointA <> nil then Result: = OldGetTextExtentPointA (hdc, PAnsiChar (s), length (s), Size) else Result: = false; end else Result: = OldGetTextExtentPointA (hdc, text, 0, Size); except Result: = false; end; end; function NewGetTextExtentPointW (hdc: HDC; text: PWideChar; len: Integer; Size: Pointer): BOOL; STDCALL; VAR S: WIDESTRING; begin try if len <0; if len> 0 Then Begin setlength (s, len); Fillchar (s [1], len * 2 2, 0) ; Move (Text ^, S [1], LEN); if @ConvertTextFunction <> nil the s: = convertTextFunction (s); if @ OldGetTextExtentPoint32W <> nil then Result: = OldGetTextExtentPointW (hdc, PWideChar (s), length (s), Size) else Result: = False; end else Result: = OldGetTextExtentPointW (hdc, text, 0, Size); except Result : = False; end; end; function PointerToFunctionAddress (code: Pointer): PPointer; Var func: PImportCode; begin Result: = nil; if code = nil then exit; try func: = code; if (func.JumpInstruction = $ 25FF ) The begin result: = func.addressofpointerTOFunction; End; Except results: = nil; end; end; function finalfunctionAddress (Code: Poinc: Pimportcode; Begin Result: = code;
if Code = nil then exit; try func: = code; if (func.JumpInstruction = $ 25FF) then begin Result: = func.AddressOfPointerToFunction ^; end; except Result: = nil; end; end; Function PatchAddress (OldFunc, NewFunc : Pointer): Integer; Var BeenDone: TList; Function PatchAddressInModule (hModule: THandle; OldFunc, newFunc: Pointer): Integer; Var Dos: PImageDosHeader; NT: PImageNTHeaders; ImportDesc: PImage_Import_Entry; rva: DWORD; Func: PPointer; DLL: String; f: Pointer; written: DWORD; begin Result: = 0; dos: = Pointer (hmodule); if Bendone.Indexof (dos)> = 0 THEN EXIT; bendone.Add (DOS); Oldfunc: = FinalFunctionAddress (Oldfunc) ); if IsBadReadPtr (Dos, SizeOf (TImageDosHeader)) then exit; if Dos.e_magic <> IMAGE_DOS_SIGNATURE then exit; NT: = Pointer (Integer (Dos) dos._lfanew); // if IsBadReadPtr (NT, SizeOf (TImageNtHeaders )) The EXIT; RVA: = NT ^ .OPTIONALHEADER.DATADIRECTORY [image_directory_entry_import] .virtualaddress; if rva = 0 Then Exit; ImportDesc: = Pointer (Integer (DOS) RVA); While (importDesc ^ .Name <> 0) Do Begin DLL: = PCHAR (Integer (DOS) ImportDesc ^ .name); PatchaddressInmodule (Pchar (DLL)), Oldfunc, NewFunc); Func: = Pointer (Integer (DOS) ImportDesc .LookupTable); While Func ^ <> nil do begin f: = FinalFunctionAddress (Func ^); if f = OldFunc then begin WriteProcessMemory (GetCurrentProcess, Func, @ newFunc, 4, written); If written> 0 then Inc (Result) End; INC); end; incortionDesc; end; end; begin bendone: = TList.create; try result: = patchaddressinmodule (getModuleHandle (NIL), Oldfunc, newFunc); finally bendone.Free; end; END;
procedure HookTextOut (ConvertFunction: TConvertTextFunction); begin if @ OldTextOutA = nil then @OldTextOutA: = FinalFunctionAddress (@TextOutA); if @ OldTextOutW = nil then @OldTextOutW: = FinalFunctionAddress (@TextOutW); if @ OldExtTextOutA = nil then @OldExtTextOutA: = FinalFunctionAddress (@ExtTextOutA); if @ OldExtTextOutW = nil then @OldExtTextOutW: = FinalFunctionAddress (@ExtTextOutW); if @ OldDrawTextA = nil then @OldDrawTextA: = FinalFunctionAddress (@DrawTextA); if @ OldDrawTextW = nil then @OldDrawTextW: = FinalFunctionAddress (@DrawTextW); if @ OldDrawTextExA = nil then @OldDrawTextExA: = FinalFunctionAddress (@DrawTextExA); if @ OldDrawTextExW = nil then @OldDrawTextExW: = FinalFunctionAddress (@DrawTextExW); if @ OldTabbedTextOutA = nil then @OldTabbedTextOutA: = FinalFunctionAddress (@ TabbedTextOutA); if @ OldTabbedTextOutW = nil then @OldTabbedTextOutW: = FinalFunctionAddress (@TabbedTextOutW); if @ OldPolyTextOutA = nil then @OldPolyTextOutA: = FinalFunctionAddress (@PolyTextOutA); if @Ol dPolyTextOutW = nil then @OldPolyTextOutW: = FinalFunctionAddress (@PolyTextOutW); if @ OldGetTextExtentExPointA = nil then @ OldGetTextExtentExPointA: = FinalFunctionAddress (@GetTextExtentExPointA); if @ OldGetTextExtentExPointW = nil then @ OldGetTextExtentExPointW: = FinalFunctionAddress (@GetTextExtentExPointW); if @ OldGetTextExtentPoint32A = nil damtextPoint32a: = finalFunctionAddress (@ gettextextentpoint32a); if @
OldGetTextExtentPoint32W = nil then @ OldGetTextExtentPoint32W: = FinalFunctionAddress (@ GetTextExtentPoint32W); if @ OldGetTextExtentPointA = nil then @OldGetTextExtentPointA: = FinalFunctionAddress (@GetTextExtentPointA); if @ OldGetTextExtentPointW = nil then @OldGetTextExtentPointW: = FinalFunctionAddress (@GetTextExtentPointW); @ConvertTextFunction: = @ConVertFunction;
procedure UnhookTextOut; begin If @OldTextOutA <> nil then begin PatchAddress (@NewTextOutA, @OldTextOutA); PatchAddress (@NewTextOutW, @OldTextOutW); PatchAddress (@NewExtTextOutA, @OldExtTextOutA); PatchAddress (@NewExtTextOutW, @OldExtTextOutW); PatchAddress ( @NewDrawTextA, @OldDrawTextA); PatchAddress (@NewDrawTextW, @OldDrawTextW); PatchAddress (@NewDrawTextExA, @OldDrawTextExA); PatchAddress (@NewDrawTextExW, @OldDrawTextExW); PatchAddress (@NewTabbedTextOutA, @OldTabbedTextOutA); PatchAddress (@NewTabbedTextOutW, @OldTabbedTextOutW ); PatchAddress (@NewPolyTextOutA, @OldPolyTextOutA); PatchAddress (@NewPolyTextOutW, @OldPolyTextOutW); PatchAddress (@NewGetTextExtentExPointA, @OldGetTextExtentExPointA); PatchAddress (@NewGetTextExtentExPointW, @OldGetTextExtentExPointW); PatchAddress (@ NewGetTextExtentPoint32A, @ OldGetTextExtentPoint32A); PatchAddress (@ NewgetTexTextentPoint32W, @ OldgetTextExtentPoint32W); Patchaddress (@newgettextextentpointa, @old GetTextExtentPointa); Patchaddress (@newgettextextentpointw, @NewGettextExtentPointw); end; end; initializationfinalization unhooktextout; end. ====================================== ====================== Unit pestuff; interfaceuses windows; type pimagedosheader = ^ TIMAGEDOSHEADER; _IMAGE_DOS_HEADER = PACKED RECORD {dos .eader = Packed Record {DOS .EXEHEADER} E_MAGIC: WORD;
{Magicnumber} e_cblp: Word; {Bytes on last page of file} e_cp: Word; {Pages infile} e_crlc: Word; {Relocations} e_cparhdr: Word; {Size of header inparagraphs} e_minalloc: Word; {Minimum extra paragraphs needed} e_maxalloc: Word; {Maximum extra paragraphs needed} e_ss: Word; {Initial (relative) SS value} e_sp: Word; {Initial SPvalue} e_csum: Word; {Checksum} e_ip: Word; {Initial IPvalue} e_cs: Word; { Initial (relative) cs value} e_lfarlc: word; {file address of relocation table} e_ovno: word; {OVERLAYNUMB Er} E_RES: Array [0..3] of Word; {reservedword; {OEM Identifier (Fore_OemInfo)} E_OEMINFO: WORD; {OEM Information; E_OEMID Specific} e_res2: array [0..9] of Word ; {Reservedwords} _lfanew: LongInt; {File address of new exe header} end; TImageDosHeader = _IMAGE_DOS_HEADER; PIMAGE_FILE_HEADER = ^ IMAGE_FILE_HEADER; IMAGE_FILE_HEADER = packed record Machine: WORD; NumberOfSections: WORD; TimeDateStamp: DWORD; PointerToSymbolTable: DWORD; NumberOfSymbols: DWORD SizeOfoptionalheader: Word;
Characteristics: WORD; end; PIMAGE_DATA_DIRECTORY = ^ IMAGE_DATA_DIRECTORY; IMAGE_DATA_DIRECTORY = packed record VirtualAddress: DWORD; Size: DWORD; end; PIMAGE_SECTION_HEADER = ^ IMAGE_SECTION_HEADER; IMAGE_SECTION_HEADER = packed record Name: packed array [0..IMAGE_SIZEOF_SHORT_NAME-1] of Char; VirtualSize : DWORD; // or VirtualSize (union); VirtualAddress: DWORD; SizeOfRawData: DWORD; PointerToRawData: DWORD; PointerToRelocations: DWORD; PointerToLinenumbers: DWORD; NumberOfRelocations: WORD; NumberOfLinenumbers: WORD; Characteristics: DWORD; end; PIMAGE_OPTIONAL_HEADER = ^ IMAGE_OPTIONAL_HEADER; IMAGE_OPTIONAL_HEADER = packed record {Standard fields.} Magic: WORD; MajorLinkerVersion: Byte; MinorLinkerVersion: Byte; SizeOfCode: DWORD; SizeOfInitializedData: DWORD; SizeOfUninitializedData: DWORD; AddressOfEntryPoint: DWORD; BaseOfCode: DWORD; Ba seOfData: DWORD; {NT additional fields.} ImageBase: DWORD; SectionAlignment: DWORD; FileAlignment: DWORD; MajorOperatingSystemVersion: WORD; MinorOperatingSystemVersion: WORD; MajorImageVersion: WORD; MinorImageVersion: WORD; MajorSubsystemVersion: WORD; MinorSubsystemVersion: WORD; Reserved1: DWORD; SizeOfImage: DWORD; SizeOfHeaders: DWORD; CheckSum: DWORD; Subsystem: WORD; DllCharacteristics: WORD; SizeOfStackReserve: DWORD; SizeOfStackCommit: DWORD; SizeOfHeapReserve: DWORD; SizeOfHeapCommit: DWORD; LoaderFlags: DWORD; NumberOfRvaAndSizes: DWORD;
DataDirectory: packed array [0..IMAGE_NUMBEROF_DIRECTORY_ENTRIES-1] of IMAGE_DATA_DIRECTORY; Sections: packed array [0..9999] of IMAGE_SECTION_HEADER; end; PIMAGE_NT_HEADERS = ^ IMAGE_NT_HEADERS; IMAGE_NT_HEADERS = packed record Signature: DWORD; FileHeader: IMAGE_FILE_HEADER; OptionalHeader: IMAGE_OPTIONAL_HEADER ; end; PImageNtHeaders = PIMAGE_NT_HEADERS; TImageNtHeaders = IMAGE_NT_HEADERS; {PIMAGE_IMPORT_DESCRIPTOR = ^ IMAGE_IMPORT_DESCRIPTOR; IMAGE_IMPORT_DESCRIPTOR = packed record Characteristics: DWORD; // or original first thunk // 0 forterminating null import descriptor // RVA to original unbound IAT TimeDateStamp: DWORD; / / 0 if not bound, // -1 if bound, and real date / time stamp // IMGE_DIRECTORY_ENTRY_BOUND_IMPORT (NEW BIND) // OW Date / Time Stamp of DLL Bound to (OLD BIND) NAME: DWORD; Firstthunk: DWORD // pimage_thunk_data // RVA to IAT (if Bound this IAT has actual addresses) ForwarderChain: DWORD; // -1 if no forwarders end; TImageImportDescriptor = IMAGE_IMPORT_DESCRIPTOR; PImageImportDescriptor = PIMAGE_IMPORT_DESCRIPTOR;} PIMAGE_IMPORT_BY_NAME = ^ IMAGE_IMPORT_BY_NAME; IMAGE_IMPORT_BY_NAME = record Hint: Word; Name: Array [0..0] of char; end; PIMAGE_THUNK_DATA = ^ IMAGE_THUNK_DATA; IMAGE_THUNK_DATA = record Whatever: DWORD; end; PImage_Import_Entry = ^ Image_Import_Entry; Image_Import_Entry = record Characteristics: DWORD; TimeDateStamp: DWORD; MajorVersion: Word; MinorVersion: Word; Name: DWORD; LookupTable: DWORD; End; constimage_dos_signature = $ 5A4D;
// MZIMAGE_OS2_SIGNATURE = $ 454E; // NEIMAGE_OS2_SIGNATURE_LE = $ 454C; // LEIMAGE_VXD_SIGNATURE = $ 454C; // LEIMAGE_NT_SIGNATURE = $ 00004550; // PE00implementationend ===================. ================================================================================================================================================================= ==================================================1 piglatinunit; InterfaceUses Windows, Messages, Sysutils , Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class (TForm) Button1: TButton; Button2: TButton; procedure Button1Click (Sender: TObject); procedure Button2Click (Sender: TObject); private {Private declarations} public {Public declarations} end; var Form1: TForm1; implementation {$ R * .DFM} procedure StartHook; stdcall; external 'PigLatinDll.DLL'; procedure StopHook; stdcall; external 'PigLatinDll.DLL'; procedure TForm1.Button1Click (Sender: TOBJECT); Begin WindowState: = WSMaximized; STArthOK; Sleep (1000); WindowsTate: = WSNORMAL; End; Procedure TFORM1.BUTTON2CLICK (Sender: TOBJECT); Begin WindowsTate: = WSMaximized; Stophook; Sleep (1000); WindowsTate: = WSNORMAL; End; InitializationFinalization StopHook; End. The above code has not been tested!