好友
阅读权限30
听众
最后登录1970-1-1
|
玖公子
发表于 2019-8-15 14:26
本帖最后由 玖公子 于 2019-8-16 09:50 编辑
我是刚来论坛的,第一次发帖!
对版规不是很熟悉,如果发错区了,请管理大大手下留情,不要扣分,谢谢!
初识破解与程序之间的关系:
1、用VC++6.0编写一个简单的C语言程序
这个程序我们输入正确的key,就能输出成功的提示信息!
程序和源代码见附件!
2、我们将程序载入OD,停在了
[Asm] 纯文本查看 复制代码 0040130D >/$ 55 push ebp
0040130E |. 8BEC mov ebp,esp
00401310 |. 6A FF push -0x1
00401312 |. 68 B8604000 push test01.004060B8
00401317 |. 68 EC2C4000 push test01.00402CEC ; SE 处理程序安装
0040131C |. 64:A1 0000000>mov eax,dword ptr fs:[0]
00401322 |. 50 push eax
00401323 |. 64:8925 00000>mov dword ptr fs:[0],esp
0040132A |. 83EC 10 sub esp,0x10
0040132D |. 53 push ebx
0040132E |. 56 push esi
0040132F |. 57 push edi
00401330 |. 8965 E8 mov [local.6],esp
00401333 |. FF15 04604000 call dword ptr ds:[<&KERNEL32.GetVersion>; kernel32.GetVersion
00401339 |. 33D2 xor edx,edx ; ntdll.KiFastSystemCallRet
0040133B |. 8AD4 mov dl,ah
0040133D |. 8915 44994000 mov dword ptr ds:[0x409944],edx ; ntdll.KiFastSystemCallRet
我们F8向下走,看到call test01.00401000
[Asm] 纯文本查看 复制代码 00401378 |> \8365 FC 00 and [local.1],0x0
0040137C |. E8 B4000000 call test01.00401435
00401381 |. FF15 00604000 call dword ptr ds:[<&KERNEL32.GetCommand>; [GetCommandLineA
00401387 |. A3 449E4000 mov dword ptr ds:[0x409E44],eax
0040138C |. E8 5C150000 call test01.004028ED
00401391 |. A3 20994000 mov dword ptr ds:[0x409920],eax
00401396 |. E8 05130000 call test01.004026A0
0040139B |. E8 47120000 call test01.004025E7
004013A0 |. E8 7E050000 call test01.00401923
004013A5 |. A1 54994000 mov eax,dword ptr ds:[0x409954]
004013AA |. A3 58994000 mov dword ptr ds:[0x409958],eax
004013AF |. 50 push eax
004013B0 |. FF35 4C994000 push dword ptr ds:[0x40994C]
004013B6 |. FF35 48994000 push dword ptr ds:[0x409948]
004013BC |. E8 3FFCFFFF call test01.00401000
00401000我们知道这是code(代码)段,004013BC这一行F7进去,来到了
[Asm] 纯文本查看 复制代码 00401000 /$ E8 BB000000 /call test01.004010C0
00401005 |. 85C0 |test eax,eax
00401007 |. 75 0F |jnz short test01.00401018
00401009 |. 68 44704000 |push test01.00407044 ; 很遗憾,失败了! \n
0040100E |. E8 7F020000 |call test01.00401292
00401013 |. 83C4 04 |add esp,0x4
00401016 |.^ EB E8 \jmp short test01.00401000
00401018 |> 68 30704000 push test01.00407030 ; 恭喜你,成功了! \n
很明显,这里有一个判断语句,只要将jnz改成jmp,将程序保存出去,就破解成功了!
3.我们在00401000这个call继续F7进去,看到了
[Asm] 纯文本查看 复制代码 004010C0 /$ 83EC 14 sub esp,0x14
004010C3 |. 57 push edi
004010C4 |. 68 68704000 push test01.00407068 ; 请输入一个key:\n
004010C9 |. E8 C4010000 call test01.00401292
004010CE |. 8D4424 08 lea eax,dword ptr ss:[esp+0x8]
004010D2 |. 50 push eax
004010D3 |. E8 EB010000 call test01.004012C3
004010D8 |. 8D7C24 0C lea edi,dword ptr ss:[esp+0xC]
004010DC |. 83C9 FF or ecx,-0x1
004010DF |. 33C0 xor eax,eax
004010E1 |. F2:AE repne scas byte ptr es:[edi]
004010E3 |. F7D1 not ecx ; test01.004070F0
004010E5 |. 49 dec ecx ; test01.004070F0
004010E6 |. 51 push ecx ; test01.004070F0
004010E7 |. 8D4C24 10 lea ecx,dword ptr ss:[esp+0x10]
004010EB |. 51 push ecx ; test01.004070F0
004010EC |. E8 5FFFFFFF call test01.00401050
004010F1 |. 83C4 10 add esp,0x10
004010F4 |. 5F pop edi ; test01.00401005
004010F5 |. 83C4 14 add esp,0x14
004010F8 \. C3 retn
这里有三个call,后面retn就回到了00401005比较的地方了!第一个call应该是获取用户输入的函数,
我们从004010D3第二个callF7进去看看!
[Asm] 纯文本查看 复制代码 004012C3 /$ 56 push esi
004012C4 |. 57 push edi
004012C5 |. 8B7C24 0C mov edi,dword ptr ss:[esp+0xC]
004012C9 |. 8BF7 mov esi,edi
004012CB |> FF0D 84704000 /dec dword ptr ds:[0x407084]
004012D1 |. 78 10 |js short test01.004012E3
004012D3 |. A1 80704000 |mov eax,dword ptr ds:[0x407080] ; 99\n\n\n
004012D8 |. 0FB600 |movzx eax,byte ptr ds:[eax]
004012DB |. FF05 80704000 |inc dword ptr ds:[0x407080] ; test01.00409E60
004012E1 |. EB 0B |jmp short test01.004012EE
004012E3 |> 68 80704000 |push test01.00407080 ; 99\n\n\n
004012E8 |. E8 13FEFFFF |call test01.00401100
004012ED |. 59 |pop ecx ; test01.004010D8
004012EE |> 83F8 0A |cmp eax,0xA
004012F1 |. 74 12 |je short test01.00401305
004012F3 |. 83F8 FF |cmp eax,-0x1
004012F6 |. 74 05 |je short test01.004012FD
004012F8 |. 8806 |mov byte ptr ds:[esi],al
004012FA |. 46 |inc esi
004012FB |.^ EB CE \jmp short test01.004012CB
004012FD |> 3BF7 cmp esi,edi
004012FF |. 75 04 jnz short test01.00401305
00401301 |. 33FF xor edi,edi
00401303 |. EB 03 jmp short test01.00401308
00401305 |> 8026 00 and byte ptr ds:[esi],0x0
00401308 |> 8BC7 mov eax,edi
0040130A |. 5F pop edi ; test01.004010D8
0040130B |. 5E pop esi ; test01.004010D8
0040130C \. C3 retn
从004012CB这里到004012FB这里就是循环加密字符串的地方,004012E8这个call我们F7进去,
F8向下继续走,看到00401148 |. E8 93040000 call test01.004015E0这一行再次F7进去。
继续F8,发现00401664这个callF8后,程序跑起来了
[Asm] 纯文本查看 复制代码 00401664 |. FF15 20604000 call dword ptr ds:[<&KERNEL32.ReadFile>] ; \ReadFile
我们切换到程序,输入几个字符,继续向下F8,观察这段代码!
[Asm] 纯文本查看 复制代码 004016E7 |> /8B45 10 /mov eax,[arg.3] ; test01.00409E60
004016EA |. |8A00 |mov al,byte ptr ds:[eax]
004016EC |. |3C 1A |cmp al,0x1A
004016EE |. |0F84 AE000000 |je test01.004017A2
004016F4 |. |3C 0D |cmp al,0xD
004016F6 |. |74 0B |je short test01.00401703
004016F8 |. |8807 |mov byte ptr ds:[edi],al
004016FA |. |47 |inc edi ; test01.00409E60
004016FB |. |FF45 10 |inc [arg.3] ; test01.00409E60
004016FE |. |E9 91000000 |jmp test01.00401794
00401703 |> |49 |dec ecx ; test01.00409E70
00401704 |. |394D 10 |cmp [arg.3],ecx ; test01.00409E70
00401707 |. |73 18 |jnb short test01.00401721
00401709 |. |8B45 10 |mov eax,[arg.3] ; test01.00409E60
0040170C |. |40 |inc eax ; test01.00409E60
0040170D |. |8038 0A |cmp byte ptr ds:[eax],0xA
00401710 |. |75 06 |jnz short test01.00401718
00401712 |. |8345 10 02 |add [arg.3],0x2
00401716 |. |EB 5E |jmp short test01.00401776
00401718 |> |C607 0D |mov byte ptr ds:[edi],0xD
0040171B |. |47 |inc edi ; test01.00409E60
0040171C |. |8945 10 |mov [arg.3],eax ; test01.00409E60
0040171F |. |EB 73 |jmp short test01.00401794
00401721 |> |8D45 F4 |lea eax,[local.3]
00401724 |. |6A 00 |push 0x0 ; /pOverlapped = NULL
00401726 |. |50 |push eax ; |pBytesRead = test01.00409E60
00401727 |. |FF45 10 |inc [arg.3] ; |test01.00409E60
0040172A |. |8D45 FF |lea eax,dword ptr ss:[ebp-0x1] ; |
0040172D |. |6A 01 |push 0x1 ; |BytesToRead = 0x1
0040172F |. |50 |push eax ; |Buffer = test01.00409E60
00401730 |. |8B03 |mov eax,dword ptr ds:[ebx] ; |
00401732 |. |FF3430 |push dword ptr ds:[eax+esi] ; |hFile = 6F6C2049
00401735 |. |FF15 20604000 |call dword ptr ds:[<&KERNEL32.ReadFile>>; \ReadFile
0040173B |. |85C0 |test eax,eax ; test01.00409E60
0040173D |. |75 0A |jnz short test01.00401749
0040173F |. |FF15 1C604000 |call dword ptr ds:[<&KERNEL32.GetLastEr>; [GetLastError
00401745 |. |85C0 |test eax,eax ; test01.00409E60
00401747 |. |75 47 |jnz short test01.00401790
00401749 |> |837D F4 00 |cmp [local.3],0x0
0040174D |. |74 41 |je short test01.00401790
0040174F |. |8B03 |mov eax,dword ptr ds:[ebx]
00401751 |. |F64430 04 48 |test byte ptr ds:[eax+esi+0x4],0x48
00401756 |. |74 13 |je short test01.0040176B
00401758 |. |8A45 FF |mov al,byte ptr ss:[ebp-0x1]
0040175B |. |3C 0A |cmp al,0xA
0040175D |. |74 17 |je short test01.00401776
0040175F |. |C607 0D |mov byte ptr ds:[edi],0xD
00401762 |. |8B0B |mov ecx,dword ptr ds:[ebx]
00401764 |. |47 |inc edi ; test01.00409E60
00401765 |. |884431 05 |mov byte ptr ds:[ecx+esi+0x5],al
00401769 |. |EB 29 |jmp short test01.00401794
0040176B |> |3B7D 0C |cmp edi,[arg.2] ; test01.00409E60
0040176E |. |75 0B |jnz short test01.0040177B
00401770 |. |807D FF 0A |cmp byte ptr ss:[ebp-0x1],0xA
00401774 |. |75 05 |jnz short test01.0040177B
00401776 |> |C607 0A |mov byte ptr ds:[edi],0xA
00401779 |. |EB 18 |jmp short test01.00401793
0040177B |> |6A 01 |push 0x1
0040177D |. |6A FF |push -0x1
0040177F |. |FF75 08 |push [arg.1]
00401782 |. |E8 E4180000 |call test01.0040306B
00401787 |. |83C4 0C |add esp,0xC
0040178A |. |807D FF 0A |cmp byte ptr ss:[ebp-0x1],0xA
0040178E |. |74 04 |je short test01.00401794
00401790 |> |C607 0D |mov byte ptr ds:[edi],0xD
00401793 |> |47 |inc edi ; test01.00409E60
00401794 |> |8B4D F8 |mov ecx,[local.2] ; test01.00409E70
00401797 |. |394D 10 |cmp [arg.3],ecx ; test01.00409E70
0040179A |.^\0F82 47FFFFFF \jb test01.004016E7
核心加密代码如下(这段代码循环对字符串进行处理):
[Asm] 纯文本查看 复制代码 004016E7 |> /8B45 10 /mov eax,[arg.3] ; test01.00409E65
004016EA |. |8A00 |mov al,byte ptr ds:[eax]
004016EC |. |3C 1A |cmp al,0x1A
004016EE |. |0F84 AE000000 |je test01.004017A2
004016F4 |. |3C 0D |cmp al,0xD
004016F6 |. |74 0B |je short test01.00401703
004016F8 |. |8807 |mov byte ptr ds:[edi],al
004016FA |. |47 |inc edi ; test01.00409E65
004016FB |. |FF45 10 |inc [arg.3] ; test01.00409E65
将我们输入的字符串赋值给eax,每次加1。这里需要百度一下inc指令的作用!
加一指令inc
inc a 相当于 add a,1 //i++
优点 速度比sub指令快,占用空间小
这条指令执行结果影响AF、OF、PF、SF、ZF标志位,但不影响CF进位标志位。
4.找到了加密算法,我们接着去找加密后的字符串,肯定是有个比较,才能判断是否跳转成功or失败!
第3步刚开始的时候有三个call,第二个call是加密字符串,第三个call肯定是进行了比较,因为retn后
就直接跳转到成功or失败了!
我们Ctrl+G输入第三个call的地址004010EC,F4运行过来(切到程序程序窗口,输入一串字母,停在了这里),
然后F7进去,看到
[Asm] 纯文本查看 复制代码 00401060 |> /8A1C08 /mov bl,byte ptr ds:[eax+ecx]
00401063 |. |FEC3 |inc bl
00401065 |. |881C08 |mov byte ptr ds:[eax+ecx],bl
00401068 |. |40 |inc eax
00401069 |. |3BC2 |cmp eax,edx
0040106B |.^\7C F3 \jl short test01.00401060
在这里我们输入的字符串一个一个就循环加密完成了!
[Asm] 纯文本查看 复制代码 0040106D |> \BE 58704000 mov esi,test01.00407058 ; J!mpwf!63qpkjf
这个J!mpwf!63qpkjf就是要比较的字符串!
[Asm] 纯文本查看 复制代码 00401074 |> /8A10 /mov dl,byte ptr ds:[eax]
00401076 |. |8A1E |mov bl,byte ptr ds:[esi]
00401078 |. |8ACA |mov cl,dl
0040107A |. |3AD3 |cmp dl,bl
0040107C |. |75 28 |jnz short test01.004010A6
0040107E |. |84C9 |test cl,cl
00401080 |. |74 16 |je short test01.00401098
00401082 |. |8A50 01 |mov dl,byte ptr ds:[eax+0x1]
00401085 |. |8A5E 01 |mov bl,byte ptr ds:[esi+0x1]
00401088 |. |8ACA |mov cl,dl
0040108A |. |3AD3 |cmp dl,bl
0040108C |. |75 18 |jnz short test01.004010A6
0040108E |. |83C0 02 |add eax,0x2
00401091 |. |83C6 02 |add esi,0x2
00401094 |. |84C9 |test cl,cl
00401096 |.^\75 DC \jnz short test01.00401074
这一段代码就是在将我们输入的字符串加密后与J!mpwf!63qpkjf这个字符串逐个比较!
如果相等,执行下面的汇编代码
[Asm] 纯文本查看 复制代码 00401098 |> \33C0 xor eax,eax
0040109A |. 33C9 xor ecx,ecx
0040109C |. 85C0 test eax,eax
0040109E |. 0f94c1 sete cl
004010A1 |. 5E pop esi ; test01.004013C1
004010A2 |. 8BC1 mov eax,ecx
004010A4 |. 5B pop ebx ; test01.004013C1
004010A5 |. C3 retn
如果不相等,执行下面的汇编代码
[Asm] 纯文本查看 复制代码 004010A6 |> \1BC0 sbb eax,eax
004010A8 |. 5E pop esi ; test01.004013C1
004010A9 |. 83D8 FF sbb eax,-0x1
004010AC |. 33C9 xor ecx,ecx
004010AE |. 85C0 test eax,eax
004010B0 |. 0f94c1 sete cl
004010B3 |. 8BC1 mov eax,ecx
004010B5 |. 5B pop ebx ; test01.004013C1
004010B6 \. C3 retn
然后就返回到00401000这一行,执行test eax,eax语句,决定输出成功or失败!
至此,程序分析完毕,如有认识不到位的地方,请大牛们指正!
源程序和代码下载的地址:https://www.lanzouj.com/i5l2laj |
免费评分
-
查看全部评分
本帖被以下淘专辑推荐:
- · 学习及教程|主题: 1126, 订阅: 1118
|