模仿春节解红包,但是Windows中级题
本帖最后由 DEATHTOUCH 于 2024-2-29 11:36 编辑今年的春节红包Windows题只有两题,除了几乎等于送分的初级题,就是巨难的高级题,全论坛就几个人做出。
我记得两年前的红包题还有Windows中级题,挺有意思的,所以就像模仿一个题给大伙玩玩。
程序使用mingw32编译,没有加壳,不过gcc优化比较抽象。
一开始忘记strip符号表了,现在附件多了一个strip后的exe,可以对比着看看。
uid可以通过这个连接获取:https://www.52pojie.cn/home.php?mod=space&do=profile
成功截图:
为了沉浸式再体验一次红包题,我就不提供具体的一组key了,不过难度不高得到自己uid的一组key应该比较容易。
解压密码:52pojie
有能力有空的可以搞个注册机(涉及到软浮点,直接看肯定复杂,可以简化)。
源码在 https://gitee.com/peazomboss/softfloat32
有兴趣可以看看,就是套了一下之前的软浮点代码。 本帖最后由 爱飞的猫 于 2024-2-28 03:27 编辑
记得把符号抹掉呀!编译器添加参数 `-O2 -s`
应该是利用浮点特性,稍微看了下跟不出来,但是可以把你的 CM 改成注册机;可以参考下面的 1337 补丁文件或直接看我在 x64dbg 下使用 Multiline Ultimate Assembler 写的补丁代码:
```s
<$crackme_2024_2_27.171C>
mov byte ptr ss:, bl
nop
nop
nop
nop
nop
nop
nop
<$crackme_2024_2_27.17DC>
mov byte ptr ss:, bl
nop
nop
nop
<$crackme_2024_2_27.0C17B>
jmp $crackme_2024_2_27.0C19C
db 0xE9
<$crackme_2024_2_27.0C1B6>
@loop_begin:
movzx eax, byte
mov dword, eax
call $crackme_2024_2_27.0BE58 ; putchar
inc ebx
cmp ebx, 0x10
jmp @f
dd 0x90909090
@@:
jl @loop_begin
jmp $crackme_2024_2_27.0C0CF
```
之后就是执行补丁好的程序,输入 uid,弹出密钥。
```
Input uid: 176017
Input flag: c72cb0c805b0d947
Press any key to continue . . .
```
(这究竟算不算注册机呢…)
---
> 除了几乎等于送分的初级题,就是巨难的高级题,全论坛就几个人做出。
今年的 Windows 高级题现在有去掉了 Themida 壳的版本可以尝试哦!期待你的分析。
本帖最后由 oscouregeo 于 2024-2-27 19:39 编辑
image.png
16位
image.png
前8位
image.png
后8位
image.png 本帖最后由 DEATHTOUCH 于 2024-2-28 12:24 编辑
爱飞的猫 发表于 2024-2-28 03:19
记得把符号抹掉呀!编译器添加参数 `-O2 -s`
应该是利用浮点特性,稍微看了下跟不出来,但是可以把 ...
我这个CM就是套了一下之前写的软浮点代码,实际上不难只能唬唬新手,所以叫“中级题”,其实偏初级的。
还有忘记strip了,不过我开的就是O2,不过gcc的优化好抽象。 DEATHTOUCH 发表于 2024-2-28 12:22
我这个CM就是套了一下之前写的软浮点代码,实际上不难只能唬唬新手,所以叫“中级题”,其实偏初级的。
...
如果把代码都挪到头文件,打上 `inline` 标记的话,产出的代码应该会比较难看一些。
坏处就是编译时间会增加… 只是 CM 的话应该没啥区别就是。 本帖最后由 solly 于 2024-3-1 12:49 编辑
正向算法还是好处理,只是代码不太好看:
#include <iostream>
#include <math.h>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
typedef unsigned long long UINT64;
typedef unsigned int UINT32;
typedef unsigned char UINT8;
union IF {
UINT32 I;
floatF;
};
UINT32 _STR_PAUSE[] = {0x3E5C8DC9, 0x3E3F03F0, 0x3E666666, 0x3E627627, 0x3E46E46E, 0x0};
UINT32 _HEX_DIG[] = {0x00039A50, 0x0003AD87, 0x0003C0BE, 0x0003D3F5, 0x0003E72C, 0x0003FA63,
0x00040D9A, 0x000420D1, 0x00043408, 0x0004473F, 0x000747D7, 0x00075B0E,
0x00076E45, 0x0007817C, 0x000794B3, 0x0007A7EA };
UINT32 _STR_IN_FLAG[] = {0x35B7BF3E, 0x50F1CF84, 0x526A9220, 0x561878A6, 0x555C1758, 0x178C29C0,
0x4B0EC514, 0x4F790CE8, 0x4760DE8E, 0x4BCB2662, 0x2AAE0BAC, 0x178C29C0, 0x0};
UINT32 _STR_IN_UID[]= {0x3EA0697A, 0x3EF1B77C, 0x3EF61C91, 0x3F008CA3, 0x3EFEE6BB, 0x3E0CA29C,
0x3F008CA3, 0x3EE6BAC8, 0x3EDBBE14, 0x3E7EE6BB, 0x3E0CA29C, 0x0};
UINT32 _STR_OK[] = {0x3F1F3E7D, 0x3F172E5D, 0x3EB162C6, 0x3E810204, 0x3F73E7D0, 0x3F5FBF7F, 0x3F6BD7AF, 0x3E810204,
0x3F43870E, 0x3F65CB97, 0x3F4B972E, 0x3E810204, 0x3F65CB97, 0x3F53A74F, 0x3F4F9F3E, 0x3F51A347,
0x3F69D3A7, 0x3EB972E6, 0x0};
UINT32 _STR_ERR[] ={0x0078911A, 0x00C73284, 0x00C73284, 0x00C1F48E, 0x00C73284, 0x004CE218, 0x0037EA40, 0x00C3B3E0,
0x00BCB698, 0x00B07B5A, 0x00A97E12, 0x00C8F1D6, 0x00B07B5A, 0x0037EA40, 0x00CAB128, 0x00C73284,
0x00D36DC2, 0x0037EA40, 0x00A97E12, 0x00B3F9FE, 0x00A97E12, 0x00B778A2, 0x00C0353C, 0x005060BC, 0};
UINT8 _initreciptable8x8[] ={0xF1, 0xD8, 0xC3, 0xB2, 0xA4, 0x98, 0x8D, 0x84};
UINT8 _initreciptable16x8[] = {0xF8, 0xEA, 0xDD, 0xD2, 0xC8, 0xBF, 0xB6, 0xAE, 0xA7, 0xA1, 0x9B, 0x95, 0x90, 0x8B, 0x86, 0x82};
UINT8 _initreciptable8x8_0[] = {0xF1, 0xD8, 0xC3, 0xB2, 0xA4, 0x98, 0x8D, 0x84};
#define MAX_UID 3000000
UINT32 _rng_seed = 0;
void tip_uid();
void tip_flag();
void tip_error();
void tip_ok();
UINT64 _getapproxrecip16x8_32(UINT32 arg);
bool check(UINT32 uid, char * flag);
bool get_flag(UINT32 uid, char * flag);
bool get_flag_part(UINT32 uid_part, char * flag);
int main(int argc, char** argv) {
printf("Hello world.\n");
//UINT64 ar = _getapproxrecip16x8_32(0x99B80000);
//printf("ar = %I64X\n", ar);
tip_uid();
//UINT32 uid = 1024510; //// "faba9cb5ad6b01f8"
//UINT32 uid = 1034567; //// "0d0e487c7a57a036"
UINT32 uid = 1234567; //// "2b9f32d2cd6b6f5d"
printf("%u\n", uid);
char flag[] = "0123456789ABCDEF\0";
bool ret = get_flag(uid, flag);
printf("flag = %s\n", flag);
/*
tip_flag();
printf("\n");
tip_error();
printf("\n");
tip_ok();
printf("\n");
*/
/*
if(uid<MAX_UID) {
bool isOK = check(uid, flag);
if(isOK) {
tip_ok();
} else {
tip_error();
}
} else {
tip_error();
}
printf("\n");
*/
return 0;
}
void tip_uid() {
IF m1, m2;
m2.I = 0x3B8CA29C;
int i=0;
while(_STR_IN_UID != 0) {
m1.I = _STR_IN_UID;
float a = ( m1.F / m2.F);
//int b = round(a);
int b = trunc(a);
printf("%c", (char)b);
}
}
void tip_flag() {
for(int i=0; i<13; i++) {
char output_ch = 0;
int f = _STR_IN_FLAG;
if(f>12345677) {
UINT32 a = 2918332797; // _getapproxrecip16x8_32(12345678 * 256)
UINT64 aa = (UINT64)f * a;
//printf("aa = %I64X\n", aa);
UINT32 ch = (UINT32)(aa >> 55);
UINT32 b = f - ch * 12345678;
//printf("ch = 0x%x\n", ch);
UINT32 c = b;
//printf("%u\n", c);
output_ch = (char)ch;
//printf("ch = %c\n", (char)output_ch);
if(b>12345677) {
b -= 12345678;
UINT64 d = (UINT64)b * 1459166399; /// 1459166398 + 1
if((d & 0x40000000000000) == 0) {
output_ch ++;
}
while(b>12345677) {
b -= 12345678 * 2;
output_ch += 2;
}
//printf("2: %u\n", output_ch);
}
}
printf("%c", (char)output_ch);
}
}
void tip_error() {
for(int i=0; i<24; i++) {
char output_ch = 0;
int e = _STR_ERR;
if(e>114513) {
UINT32 a = 2457996198; // _getapproxrecip16x8_32(114514 * 32768)
UINT64 aa = (UINT64)e * a;
//printf("aa = %I64X\n", aa);
UINT32 ch = (UINT32)(aa >> 48);
UINT32 b = e - ch * 114514;
//printf("ch = 0x%x\n", ch);
UINT32 c = b;
//printf("%u\n", c);
output_ch = (char)ch;
//printf("ch = %c\n", (char)output_ch);
if(b>114513) {
b -= 114514;
UINT64 d = (UINT64)b * 2457996199;// 2457996198 + 1
if((d & 0x40000000000000) == 0) {
output_ch ++;
}
while(b>114513) {
b -= 114514 * 2;
output_ch += 2;
}
//printf("2: %u\n", output_ch);
}
}
printf("%c", (char)output_ch);
}
}
void tip_ok() {
IF m1;
float m2 = 127;
for(int i=0; i<18; i++) {
m1.I = _STR_OK;
float a = ( m1.F * m2);
//int b = round(a);
int b = trunc(a);
printf("%c", (char)b);
}
}
UINT64 _getapproxrecip16x8_32(UINT32 arg) {
UINT32 a = _initreciptable16x8 * 0x1000000;
UINT64 b = -(UINT32)(((UINT64)a * arg) >> 32);
UINT64 c = ((b * a)>>32) * 2;
UINT32 d = -((arg * c) >> 32);
UINT64 e = d * c;
UINT64 f = (e >> 32) * 2;
UINT32 g = (UINT32)((arg * f)>>32);
UINT64 h = (~(g)) * f;
return (h >> 31);
}
void rand_generator(UINT32 seed, UINT32 &rnd1, UINT32 &rnd2) {
float max_uid = MAX_UID;
float flt_uid = seed;
float a = flt_uid / max_uid;
float b = a - 0.5;
IF stu_b;
stu_b.F = b;
if(b>0) {
stu_b.I --;
} else {
stu_b.I ++;
}
float d = stu_b.F;
UINT32 d2 = stu_b.I;
IF stu_e;
stu_e.I = 0x3C9D89D9; /// 0.01923076994717121
float e = stu_e.F;
float f = e * flt_uid;
//UINT32 g = round(f);
UINT32 g = trunc(f);
if(f>28846) {
g /= 2;
}
UINT32 h = g + 1024;
IF stu_j;
stu_j.F = d;
UINT32 j = stu_j.I;
if(h>1) {
int k = 1;
do {
j = j * 134775813 + 1;
k++;
} while(h != k);
}
rnd1 = j * 134775813 + 1; /// 0xC784E0D0
UINT32 k = rnd1 * 134775813 + 1;
_rng_seed = k;
UINT32 u = rnd1 + d2;
UINT32 v = u + k;
rnd2 = (v<<16) | (v>>16);
}
bool get_flag(UINT32 uid, char * flag) {
//// random
UINT32 rnd1=0, rnd2=0;
rand_generator(uid, rnd1, rnd2);
//printf("rnd1 = 0x%08X, rnd2 = 0x%08X\n", rnd1, rnd2);
//// part 1
bool ret1 = get_flag_part(rnd1, &flag);
//// part 2
bool ret2 = get_flag_part(rnd2, &flag);
return ret1 && ret2;
}
bool get_flag_part(UINT32 uid_part, char * flag) {
int i = 0;
do {
//char ch_a = flag;
UINT32 flag_ch=0;
UINT32 p = _HEX_DIG;
if(p>4918) {
UINT64 ar = _getapproxrecip16x8_32(0x99B80000);
//UINT32 ar_a = 0xD52B24CA;
UINT32 ar_a = (UINT32)(ar);
//UINT32 ar_d = 0x6A959265;
UINT64 q = (UINT64)p * ar_a;
flag_ch = (UINT64)(q >> 44);
UINT32 r = (UINT32)(flag_ch * 4919);
UINT32 s = p - r;
if(s>4918) {
s -= 4919;
UINT64 t = (UINT64)s * 894093619;
if(( t & 0x040000000000) == 0) {
flag_ch ++;
if(s>4918) {
do {
s -= 9838;
flag_ch+=2;
} while(s > 4918);
}
}
}
}
uid_part = uid_part / 16; /// l>>=4;
//printf("%c", flag_ch);
flag = (char)flag_ch;
i++;
} while(i<8);
return true;
}
bool check(UINT32 uid, char * flag) {
return true;
}
有3个除法的代码,美化了一下:
#include <iostream>
#include <math.h>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
typedef unsigned long long UINT64;
typedef unsigned int UINT32;
typedef unsigned char UINT8;
union IF {
UINT32 I;
floatF;
};
UINT32 _STR_PAUSE[] = {0x3E5C8DC9, 0x3E3F03F0, 0x3E666666, 0x3E627627, 0x3E46E46E, 0x0};
UINT32 _HEX_DIG[] = {0x00039A50, 0x0003AD87, 0x0003C0BE, 0x0003D3F5, 0x0003E72C, 0x0003FA63,
0x00040D9A, 0x000420D1, 0x00043408, 0x0004473F, 0x000747D7, 0x00075B0E,
0x00076E45, 0x0007817C, 0x000794B3, 0x0007A7EA };
UINT32 _STR_IN_FLAG[] = {0x35B7BF3E, 0x50F1CF84, 0x526A9220, 0x561878A6, 0x555C1758, 0x178C29C0,
0x4B0EC514, 0x4F790CE8, 0x4760DE8E, 0x4BCB2662, 0x2AAE0BAC, 0x178C29C0, 0x0};
UINT32 _STR_IN_UID[]= {0x3EA0697A, 0x3EF1B77C, 0x3EF61C91, 0x3F008CA3, 0x3EFEE6BB, 0x3E0CA29C,
0x3F008CA3, 0x3EE6BAC8, 0x3EDBBE14, 0x3E7EE6BB, 0x3E0CA29C, 0x0};
UINT32 _STR_OK[] = {0x3F1F3E7D, 0x3F172E5D, 0x3EB162C6, 0x3E810204, 0x3F73E7D0, 0x3F5FBF7F, 0x3F6BD7AF, 0x3E810204,
0x3F43870E, 0x3F65CB97, 0x3F4B972E, 0x3E810204, 0x3F65CB97, 0x3F53A74F, 0x3F4F9F3E, 0x3F51A347,
0x3F69D3A7, 0x3EB972E6, 0x0};
UINT32 _STR_ERR[] ={0x0078911A, 0x00C73284, 0x00C73284, 0x00C1F48E, 0x00C73284, 0x004CE218, 0x0037EA40, 0x00C3B3E0,
0x00BCB698, 0x00B07B5A, 0x00A97E12, 0x00C8F1D6, 0x00B07B5A, 0x0037EA40, 0x00CAB128, 0x00C73284,
0x00D36DC2, 0x0037EA40, 0x00A97E12, 0x00B3F9FE, 0x00A97E12, 0x00B778A2, 0x00C0353C, 0x005060BC, 0};
UINT8 _initreciptable8x8[] ={0xF1, 0xD8, 0xC3, 0xB2, 0xA4, 0x98, 0x8D, 0x84};
UINT8 _initreciptable16x8[] = {0xF8, 0xEA, 0xDD, 0xD2, 0xC8, 0xBF, 0xB6, 0xAE, 0xA7, 0xA1, 0x9B, 0x95, 0x90, 0x8B, 0x86, 0x82};
UINT8 _initreciptable8x8_0[] = {0xF1, 0xD8, 0xC3, 0xB2, 0xA4, 0x98, 0x8D, 0x84};
#define MAX_UID 3000000
UINT32 _rng_seed = 0;
void tip_uid();
void tip_flag();
void tip_error();
void tip_ok();
UINT64 _getapproxrecip16x8_32(UINT32 arg);
bool check(UINT32 uid, char * flag);
bool get_flag(UINT32 uid, char * flag);
bool get_flag_part(UINT32 uid_part, char * flag);
int main(int argc, char** argv) {
printf("Hello world.\n");
//UINT64 ar = _getapproxrecip16x8_32(0x99B80000);
//printf("ar = %I64X\n", ar);
tip_uid();
//UINT32 uid = 1024510; //// "faba9cb5ad6b01f8"
//UINT32 uid = 1034567; //// "0d0e487c7a57a036"
UINT32 uid = 1234567; //// "2b9f32d2cd6b6f5d"
printf("%u\n", uid);
char flag[] = "0123456789ABCDEF\0";
bool ret = get_flag(uid, flag);
printf("flag = %s\n", flag);
///*
tip_flag();
printf("\n");
tip_error();
printf("\n");
tip_ok();
printf("\n");
//*/
/*
if(uid<MAX_UID) {
bool isOK = check(uid, flag);
if(isOK) {
tip_ok();
} else {
tip_error();
}
} else {
tip_error();
}
printf("\n");
*/
return 0;
}
void tip_uid() {
IF m1, m2;
m2.I = 0x3B8CA29C;
int i=0;
while(_STR_IN_UID != 0) {
m1.I = _STR_IN_UID;
float a = ( m1.F / m2.F);
//int b = round(a);
int b = trunc(a);
printf("%c", (char)b);
}
}
void tip_flag() {
for(int i=0; i<13; i++) {
char output_ch = _STR_IN_FLAG / 12345678;
printf("%c", (char)output_ch);
}
}
void tip_error() {
for(int i=0; i<24; i++) {
char output_ch = _STR_ERR / 114514;
printf("%c", (char)output_ch);
}
}
void tip_ok() {
IF m1;
float m2 = 127;
for(int i=0; i<18; i++) {
m1.I = _STR_OK;
float a = ( m1.F * m2);
//int b = round(a);
int b = trunc(a);
printf("%c", (char)b);
}
}
UINT64 _getapproxrecip16x8_32(UINT32 arg) {
UINT32 a = _initreciptable16x8 * 0x1000000;
UINT64 b = -(UINT32)(((UINT64)a * arg) >> 32);
UINT64 c = ((b * a)>>32) * 2;
UINT32 d = -((arg * c) >> 32);
UINT64 e = d * c;
UINT64 f = (e >> 32) * 2;
UINT32 g = (UINT32)((arg * f)>>32);
UINT64 h = (~(g)) * f;
return (h >> 31);
}
void rand_generator(UINT32 seed, UINT32 &rnd1, UINT32 &rnd2) {
float max_uid = MAX_UID;
float flt_uid = seed;
float a = flt_uid / max_uid;
float b = a - 0.5;
IF stu_b;
stu_b.F = b;
if(b>0) {
stu_b.I --;
} else {
stu_b.I ++;
}
float d = stu_b.F;
UINT32 d2 = stu_b.I;
IF stu_e;
stu_e.I = 0x3C9D89D9; /// 0.01923076994717121
float e = stu_e.F;
float f = e * flt_uid;
//UINT32 g = round(f);
UINT32 g = trunc(f);
if(f>28846) {
g /= 2;
}
UINT32 h = g + 1024;
IF stu_j;
stu_j.F = d;
UINT32 j = stu_j.I;
if(h>1) {
int k = 1;
do {
j = j * 134775813 + 1;
k++;
} while(h != k);
}
rnd1 = j * 134775813 + 1; /// 0xC784E0D0
UINT32 k = rnd1 * 134775813 + 1;
_rng_seed = k;
UINT32 u = rnd1 + d2;
UINT32 v = u + k;
rnd2 = (v<<16) | (v>>16);
}
bool get_flag(UINT32 uid, char * flag) {
//// random
UINT32 rnd1=0, rnd2=0;
rand_generator(uid, rnd1, rnd2);
//// part 1
bool ret1 = get_flag_part(rnd1, &flag);
//// part 2
bool ret2 = get_flag_part(rnd2, &flag);
return ret1 && ret2;
}
bool get_flag_part(UINT32 uid_part, char * flag) {
int i = 0;
do {
//char ch_a = flag;
UINT32 flag_ch = _HEX_DIG / 4919;
uid_part = uid_part / 16; /// l>>=4;
//printf("%c", flag_ch);
flag = (char)flag_ch;
i++;
} while(i<8);
return true;
}
bool check(UINT32 uid, char * flag) {
return true;
}
页:
[1]