VCLSkin 的破解方法

本文介绍了一种修改VCLSkin皮肤库的方法,通过重写DrawTextA函数来去除特定文字显示,实现去除“VCLSkinDemo”字样,但可能会导致其他标题显示不正确。

破解代码,以下代码在VCLSkin4.85上测试通过

须然用此方法可有效的去除了VCLSkin Demo字样,但会导至原标题不正确显示(此问题是发表文章后才发现的)
Uses CodeHook;

Var
  DrawTextA: Function(hDC: hDC; lpString: PAnsiChar; nCount: Integer;
    Var lpRect: TRect; uFormat: UINT): Integer; stdcall;

Function MyDrawTextA(hDC: hDC; lpString: PAnsiChar; nCount: Integer;
  Var lpRect: TRect; uFormat: UINT): Integer; Stdcall;
Var
  R: TRect;
Begin
  R := Rect(0, 0, 0, 0);
  If lpString = 'VCLSkin Demo' Then
    Result := DrawTextA(hDC, Nil, -1, R, 0)
  Else Result := DrawTextA(hDC, lpString, nCount, lpRect, uFormat);
End;

Procedure TForm1.FormCreate(Sender: TObject);
Begin
  SkinData1.Active := true;
End;

Initialization
  HookCode(user32, 'DrawTextA', @MyDrawTextA, @DrawTextA);
Finalization
  UnhookCode(@DrawTextA);
End.

{===========================================================================}

CodeHook.Pas

Unit CodeHook;

{$IMAGEBASE $13140000}

Interface

Uses
  Windows;

Function HookCode(TargetModule, TargetProc: String; NewProc: pointer; Var OldProc: pointer): boolean;
Function UnhookCode(OldProc: pointer): boolean;

Implementation

