首页
社区
课程
招聘
[翻译]haggar教程:PESpin 1.304 public - repairing IAT
发表于: 2019-2-16 21:56 7988

[翻译]haggar教程:PESpin 1.304 public - repairing IAT

2019-2-16 21:56
7988
======================================
 PESpin 1.304 public - 修复 IAT
======================================

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

这个版本的PESpin和以前的1.3完全无关。在这个公开版本中,对脱壳来说没有什么新的东西(除了新的重定向JMP-CMP),因为这个版本只是为了解决可兼容性问题。但是在前面的教程中,没有解释如何正确修复IAT,只是一些在用户机器上运行转储的技巧,所以这部分将在本教程中得到更好的介绍。



1. 工具和材料

工具是常见的:

- OllyDbg 1.10
- ImpREC
- LordPE
- Windows XP
- 目标在这: [http://www.reversing.be/binaries/articles/20060224214414479.rar]


本教程将是简短的,因此,您将检查前面的更详细的那些不会是坏事。



2. OEP and stolen code

如果您记得过去的教程,PESpin在跳转到OEP之前将使用的最后一个API是GetTickCount。 它可能会使用它来获取一些随机值,以破坏它不再需要的代码/数据。 因此,我们可以在该API的末尾放置断点(PESpin检查CC字节的第一个字节)并返回保护代码。 所以我们现在非常接近OEP跳转。 PESpin将使用远跳转到原始代码部分。 所以我们可以到这个PESpin部分的开始并搜索对应于远跳的字节E9 ?????? FF。 然后我们找到所有那些可能的跳转,并且在401000部分跳转的第一个是好的。 我发现了这个跳转:
00417BC4  -E9 0F9AFEFF      JMP KeygenMe.004015D8
但是如前所述,PESpin也可以从OEP中窃取一些字节。 被窃取的代码被混淆了,但它始终以POPAD操作码开头,就是16进制的61。 因此向上滚动并搜索此字节。 你会发现它在调用操作码中被混淆:
00417BC4  -E9 0F9AFEFF      JMP KeygenMe.004015D8
但是如前所述,PESpin也可以从OEP中窃取一些字节。 被窃取的代码被混淆了,但它始终以POPAD操作码开头,就是16进制的61。 因此向上滚动并搜索此字节。 你会发现它在调用操作码中被混淆:
00417AD8   E8 61F7D239      CALL 3A14723E
Patch第一个字节:
00417AD8   E8 61F7D239      CALL 3A14723E
Patch第一个字节:
00417AD8   90               NOP
00417AD9   61               POPAD
现在将bp放在POPAD上,运行,你将在那里中断。 在POPAD之后就开始执行被盗代码。 但是被盗的字节被垃圾代码混淆了。 如果我们知道我们的目标是Visual C ++程序,那么找到它并不是什么大问题。 代码混淆并不难,我可以找到确切的字节:
00417AD8   90               NOP
00417AD9   61               POPAD
现在将bp放在POPAD上,运行,你将在那里中断。 在POPAD之后就开始执行被盗代码。 但是被盗的字节被垃圾代码混淆了。 如果我们知道我们的目标是Visual C ++程序,那么找到它并不是什么大问题。 代码混淆并不难,我可以找到确切的字节:
00417B36   55               PUSH EBP
00417B3A   8BEC             MOV EBP,ESP
00417B3F   6A FF            PUSH -1

00417B44   68 3482111F      PUSH 1F118234 <------------------ 这4个操作码只是两个PUSH的混淆。
00417B49   812C24 6421D11E  SUB DWORD PTR SS:[ESP],1ED12164
00417B50   68 48F020F7      PUSH F720F048
00417B55   810424 B03D1F09  ADD DWORD PTR SS:[ESP],91F3DB0

00417B5C   64:A1 00000000   MOV EAX,DWORD PTR FS:[0]
00417B65   50               PUSH EAX
00417B69   64:8925 00000000 MOV DWORD PTR FS:[0],ESP
00417B73   83EC 58          SUB ESP,58
00417B79   53               PUSH EBX
00417B7D   56               PUSH ESI
00417B81   57               PUSH EDI
00417B85   8965 E8          MOV DWORD PTR SS:[EBP-18],ESP
00417B8B   FF15 CDA44100    CALL DWORD PTR DS:[41A4CD] <---- 混淆的API调用!
00417B94   33D2             XOR EDX,EDX
00417B99   8AD4             MOV DL,AH
00417B9E   8915 5C764000    MOV DWORD PTR DS:[40765C],EDX
00417BA7   8BC8             MOV ECX,EAX
00417BAC   81E1 FF000000    AND ECX,0FF
00417BB5   890D 58764000    MOV DWORD PTR DS:[407658],ECX
00417BBE   C1E1 08          SHL ECX,8
00417BC4  -E9 0F9AFEFF      JMP KeygenMe.004015D8 <------ 没有被盗,它会跳到假的OEP.
我们可以稍后恢复这些字节。 但这4个:
00417B36   55               PUSH EBP
00417B3A   8BEC             MOV EBP,ESP
00417B3F   6A FF            PUSH -1

00417B44   68 3482111F      PUSH 1F118234 <------------------ 这4个操作码只是两个PUSH的混淆。
00417B49   812C24 6421D11E  SUB DWORD PTR SS:[ESP],1ED12164
00417B50   68 48F020F7      PUSH F720F048
00417B55   810424 B03D1F09  ADD DWORD PTR SS:[ESP],91F3DB0

00417B5C   64:A1 00000000   MOV EAX,DWORD PTR FS:[0]
00417B65   50               PUSH EAX
00417B69   64:8925 00000000 MOV DWORD PTR FS:[0],ESP
00417B73   83EC 58          SUB ESP,58
00417B79   53               PUSH EBX
00417B7D   56               PUSH ESI
00417B81   57               PUSH EDI
00417B85   8965 E8          MOV DWORD PTR SS:[EBP-18],ESP
00417B8B   FF15 CDA44100    CALL DWORD PTR DS:[41A4CD] <---- 混淆的API调用!
00417B94   33D2             XOR EDX,EDX
00417B99   8AD4             MOV DL,AH
00417B9E   8915 5C764000    MOV DWORD PTR DS:[40765C],EDX
00417BA7   8BC8             MOV ECX,EAX
00417BAC   81E1 FF000000    AND ECX,0FF
00417BB5   890D 58764000    MOV DWORD PTR DS:[407658],ECX
00417BBE   C1E1 08          SHL ECX,8
00417BC4  -E9 0F9AFEFF      JMP KeygenMe.004015D8 <------ 没有被盗,它会跳到假的OEP.
我们可以稍后恢复这些字节。 但这4个:
PUSH 1F118234
SUB DWORD PTR SS:[ESP],1ED12164
PUSH F720F048
ADD DWORD PTR SS:[ESP],91F3DB0
有:
PUSH 1F118234
SUB DWORD PTR SS:[ESP],1ED12164
PUSH F720F048
ADD DWORD PTR SS:[ESP],91F3DB0
有:
PUSH 4060D0
PUSH 402DF8
但所有这一切都没有必要。 我们可以在这一行上转储:
PUSH 4060D0
PUSH 402DF8
但所有这一切都没有必要。 我们可以在这一行上转储:
00417B36   55               PUSH EBP
并且转储会很好。 只是OEP将在PESpin部分,而不是在第一部分。
00417B36   55               PUSH EBP
并且转储会很好。 只是OEP将在PESpin部分,而不是在第一部分。

3. Redirected code(三种重定向到PE头)

如果我们执行OEP跳转:
00417BC4  -E9 0F9AFEFF      JMP KeygenMe.004015D8
我们将在代码部分中看到第一种重定向的代码(CALL-JMP):特征码#E8??????FF#
00417BC4  -E9 0F9AFEFF      JMP KeygenMe.004015D8
我们将在代码部分中看到第一种重定向的代码(CALL-JMP):特征码#E8??????FF#
004015EB   . E8 E8EBFFFF    CALL KeygenMe.004001D8
众所周知,从以前的版本中,CALL导致
004015EB   . E8 E8EBFFFF    CALL KeygenMe.004001D8
众所周知,从以前的版本中,CALL导致
004001D8  -E9 E6160000      JMP KeygenMe.004018C3
并且JMP只是返回某个位置。 所以CALL到PE头是原始文件CALL到某个地址。 
004001D8  -E9 E6160000      JMP KeygenMe.004018C3
并且JMP只是返回某个位置。 所以CALL到PE头是原始文件CALL到某个地址。 

第二种重定向如下所示(JMP-PUSH):特征码#E9??????FF#
0040169E   .-E9 95EBFFFF    JMP KeygenMe.00400238
跳转到
0040169E   .-E9 95EBFFFF    JMP KeygenMe.00400238
跳转到
00400238   68 FF000000      PUSH 0FF <--------------- 这是重定向的操作码。
0040023D  -E9 61140000      JMP KeygenMe.004016A3 <-- 回来了。

Jumps 替代了 pushes.

00400238   68 FF000000      PUSH 0FF <--------------- 这是重定向的操作码。
0040023D  -E9 61140000      JMP KeygenMe.004016A3 <-- 回来了。

Jumps 替代了 pushes.

第三种我在1.3版本的PEspin中没有看到的新的重定向(JMP-CMP):特征码#E9??????FF9090#
00401687   $-E9 94EBFFFF    JMP KeygenMe.00400220
0040168C     90             NOP
0040168D     90             NOP
跳转到
00401687   $-E9 94EBFFFF    JMP KeygenMe.00400220
0040168C     90             NOP
0040168D     90             NOP
跳转到
00400220   833D 38764000 01   CMP DWORD PTR DS:[407638],1 <------ 重定向的操作码。
00400227  -E9 62140000        JMP KeygenMe.0040168E <------------ 回来了。
现在我可以编写可以修复该代码的OllyScript插件的小脚本。 在附件中看到它。 该脚本适用于所有1.x版本的PEPsin(应该)。
00400220   833D 38764000 01   CMP DWORD PTR DS:[407638],1 <------ 重定向的操作码。
00400227  -E9 62140000        JMP KeygenMe.0040168E <------------ 回来了。
现在我可以编写可以修复该代码的OllyScript插件的小脚本。 在附件中看到它。 该脚本适用于所有1.x版本的PEPsin(应该)。

在运行时解密的代码块,所谓的“清除和加密标记”将不在本教程中讨论。 检查最后一个。

这就是全部。 只是IAT需要修复 :)

