PE逆向-迷宫程序-KeyFile保护破解

admin 2024年1月25日14:44:26评论7 views字数 6217阅读20分43秒阅读模式

最近一直在学习逆向,就记录一下新手难关如何一步一步分析,最后得到结果的吧!

因为录了一个视频总结,所以这里就放分析时的笔记了。

视频说的比较繁琐,因为是基础,所以说的太繁琐了。有基础的还是跳着看把。

视频地址:https://www.bilibili.com/video/BV1ZK411Y7u1


004016D9 . E8 1C010000 call <jmp.&KERNEL32.CreateFileA> ; CreateFileA
004016DE . 83F8 FF cmp eax, -1 ; eax 文件句柄
004016E1 . 74 64 je short 00401747
004016E3 . A3 44344000 mov dword ptr [403444], eax ; 文件句柄放在0X403444
004016E8 . 6A 00 push 0 ; /pOverlapped = NULL
004016EA . 68 48344000 push 00403448 ; |pBytesRead = PacMe.00403448
004016EF . 6A 01 push 1 ; |读一个字节
004016F1 . 68 FA344000 push 004034FA ; |读取的值存放的地址
004016F6 . FF35 44344000 push dword ptr [403444] ; |hFile = NULL
004016FC . E8 11010000 call <jmp.&KERNEL32.ReadFile> ; 第一个ReadFile
00401701 . 0FB605 FA3440>movzx eax, byte ptr [4034FA] ; EAX 现在就等于第一个ReadFile读到的值
00401708 . 85C0 test eax, eax
0040170A . 74 3B je short 00401747
0040170C . 6A 00 push 0 ; /pOverlapped = NULL
0040170E . 68 48344000 push 00403448 ; |pBytesRead = PacMe.00403448
00401713 . 50 push eax ; |BytesToRead
00401714 . 68 88324000 push 00403288 ; |Buffer = PacMe.00403288
00401719 . FF35 44344000 push dword ptr [403444] ; |hFile = NULL
0040171F . E8 EE000000 call <jmp.&KERNEL32.ReadFile> ; 第二个ReadFile
00401724 . E8 D7F8FFFF call 00401000
{
00401000 /$ 33C0 xor eax, eax ; 清0
00401002 |. 33D2 xor edx, edx ; 清0
00401004 |. 33C9 xor ecx, ecx ; 清0
00401006 |. 8A0D FA344000 mov cl, byte ptr [4034FA] ; 第一次读取的值,赋值给cl
0040100C |. BE 88324000 mov esi, 00403288 ; 第二次读取的值赋值给esi
00401011 |> AC /lods byte ptr [esi]
00401012 |. 03D0 |add edx, eax ; 相加结果放在edx中
00401014 |.^ E2 FB loopd short 00401011
00401016 |. 8815 FB344000 mov byte ptr [4034FB], dl ; 取最低位的一个字节 放在[4034FB],
0040101C . C3 retn
0040101D /$ 8A15 FB344000 mov dl, byte ptr [4034FB] ; 相加的最低位的一个字节 给dl
00401023 |. B9 12000000 mov ecx, 12 ; ecx==18
00401028 |. B8 E8344000 mov eax, 004034E8 ; 第三次读取的内容存放首地址
0040102D |> 3010 /xor byte ptr [eax], dl ; 第三次读取的buf3与相加的底位1字节亦或18次
0040102F |. 40 |inc eax
00401030 |.^ E2 FB loopd short 0040102D
00401032 . C3 retn


}
00401729 . 6A 00 push 0 ; /pOverlapped = NULL
0040172B . 68 48344000 push 00403448 ; |pBytesRead = PacMe.00403448
00401730 . 6A 12 push 12 ; |BytesToRead = 12 (18.)
00401732 . 68 E8344000 push 004034E8 ; |Buffer = PacMe.004034E8
00401737 . FF35 44344000 push dword ptr [403444] ; |hFile = NULL
0040173D . E8 D0000000 call <jmp.&KERNEL32.ReadFile> ; 第三个ReadFile
00401742 . E8 82F9FFFF call 004010C9
{
004010C9 /$ 55 push ebp
004010CA |. 8BEC mov ebp, esp
004010CC |. 83C4 FC add esp, -4
004010CF |. 68 65334000 push 00403365 ; /String2 = "****************C*......*...****.*.****...*....*.*..**********.*..*....*...*...**.****.*.*...****.*....*.*******..*.***..*.....*.*..***.**.***.*...****....*X..*****************"
004010D4 |. 68 BC314000 push 004031BC ; |String1 = PacMe.004031BC
004010D9 |. E8 3A070000 call <jmp.&KERNEL32.lstrcpyA> ; lstrcpyA
004010DE |. C705 84314000>mov dword ptr [403184], 004031CC ; 存放C
004010E8 |. E8 30FFFFFF call 0040101D ; call完之后4034E8存放的是亦或后的结果
004010ED |. C645 FE 00 mov byte ptr [ebp-2], 0 ; ebp-2 = 0
004010F1 |. 33C0 xor eax, eax ; 清0
004010F3 |. 33C9 xor ecx, ecx ; 清0
004010F5 |> C645 FF 08 /mov byte ptr [ebp-1], 8 ; ebp-1 = 8
004010F9 |> 806D FF 02 |/sub byte ptr [ebp-1], 2 ; ebp-1 = 8-2=6
004010FD |. 0FB64D FE ||movzx ecx, byte ptr [ebp-2] ; ecx =ebp-2 = 0
00401101 |. 81C1 E8344000 ||add ecx, 004034E8 ; buf3+0
00401107 |. 8A01 ||mov al, byte ptr [ecx] ; buf3的第一个值给al
00401109 |. 8A4D FF ||mov cl, byte ptr [ebp-1] ; cl ==6
0040110C |. D2E8 ||shr al, cl ; 右移6位
0040110E |. 24 03 ||and al, 3 ; 剩下2位

00401110 |. E8 1EFFFFFF ||call 00401033
{
00401033 $ 55 push ebp
00401034 . 8BEC mov ebp, esp
00401036 . 83C4 F8 add esp, -8
00401039 . 8B15 84314000 mov edx, dword ptr [403184] ; PacMe.004031CC
0040103F . 8955 FC mov dword ptr [ebp-4], edx
00401042 . 0AC0 or al, al ; 判断是否为0; Switch (cases 0..2)
00401044 . 75 09 jnz short 0040104F
00401046 . 832D 84314000>sub dword ptr [403184], 10 ; Case 0 of switch 00401042
0040104D . EB 1F jmp short 0040106E
0040104F > 3C 01 cmp al, 1
00401051 . 75 08 jnz short 0040105B
00401053 . FF05 84314000 inc dword ptr [403184] ; PacMe.004031CC; Case 1 of switch 00401042
00401059 . EB 13 jmp short 0040106E
0040105B > 3C 02 cmp al, 2
0040105D . 75 09 jnz short 00401068
0040105F . 8305 84314000>add dword ptr [403184], 10 ; Case 2 of switch 00401042
00401066 . EB 06 jmp short 0040106E
00401068 > FF0D 84314000 dec dword ptr [403184] ; PacMe.004031CC; Default case of switch 00401042
0040106E > 8B15 84314000 mov edx, dword ptr [403184] ; PacMe.004031CC
00401074 . 8A02 mov al, byte ptr [edx]
00401076 . 3C 2A cmp al, 2A
00401078 . 75 06 jnz short 00401080
0040107A . 33C0 xor eax, eax
0040107C . C9 leave
0040107D . C3 retn
0040107E . EB 33 jmp short 004010B3
00401080 > 3C 58 cmp al, 58
00401082 . 75 2F jnz short 004010B3
00401084 . 6A 00 push 0 ; /Style = MB_OK|MB_APPLMODAL
00401086 . 8D15 59334000 lea edx, dword ptr [403359] ; |
0040108C . 52 push edx ; |Title => "Success.."
0040108D . 8D15 EC324000 lea edx, dword ptr [4032EC] ; |
00401093 . 52 push edx ; |Text => "Congratulations!",LF,CR,"Mail me ([email protected]) how you did it.",LF,CR,"Dont forget to include your keyfile! =]"
00401094 . 6A 00 push 0 ; |hOwner = NULL
00401096 . 8D15 AC174000 lea edx, dword ptr [4017AC] ; |
0040109C . FFD2 call edx ; MessageBoxA
0040109E . 8D15 7B324000 lea edx, dword ptr [40327B]
004010A4 . 52 push edx ; /Text => "Cracked by : "
004010A5 . FF35 20344000 push dword ptr [403420] ; |hWnd = 00050938 ('UNREGISTERED!',class='Edit',parent=000F08BE)
004010AB . 8D15 DC174000 lea edx, dword ptr [4017DC] ; |
004010B1 . FFD2 call edx ; SetWindowTextA
004010B3 > 8B15 84314000 mov edx, dword ptr [403184] ; PacMe.004031CC
004010B9 . C602 43 mov byte ptr [edx], 43
004010BC . 8B55 FC mov edx, dword ptr [ebp-4]
004010BF . C602 20 mov byte ptr [edx], 20
004010C2 . B8 01000000 mov eax, 1
004010C7 . C9 leave
004010C8 . C3 retn

}
00401115 |. 85C0 ||test eax, eax
00401117 |. 74 11 ||je short 0040112A
00401119 |. 0FB655 FF ||movzx edx, byte ptr [ebp-1]
0040111D |. 85D2 ||test edx, edx
0040111F |.^ 75 D8 |jnz short 004010F9 ; 循环4次,将第一个值变成了4个四进制
00401121 |. FE45 FE |inc byte ptr [ebp-2] ; ebp-2==0+1=1
00401124 |. 807D FE 12 |cmp byte ptr [ebp-2], 12 ; ebp-2 与18谁大
00401128 |.^ 75 CB jnz short 004010F5 ; 循环18次
}
  • 一些指令的解释:

    • lods    byte ptr [esi]  类似于mov eax,esi(并不是这样的,但是可以简单的理解) 还有一部操作就是,把esi往前走有一步

    • loopd   short 00401011 类似于jmp 00401011 同时ecx减1  ecx一般在32位中是计数器