Const
  Opcodes1: Array[0..255] Of word =
  (
    (16913), (17124), (8209), (8420), (33793), (35906), (0), (0), (16913), (17124), (8209), (8420), (33793), (35906), (0), (0), (16913),
    (17124), (8209), (8420), (33793), (35906), (0), (0), (16913), (17124), (8209), (8420), (33793), (35906), (0), (0), (16913),
    (17124), (8209), (8420), (33793), (35906), (0), (32768), (16913), (17124), (8209), (8420), (33793), (35906), (0), (32768), (16913),
    (17124), (8209), (8420), (33793), (35906), (0), (32768), (529), (740), (17), (228), (1025), (3138), (0), (32768), (24645),
    (24645), (24645), (24645), (24645), (24645), (24645), (24645), (24645), (24645), (24645), (24645), (24645), (24645), (24645), (24645), (69),
    (69), (69), (69), (69), (69), (69), (69), (24645), (24645), (24645), (24645), (24645), (24645), (24645), (24645), (0),
    (32768), (228), (16922), (0), (0), (0), (0), (3072), (11492), (1024), (9444), (0), (0), (0), (0), (5120),
    (5120), (5120), (5120), (5120), (5120), (5120), (5120), (5120), (5120), (5120), (5120), (5120), (5120), (5120), (5120), (1296),
    (3488), (1296), (1440), (529), (740), (41489), (41700), (16913), (17124), (8209), (8420), (17123), (8420), (227), (416), (0),
    (57414), (57414), (57414), (57414), (57414), (57414), (57414), (32768), (0), (0), (0), (0), (0), (0), (32768), (33025),
    (33090), (769), (834), (0), (0), (0), (0), (1025), (3138), (0), (0), (32768), (32768), (0), (0), (25604),
    (25604), (25604), (25604), (25604), (25604), (25604), (25604), (27717), (27717), (27717), (27717), (27717), (27717), (27717), (27717), (17680),
    (17824), (2048), (0), (8420), (8420), (17680), (19872), (0), (0), (2048), (0), (0), (1024), (0), (0), (16656),
    (16800), (16656), (16800), (33792), (33792), (0), (32768), (8), (8), (8), (8), (8), (8), (8), (8), (5120),
    (5120), (5120), (5120), (33793), (33858), (1537), (1602), (7168), (7168), (0), (5120), (32775), (32839), (519), (583), (0),
    (0), (0), (0), (0), (0), (8), (8), (0), (0), (0), (0), (0), (0), (16656), (416)
    );

  Opcodes2: Array[0..255] Of word =
  (
    (280), (288), (8420), (8420), (65535), (0), (0), (0), (0), (0), (65535), (65535), (65535), (272), (0), (1325), (63),
    (575), (63), (575), (63), (63), (63), (575), (272), (65535), (65535), (65535), (65535), (65535), (65535), (65535), (16419),
    (16419), (547), (547), (65535), (65535), (65535), (65535), (63), (575), (47), (575), (61), (61), (63), (63), (0),
    (32768), (32768), (32768), (0), (0), (65535), (65535), (65535), (65535), (65535), (65535), (65535), (65535), (65535), (65535), (8420),
    (8420), (8420), (8420), (8420), (8420), (8420), (8420), (8420), (8420), (8420), (8420), (8420), (8420), (8420), (8420), (16935),
    (63), (63), (63), (63), (63), (63), (63), (63), (63), (63), (63), (63), (63), (63), (63), (237),
    (237), (237), (237), (237), (237), (237), (237), (237), (237), (237), (237), (237), (237), (101), (237), (1261),
    (1192), (1192), (1192), (237), (237), (237), (0), (65535), (65535), (65535), (65535), (65535), (65535), (613), (749), (7168),
    (7168), (7168), (7168), (7168), (7168), (7168), (7168), (7168), (7168), (7168), (7168), (7168), (7168), (7168), (7168), (16656),
    (16656), (16656), (16656), (16656), (16656), (16656), (16656), (16656), (16656), (16656), (16656), (16656), (16656), (16656), (16656), (0),
    (0), (32768), (740), (18404), (17380), (49681), (49892), (0), (0), (0), (17124), (18404), (17380), (32), (8420), (49681),
    (49892), (8420), (17124), (8420), (8932), (8532), (8476), (65535), (65535), (1440), (17124), (8420), (8420), (8532), (8476), (41489),
    (41700), (1087), (548), (1125), (9388), (1087), (33064), (24581), (24581), (24581), (24581), (24581), (24581), (24581), (24581), (65535),
    (237), (237), (237), (237), (237), (749), (8364), (237), (237), (237), (237), (237), (237), (237), (237), (237),
    (237), (237), (237), (237), (237), (63), (749), (237), (237), (237), (237), (237), (237), (237), (237), (65535),
    (237), (237), (237), (237), (237), (237), (237), (237), (237), (237), (237), (237), (237), (237), (0)
    );

  Opcodes3: Array[0..9] Of Array[0..15] Of word =
  (
    ((1296), (65535), (16656), (16656), (33040), (33040), (33040), (33040), (1296), (65535), (16656), (16656), (33040), (33040), (33040), (33040)),
    ((3488), (65535), (16800), (16800), (33184), (33184), (33184), (33184), (3488), (65535), (16800), (16800), (33184), (33184), (33184), (33184)),
    ((288), (288), (288), (288), (288), (288), (288), (288), (54), (54), (48), (48), (54), (54), (54), (54)),
    ((288), (65535), (288), (288), (272), (280), (272), (280), (48), (48), (0), (48), (0), (0), (0), (0)),
    ((288), (288), (288), (288), (288), (288), (288), (288), (54), (54), (54), (54), (65535), (0), (65535), (65535)),
    ((288), (65535), (288), (288), (65535), (304), (65535), (304), (54), (54), (54), (54), (0), (54), (54), (0)),
    ((296), (296), (296), (296), (296), (296), (296), (296), (566), (566), (48), (48), (566), (566), (566), (566)),
    ((296), (65535), (296), (296), (272), (65535), (272), (280), (48), (48), (48), (48), (48), (48), (65535), (65535)),
    ((280), (280), (280), (280), (280), (280), (280), (280), (566), (566), (48), (566), (566), (566), (566), (566)),
    ((280), (65535), (280), (280), (304), (296), (304), (296), (48), (48), (48), (48), (0), (54), (54), (65535))
    );

Function SizeOfCode(Code: pointer): LongWord;
Var
  Opcode: word;
  Modrm: byte;
  Fixed, AddressOveride: boolean;
  Last, OperandOveride, Flags, Rm, Size, Extend: LongWord;
