某道简单的crackme

来源:互联网 发布:HIS系统数据库类型 编辑:程序博客网 时间:2024/05/21 18:48
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里的转换为十六进制进行异或运算 最终用过字符串输出结果






原创粉丝点击