[原创]第二阶段第一题简单分析,加入如何得到51字节文件的方法,计算出的,不是穷举
发表于:
2007-8-30 12:18
6331
[原创]第二阶段第一题简单分析,加入如何得到51字节文件的方法,计算出的,不是穷举
关键是前面的计算出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直播授课