首页
社区
课程
招聘
[翻译]haggar教程:PESpin 0.3 - manually unpacking翻译
发表于: 2019-2-14 12:20 7504

[翻译]haggar教程:PESpin 0.3 - manually unpacking翻译

2019-2-14 12:20
7504
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   PESpin v0.3 - 手动脱壳
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

原文地址:http://www.reversing.be/article.php?story=20050726211417143

作者: haggar
OS: Windows XP
水平: 菜鸟-飞鸡
目标和材料: http://www.reversing.be/binaries/articles/200507262109322.rar(亲测可以下载)


欢迎!

这是PESpin的旧版本,但我决定从它开始,稍后尝试新版本会更容易。 教程适用于有脱壳经验的初学者,也必须熟悉工具 (Olly, ImpREc, LordPE).

PESpin v0.3 有一些很好的功能; 良好的IAT重定向与一些仿真API操作码和被盗的OEP是它的最佳武器。 它也有一些基于异常的反调试技巧,但是Olly是免疫的,它检查SoftICE和NTICE,它有几个CRC校验,它有密码锁定和时间限制,但这不是问题。 在使用不同编译器编译的打包文件之间也存在一些小的差异 (VC++,Borland C++, Delphi, VB, ASM...).


1. 分析 PESpin 代码

