1. private void printAssemble(PrintStream out, Instruction[] insns, long address, boolean thumb, int maxLengthLibraryName, InstructionVisitor visitor) {
  2. StringBuilder builder = new StringBuilder();
  3. for (Instruction ins : insns) {
  4. if(visitor != null) {
  5. visitor.visitLast(builder);
  6. }
  7. builder.append('\n');
  8. builder.append(dateFormat.format(new Date()));
  9. builder.append(ARM.assembleDetail(this, ins, address, thumb, maxLengthLibraryName));
  10. if (visitor != null) {
  11. visitor.visit(builder, ins);
  12. }
  13. address += ins.getSize();
  14. }
  15. out.print(builder);
  16. }

我们发现这就是加密结果的前8个数,读者可以自行验证第二第三第四部分,同理。
我们通过这种方式确认了,MD5的结果就是加密的结果。
那么做另一件事——Trace汇编中析出MD5的明文,这不是一件简单的事
image.png
在MD5具体流程中,每轮运算都需要64步,每步的第三个操作是选取明文的一截进行加法运算,第四个操作是和K相加。我们无法定位第三个操作,但因为第四个操作的K都是已知的,所以可以这样描述“第四个操作上方第一个add运算就是明文的一截+中间结果”

但是呢。。这前四步其实并没有硬性的顺序要求,生成的汇编代码常常不遵照顺序。。

但好在第一个F(B,C,D)的结果是固定的0xffffffff,它是一个很好的“锚点“

基于K值和这个锚点,我们可以在汇编trace中准确的析出明文——仅依靠trace汇编,不管OLLVM或者花指令将指令流变成10w行还是100w行,还是SO做了保护,明文不会完整出现在内存中,都不影响这个分析过程。


image.png

红框即定位的明文块1的小端序
所以明文就是34413545,cyberchef中看一下

image.png
第一个明文块:4A5E

依照着上述锚点,不断往下追

第二个明文块:9A20

第三个明文块:-893

第四个明文块:3-4E

第五个明文块:2D-8

第六个明文块:39A-

第七个明文块:0DFC

第八个明文块:F9EA

第九个明文块:7247

第十个明文块:1623

第十一个明文块:4180

第十二个明文块:1589

第十三个明文块:1r0y

第十四个明文块:suet

第十五个明文块:d9#K

第十六个明文块:n_p7

开始第二个分组

第十七个明文块:vUw.(.即0x80填充开始)

更严谨些,通过K15确认明文长0x218比特,即512比特+ 24比特,所以明文到此结束。

合并起来就是

4A5E9A20-8933-4E2D-839A-0DFCF9EA72471623418015891r0ysuetd9#Kn_p7vUw

首先迫不及待求一下MD5,验证结果
image.png
完全正确

接下来仔细瞧瞧明文的组成

这是我们的输出

nonce=4A5E9A20-8933-4E2D-839A-0DFCF9EA7247&timestamp=1623418015891&devicetoken=r0ysue&sign=EE7219C352A74B6058B22CE8A5FB282E

这是明文

4A5E9A20-8933-4E2D-839A-0DFCF9EA72471623418015891r0ysuetd9#Kn_p7vUw

nonce+timestamp+devicetoken+(固定的salt)td9#Kn_p7vUw

大功告成!

image.png
第一个 就是第一个add 里 之后 的都在第二个add 然后 k值有一个 K10 0xffff5bb1 搜不到

image.png

image.png
image.png
image.png
FF16

/ Round 1 /
FF(a, b, c, d, x[0], 7, 0xd76aa478); / 1 /
FF(d, a, b, c, x[1], 12, 0xe8c7b756); / 2 /
FF(c, d, a, b, x[2], 17, 0x242070db); / 3 /
FF(b, c, d, a, x[3], 22, 0xc1bdceee); / 4 /
FF(a, b, c, d, x[4], 7, 0xf57c0faf); / 5 /
FF(d, a, b, c, x[5], 12, 0x4787c62a); / 6 /
FF(c, d, a, b, x[6], 17, 0xa8304613); / 7 /
FF(b, c, d, a, x[7], 22, 0xfd469501); / 8 /
FF(a, b, c, d, x[8], 7, 0x698098d8); / 9 /
FF(d, a, b, c, x[9], 12, 0x8b44f7af); / 10 /
FF(c, d, a, b, x[10], 17, 0xffff5bb1); / 11 /
FF(b, c, d, a, x[11], 22, 0x895cd7be); / 12 /
FF(a, b, c, d, x[12], 7, 0x6b901122); / 13 /
FF(d, a, b, c, x[13], 12, 0xfd987193); / 14 /
FF(c, d, a, b, x[14], 17, 0xa679438e); / 15 /
FF(b, c, d, a, x[15], 22, 0x49b40821); / 16 /

