某道简单的crackme

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里的转换为十六进制进行异或运算 最终用过字符串输出结果






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值