有点难度的KeygenMe
本帖最后由 huoji120 于 2018-8-27 00:08 编辑研究了一天没研究起来.现在头晕眼花的.拿给你们看看吧、
算法没时间看
0040111B | EB 17 | jmp give_a_try.401134 |
004011F5 | EB 12 | jmp give_a_try.401209 | 自己跑一下出 flag
```
// ConsoleApplication1.cpp : 定义控制台应用程序的入口点。
//
#include <windows.h>
#include <stdio.h>
#include <math.h>
#include <limits.h>
#include <random>
int main(int argc, char* argv[])
{
int hash = {
0x63B25AF1, 0xC5659BA5, 0x4C7A3C33, 0x0E4E4267, 0xB611769B, 0x3DE6438C, 0x84DBA61F, 0xA97497E6,
0x650F0FB3, 0x84EB507C, 0xD38CD24C, 0xE7B912E0, 0x7976CD4F, 0x84100010, 0x7FD66745, 0x711D4DBF,
0x5402A7E5, 0xA3334351, 0x1EE41BF8, 0x22822EBE, 0xDF5CEE48, 0xA8180D59, 0x1576DEDC, 0xF0D62B3B,
0x32AC1F6E, 0x9364A640, 0xC282DD35, 0x14C5FC2E, 0xA765E438, 0x7FCF345A, 0x59032BAD, 0x9A5600BE,
0x5F472DC5, 0x5DDE0D84, 0x8DF94ED5, 0xBDF826A6, 0x515A737A, 0x4248589E, 0x38A96C20, 0xCC7F61D9,
0x2638C417, 0xD9BEB996
};
//
//先算出第一个 rand 值
//
unsigned int i = 1;
unsigned int result;
while (i < UINT_MAX)
{
__asm{
mov eax, i //rand
mov ecx, 66h //'f'
mul ecx
mov ecx, 0xFAC96621
push eax
xor edx, edx
div ecx
pop eax
push edx
mul eax
div ecx
mov eax, edx
mul edx
div ecx
mov eax, edx
mul edx
div ecx
mov eax, edx
mul edx
div ecx
mov eax, edx
mul edx
div ecx
mov eax, edx
mul edx
div ecx
mov eax, edx
mul edx
div ecx
mov eax, edx
mul edx
div ecx
mov eax, edx
mul edx
div ecx
mov eax, edx
mul edx
div ecx
mov eax, edx
mul edx
div ecx
mov eax, edx
mul edx
div ecx
mov eax, edx
mul edx
div ecx
mov eax, edx
mul edx
div ecx
mov eax, edx
mul edx
div ecx
mov eax, edx
mul edx
div ecx
mov eax, edx
pop edx
mul edx
div ecx
mov result, edx;
}
if (result == hash)
{
printf("first rand = %x\n", i);
break;
}
i++;
}
//
//反推算出 srand值
//
for (unsigned int i = 1; i < UINT_MAX; i++)
{
int random = 0x31333359 + i; //此值固定nt函数returnlen,xor常量 ,xor OEP第一个字节
srand(random);
if (rand() == 0x4077) // first rand
{
printf("srand = %x strHexCount = %x\n", random, i);
break;
}
}
//
//得出flags
//
srand(0x31333d38);
int randnum;
for (int i = 0; i < 42; i++)
{
randnum = rand();
for (char c = 1; c <= 0xff; c++)
{
__asm{
mov eax, randnum //rand
xor ecx, ecx
movzx ecx, c //'f'
mul ecx
mov ecx, 0xFAC96621
push eax
xor edx, edx
div ecx
pop eax
push edx
mul eax
div ecx
mov eax, edx
mul edx
div ecx
mov eax, edx
mul edx
div ecx
mov eax, edx
mul edx
div ecx
mov eax, edx
mul edx
div ecx
mov eax, edx
mul edx
div ecx
mov eax, edx
mul edx
div ecx
mov eax, edx
mul edx
div ecx
mov eax, edx
mul edx
div ecx
mov eax, edx
mul edx
div ecx
mov eax, edx
mul edx
div ecx
mov eax, edx
mul edx
div ecx
mov eax, edx
mul edx
div ecx
mov eax, edx
mul edx
div ecx
mov eax, edx
mul edx
div ecx
mov eax, edx
mul edx
div ecx
mov eax, edx
pop edx
mul edx
div ecx
mov result, edx;
}
if (result == hash)
{
printf("%c", c);
break;
}
}
}
getchar();
return 0;
}
``` 研究一下,没甚麽想法 只能知道记忆体内的位置 但抓不出来比较值
004011E6 之後开始比较 Incorrect 在 004011FB Congrats在 0040120B 这是一道求解方程的数学题。。。。。 哪弄来的东西?感觉就是个坑。先读取输入框中字符串长度,然而字符串最大只能接受41个,要想正确通过得42个字符串,因此不爆破应该是没法成功的吧,感觉是个坑 xjun 发表于 2018-8-27 13:35
自己跑一下出 flag
```
@Pizza 是这题的作者,就是网顶杯 第二轮的 Reverse 块 这道题目是汇编编译的,可见出题人汇编掌握的熟练程度之高。这道题目使用了两个微软未公布的反调试api:
00402091 E8 A0F2FFFF call <jmp.&ntdll.NtSetInformationThread>
004020BF E8 6CF2FFFF call <jmp.&ntdll.NtQueryInformationProcess>
可见出题人对反调试方法的了解之多
根据题目的提示输入的格式是
flag{.................}
长度是42,未知数据长度是36
本题目使用了srand在固定seed下产生相同随机数列的特点,以保证flag是唯一存在的
http://ww1.sinaimg.cn/large/005NSGrZly1fuoexbeuw8j30kk03hdfn.jpg 感谢分享
页:
[1]
2