/ Round 2 /
GG(a, b, c, d, x[1], 5, 0xf61e2562); / 17 /
GG(d, a, b, c, x[6], 9, 0xc040b340); / 18 /
GG(c, d, a, b, x[11], 14, 0x265e5a51); / 19 /
GG(b, c, d, a, x[0], 20, 0xe9b6c7aa); / 20 /
GG(a, b, c, d, x[5], 5, 0xd62f105d); / 21 /
GG(d, a, b, c, x[10], 9, 0x2441453); / 22 /
GG(c, d, a, b, x[15], 14, 0xd8a1e681); / 23 /
GG(b, c, d, a, x[4], 20, 0xe7d3fbc8); / 24 /
GG(a, b, c, d, x[9], 5, 0x21e1cde6); / 25 /
GG(d, a, b, c, x[14], 9, 0xc33707d6); / 26 /
GG(c, d, a, b, x[3], 14, 0xf4d50d87); / 27 /
GG(b, c, d, a, x[8], 20, 0x455a14ed); / 28 /
GG(a, b, c, d, x[13], 5, 0xa9e3e905); / 29 /
GG(d, a, b, c, x[2], 9, 0xfcefa3f8); / 30 /
GG(c, d, a, b, x[7], 14, 0x676f02d9); / 31 /
GG(b, c, d, a, x[12], 20, 0x8d2a4c8a); / 32 /

/ Round 3 /
HH(a, b, c, d, x[5], 4, 0xfffa3942); / 33 /
HH(d, a, b, c, x[8], 11, 0x8771f681); / 34 /
HH(c, d, a, b, x[11], 16, 0x6d9d6122); / 35 /
HH(b, c, d, a, x[14], 23, 0xfde5380c); / 36 /
HH(a, b, c, d, x[1], 4, 0xa4beea44); / 37 /
HH(d, a, b, c, x[4], 11, 0x4bdecfa9); / 38 /
HH(c, d, a, b, x[7], 16, 0xf6bb4b60); / 39 /
HH(b, c, d, a, x[10], 23, 0xbebfbc70); / 40 /
HH(a, b, c, d, x[13], 4, 0x289b7ec6); / 41 /
HH(d, a, b, c, x[0], 11, 0xeaa127fa); / 42 /
HH(c, d, a, b, x[3], 16, 0xd4ef3085); / 43 /
HH(b, c, d, a, x[6], 23, 0x4881d05); / 44 /
HH(a, b, c, d, x[9], 4, 0xd9d4d039); / 45 /
HH(d, a, b, c, x[12], 11, 0xe6db99e5); / 46 /
HH(c, d, a, b, x[15], 16, 0x1fa27cf8); / 47 /
HH(b, c, d, a, x[2], 23, 0xc4ac5665); / 48 /

/ Round 4 /
II(a, b, c, d, x[0], 6, 0xf4292244); / 49 /
II(d, a, b, c, x[7], 10, 0x432aff97); / 50 /
II(c, d, a, b, x[14], 15, 0xab9423a7); / 51 /
II(b, c, d, a, x[5], 21, 0xfc93a039); / 52 /
II(a, b, c, d, x[12], 6, 0x655b59c3); / 53 /
II(d, a, b, c, x[3], 10, 0x8f0ccc92); / 54 /
II(c, d, a, b, x[10], 15, 0xffeff47d); / 55 /
II(b, c, d, a, x[1], 21, 0x85845dd1); / 56 /
II(a, b, c, d, x[8], 6, 0x6fa87e4f); / 57 /
II(d, a, b, c, x[15], 10, 0xfe2ce6e0); / 58 /
II(c, d, a, b, x[6], 15, 0xa3014314); / 59 /
II(b, c, d, a, x[13], 21, 0x4e0811a1); / 60 /
II(a, b, c, d, x[4], 6, 0xf7537e82); / 61 /
II(d, a, b, c, x[11], 10, 0xbd3af235); / 62 /
II(c, d, a, b, x[2], 15, 0x2ad7d2bb); / 63 /
II(b, c, d, a, x[9], 21, 0xeb86d391); / 64 /

其中:

FF(b, c, d, a, x[15], 22, 0x49b40821); / 16 /
GG(a, b, c, d, x[1], 5, 0xf61e2562); / 17 /

defineROTATE_LEFT(x,n) ((x << n) | (x >> (32-n)))
#defineF(x,y,z) ((x & y) | (~x & z))
#defineG(x,y,z) ((x & z) | (y & ~z))
#defineH(x,y,z) (x^y^z)
#defineI(x,y,z) (y ^ (x | ~z))
#defineFF(a,b,c,d,x,s,ac) { a += F(b, c, d) + x + ac; a = ROTATE_LEFT(a, s); a += b; }
#defineGG(a,b,c,d,x,s,ac) { a += G(b, c, d) + x + ac; a = ROTATE_LEFT(a, s); a += b; }
#defineHH(a,b,c,d,x,s,ac) { a += H(b, c, d) + x + ac; a = ROTATE_LEFT(a, s); a += b; }
#defineII(a,b,c,d,x,s,ac) { a += I(b, c, d) + x + ac; a = ROTATE_LEFT(a, s); a += b; }

(7.4)最终A+=a、B+=b、C+=c、D+=d,即A、B、C、D为更新后的链接变量。