首页
社区
课程
招聘
[原创][看雪读书月][学习心得]软件加密保护演示
2008-7-17 15:26 13498

[原创][看雪读书月][学习心得]软件加密保护演示

vxin 活跃值
10
2008-7-17 15:26
13498
【看雪读书月】【学习心得】软件加密保护演示

响应看雪读书活动~~

搞定不题目,只好另辟新路。。。,再者文章貌似心得文章较少。。。

此文章加密演示以CrackMe做为示例。

源代码在被破解后或是月底仍没人破解后放出密码。(暴破除外)

此CM应该比较有意思的~~

unit Unit1;
{=====================================
软件保护思路 :
  KeyFile验证而且是利用图片加密比较
                              by:VxinLv
           HomePage:www.3WorkRoom.cn
=====================================}

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs,Registry, WinSkinData, StdCtrls,  ExtCtrls, Mask;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Image1: TImage;
    SkinData1: TSkinData;
    Image2: TImage;
    Edit_Name: TEdit;
    Label1: TLabel;
    Edit_Code: TEdit;
    Label3: TLabel;
    procedure Button1Click(Sender: TObject);
    procedure FormShow(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}
function GetIdeSerialNumber: pchar;  //=============获取硬盘的出厂系列号
  const IDENTIFY_BUFFER_SIZE = 512;
type
   TIDERegs = packed record
     bFeaturesReg: BYTE;
     bSectorCountReg: BYTE;
     bSectorNumberReg: BYTE;
     bCylLowReg: BYTE;
     bCylHighReg: BYTE;
     bDriveHeadReg: BYTE;
     bCommandReg: BYTE;
     bReserved: BYTE;
  end;
  TSendCmdInParams = packed record
    cBufferSize: DWORD;
    irDriveRegs: TIDERegs;
    bDriveNumber: BYTE;
    bReserved: array[0..2] of Byte;
    dwReserved: array[0..3] of DWORD;
    bBuffer: array[0..0] of Byte;
  end;
  TIdSector = packed record
    wGenConfig: Word;
    wNumCyls: Word;
    wReserved: Word;
    wNumHeads: Word;
    wBytesPerTrack: Word;
    wBytesPerSector: Word;
    wSectorsPerTrack: Word;
    wVendorUnique: array[0..2] of Word;
    sSerialNumber: array[0..19] of CHAR;
    wBufferType: Word;
    wBufferSize: Word;
    wECCSize: Word;
    sFirmwareRev: array[0..7] of Char;
    sModelNumber: array[0..39] of Char;
    wMoreVendorUnique: Word;
    wDoubleWordIO: Word;
    wCapabilities: Word;
    wReserved1: Word;
    wPIOTiming: Word;
    wDMATiming: Word;
    wBS: Word;
    wNumCurrentCyls: Word;
    wNumCurrentHeads: Word;
    wNumCurrentSectorsPerTrack: Word;
    ulCurrentSectorCapacity: DWORD;
    wMultSectorStuff: Word;
    ulTotalAddressableSectors: DWORD;
    wSingleWordDMA: Word;
    wMultiWordDMA: Word;
    bReserved: array[0..127] of BYTE;
  end;
  PIdSector = ^TIdSector;
  TDriverStatus = packed record
    bDriverError: Byte;
    bIDEStatus: Byte;
    bReserved: array[0..1] of Byte;
    dwReserved: array[0..1] of DWORD;
  end;
  TSendCmdOutParams = packed record
    cBufferSize: DWORD;
    DriverStatus: TDriverStatus;
    bBuffer: array[0..0] of BYTE;
  end;
var
  hDevice: Thandle;
  cbBytesReturned: DWORD;
  SCIP: TSendCmdInParams;
  aIdOutCmd: array[0..(SizeOf(TSendCmdOutParams) + IDENTIFY_BUFFER_SIZE-1)-1] of Byte;
  IdOutCmd: TSendCmdOutParams absolute aIdOutCmd;
procedure ChangeByteOrder(var Data; Size: Integer);
var
  ptr: Pchar;
  i: Integer;
  c: Char;
begin
  ptr := @Data;
  for I := 0 to (Size shr 1) - 1 do begin
    c := ptr^;
    ptr^ := (ptr + 1)^;
    (ptr + 1)^ := c;
    Inc(ptr, 2);
  end;
