首页
社区
课程
招聘
[原创]第二阶段第一题简单分析,加入如何得到51字节文件的方法,计算出的,不是穷举
发表于: 2007-8-30 12:18 6332

[原创]第二阶段第一题简单分析,加入如何得到51字节文件的方法,计算出的,不是穷举

2007-8-30 12:18
6332

关键是前面的计算出0x0D的部分
这部分其实就是
((a*0x78CC02A869948F1B mod 2^64) mod 0x5BE6FF82A5164785) mod 2^32 =0x0D
求解的算法zmworm以前有过一篇帖子介绍的很详细
我再贴一下详细的求解过程吧
为了简化求解过程,我把最后的mod 2^32去掉,原始方程变为
(a*0x78CC02A869948F1B mod 2^64) mod 0x5BE6FF82A5164785=0x0D
由于前面的部分肯定小于2^64,0x5BE6FF82A5164785*3则大于2^64
所以前面的部分(a*0x78CC02A869948F1B mod 2^64)只能有3种情况,0x0D,0x5BE6FF82A5164785+0x0D,0x5BE6FF82A5164785*2+0x0D
题目化简为
a*0x78CC02A869948F1B mod 2^64=d
a                      b                          c      d
根据不同的d会有3个方程
求解方法为
b=0x78CC02A869948F1B
由于gcd(b,c)=1所以这个方程比较好解
求乘法逆元
求解b*b' mod 2^64=1
使用扩展欧几里德算法可以求出
b'=90B22DD80D53313
a=d*b' mod 2^64
针对不同的d求解a
(1)
a=0x7590C53F8AD397F7
xor 0x1C后的指令
00B40000   /EB 7C           jmp     short 00B4007E
00B40002   |CF              iretd
00B40003   |45              inc     ebp
00B40004   |23E6            and     esp, esi
00B40006   |8CF9            mov     cx, seg?                         ; 未定义的段寄存器
由于要跳到7E处执行,马上跳回来也要128字节(0x80)
(2)
a=0x704DA9F23D6365D6
00B40000    CA AF7F         retf    7FAF
00B40003    42              inc     edx
00B40004    EE              out     dx, al
00B40005    47              inc     edi
00B40006    51              push    ecx
xor 0x1C后的指令
这个肯定没戏了
(3)
a=0x6B0A8EA4EFF333B5
00B40000    A9 9AEF00B8     test    eax, B800EF9A
00B40005    36:16           push    ss
00B40007    7D 6B           jge     short 00B40074
这个其实还有希望,之前没发现
选择(1)的计算结果的好处是后面xor 0x1C后,前两个字节会变成EB 7C
作题的时候被算法搞晕了,没仔细研究(3)的代码,确实是应该选(3)
当时看了(1)的跳转和(2)肯定不行,就没有多想(3),结果最小代码长度竟然就出在(3)上
加入当时忽略的MOD 2^32条件
由于此条件并不影响计算结果的低32位,所以对(1)和(2)并没有什么影响
下面针对不同的高32位计算新的k
d=0x0000000100000000+0x5BE6FF82A5164785*2+0x0D时
k=0xEBDFC1B7 EFF333B5
xor 0x1C后代码为
00B40000    A9 9AEF00AB     test    eax, AB00EF9A
00B40005    6A C3           push    -3D
00B40007    28                ??
d=0x0000000200000000+0x5BE6FF82A5164785*2+0x0D时
k=0x6CB4F4CA EFF333B5
xor 0x1C后代码为
00B40000    A9 9AEF00D6     test    eax, D600EF9A
00B40005    22A8 C4XXXXXX   and     ch, byte ptr [eax+XXXXXXC4]
d=0x0000000300000000+0x5BE6FF82A5164785*2+0x0D时
k=0xED8A27DD EFF333B5
xor 0x1C后代码为
00B40000    A9 9AEF00C1     test    eax, C100EF9A
00B40005    E6 96           out     96, al
00B40007    7B                jpo
d=0x0000000400000000+0x5BE6FF82A5164785*2+0x0D时
k=0x6E5F5AF0 EFF333B5
xor 0x1C后代码为
00B40000    A9 9AEF00EC     test    eax, EC00EF9A
00B40005    B6 43           mov     dh, 43
00B40007    2D 00000000     sub     eax, 0
d=0x0000000500000000+0x5BE6FF82A5164785*2+0x0D时
k=0xEF348E03 EFF333B5
xor 0x1C后代码为
00B40000    A9 9AEF001F     test    eax, 1F00EF9A
00B40005    91              xchg    eax, ecx
00B40006    28C7            sub     bh, al
...........
在里面选一个不改变原来程序流程(不会跳走,也不会异常)的,然后根据前面8个字节的代码补上其余的修改字符的指令,平衡堆栈,就可以达到51个字节的极限值


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

收藏
免费 7
支持
分享
最新回复 (7)
雪    币: 325
活跃值: (97)
能力值: ( LV13,RANK:530 )
在线值:
发帖
回帖
粉丝
2
[QUOTE='火翼[CCG];352742']关键是前面的计算出0x0D的部分
这部分其实就是
((a*0x78CC02A869948F1B mod 2^64) mod 0x5BE6FF82A5164785) mod 2^32 =0x0D
求解的算法zmworm以前有过一篇帖子介绍的很详细[/QUOTE]

为啥要
mod 2^64呢? 偶数学不好。 还有那篇文章没有找到 麻烦搂主可否共享一下~
2007-8-30 12:20
0
雪    币: 435
活跃值: (172)
能力值: ( LV13,RANK:280 )
在线值:
发帖
回帖
粉丝
3
因为溢出了,程序使用了__int64类型
2007-8-30 12:22
0
雪    币: 179
活跃值: (131)
能力值: ( LV12,RANK:290 )
在线值:
发帖
回帖
粉丝
4
我就是没解开这个方程...
2007-8-30 12:23
0
雪    币: 202
活跃值: (77)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
5
90B22DD80D53313*(5be6ff82a5164785*2+xxxxxxxxxxxx000d)
保证5be6ff82a5164785*2+xxxxxxxxxxxx000d<10000000000000000
xxxxxxxxxxxx可以任意取值(当然也可能取错,不过大多数都好使)
2007-8-30 12:28
0
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
学习了。

我搞半天,没解出来,呵呵
2007-8-30 13:19
0
雪    币: 105
活跃值: (10)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
7
应该是(3)
可得到最小代码51B
2007-8-30 14:40
0
雪    币: 159
活跃值: (339)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
8
算法的最后是一个一元二次方程
y = -x^2+26x+169
可以知道在Y得到最大值的时候,x为13也就是0xD,这个数值正好将ret的地址覆盖,而多一分不让,少一点也不行!

然后穷举就ok了....
2007-8-30 14:55
0
游客
登录 | 注册 方可回帖
返回
//