Begin
  Try
    Last := LongWord(Code);
    If Code <> Nil Then
    Begin
      AddressOveride := False;
      Fixed := False;
      OperandOveride := 4;
      Extend := 0;
      Repeat
        Opcode := byte(Code^);
        Code := pointer(LongWord(Code) + 1);
        If Opcode = $66 Then
        Begin
          OperandOveride := 2;
        End
        Else If Opcode = $67 Then
        Begin
          AddressOveride := True;
        End
        Else
        Begin
          If Not ((Opcode And $E7) = $26) Then
          Begin
            If Not (Opcode In [$64..$65]) Then
            Begin
              Fixed := True;
            End;
          End;
        End;
      Until Fixed;
      If Opcode = $0F Then
      Begin
        Opcode := byte(Code^);
        Flags := Opcodes2[Opcode];
        Opcode := Opcode + $0F00;
        Code := pointer(LongWord(Code) + 1);
      End
      Else
      Begin
        Flags := Opcodes1[Opcode];
      End;
      If ((Flags And $0038) <> 0) Then
      Begin
        Modrm := byte(Code^);
        Rm := Modrm And $7;
        Code := pointer(LongWord(Code) + 1);
        Case (Modrm And $C0) Of
          $40: Size := 1;
          $80:
            Begin
              If AddressOveride Then
              Begin
                Size := 2;
              End
              Else
                Size := 4;
            End;
        Else
          Begin
            Size := 0;
          End;
        End;
        If Not (((Modrm And $C0) <> $C0) And AddressOveride) Then
        Begin
          If (Rm = 4) And ((Modrm And $C0) <> $C0) Then
          Begin
            Rm := byte(Code^) And $7;
          End;
          If ((Modrm And $C0 = 0) And (Rm = 5)) Then
          Begin
            Size := 4;
          End;
          Code := pointer(LongWord(Code) + Size);
        End;
        If ((Flags And $0038) = $0008) Then
        Begin
          Case Opcode Of
            $F6: Extend := 0;
            $F7: Extend := 1;
            $D8: Extend := 2;
            $D9: Extend := 3;
            $DA: Extend := 4;
            $DB: Extend := 5;
            $DC: Extend := 6;
            $DD: Extend := 7;
            $DE: Extend := 8;
            $DF: Extend := 9;
          End;
          If ((Modrm And $C0) <> $C0) Then
          Begin
            Flags := Opcodes3[Extend][(Modrm Shr 3) And $7];
          End
          Else
          Begin
            Flags := Opcodes3[Extend][((Modrm Shr 3) And $7) + 8];
          End;
        End;
      End;
      Case (Flags And $0C00) Of
        $0400: Code := pointer(LongWord(Code) + 1);
        $0800: Code := pointer(LongWord(Code) + 2);
        $0C00: Code := pointer(LongWord(Code) + OperandOveride);
      Else
        Begin
          Case Opcode Of
            $9A, $EA: Code := pointer(LongWord(Code) + OperandOveride + 2);
            $C8: Code := pointer(LongWord(Code) + 3);
            $A0..$A3:
              Begin
                If AddressOveride Then
                Begin
                  Code := pointer(LongWord(Code) + 2)
                End
                Else
                Begin
                  Code := pointer(LongWord(Code) + 4);
                End;
              End;
          End;
        End;
      End;
    End;
    Result := LongWord(Code) - Last;
  Except
    Result := 0;
  End;
End;

Function SaveOldFunction(Proc: pointer; Old: pointer): LongWord;
Var
  SaveSize, Size: LongWord;
  Next: pointer;
Begin
  SaveSize := 0;
  Next := Proc;
  While SaveSize < 5 Do
  Begin
    Size := SizeOfCode(Next);
    Next := pointer(LongWord(Next) + Size);
    Inc(SaveSize, Size);
  End;
  CopyMemory(Old, Proc, SaveSize);
  byte(pointer(LongWord(Old) + SaveSize)^) := $E9;
  LongWord(pointer(LongWord(Old) + SaveSize + 1)^) := LongWord(Next) - LongWord(Old) - SaveSize - 5;
  Result := SaveSize;
End;

Function HookCode(TargetModule, TargetProc: String; NewProc: pointer; Var OldProc: pointer): boolean;
Var
  Address: LongWord;
  OldProtect: LongWord;
  OldFunction: pointer;
  Proc: pointer;
  HMODULE: LongWord;
