VCLSkin 的破解方法

破解代码,以下代码在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. 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值