end;
begin
Result := '';
if SysUtils.Win32Platform = VER_PLATFORM_WIN32_NT then begin // Windows NT, Windows 2000
hDevice := CreateFile('\\.\PhysicalDrive0', GENERIC_READ or GENERIC_WRITE,
FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);
end else // Version Windows 95 OSR2, Windows 98
hDevice := CreateFile('\\.\SMARTVSD', 0, 0, nil, CREATE_NEW, 0, 0);
if hDevice = INVALID_HANDLE_VALUE then Exit;
try
FillChar(SCIP, SizeOf(TSendCmdInParams) - 1, #0);
FillChar(aIdOutCmd, SizeOf(aIdOutCmd), #0);
cbBytesReturned := 0;
with SCIP do begin
cBufferSize := IDENTIFY_BUFFER_SIZE;
with irDriveRegs do begin
bSectorCountReg := 1;
bSectorNumberReg := 1;
bDriveHeadReg := $A0;
bCommandReg := $EC;
end;
end;
if not DeviceIoControl(hDevice, $0007C088, @SCIP, SizeOf(TSendCmdInParams) - 1,
@aIdOutCmd, SizeOf(aIdOutCmd), cbBytesReturned, nil) then Exit;
finally
CloseHandle(hDevice);
end;
with PIdSector(@IdOutCmd.bBuffer)^ do begin
ChangeByteOrder(sSerialNumber, SizeOf(sSerialNumber));
(Pchar(@sSerialNumber) + SizeOf(sSerialNumber))^:= #0;
Result := Pchar(@sSerialNumber);
end;
end;

function ASCII10ADD(s: string): Integer;  //=============取10进制累加值
var i,sum:integer;
begin
   sum:=0;  for i:=1 to length(s) do
begin
   sum:=sum+ord(s[i]);
end;
   Result :=sum;
end;

function myHextoStr(S: string): string;   //=============16进制字符串转原字符串
var hexS,tmpstr:string;
    i:integer;
    a:byte;
begin
    hexS  :=s;//应该是该字符串
    if length(hexS) mod 2=1 then
    begin
        hexS:=hexS+'0';
    end;
    tmpstr:='';
    for i:=1 to (length(hexS) div 2) do
    begin
        a:=strtoint('$'+hexS[2*i-1]+hexS[2*i]);
        tmpstr := tmpstr+chr(a);
    end;
    result :=tmpstr;
end;

procedure EncryptBMP(const BMP: TBitmap; Key: Integer);  //=============加密图片
var
  BytesPorScan: Integer;
  w, h: integer;
  p: pByteArray;
begin
  try
    BytesPorScan := Abs(Integer(BMP.ScanLine[1]) -
      Integer(BMP.ScanLine[0]));
  except
    raise Exception.Create('Error');
  end;
  RandSeed := Key;
  for h := 0 to BMP.Height - 1 do
  begin
    P := BMP.ScanLine[h];
    for w := 0 to BytesPorScan - 1 do
      P^[w] := P^[w] xor Random(256);
  end;
end;

function IsHomology(bmp1, bmp2: TbitMap): boolean;   //=============图片验证
type
  PRGBTripleArray = ^TRGBTripleArray;
  TRGBTripleArray = array[0..32767] of TRGBTriple;
var
  x, y: integer;
  p0, p1: PRGBTripleArray;
  sBmp, dBmp: TBitMap;
begin
  Result := False;

  if (bmp1.Height <> bmp2.Height) or
    (bmp1.Width <> bmp2.Width) then
  begin
    Exit;
  end;

  sBmp := TBitmap.Create;
  dBmp := TBitmap.Create;
  try
    sBmp.Assign(bmp1);
    dBmp.Assign(bmp2);
    sBmp.PixelFormat := pf24bit;
    dBmp.PixelFormat := pf24bit;
    for y := 0 to sBmp.Height - 1 do
    begin
      p0 := sBmp.ScanLine[y];
      p1 := dBmp.ScanLine[y];
      for x := 0 to sBmp.Width - 1 do
        if (p0[x].rgbtBlue = p1[x].rgbtBlue) and
          (p0[x].rgbtGreen = p1[x].rgbtGreen) and
          (p0[x].rgbtRed = p1[x].rgbtRed) then
        begin
          Result := True;
        end
        else
        begin
          Break;
        end;
    end;
  finally
    sBmp.Free;
    dBmp.Free;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
     try
      if (Length(Edit_Name.Text)>2) and (FileExists('3w.bmp')) //=========忽悠一下Cracker
          and (myHextoStr(Edit_Code.Text)=Edit_Name.Text)  then //====重点就是验证图片
      begin
       Image2.Picture.LoadFromFile('3w.bmp'); //=========载入图片
       EncryptBMP(Image2.Picture.Bitmap, ASCII10ADD(Trim(strpas(GetIdeSerialNumber)))); //===恢复加密过的图片
       Image2.Refresh;
       if IsHomology(Image1.Picture.Bitmap,Image2.Picture.Bitmap) then  //============验证图片
         begin
           Application.MessageBox(PChar('注册成功!正式授权给:'+Edit_name.text),'提示',MB_OK+64);
         end;
         end
     else
      Application.MessageBox(PChar('非法用户!请与软件开发商联系。'),'错误',MB_OK+64);
       except
     end;
end;
       
procedure TForm1.FormShow(Sender: TObject);
begin
     Edit_Name.SetFocus;
end;

end.



解压密码:4f4982f210c9fe866bba0fa6114cad15

[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

上传的附件:
收藏
点赞7
打赏
分享
最新回复 (26)
雪    币: 372
活跃值: (31)
能力值: ( LV12,RANK:410 )
在线值:
发帖
回帖
粉丝
vxin 10 2008-7-17 16:04
2
0
沙发。。。

提示一下

软件保护思路 :
  KeyFile验证而且是利用图片加密比较
雪    币: 7300
活跃值: (3758)
能力值: (RANK:1130 )
在线值:
发帖
回帖
粉丝
海风月影 22 2008-7-17 16:09
3
0
我等ccfer
雪    币: 372
活跃值: (31)
能力值: ( LV12,RANK:410 )
在线值:
发帖
回帖
粉丝
vxin 10 2008-7-17 16:15
4
0
我等你出手~~
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
太难了 2008-7-17 16:42
5
0
3w.bmp  很复杂。。。。。。。。。
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
小小愿望 2008-7-17 16:51
6
0
爆破多简单,把0x454756nop掉就行了
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
太难了 2008-7-17 16:58
7
0
不会吧,貌似成功不成功都是那个对话框啊,你 NOP 了,如何有

注册成功!

正式授权给:tainanle

的对话框呢
雪    币: 7300
活跃值: (3758)
能力值: (RANK:1130 )
在线值:
发帖
回帖
粉丝
海风月影 22 2008-7-17 17:20
8
0
0047F8E3      90               nop
0047F8E4      E9 D2000000      jmp     0047F9BB

47F8E3处改成 90 E9 D2 00
雪    币: 224
活跃值: (13)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
glts 2008-7-17 17:23
9
0
加密思路很好支持小黑哥
雪    币: 451
活跃值: (78)
能力值: ( LV12,RANK:470 )
在线值:
发帖
回帖
粉丝
zhuwg 11 2008-7-17 17:45
10
0
支持小黑哥123456
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
太难了 2008-7-17 17:47
11
0
这个我看到了。。。。。。。。。。。。。。。。。,注册码在凑拼中
雪    币: 232
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
deryope 1 2008-7-17 18:41
12
0
没看明白怎么做的,有三个地方都跳向出错提示
查UniCode字符串找到这个地方,暴力破解的话也就是像楼上几位说的改跳到蓝色那行继续执行。
0047F8E3     /0F8E 0F010000 JLE CrackMe.0047F9F8
0047F8E9   . |B8 7CFA4700   MOV EAX,CrackMe.0047FA7C                 ;  3w.bmp
0047F8EE   . |E8 DD8BF8FF   CALL CrackMe.004084D0
0047F8F3   . |84C0          TEST AL,AL
0047F8F5     |0F84 FD000000 JE CrackMe.0047F9F8
0047F8FB   . |8D55 F4       LEA EDX,DWORD PTR SS:[EBP-C]
...
0047F92F     |0F85 C3000000 JNZ CrackMe.0047F9F8
0047F935   . |8B83 04030000 MOV EAX,DWORD PTR DS:[EBX+304]
0047F93B   . |8B80 68010000 MOV EAX,DWORD PTR DS:[EAX+168]
0047F941   . |BA 7CFA4700   MOV EDX,CrackMe.0047FA7C                 ;  3w.bmp
...
0047F9B9   . |74 55         JE SHORT CrackMe.0047FA10
0047F9BB   . |6A 40         PUSH 40
0047F9BD   . |8D55 E0       LEA EDX,DWORD PTR SS:[EBP-20]
0047F9C0   . |8B83 08030000 MOV EAX,DWORD PTR DS:[EBX+308]
0047F9C6   . |E8 CD51FBFF   CALL CrackMe.00434B98
0047F9CB   . |8B4D E0       MOV ECX,DWORD PTR SS:[EBP-20]
0047F9CE   . |8D45 E4       LEA EAX,DWORD PTR SS:[EBP-1C]
0047F9D1   . |BA 8CFA4700   MOV EDX,CrackMe.0047FA8C                 ;  注册成功!正式授权给:
....
0047F9F6   . |EB 18         JMP SHORT CrackMe.0047FA10               ; 跳到这里连注册提示都没有,直接进入正常流程
0047F9F8   > \6A 40         PUSH 40
0047F9FA   .  B9 ACFA4700   MOV ECX,CrackMe.0047FAAC                 ;  错误
0047F9FF   .  BA B4FA4700   MOV EDX,CrackMe.0047FAB4                 ;  非法用户!请与软件开发商联系。
...

等高人了,有看懂那个3w.bmp怎么用的不
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
太难了 2008-7-17 18:47
13
0
在文件夹里建立一个 3w.bmp 的图像文件,记着一定是真的 .bmp 不然就被  EInvalidGraphicOperation 和你玩异常
雪    币: 1969
活跃值: (46)
能力值: (RANK:550 )
在线值:
发帖
回帖
粉丝
hawking 12 2008-7-17 18:48
14
0
支持一下Vxin 等高人出手
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
太难了 2008-7-17 18:55
15
0
难道图像的数据也有问题,等高人出手
雪    币: 231
活跃值: (10)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
usufu 2 2008-7-17 19:03
16
0
等高人出手了。
雪    币: 6051
活跃值: (1441)
能力值: ( LV15,RANK:1473 )
在线值:
发帖
回帖
粉丝
lelfei 23 2008-7-17 22:30
17
0
User:lelfei

Code:6C656C666569

Image: Look!
上传的附件:
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
太难了 2008-7-17 23:17
18
0
楼上的高手可以注册成功吗???

你贴的那段注册码,过 那个 CALL 的时候就看见,但我想是 key 文件的问题,你提供的

3w.bmp 在我机器上注册不了 , 难道机器码的那段是融合了在你的 3w.bmp 里
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
太难了 2008-7-18 00:01
19
0
不用说了,我知道了 。。。。。。。。
雪    币: 6051
活跃值: (1441)
能力值: ( LV15,RANK:1473 )
在线值:
发帖
回帖
粉丝
lelfei 23 2008-7-18 07:13
20
0
确切来说,应该是硬盘的序列号的ASC累加值与一数相乘,取高8位对图像数据进行XOR,生成的新图像与一固定图像按字节进行比较,每次比较3字节,当有连续3位字节相同时则置标志位为1,即注册成功

注意这里,也就是说不需要图像完全相同,只要某连续3字节相同就可以注册成功了

从某种程度上说,这也算是明码比较了,只需要把生成的数据另存出来,再加上一个BMP头格式的前0x36字节就行了
雪    币: 372
活跃值: (31)
能力值: ( LV12,RANK:410 )
在线值:
发帖
回帖
粉丝
vxin 10 2008-7-18 08:05
21
0
写个破文上来。。。,我开放源码~~
雪    币: 440
活跃值: (46)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
hflywolf 1 2008-7-18 13:24
22
0
   

依照lelfei兄提示....改了那3字节......搞定.....
上传的附件:
雪    币: 6051
活跃值: (1441)
能力值: ( LV15,RANK:1473 )
在线值:
发帖
回帖
粉丝
lelfei 23 2008-7-18 13:43
23
0
【原创】【看雪读书月】vxin的【学习心得】软件加密保护演示 算法分析http://bbs.pediy.com/showthread.php?t=68764

想看一下vxin的源代码``
雪    币: 563
活跃值: (95)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
lixupeng 2008-7-18 14:49
24
0
好东东研究下
雪    币: 299
活跃值: (300)
能力值: ( LV9,RANK:290 )
在线值:
发帖
回帖
粉丝
clide2000 7 2008-7-19 01:52
25
0
楼主顺便把CrackMe_src.rar的解压密码也公布了吧。
游客
登录 | 注册 方可回帖
返回