打开 Olly,不忽略所有异常选项和加载目标,cruehead的CRACKME3.EXE,我用PESpin打包。 向下滚动,您将看到两个解密PESpin代码段的循环:
00407127  XOR BYTE PTR DS:[ECX+EDI],BL
0040712A  DEC BL
0040712C  LOOPD SHORT CRACKME3.00407127       ;First loop.
0040712E  PUSH 13C
00407133  POP ECX
00407134  LEA EDI,DWORD PTR SS:[EBP+4036B6]
0040713A  ROR BYTE PTR DS:[ECX+EDI],2
0040713E  LOOPD SHORT CRACKME3.0040713A       ;Second loop.
00407140  CALL CRACKME3.00407147              ;将bp放在这里以通过它们。
00407127  XOR BYTE PTR DS:[ECX+EDI],BL
0040712A  DEC BL
0040712C  LOOPD SHORT CRACKME3.00407127       ;First loop.
0040712E  PUSH 13C
00407133  POP ECX
00407134  LEA EDI,DWORD PTR SS:[EBP+4036B6]
0040713A  ROR BYTE PTR DS:[ECX+EDI],2
0040713E  LOOPD SHORT CRACKME3.0040713A       ;Second loop.
00407140  CALL CRACKME3.00407147              ;将bp放在这里以通过它们。
经过这些循环并且跟踪到这里:
00408138  MOV EDI,DWORD PTR SS:[ESP+20]
0040813C  AND EDI,FFFF0000
00408142  CMP WORD PTR DS:[EDI],5A4D
00408147  JNZ SHORT CRACKME3.0040815A
00408149  MOVZX EDX,WORD PTR DS:[EDI+3C]
0040814D  TEST DX,0F800
00408152  JNZ SHORT CRACKME3.0040815A
00408154  CMP EDI,DWORD PTR DS:[EDX+EDI+34]
00408158  JE SHORT CRACKME3.00408162
0040815A  SUB EDI,10000
00408160  JMP SHORT CRACKME3.00408142
00408162  XCHG EAX,EDI
00408163  PUSH CRACKME3.00402CFC
00408168  PUSH EAX
00408169  XCHG DWORD PTR SS:[EBP+402CED],EAX
0040816F  ADD DWORD PTR SS:[ESP+4],EBP
00408173  LEA EAX,DWORD PTR SS:[EBP+EB8382F8]
00408179  LEA EAX,DWORD PTR DS:[EAX+14BCAABD]
0040817F  CALL EAX
这里启动的程序将找到PESpin工作所需的kernel32中的所有API。 首先要确保它在kernel32.dll中。 然后你将进入CALL EAX,那里PESpin以某种奇怪的方式搜索API。 对我们来说重要的是那些API。 跟踪到这里,你会看到这里的API地址存储在某个位置:
00408138  MOV EDI,DWORD PTR SS:[ESP+20]
0040813C  AND EDI,FFFF0000
00408142  CMP WORD PTR DS:[EDI],5A4D
00408147  JNZ SHORT CRACKME3.0040815A
00408149  MOVZX EDX,WORD PTR DS:[EDI+3C]
0040814D  TEST DX,0F800
00408152  JNZ SHORT CRACKME3.0040815A
00408154  CMP EDI,DWORD PTR DS:[EDX+EDI+34]
00408158  JE SHORT CRACKME3.00408162
0040815A  SUB EDI,10000
00408160  JMP SHORT CRACKME3.00408142
00408162  XCHG EAX,EDI
00408163  PUSH CRACKME3.00402CFC
00408168  PUSH EAX
00408169  XCHG DWORD PTR SS:[EBP+402CED],EAX
0040816F  ADD DWORD PTR SS:[ESP+4],EBP
00408173  LEA EAX,DWORD PTR SS:[EBP+EB8382F8]
00408179  LEA EAX,DWORD PTR DS:[EAX+14BCAABD]
0040817F  CALL EAX
这里启动的程序将找到PESpin工作所需的kernel32中的所有API。 首先要确保它在kernel32.dll中。 然后你将进入CALL EAX,那里PESpin以某种奇怪的方式搜索API。 对我们来说重要的是那些API。 跟踪到这里,你会看到这里的API地址存储在某个位置:
00408307  MOV DWORD PTR DS:[EDI+1],EAX ;这里F2下断,F9多次直到GetModuleFileNameA出现,删除断点
PESpin想要的API是:
00408307  MOV DWORD PTR DS:[EDI+1],EAX ;这里F2下断,F9多次直到GetModuleFileNameA出现,删除断点
PESpin想要的API是:
LoadLibraryA
ExitProcess
GetProcAddress
VirtualProtect
CloseHandle
VirtualAlloc
VirtualFree
CreateFileA
ReadFile
VirtualQuery
GetTickCount
GetModuleHandleA
CreateThread
Sleep
GetCurrentProcessId
OpenProcess
TerminateProcess
GetFileSize
GetModuleFileNameA
然后PESpin会制造一些异常,目的是检测调试器,但是olly不会失足在这上面。所以你这样做:按Shift + F9 四次,然后将内存bp(在该处F2)放在PESpin段(.taz),按Shift + F9直到你中断在mem bp。 我们跳过的代码对于我们的解包没有任何重要意义,只要跳过一些异常暗桩和一个解码循环。 你应该在这:
LoadLibraryA
ExitProcess
GetProcAddress
VirtualProtect
CloseHandle
VirtualAlloc
VirtualFree
CreateFileA
ReadFile
VirtualQuery
GetTickCount
GetModuleHandleA
CreateThread
Sleep
GetCurrentProcessId
OpenProcess
TerminateProcess
GetFileSize
GetModuleFileNameA
然后PESpin会制造一些异常,目的是检测调试器,但是olly不会失足在这上面。所以你这样做:按Shift + F9 四次,然后将内存bp(在该处F2)放在PESpin段(.taz),按Shift + F9直到你中断在mem bp。 我们跳过的代码对于我们的解包没有任何重要意义,只要跳过一些异常暗桩和一个解码循环。 你应该在这:
00407276  MOV ECX,13
0040727B  CALL CRACKME3.00407280
...
...
用F7跟踪,你会到达这里:
00407276  MOV ECX,13
0040727B  CALL CRACKME3.00407280
...
...
用F7跟踪,你会到达这里:
004072BF  JMP DWORD PTR SS:[EBP+402D57]
有一个名为GetModuleFileNameA的API,它搜索我们打包文件的路径,然后CreateFile打开我们的文件,GetFileSize,VirtualAlloc将在内存中保留足够的位置(从我的计算机上的390000开始)加载该文件,ReadFile会将它加载到该分配的位置,CloseHandle等。 然后你将进入计算整个文件CRC的计算程序:
004072BF  JMP DWORD PTR SS:[EBP+402D57]
有一个名为GetModuleFileNameA的API,它搜索我们打包文件的路径,然后CreateFile打开我们的文件,GetFileSize,VirtualAlloc将在内存中保留足够的位置(从我的计算机上的390000开始)加载该文件,ReadFile会将它加载到该分配的位置,CloseHandle等。 然后你将进入计算整个文件CRC的计算程序:
00408864  PUSH ECX
00408865  OR DL,4
00408868  INC EDI
00408869  XOR AH,BYTE PTR DS:[EDI]
0040886B  SHR EAX,3
0040886E  XOR AL,BH
00408870  ADD EAX,7801A018
00408875  XOR EAX,EBX
00408877  MOV CL,BL
00408879  ROR EAX,CL
0040887B  XCHG EAX,EBX
0040887C  DEC EDX
0040887D  JNZ SHORT CRACKME3.0040886E
0040887F  POP ECX
00408880  LOOPD SHORT CRACKME3.00408864
00408882  XCHG EAX,EBX
00408883  POP EBX
00408884  POP EDX
00408885  RETN
然后从真实的CRC中减去计算所得CRC(这个真实的CRC写在文件中并存储到它的位置):
00408864  PUSH ECX
00408865  OR DL,4
00408868  INC EDI
00408869  XOR AH,BYTE PTR DS:[EDI]
0040886B  SHR EAX,3
0040886E  XOR AL,BH
00408870  ADD EAX,7801A018
00408875  XOR EAX,EBX
00408877  MOV CL,BL
00408879  ROR EAX,CL
0040887B  XCHG EAX,EBX
0040887C  DEC EDX
0040887D  JNZ SHORT CRACKME3.0040886E
0040887F  POP ECX
00408880  LOOPD SHORT CRACKME3.00408864
00408882  XCHG EAX,EBX
00408883  POP EBX
00408884  POP EDX
00408885  RETN
然后从真实的CRC中减去计算所得CRC(这个真实的CRC写在文件中并存储到它的位置):
00407397  SUB DWORD PTR SS:[EBP+403827],EAX
eax=63A54CF8;ss:[00408CE8]=CE0C6BFF
注:打开M镜像,双击.taz段Hex视图找到real CRC如下
00407397  SUB DWORD PTR SS:[EBP+403827],EAX
eax=63A54CF8;ss:[00408CE8]=CE0C6BFF
注:打开M镜像,双击.taz段Hex视图找到real CRC如下
00408CE0  00 3A 00 00 00 00 00 00 FF 6B 0C CE 00 00 00 00  .:......k.?...
如果你在十六进制编辑器中打开crackme或者看一下olly dump的最后一节,你可以找到real CRC写的地方。 那被称为VirtualFree。 在那之后你会遇到一个异常,把内存访问断点放在.taz部分然后按Shift + F9直到你中断在这里:
00408CE0  00 3A 00 00 00 00 00 00 FF 6B 0C CE 00 00 00 00  .:......k.?...
如果你在十六进制编辑器中打开crackme或者看一下olly dump的最后一节,你可以找到real CRC写的地方。 那被称为VirtualFree。 在那之后你会遇到一个异常,把内存访问断点放在.taz部分然后按Shift + F9直到你中断在这里:
00408240  NOP
00408241  NOP
00408242  XOR EBX,EBX
00408244  POP DWORD PTR FS:[EBX]
00408247  POP EBX
00408248  SUB EBX,16
0040824E  JMP SHORT CRACKME3.00408251
....
....
删除内存访问断点并追踪到:
00408240  NOP
00408241  NOP
00408242  XOR EBX,EBX
00408244  POP DWORD PTR FS:[EBX]
00408247  POP EBX
00408248  SUB EBX,16
0040824E  JMP SHORT CRACKME3.00408251
....
....
删除内存访问断点并追踪到:
00408251  CMP BYTE PTR DS:[EBX],0CC
00408254  JNZ SHORT CRACKME3.00408261
00408256  AND ESP,0FFFF
0040825C  CALL CRACKME3.0040827B
00408261  JMP EBX
这里壳正在检查是否在[ebx] = 4073e0地址上放置了断点。 通过检查,你将到达那个地址,然后跟踪和追踪,直到你到达这里:
00408251  CMP BYTE PTR DS:[EBX],0CC
00408254  JNZ SHORT CRACKME3.00408261
00408256  AND ESP,0FFFF
0040825C  CALL CRACKME3.0040827B
00408261  JMP EBX
这里壳正在检查是否在[ebx] = 4073e0地址上放置了断点。 通过检查,你将到达那个地址,然后跟踪和追踪,直到你到达这里:
0040745A  MOVZX ECX,WORD PTR SS:[EBP+402CCF]
00407461  MOV EDX,DWORD PTR SS:[EBP+402CD5]
00407467  ADD EDX,0F8
0040746D  MOV EBX,DWORD PTR SS:[EBP+403817]
00407473  XOR EAX,EAX
00407475  PUSH ECX
00407476  BT EBX,EAX
00407479  JNB SHORT CRACKME3.0040749F
0040747B  PUSH EDX
0040747C  MOV EDI,DWORD PTR DS:[EDX+C]
0040747F  ADD EDI,DWORD PTR SS:[EBP+402CCB]
00407485  MOV ECX,DWORD PTR DS:[EDX+10]
00407488  MOV EDX,DWORD PTR SS:[EBP+403827]     ;采用CRC值=真-算。
0040748E  SHR EDX,1
00407490  JB SHORT CRACKME3.00407498
00407492  XOR EDX,ED43AF32
00407498  XOR BYTE PTR DS:[EDI],DL              ;解密段。
0040749A  INC EDI
0040749B  DEC ECX
0040749C  LOOPD SHORT CRACKME3.0040748E
0040749E  POP EDX
0040749F  INC EAX
004074A0  ADD EDX,28
004074A3  POP ECX
004074A4  LOOPD SHORT CRACKME3.00407475
004074A6  OR DWORD PTR SS:[EBP+4036B0],0
004074AD  JE SHORT CRACKME3.004074BC
004074AF  LEA EAX,DWORD PTR SS:[EBP+403524]
004074B5  SUB EAX,3D1
004074BA  CALL EAX
好的,我们看到它采用那个CRC值,然后用它解密.code部分。 嗯,也许这个值根本不是CRC,只是一些解密段的关键值? 也许两者都是? 我认为是一些解密段的关键值。 通过此检查,所有部分都将被解密,但这只是一层。 进一步跟踪,你将进入SOFTICE检查,程序从408620开始,到40867D结束。 它使用CreateFileA搜索SICE和NTICE文件,如果找到它们,程序将终止。 进一步追踪,你会发现另一个解密循环在4074dc,另一个在4088B9,对我们来说没有多大意义。 让我们加速一点,在命令栏放置bp VirtualAlloc下断,然后按Shift + F9直到我们中断它。 删除它并继续跟踪直到你到达这里:
0040745A  MOVZX ECX,WORD PTR SS:[EBP+402CCF]
00407461  MOV EDX,DWORD PTR SS:[EBP+402CD5]
00407467  ADD EDX,0F8
0040746D  MOV EBX,DWORD PTR SS:[EBP+403817]
00407473  XOR EAX,EAX
00407475  PUSH ECX
00407476  BT EBX,EAX
00407479  JNB SHORT CRACKME3.0040749F
0040747B  PUSH EDX
0040747C  MOV EDI,DWORD PTR DS:[EDX+C]
0040747F  ADD EDI,DWORD PTR SS:[EBP+402CCB]
00407485  MOV ECX,DWORD PTR DS:[EDX+10]
00407488  MOV EDX,DWORD PTR SS:[EBP+403827]     ;采用CRC值=真-算。
0040748E  SHR EDX,1
00407490  JB SHORT CRACKME3.00407498
00407492  XOR EDX,ED43AF32
00407498  XOR BYTE PTR DS:[EDI],DL              ;解密段。
0040749A  INC EDI
0040749B  DEC ECX
0040749C  LOOPD SHORT CRACKME3.0040748E
0040749E  POP EDX
0040749F  INC EAX
004074A0  ADD EDX,28
004074A3  POP ECX
004074A4  LOOPD SHORT CRACKME3.00407475
004074A6  OR DWORD PTR SS:[EBP+4036B0],0
004074AD  JE SHORT CRACKME3.004074BC
004074AF  LEA EAX,DWORD PTR SS:[EBP+403524]
004074B5  SUB EAX,3D1
004074BA  CALL EAX
好的,我们看到它采用那个CRC值,然后用它解密.code部分。 嗯,也许这个值根本不是CRC,只是一些解密段的关键值? 也许两者都是? 我认为是一些解密段的关键值。 通过此检查,所有部分都将被解密,但这只是一层。 进一步跟踪,你将进入SOFTICE检查,程序从408620开始,到40867D结束。 它使用CreateFileA搜索SICE和NTICE文件,如果找到它们,程序将终止。 进一步追踪,你会发现另一个解密循环在4074dc,另一个在4088B9,对我们来说没有多大意义。 让我们加速一点,在命令栏放置bp VirtualAlloc下断,然后按Shift + F9直到我们中断它。 删除它并继续跟踪直到你到达这里:
004078A4  PUSHAD
004078A5  MOV ESI,DWORD PTR SS:[ESP+24]
004078A9  MOV EDI,DWORD PTR SS:[ESP+28]
004078AD  CLD
004078AE  MOV DL,80
004078B0  XOR EBX,EBX
004078B2  MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]
004078B3  MOV BL,2
004078B5  CALL CRACKME3.00407927
004078BA  JNB SHORT CRACKME3.004078B2
...
...
0040792D  INC ESI
0040792E  ADC DL,DL
00407930  RETN
00407931  XOR ECX,ECX
00407933  INC ECX
00407934  CALL CRACKME3.00407927
00407939  ADC ECX,ECX
0040793B  CALL CRACKME3.00407927
00407940  JB SHORT CRACKME3.00407934
00407942  RETN
00407943  SUB EDI,DWORD PTR SS:[ESP+28]
00407947  MOV DWORD PTR SS:[ESP+1C],EDI
0040794B  POPAD
0040794C  RETN                                     ;这里下断!!!
这是自脱壳过程,它将自脱壳或解密段。 它是这样的:首先分配了足够的内存,然后在那里解压缩段,然后原始段被擦除并且已解压段从被分配的内存复制到原始段,然后调用VirtuallFree和VirtualProtect。 将bp放在最后一个RETN并运行2次,直到加壳段被解码,删除bp,将bp放在VirtualFree上,Shift+F9直到你中断它,返回用户代码你应该在这里:
004078A4  PUSHAD
004078A5  MOV ESI,DWORD PTR SS:[ESP+24]
004078A9  MOV EDI,DWORD PTR SS:[ESP+28]
004078AD  CLD
004078AE  MOV DL,80
004078B0  XOR EBX,EBX
004078B2  MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]
004078B3  MOV BL,2
004078B5  CALL CRACKME3.00407927
004078BA  JNB SHORT CRACKME3.004078B2
...
...
0040792D  INC ESI
0040792E  ADC DL,DL
00407930  RETN
00407931  XOR ECX,ECX
00407933  INC ECX
00407934  CALL CRACKME3.00407927
00407939  ADC ECX,ECX
0040793B  CALL CRACKME3.00407927
00407940  JB SHORT CRACKME3.00407934
00407942  RETN
00407943  SUB EDI,DWORD PTR SS:[ESP+28]
00407947  MOV DWORD PTR SS:[ESP+1C],EDI
0040794B  POPAD
0040794C  RETN                                     ;这里下断!!!
这是自脱壳过程,它将自脱壳或解密段。 它是这样的:首先分配了足够的内存,然后在那里解压缩段,然后原始段被擦除并且已解压段从被分配的内存复制到原始段,然后调用VirtuallFree和VirtualProtect。 将bp放在最后一个RETN并运行2次,直到加壳段被解码,删除bp,将bp放在VirtualFree上,Shift+F9直到你中断它,返回用户代码你应该在这里:
00408B60  LEA ESP,DWORD PTR SS:[ESP+4]
00408B64  LEA EAX,DWORD PTR SS:[EBP+12256A5]
00408B6A  SUB EAX,0E23546
00408B6F  JMP EAX
进入那个EAX,你就会到达最有趣的地方:
00408B60  LEA ESP,DWORD PTR SS:[ESP+4]
00408B64  LEA EAX,DWORD PTR SS:[EBP+12256A5]
00408B6A  SUB EAX,0E23546
00408B6F  JMP EAX
进入那个EAX,你就会到达最有趣的地方:
00407620  CALL CRACKME3.00407628                ;你在这里!!!!
00407625  JMP SHORT CRACKME3.0040762B
00407627  STC
00407628  JMP SHORT CRACKME3.00407625
0040762A  SBB EAX,DWORD PTR DS:[EBX+C30C2404]
00407630  CMP BYTE PTR SS:[EBP+40218485],CL
00407636  ADD BYTE PTR DS:[EAX+9D8D7C00],AL
0040763C  MOV FS,WORD PTR DS:[EAX+EAX*2]
0040763F  ADD BYTE PTR DS:[EBX],CH
00407641  FADD DWORD PTR DS:[EAX-77]
00407644  SBB BYTE PTR SS:[EBP-5],CH
00407647  AAA
00407648  MOV AL,BYTE PTR DS:[EAX]
0040764A  CALL CRACKME3.00407669
0040764F  PUSHAD                                ;这里开始输入表重定向:
....
....                                            ;很多跳转和东西在这里。
....
....
00407708  POPAD                                 ;这里结束输入表重定向。
00407709  RETN
0040770A  ADD DWORD PTR DS:[EDI],ECX
0040770C  PUSH EDI
0040770D  ADD EDX,ECX
0040770F  MOV EDI,ESI
00407711  MOV ESI,EAX
00407713  REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[>
00407715  MOV EAX,ESI
00407717  MOV ESI,EDI
00407719  POP EDI
0040771A  JMP CRACKME3.00407675
我们现在还不会进入输入表重定向程序,我将在稍后讨论。 所以进一步F7跟踪,你将再次到达VirtualProtect,直到你到达这个看起来像死胡同街的地方:
00407620  CALL CRACKME3.00407628                ;你在这里!!!!
00407625  JMP SHORT CRACKME3.0040762B
00407627  STC
00407628  JMP SHORT CRACKME3.00407625
0040762A  SBB EAX,DWORD PTR DS:[EBX+C30C2404]
00407630  CMP BYTE PTR SS:[EBP+40218485],CL
00407636  ADD BYTE PTR DS:[EAX+9D8D7C00],AL
0040763C  MOV FS,WORD PTR DS:[EAX+EAX*2]
0040763F  ADD BYTE PTR DS:[EBX],CH
00407641  FADD DWORD PTR DS:[EAX-77]
00407644  SBB BYTE PTR SS:[EBP-5],CH
00407647  AAA
00407648  MOV AL,BYTE PTR DS:[EAX]
0040764A  CALL CRACKME3.00407669
0040764F  PUSHAD                                ;这里开始输入表重定向:
....
....                                            ;很多跳转和东西在这里。
....
....
00407708  POPAD                                 ;这里结束输入表重定向。
00407709  RETN
0040770A  ADD DWORD PTR DS:[EDI],ECX
0040770C  PUSH EDI
0040770D  ADD EDX,ECX
0040770F  MOV EDI,ESI
00407711  MOV ESI,EAX
00407713  REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[>
00407715  MOV EAX,ESI
00407717  MOV ESI,EDI
00407719  POP EDI
0040771A  JMP CRACKME3.00407675
我们现在还不会进入输入表重定向程序,我将在稍后讨论。 所以进一步F7跟踪,你将再次到达VirtualProtect,直到你到达这个看起来像死胡同街的地方:
004001F8  MOV ESI,CRACKME3.004001FF
004001FD  POP DWORD PTR DS:[ESI]
004001FF  ADD BYTE PTR DS:[EAX],AL
00400201  ADC BYTE PTR DS:[EAX],AL
00400203  ADD BYTE PTR DS:[EAX],AL
00400205  ADC BYTE PTR DS:[EAX],AL
00400207  ADD BYTE PTR DS:[EAX],AL
00400209  ADD AL,0
0040020B  ADD BYTE PTR DS:[EAX],AL
0040020D  PUSH ES
0040020E  ADD BYTE PTR DS:[EAX],AL
00400210  ADD BYTE PTR DS:[EAX],AL
将内存访问断点放在.taz部分并Shift + F9运行,直到你中断到:
004001F8  MOV ESI,CRACKME3.004001FF
004001FD  POP DWORD PTR DS:[ESI]
004001FF  ADD BYTE PTR DS:[EAX],AL
00400201  ADC BYTE PTR DS:[EAX],AL
00400203  ADD BYTE PTR DS:[EAX],AL
00400205  ADC BYTE PTR DS:[EAX],AL
00400207  ADD BYTE PTR DS:[EAX],AL
00400209  ADD AL,0
0040020B  ADD BYTE PTR DS:[EAX],AL
0040020D  PUSH ES
0040020E  ADD BYTE PTR DS:[EAX],AL
00400210  ADD BYTE PTR DS:[EAX],AL
将内存访问断点放在.taz部分并Shift + F9运行,直到你中断到:
00408553  SUB EBX,EBX
00408555  MOV ESP,DWORD PTR SS:[ESP+8]
00408559  POP DWORD PTR FS:[EBX]
0040855C  POP ECX
0040855D  POP EBP
0040855E  MOV EDI,CRACKME3.00400100
清除内存访问断点继续跟踪,直到您抵达第一个GetTickCount API调用:
00408553  SUB EBX,EBX
00408555  MOV ESP,DWORD PTR SS:[ESP+8]
00408559  POP DWORD PTR FS:[EBX]
0040855C  POP ECX
0040855D  POP EBP
0040855E  MOV EDI,CRACKME3.00400100
清除内存访问断点继续跟踪,直到您抵达第一个GetTickCount API调用:
0040857D  CALL DWORD PTR SS:[ESP]                  ; kernel32.GetTickCount
然后直到第二次抵达 (恰好在它下面):
0040857D  CALL DWORD PTR SS:[ESP]                  ; kernel32.GetTickCount
然后直到第二次抵达 (恰好在它下面):
00408591  JMP DWORD PTR SS:[ESP+EBX-4]             ; kernel32.GetTickCount
壳使用了两个GetTickCount调用,为什么我不知道,但这对我们来说是有用的信息。 按Shift + F9一次,进入INT3异常(004089B6 2BDB sub ebx,ebx)。 这是另一个调试器检查,将内存访问断点放在.taz部分,Shift + F9运行,你就在这里(如下):
00408591  JMP DWORD PTR SS:[ESP+EBX-4]             ; kernel32.GetTickCount
壳使用了两个GetTickCount调用,为什么我不知道,但这对我们来说是有用的信息。 按Shift + F9一次,进入INT3异常(004089B6 2BDB sub ebx,ebx)。 这是另一个调试器检查,将内存访问断点放在.taz部分,Shift + F9运行,你就在这里(如下):
00408A27  JMP SHORT CRACKME3.00408A2A
清除内存访问断点,现在跟踪和跟踪,直到您进入Virtualalloc,退出它,跟踪和跟踪…在这里,壳自己可以解码DLL名称:
00408A27  JMP SHORT CRACKME3.00408A2A
清除内存访问断点,现在跟踪和跟踪,直到您进入Virtualalloc,退出它,跟踪和跟踪…在这里,壳自己可以解码DLL名称:
004086B3  JE SHORT CRACKME3.004086BA
004086B5  NOT BYTE PTR DS:[EDI]          ;这个解码。
004086B7  INC EDI
004086B8  JMP SHORT CRACKME3.004086B0
004086BA  POP EDI
004086BB  RETN
跟踪,你就会被扔进LoadLibraryA。将mem bp放置在.taz段上,然后按Shift F9离开(直接执行到返回也可以):
004086B3  JE SHORT CRACKME3.004086BA
004086B5  NOT BYTE PTR DS:[EDI]          ;这个解码。
004086B7  INC EDI
004086B8  JMP SHORT CRACKME3.004086B0
004086BA  POP EDI
004086BB  RETN
跟踪,你就会被扔进LoadLibraryA。将mem bp放置在.taz段上,然后按Shift F9离开(直接执行到返回也可以):
77ED6FC4 >JMP BAE8CFE1
77ED6FC9  NOP
77ED6FCA  NOP
77ED6FCB  NOP
77ED6FCC  NOP
77ED6FCD  NOP
77ED6FCE  NOP
77ED6FCF  NOP
77ED6FD0  NOP
77ED6FD1  NOP
77ED6FD2  NOP
77ED6FD3 >JMP BAE8D155
77ED6FD8  NOP
77ED6FD9  NOP
77ED6FDA  NOP
77ED6FDB  NOP
你应该在这里:
77ED6FC4 >JMP BAE8CFE1
77ED6FC9  NOP
77ED6FCA  NOP
77ED6FCB  NOP
77ED6FCC  NOP
77ED6FCD  NOP
77ED6FCE  NOP
77ED6FCF  NOP
77ED6FD0  NOP
77ED6FD1  NOP
77ED6FD2  NOP
77ED6FD3 >JMP BAE8D155
77ED6FD8  NOP
77ED6FD9  NOP
77ED6FDA  NOP
77ED6FDB  NOP
你应该在这里:
00407A4D  TEST EAX,EAX
你知道怎么做 :), 再次跟踪,您将抵达DLL名擦除:
00407A4D  TEST EAX,EAX
你知道怎么做 :), 再次跟踪,您将抵达DLL名擦除:
00407A8A  OR BYTE PTR DS:[EBX],0
00407A8D  JE SHORT CRACKME3.00407A9C
00407A8F  MOV BYTE PTR DS:[EBX],DL
00407A91  ROL EDX,4
当擦除完了就跟到这个有趣的地方:
00407A8A  OR BYTE PTR DS:[EBX],0
00407A8D  JE SHORT CRACKME3.00407A9C
00407A8F  MOV BYTE PTR DS:[EBX],DL
00407A91  ROL EDX,4
当擦除完了就跟到这个有趣的地方:
004077D4  CMP BYTE PTR SS:[EBP+4026E5],0CC;
注:这儿有ss:[00407BA6]=F9
004077DB  JNZ SHORT CRACKME3.004077E2
004077DD  JE SHORT CRACKME3.004077E0
这里检查BP放在[EBP+xxxxx]地址上的情况,地址是:
004077D4  CMP BYTE PTR SS:[EBP+4026E5],0CC;
注:这儿有ss:[00407BA6]=F9
004077DB  JNZ SHORT CRACKME3.004077E2
004077DD  JE SHORT CRACKME3.004077E0
这里检查BP放在[EBP+xxxxx]地址上的情况,地址是:
00407BA6  STC
00407BA7  JB SHORT CRACKME3.00407BAE
00407BA9  CALL CRACKME3.0040867E
00407BAE  JMP SHORT CRACKME3.00407BB1
那是很重要的地方,因为PESpin正在检查它。这个地方离壳保护代码末端很近。两个跳转之间的调用是可选的;如果您在PESpin选项中选择“在:xxx分钟之后关闭程序”,则调用将被执行,并将在指定的时间之后启动关闭程序的线程。在此之后,壳保护将从IAT重定向开始,就像我前面提到的那样。那么我们必须找到被盗的OEP字节。离这里不远。我们必须找到一个POPAD操作码,这是最后的PESpin代码之前被盗的字节,并跳转到真正的OEP。向下滚动:
00407BA6  STC
00407BA7  JB SHORT CRACKME3.00407BAE
00407BA9  CALL CRACKME3.0040867E
00407BAE  JMP SHORT CRACKME3.00407BB1
那是很重要的地方,因为PESpin正在检查它。这个地方离壳保护代码末端很近。两个跳转之间的调用是可选的;如果您在PESpin选项中选择“在:xxx分钟之后关闭程序”,则调用将被执行,并将在指定的时间之后启动关闭程序的线程。在此之后,壳保护将从IAT重定向开始,就像我前面提到的那样。那么我们必须找到被盗的OEP字节。离这里不远。我们必须找到一个POPAD操作码,这是最后的PESpin代码之前被盗的字节,并跳转到真正的OEP。向下滚动:
00407BFA   68 E8030000    PUSH 3E8
00407BFF   00EB           ADD BL,CH
00407C01   04 1F          ADD AL,1F
00407C03  ^EB FB          JMP SHORT CRACKME3.00407C00
00407C05  ^7C 83          JL SHORT CRACKME3.00407B8A
00407C07   04 24          ADD AL,24
00407C09   0C C3          OR AL,0C3
00407C0B   E8 616A00EB    CALL EB40E671              ;这里是POPAD操作码!!!!!!!
00407C10   01E4           ADD ESP,ESP
00407C12   E8 6D98FFFF    CALL CRACKME3.00401484
00407C17  -E9 EB93FFFF    JMP CRACKME3.00401007
00407C1C   AE             SCAS BYTE PTR ES:[EDI]
因为这个地方有混淆的代码,Olly没有正确地显示它,但是在407C0B你会看到一个61字节。61十六进制=POPAD.二进制编辑(NOP一个字节),这一行代码清楚地表明:
00407BFA   68 E8030000    PUSH 3E8
00407BFF   00EB           ADD BL,CH
00407C01   04 1F          ADD AL,1F
00407C03  ^EB FB          JMP SHORT CRACKME3.00407C00
00407C05  ^7C 83          JL SHORT CRACKME3.00407B8A
00407C07   04 24          ADD AL,24
00407C09   0C C3          OR AL,0C3
00407C0B   E8 616A00EB    CALL EB40E671              ;这里是POPAD操作码!!!!!!!
00407C10   01E4           ADD ESP,ESP
00407C12   E8 6D98FFFF    CALL CRACKME3.00401484
00407C17  -E9 EB93FFFF    JMP CRACKME3.00401007
00407C1C   AE             SCAS BYTE PTR ES:[EDI]
因为这个地方有混淆的代码,Olly没有正确地显示它,但是在407C0B你会看到一个61字节。61十六进制=POPAD.二进制编辑(NOP一个字节),这一行代码清楚地表明:
00407C07   04 24          ADD AL,24
00407C09   0C C3          OR AL,0C3
00407C0B   90             NOP
00407C0C   61             POPAD
00407C0D   6A 00          PUSH 0
00407C0F   EB 01          JMP SHORT CRACKME3.00407C12
00407C07   04 24          ADD AL,24
00407C09   0C C3          OR AL,0C3
00407C0B   90             NOP
00407C0C   61             POPAD
00407C0D   6A 00          PUSH 0
00407C0F   EB 01          JMP SHORT CRACKME3.00407C12
(先处理暗桩:转到00407BDC改为jmp)现在把BP放在POPAD上,然后运行crackme。跟踪,您将在401xxx地址进入代码段,但您可能会对代码的外观感到困惑。接着你进入kernel32,然后返回到壳代码。这是因为PESpin偷了一对初始指令,这个crackme的初始指令是一些API调用,所以这里PESpin仍然干扰crackme。如果您愿意,您可以进一步跟踪并进入IAT重定位。在这里你可以看到PESpin是如何破坏入口的。


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2019-2-25 21:30 被ejamse编辑 ,原因: 添加附件
上传的附件:
收藏
免费 1
支持
分享
最新回复 (2)
雪    币: 2166
活跃值: (3226)
能力值: (RANK:260 )
在线值:
发帖
回帖
粉丝
2
原文在哪里?我看一下
2019-2-15 17:58
0
雪    币: 2545
活跃值: (208)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
3
xiaohang 原文在哪里?我看一下
谢谢版主支持!http://www.reversing.be/article.php?story=20050726211417143&query=PESpin
2019-2-15 19:19
0
游客
登录 | 注册 方可回帖
返回
//