KeyFile保护

KeyFile的意思就是密钥文件,它主要呢存在于某些需要注册的软件中,就是说你用一款软件它需要注册并且购买它才可以解锁使用它,这个KeyFile呢就是软件的某个文件,每次软件启动都要从系统根目录或者软件目录中搜寻这个密钥文件,文件里面记录着你的注册信息和注册码以及一些数据,软件利用某种函数将这些数据转化为它可以识别的数据在判断注册的信息是否一致如果一致就进入购买后的版本如果不一致就进入一个试用期的版本。当然呢,还有一种情况是你当时下载的就是个未注册版本,当你注册之后软件向后台发送一些注册数据,然后作者将KeyFile文件发给你,让你放在某个目录下。
 

相关API函数

FindFirstFileA     ;确定注册文件是否存在
CreateFileA、_Iopen  ;确认文件是否存在;打开文件以获得其句柄
GetFileSize、GetFileSizeEx  ;获得注册文件的大小
GetFileAttributesA、GetFileAttributesExA ; 获得注册文件的属性
SetFilePointer、SetFilePointerEx ;移动文件指针
ReadFile  ;读取文件内容

拆解的一般思路:用Process Monitor 等工具监视软件对文件的操作,以找到KeyFile的文件名

                            伪造一个KeyFile文件用十六进制工具编辑和修改

                            在调试器里用CreateFileA函数设段,查看打开文件名的指针

                            用ReadFile设段,分析给ReadFile函数的文件句柄和缓冲区地址。

用CreateFileA函数设段举例子

下断点

004016D8       .  52                   push edx                                             ; |FileName = "j"
004016D9       .  E8 1C010000          call <jmp.&KERNEL32.CreateFileA>                     ; \CreateFileA
004016DE       .  83F8 FF              cmp eax,-0x1
004016E1       .  74 64                je short PacMe.00401747

观察其FileNme

check之后

 

004016D9       .  E8 1C010000          call <jmp.&KERNEL32.CreateFileA>             ; \CreateFileA
004016DE       .  83F8 FF              cmp eax,-0x1
004016E1       .  74 64                je short PacMe.00401747
004016E3       .  A3 44344000          mov dword ptr ds:[0x403444],eax
004016E8       .  6A 00                push 0x0                                     ; /pOverlapped = NULL
004016EA       .  68 48344000          push PacMe.00403448                          ; |pBytesRead = PacMe.00403448
004016EF       .  6A 01                push 0x1                                     ; |BytesToRead = 0x1
004016F1       .  68 FA344000          push PacMe.004034FA                          ; |Buffer = PacMe.004034FA
004016F6       .  FF35 44344000        push dword ptr ds:[0x403444]                 ; |hFile = NULL
004016FC       .  E8 11010000          call <jmp.&KERNEL32.ReadFile>                ; \ReadFile
00401701       .  0FB605 FA344000      movzx eax,byte ptr ds:[0x4034FA]
00401708       .  85C0                 test eax,eax
0040170A       .  74 3B                je short PacMe.00401747
0040170C       .  6A 00                push 0x0                                     ; /pOverlapped = NULL
0040170E       .  68 48344000          push PacMe.00403448                          ; |pBytesRead = PacMe.00403448
00401713       .  50                   push eax                                     ; |BytesToRead = 0x0
00401714       .  68 88324000          push PacMe.00403288                          ; |Buffer = PacMe.00403288
00401719       .  FF35 44344000        push dword ptr ds:[0x403444]                 ; |hFile = NULL
0040171F       .  E8 EE000000          call <jmp.&KERNEL32.ReadFile>                ; \ReadFile
00401724       .  E8 D7F8FFFF          call PacMe.00401000
00401729       .  6A 00                push 0x0                                     ; /pOverlapped = NULL
0040172B       .  68 48344000          push PacMe.00403448                          ; |pBytesRead = PacMe.00403448
00401730       .  6A 12                push 0x12                                    ; |BytesToRead = 12 (18.)
00401732       .  68 E8344000          push PacMe.004034E8                          ; |Buffer = PacMe.004034E8
00401737       .  FF35 44344000        push dword ptr ds:[0x403444]                 ; |hFile = NULL
0040173D       .  E8 D0000000          call <jmp.&KERNEL32.ReadFile>                ; \ReadFile
00401742       .  E8 82F9FFFF          call PacMe.004010C9
00401747       >  FF35 44344000        push dword ptr ds:[0x403444]                 ; /hObject = NULL
0040174D       .  E8 A2000000          call <jmp.&KERNEL32.CloseHandle>             ; \CloseHandle

分有三次读取数据,第三次为核心数据 40173D 

call 4010c9

004010C9      /$  55                   push ebp
004010CA      |.  8BEC                 mov ebp,esp
004010CC      |.  83C4 FC              add esp,-0x4
004010CF      |.  68 65334000          push PacMe.00403365                          ;