Begin
  Result := False;
  Try
    HMODULE := LoadLibrary(pchar(TargetModule));
    Proc := GetProcAddress(HMODULE, pchar(TargetProc));
    Address := LongWord(NewProc) - LongWord(Proc) - 5;
    VirtualProtect(Proc, 5, PAGE_EXECUTE_READWRITE, OldProtect);
    GetMem(OldFunction, 255);
    LongWord(OldFunction^) := LongWord(Proc);
    byte(pointer(LongWord(OldFunction) + 4)^) := SaveOldFunction(Proc, pointer(LongWord(OldFunction) + 5));
    byte(pointer(Proc)^) := $E9;
    LongWord(pointer(LongWord(Proc) + 1)^) := Address;
    VirtualProtect(Proc, 5, OldProtect, OldProtect);
    OldProc := pointer(LongWord(OldFunction) + 5);
    FreeLibrary(HMODULE);
  Except
    Exit;
  End;
  Result := True;
End;

Function UnhookCode(OldProc: pointer): boolean;
Var
  OldProtect: LongWord;
  Proc: pointer;
  SaveSize: LongWord;
Begin
  Result := True;
  Try
    Proc := pointer(LongWord(pointer(LongWord(OldProc) - 5)^));
    SaveSize := byte(pointer(LongWord(OldProc) - 1)^);
    VirtualProtect(Proc, 5, PAGE_EXECUTE_READWRITE, OldProtect);
    CopyMemory(Proc, OldProc, SaveSize);
    VirtualProtect(Proc, 5, OldProtect, OldProtect);
    FreeMem(pointer(LongWord(OldProc) - 5));
  Except
    Result := False;
  End;
End;
End. 

uses winskindlg; Type TMySkinManage=class(TSkinManage); procedure TForm1.btn1Click(Sender: TObject); //破解后的2.6版不能够动态改变窗体的caption,下面是补充解决办法 var P: Pchar; begin P := Pointer(TMySkinManage(SkinManager).FindSkinForm(Handle)); if P = nil then exit; P := P+104; //D5的话请将104改为88,未经测试 Pstring(P)^ := 'Edit1.Text'; Caption := 'Edit1.Text'; ////////////////////////////////////////////// end; Delphi VclSkin 2.60 VCLSkin is an VCL library that extend Delphi application with skinnable user interface . Unlike other skin component that you must modify source code to build skinnable application, VCLskin can skin existing application using VCL components without source code modification. VclSkin automatically skin kinds of windows in application, include Delphi forms,MDIform and common Windows dialogs (MsgBox,Open/Save,Font,Print), even the Exception MsgBox. Vclskin not only support Delphi standard controls, but also support many third-party component, such as TMS Grid pack, EnLib Grid, Developer Express QuantumGrid. It is an excellent choice for those wanting to skin existing applications. The cool thing is that it uses existing VCL components. Demo version adds a string 'VclSkin demo' on form caption, but allows to test all available functions. News in 2.60 *Support Arabic language, BiDiMode is righttoleft. *Fixed some bugs when application closed. News in 2.55 *Fixed bug that Tspeedbutton destory at runtime. *Improve performance when change menutitem at runtime. *Fixed OpenDialog bug. News in 2.50 *Support LMD tools. *Fixed bug of checkbox that is disabled . *Add TSkindata.Skin3rd property to add 3rd control easily. News in 2.45 *Some bugs fixed. *Improve compatibility with Billenium effects. News in 2.4 *Support to skin an application but keep the menu bar and title bar the default Windows standard. *DBCheckbox bug fixed. *Fixed bug in cascade,tile command in MIDform. *Bug with minimized state when form created. *Suport ReportBuilder News in 2.3 *Support TUpDown and TSpinEdit. *Support TrackBar. *Restore form size when remove skin. *Fix more bugs. News in 2.25 *Fix bug with QuickReport and FastReport. *Fix bug in Tstatusbar. *Fix bug in Application. News in 2.20 *Support Header control in TlistView. *Fix Menuitem ShortCut bug. *Fix bug that change windows Z-Order when skin change at runtime. *Support Tframe created at runtime. News in 2.10 *Fix Scrollbar drag thumb problem. News in 2.05 *Support multi-skindata in application,Mainform and messagebox can use different skindate. *Nested form support. *Fixed Title flicker problem when form resize. *Support Mainmenu change at runtime. News in 2.0 *skin kinds of windows in your project, Delphi forms,MDIform and common Windows dialogs (MsgBox,Open/Save,Font,Print), even the Exception MsgBox. *Enable/Disable skin at runtime. *fixed many bugs in MDIform. *system menu enchanced. website : http://www.link-rank.com email : info@link-rank.com
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值