4. Problem with IAT

这不是一个难题,但在之前的教程中我没有足够的知识来了解ImpREC,PE结构等。首先我们需要看看我们的导入发生了什么,然后我们会考虑如何修复它们。 我在LoadLibraryA和GetProcAddress上放置断点以捕获正在处理导入的位置,但我什么也没找到。 这意味着PESpin不会使用这些api来加载库并找到api,而是可能有自定义编码函数来完成这项工作。 然后我检查已经加载的模块,当olly打开目标并播种(已经被Windows加载器加载)所有需要的dll:
Executable modules
Base       Size       Entry      Name       File version      Path
00400000   0001C000   004160D4   KeygenMe                     D:\PESpin\PESpin v1.304\KeygenMe.exe
77340000   0008B000   773419ED   COMCTL32   5.82 (xpsp1.0208  C:\WINDOWS\system32\COMCTL32.DLL
77D40000   0008C000   77D53A05   USER32     5.1.2600.1561 (x  C:\WINDOWS\system32\USER32.DLL
77DD0000   0008D000   77DD1D3D   ADVAPI32   5.1.2600.1106 (x  C:\WINDOWS\system32\ADVAPI32.dll
77E60000   000E6000   77E7ADB3   kernel32   5.1.2600.1560 (x  C:\WINDOWS\system32\kernel32.dll
77F50000   000A7000              ntdll      5.1.2600.1106 (x  C:\WINDOWS\System32\ntdll.dll
78000000   00087000   78001E0D   RPCRT4     5.1.2600.1361 (x  C:\WINDOWS\system32\RPCRT4.dll
7F000000   00041000              GDI32      5.1.2600.1561 (x  C:\WINDOWS\system32\GDI32.dll

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 1
支持
分享
最新回复 (1)
雪    币: 403
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
2019-2-18 10:59
0
游客
登录 | 注册 方可回帖
返回
//