****************
C*......*...****
.*.****...*....*
.*..**********.*
..*....*...*...*
*.****.*.*...***
*.*....*.*******
..*.***..*.....*
.*..***.**.***.*
...****....*X..*
****************
004010D4      |.  68 BC314000          push PacMe.004031BC                          ; 

****************
C*......*...****
.*.****...*....*
.*..**********.*
..*....*...*...*
*.****.*.*...***
*.*....*.*******
..*.***..*.....*
.*..***.**.***.*
...****....*X..*
****************
004010D9      |.  E8 3A070000          call <jmp.&KERNEL32.lstrcpyA>                ; \lstrcpyA  为复制字串

吃豆子柚子 C吃家 X终点 *墙壁 。豆子

00401033       $  55                   push ebp
00401034       .  8BEC                 mov ebp,esp
00401036       .  83C4 F8              add esp,-0x8
00401039       .  8B15 84314000        mov edx,dword ptr ds:[0x403184]              ;  C*......*...****.*.****...*....*.*..**********.*..*....*...*...**.****.*.*...****.*....*.*******..*.***..*.....*.*..***.**.***.*...****....*X..*****************
0040103F       .  8955 FC              mov dword ptr ss:[ebp-0x4],edx               ;  PacMe.00403192
00401042       .  0AC0                 or al,al                                     ;  Switch (cases 0..2)
00401044       .  75 09                jnz short PacMe.0040104F   ;向上移
00401046       .  832D 84314000 10     sub dword ptr ds:[0x403184],0x10             ;  Case 0 of switch 00401042
0040104D       .  EB 1F                jmp short PacMe.0040106E
0040104F       >  3C 01                cmp al,0x1             
00401051       .  75 08                jnz short PacMe.0040105B
00401053       .  FF05 84314000        inc dword ptr ds:[0x403184]                  ;  向右移
00401059       .  EB 13                jmp short PacMe.0040106E
0040105B       >  3C 02                cmp al,0x2
0040105D       .  75 09                jnz short PacMe.00401068
0040105F       .  8305 84314000 10     add dword ptr ds:[0x403184],0x10             ;  向下移
00401066       .  EB 06                jmp short PacMe.0040106E
00401068       >  FF0D 84314000        dec dword ptr ds:[0x403184]                  ;  向左移
0040106E       >  8B15 84314000        mov edx,dword ptr ds:[0x403184]              ;  C*......*...****.*.****...*....*.*..**********.*..*....*...*...**.****.*.*...****.*....*.*******..*.***..*.....*.*..***.**.***.*...****....*X..*****************
00401074       .  8A02                 mov al,byte ptr ds:[edx]
00401076       .  3C 2A                cmp al,0x2A
00401078       .  75 06                jnz short PacMe.00401080
0040107A       .  33C0                 xor eax,eax
0040107C       .  C9                   leave
0040107D       .  C3                   retn
0040107E       . /EB 33                jmp short PacMe.004010B3
00401080       > |3C 58                cmp al,0x58    ;检查最后是否为“X”
00401082       . |75 2F                jnz short PacMe.004010B3
00401084       . |6A 00                push 0x0                                     ; /Style = MB_OK|MB_APPLMODAL
00401086       . |8D15 59334000        lea edx,dword ptr ds:[0x403359]              ; |Success..
0040108C       . |52                   push edx                                     ; |Title = "KwazyWeb.bit"
0040108D       . |8D15 EC324000        lea edx,dword ptr ds:[0x4032EC]              ; |Congratulations!\n\rMail me (KwazyWebbit@hotmail.com) how you did it.\n\rDont forget to include your keyfile! =]
00401093       . |52                   push edx                                     ; |Text = "KwazyWeb.bit"
00401094       . |6A 00                push 0x0                                     ; |hOwner = NULL
00401096       . |8D15 AC174000        lea edx,dword ptr ds:[0x4017AC]              ; |
0040109C       . |FFD2                 call edx                                     ; \MessageBoxA
0040109E       . |8D15 7B324000        lea edx,dword ptr ds:[0x40327B]              ;  Cracked by :
004010A4       . |52                   push edx                                     ; /Text = "KwazyWeb.bit"
004010A5       . |FF35 20344000        push dword ptr ds:[0x403420]                 ; |hWnd = 00420D8E ('UNREGISTERED!',class='Edit',parent=00310DA8)
004010AB       . |8D15 DC174000        lea edx,dword ptr ds:[0x4017DC]              ; |
004010B1       . |FFD2                 call edx                                     ; \SetWindowTextA
004010B3       > \8B15 84314000        mov edx,dword ptr ds:[0x403184]              ;  C*......*...****.*.****...*....*.*..**********.*..*....*...*...**.****.*.*...****.*....*.*******..*.***..*.....*.*..***.**.***.*...****....*X..*****************
004010B9       .  C602 43              mov byte ptr ds:[edx],0x43  ;"C"的值为43
004010BC       .  8B55 FC              mov edx,dword ptr ss:[ebp-0x4]
004010BF       .  C602 20              mov byte ptr ds:[edx],0x20
004010C2       .  B8 01000000          mov eax,0x1
004010C7       .  C9                   leave
004010C8       .  C3                   retn


