CheatEngine附加程序,搜索输入的mInput下,遍历几次就可以锁定唯一的数据了,对其下上硬件访问断点。
最终,我们会定位到这个函数。
140001350 int64_t sub_140001350(int16_t* arg1, char* arg2)
控制流代码很简单,直接修改 “关键跳3”程序出现“Good,Job”。
140001790 if (mSuccessLength == SuccessLength)
14000178d {
140001799 mIsFailFlag = memcmp(mInput, &mSuccess, mSuccessLength);
1400017a0 if (mIsFailFlag == 0) // 关键跳2
14000179e {
1400017a2 mIsFailFlag2 = 0; // 如果为0,则走1400026c7
1400017a2 }
14000178d }
1400017a0 // 关键跳2
1400017a0 if ((mSuccessLength != SuccessLength || (mSuccessLength == SuccessLength && mIsFailFlag != 0)))
14000179e {
1400017a7 mIsFailFlag2 = 1; // 如果为1,则跳过1400026c7
1400017a7 }
140001813 int128_t zmm1_11; // 关键跳3
140001813 int128_t zmm0_11;
140001813 if (mIsFailFlag2 == 0)
140001810 {
1400026c7 int64_t var_14a0 = 0x413c0458d70ea426;
1400026d6 int64_t var_1498_1 = -0x6d6d5a1eee442c04;
1400026f4 int64_t var_b28_1 = -0x6d6d5a1eee442c04;
14000270b var_14a0 = (var_14a0 ^ 0x413c0428d77ea447);
140002716 int128_t var_13f8 = 0;
140002739 do
140002739 {
140002730 r8_3 = ((char*)r8_3 + 1);
140002730 } while (*(int16_t*)(&var_14a0 + (r8_3 << 1)) != 0);
140002749 ......
我们到“关键跳2”中调用memcmp函数的地址140001799下断点,可以获取的信息:mSuccess字符串:“SQAgAFcASQBMAEwAIABMAE8A”与要对比的字符串长度:0x18。
很明显的base64编码,如果不知道,可以在论坛搜索base64,base58,basexx。
我们在百度上搜索这一字符串,看到了与该字符串非常相似的内容。
https://tieba.baidu.com/p/8100877449
看看是不是base64编码
这东西没法子说,像aes 又像base64
到base64在线解码的网站上解码,看样子是有不错的信息。
https://base64.us/
I WILL LO
奇怪?似乎该字符串只有9的长度,但是要求我们输入字符串长度为24。
现在,我们要做的就是对数据流进行分析,可以直接将"I WILL LO"字符串扩展到24字符串的格式,不过我的习惯是先通过00,11进行测试。
对该地址下断点,点击btn,进行登录操作。
140001490 f30f6f1410 movdqu xmm2, xmmword [rax+rdx]
对rax+rdx地址进行数据填充00,对该地址进行下断点,F8步过该地址后,数据变化如下,此时我们进行单步分析。
1400014eb f30f7f09 movdqu xmmword [rcx], xmm1
41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41
很长的一段汇编,实际上只是对字符串进行解码操作。猜测楼主使用了编译时保护技术,如果是简单的嵌入汇编,只能佩服楼主的耐心与汇编能力了,竟然用到了SSE,MMX指令集。
140001633 48b814f53fb06942…mov rax, 0x5f4269b03ff514
14000163d 48894500 mov qword [rbp {var_1560}], rax {0x5f4269b03ff514}
140001641 488b4500 mov rax, qword [rbp {var_1560}] {0x5f4269b03ff514}
140001645 48898560030000 mov qword [rbp+0x360 {mSuccess}], rax {0x5f4269b03ff514}
14000164c 48b8af82f95ca0e0…mov rax, 0xd3e5e0a05cf982af
140001656 48894500 mov qword [rbp {var_1560}], rax {0xd3e5e0a05cf982af}
14000165a 488b4500 mov rax, qword [rbp {var_1560}] {0xd3e5e0a05cf982af}
14000165e 48898568030000 mov qword [rbp+0x368 {var_11f8_1}], rax {0xd3e5e0a05cf982af}
140001665 48b868a9b34ac7a7…mov rax, 0x1beea7c74ab3a968
14000166f 48894500 mov qword [rbp {var_1560}], rax {0x1beea7c74ab3a968}
140001673 488b4500 mov rax, qword [rbp {var_1560}] {0x1beea7c74ab3a968}
140001677 48898570030000 mov qword [rbp+0x370 {var_11f0_1}], rax {0x1beea7c74ab3a968}
14000167e 48b9a6b046eca711…mov rcx, 0xe2da11a7ec46b0a6
140001688 48894d00 mov qword [rbp {var_1560}], rcx {0xe2da11a7ec46b0a6}
14000168c 488b4500 mov rax, qword [rbp {var_1560}] {0xe2da11a7ec46b0a6}
140001690 48898578030000 mov qword [rbp+0x378 {var_11e8_1}], rax {0xe2da11a7ec46b0a6}
140001697 49bd47a47ed72804…mov r13, 0x413c0428d77ea447
1400016a1 4c896d00 mov qword [rbp {var_1560}], r13 {0x413c0428d77ea447}
1400016a5 488b4500 mov rax, qword [rbp {var_1560}] {0x413c0428d77ea447}
1400016a9 488985a00b0000 mov qword [rbp+0xba0 {var_9c0_1}], rax {0x413c0428d77ea447}
1400016b0 49bffcd3bb11e1a5…mov r15, 0x9292a5e111bbd3fc
1400016ba 4c897d00 mov qword [rbp {var_1560}], r15 {0x9292a5e111bbd3fc}
1400016be 488b4500 mov rax, qword [rbp {var_1560}] {0x9292a5e111bbd3fc}
1400016c2 488985a80b0000 mov qword [rbp+0xba8 {var_9b8_1}], rax {0x9292a5e111bbd3fc}
1400016c9 48b821e8f10786e2…mov rax, 0x5ad6e28607f1e821
1400016d3 48894500 mov qword [rbp {var_1560}], rax {0x5ad6e28607f1e821}
1400016d7 488b4500 mov rax, qword [rbp {var_1560}] {0x5ad6e28607f1e821}
1400016db 488985b00b0000 mov qword [rbp+0xbb0 {var_9b0_1}], rax {0x5ad6e28607f1e821}
1400016e2 48894d00 mov qword [rbp {var_1560}], rcx {0xe2da11a7ec46b0a6}
1400016e6 488b4500 mov rax, qword [rbp {var_1560}] {0xe2da11a7ec46b0a6}
1400016ea 488985b80b0000 mov qword [rbp+0xbb8 {var_9a8_1}], rax {0xe2da11a7ec46b0a6}
1400016f1 c5fe6f8560030000 vmovdqu ymm0, ymmword [rbp+0x360 {mSuccess}]
1400016f9 c5fdef8da00b0000 vpxor ymm1, ymm0, ymmword [rbp+0xba0 {var_9c0_1}]
140001701 c5fd7f8d60030000 vmovdqa ymmword [rbp+0x360 {mSuccess}], ymm1
140001709 c5f857c0 vxorps xmm0, xmm0, xmm0
14000170d c5f8118520010000 vmovups xmmword [rbp+0x120 {var_1440}], xmm0
140001715 c5f057c9 vxorps xmm1, xmm1, xmm1
140001719 c5fa7f8d30010000 vmovdqu xmmword [rbp+0x130 {var_1430_1}], xmm1
140001721 488d85c00c0000 lea rax, [rbp+0xcc0 {var_8a0}]
140001728 48c7c6ffffffff mov rsi, 0xffffffffffffffff
14000172f 4c8bc6 mov r8, rsi {0xffffffffffffffff}
140001732 c5f877 vzeroupper
最终解码出0000000140001782 | rcx:"SQAgAFcASQBMAEwAIABMAE8A"
继续单步分析,步过了这个Call。wow,似乎rdx的字符串长度刚好是0x9了。注意到了吗,在日志里,还没进CALL ,rdx指向的字符串长度就已经是9了,这说明咱们找错了,哈哈。
不过我们知道了程序是如何定位到的字符串,0xcc0是关键,我们找到了对字符串进行赋值的地址。
14000173f 488d95c00c0000 lea rdx, [rbp+0xcc0 {var_8a0}] rdx:"AAAAAAAAA"
140001746 488d8d20010000 lea rcx, [rbp+0x120 {var_1440}] rcx是存储新字符串的地址
14000174d e8ced20000 call sub_14000ea20
140001752 488d8d60030000 lea rcx, [rbp+0x360 {mSuccess}]
rdx:41 41 41 41 41 41 41 41 41 00 41 41 41 41 41 41
往上翻翻,我们找到了赋值为0的地址了。
1400015cc c68405c00c000000 mov byte [rbp+rax+0xcc0 {var_8a0}], 0x0
接下来,我们重复一下上面的操作,这次覆盖的数值如下,后面的数值依旧没有变化,这能证明楼主写的base64有问题,如果我们输入的是“1234567812345678”,base64解码后。
01 00 02 00 03 00 04 00 05 00 06 00 07 00 08 00 09 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
---->
41 51 41 43 41 41 4D 41 42 41 41 46 41 41 59 41 42 77 41 49 41 41 6B 41 00 41 41 41 41 41 41 41
“1234567812345678”
---->
“123456781234”
既然程序给了一个非常有用的字符串,我们试试猜答案,“I WILL LO”+15个任意字符便是正确flag。
楼主心中的flag是什么呢?也许是“将喜欢逆向一千万年”、“我将丢掉腐败的习惯”?
I WILL LOVE 逆向10000000年。
I WILL LOSE CORRUPT ALL。
楼主的编辑框控件在复制粘贴时是有漏洞的,小声。:)