int __cdecl main(int argc, const char **argv, const char **envp) { int result; // eax int v4; // eax char Buf; // [esp+4h] [ebp-38h] char Dst; // [esp+5h] [ebp-37h] Buf = 0; memset(&Dst, 0, 0x31u); printf("Please Input Flag:"); gets_s(&Buf, 0x2Cu); if ( strlen(&Buf) == 42 ) { v4 = 0; while ( (*(&Buf + v4) ^ byte_402130[v4 % 16]) == dword_402150[v4] ) { if ( ++v4 >= 42 ) { printf("right!\n"); goto LABEL_8; } } printf("error!\n"); LABEL_8: result = 0; } else { printf("error!\n"); result = -1; } return result; }
#include<stdio.h> #include <string.h> int Getflag(FILE *crack) { char byte[17]; char a[43]; char b[43]; char flag[43]; int tmp; fseek(crack, 0x2130, SEEK_SET); fread(byte, 1 , 16 , crack); byte[16] = 0; fseek(crack, 0x2150, SEEK_SET); for (int i = 0; i < 42; ++i) { fread(&tmp, 4 , 1 , crack); a[i] = (char)tmp; } a[42] = 0; for (int i = 0; i < 42; i++) { b[i] = byte[i % 16]; }; for (int i = 0; i < 42; ++i) { flag[i] = a[i] ^ b[i]; }; flag[42] = 0; puts(flag); return 0; } int main(int argc, char const *argv[]) { FILE *crack = fopen("crackm_n.exe", "rb+"); Getflag(crack); return 0; }
将crackme 北斗脱壳后
上面是通过ida f5看到编译后的c语言。
在缓冲区有42位 需要输入42位的flag
往下继续看while ( (*(&Buf + v4) ^ byte_402130[v4 % 16]) == dword_402150[v4] )
^这是异或门符号 有个重要的定理,三个来回异或是可以相互转换的。
我们只需从402130 和 402150中进行异或就可以得到最终的flag
通过强制类型转换 将四个字节 变为一个字节存入数组中这时候是16进制的
将byte里的转换为十六进制进行异或运算 最终用过字符串输出结果
某道简单的crackme
最新推荐文章于 2024-04-15 13:44:46 发布