可以看到 0 1 2 3 分别代表上右下左

004010F5      |> /C645 FF 08           /mov byte ptr ss:[ebp-0x1],0x8
004010F9      |> |806D FF 02           |/sub byte ptr ss:[ebp-0x1],0x2
004010FD      |. |0FB64D FE            ||movzx ecx,byte ptr ss:[ebp-0x2]
00401101      |. |81C1 E8344000        ||add ecx,PacMe.004034E8
00401107      |. |8A01                 ||mov al,byte ptr ds:[ecx]
00401109      |. |8A4D FF              ||mov cl,byte ptr ss:[ebp-0x1]
0040110C      |. |D2E8                 ||shr al,cl
0040110E      |. |24 03                ||and al,0x3
00401110      |. |E8 1EFFFFFF          ||call PacMe.00401033
00401115      |.  85C0                 ||test eax,eax
00401117      |.  74 11                ||je short PacMe.0040112A
00401119      |.  0FB655 FF            ||movzx edx,byte ptr ss:[ebp-0x1]
0040111D      |.  85D2                 ||test edx,edx                               ;  PacMe.00403192
0040111F      |.^ 75 D8                |\jnz short PacMe.004010F9   ;进行小循环 len=8 每次-6 则为4次
00401121      |.  FE45 FE              |inc byte ptr ss:[ebp-0x2]
00401124      |.  807D FE 12           |cmp byte ptr ss:[ebp-0x2],0x12  ;遍历12H字节
00401128      |.^ 75 CB                \jnz short PacMe.004010F5        ;没有则继续
0040112A      |>  C9                   leave
0040112B      \.  C3                   retn

 

一共可以走18次 每次可以走4步

则为 2221 2223 2211 0100 1110 0333 0300 1111 1211 0112 1112 2332 3303 3222 3221 1100 1111 2233

四进制转十六进制

A9 AB A5 10 54 3F 30 55 65 16 56 BE F3 EA E9 50 55 AF

用pediy作为用户名可以推出Filekey

05  70  65  64  69  79  B2  B0  BE  0B  4F  24  2B  4E  7E  0D  4D  A5  E8  F1  F2  4B  4E  B4

05为姓名字符数   70-79为姓名ASCII 后面为数据

名字和取低8位 1Bh 依此与数据异或得到 B2  B0  BE  0B  4F  24  2B  4E  7E  0D  4D  A5  E8  F1  F2  4B  4E  B4

小总结:通过演示 可以得出keyfile会有几个组成部分· 名字字符 名字和 数据  (不过具体情况具体分析)

注意循环与大循环之间的代码·

 

要实现USBKey的Java应用程序,您需要使用Java Cryptography Architecture(JCA)和Java Cryptography Extension(JCE)等Java安全API。以下是一个简单的USBKey Java实现的示例: ```java import java.io.FileInputStream; import java.security.KeyStore; import java.security.PrivateKey; import java.security.Signature; import java.security.cert.Certificate; public class USBKey { private static final String USBKEY_FILE = "path/to/usbkey/file"; private static final String USBKEY_PASSWORD = "usbkey-password"; private static final String KEY_ALIAS = "key-alias"; private static final String SIGNATURE_ALGORITHM = "SHA256withRSA"; public static void main(String[] args) throws Exception { // 加载USBKey文件 KeyStore keyStore = KeyStore.getInstance("PKCS12"); FileInputStream fis = new FileInputStream(USBKEY_FILE); keyStore.load(fis, USBKEY_PASSWORD.toCharArray()); // 获取私钥和证书 PrivateKey privateKey = (PrivateKey) keyStore.getKey(KEY_ALIAS, USBKEY_PASSWORD.toCharArray()); Certificate cert = keyStore.getCertificate(KEY_ALIAS); // 签名数据 byte[] data = "Hello, USBKey!".getBytes(); Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); signature.initSign(privateKey); signature.update(data); byte[] signedData = signature.sign(); // 验证签名 signature.initVerify(cert); signature.update(data); boolean valid = signature.verify(signedData); System.out.println("签名是否合法: " + valid); } } ``` 该示例加载了USBKey文件,获取了私钥和证书,并使用SHA256withRSA算法对数据进行签名和验证。您可以根据需要调整代码,以便在您的应用程序中使用USBKey进行身份验证和数据保护
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值