lods    byte ptr [esi]  类似于mov eax,esi(并不是这样的,但是可以简单的理解) 还有一部操作就是,把esi往前走有一步
add edx, eax
loopd short 00401011 类似于jmp 00401011 同时ecx减1 ecx一般在32位中是计数器

buf2
int i(edx) = 0
for(int j = 0;j<2;j++){
i=i+buf[j]
}
  • 小循环4次和大循环18次的解释:

有两个循环:一个是大循环18次,一个是小循环,在18次的内部,每次大循环一次,内部要循环4次,
每次将buf3的值变成4个四进制。小循环结束之后,buf3要前进一步,
也就是inc byte ptr [ebp-2]



第一个四进制
11
11
11

al是1字节,1字节是8位
1111 1111 11
结合and 3操作
6:6的时候,右移6位 11
11
4:4的时候,右移4位 1111
11
2:2的时候,右移2位 1111 11
11

0:1111 1111
又因为:
1个四进制是2位:11
1个十六进制是8位,所以4个四进制组成一个16进制。

****************
C*......*...****
.*.****...*....*
.*..**********.*
..*....*...*...*
*.****.*.*...***
*.*....*.*******
..*.***..*.....*
.*..***.**.***.*
...****....*X..*
****************

四个四进制,0,1,2,3
如果为0则为↑
如果为1则为→
如果为2则为↓
如果为3则为←

2A=*
58=X
43=C

大循环18次,小循环4次,也就是说,每次一个大循环,小循环要循环4次,
在换言之,就是一个大循环,要把一个一字节分成4个4进制
而每个4进制,代表一步,
也就是说,每个大循环要走4步

第一次的四步:2221
第二次的四步:2223
........
总共18

0000000215

异或操作原理:
1111
1001
------
0110
1001
-----
1111

原文始发于微信公众号(loochSec):PE逆向-迷宫程序-KeyFile保护破解

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年1月25日14:44:26
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   PE逆向-迷宫程序-KeyFile保护破解http://cn-sec.com/archives/2404644.html

发表评论

匿名网友 填写信息