新手逆向练习与详解(5)(详解带有源文件)127-CrackMe

链接:百度云盘 密码:tja5

我这里和大家声明一下 我这个是文件 是来自吾爱破解的creakme 160   导航链接  帖子里面有更厉害的思路  

本帖是编号为127的creakme 

这个页面是dos 看起来很友好 毕竟没有那么多花里胡哨的东西

但是这里确实体现出了OD用字符串的坏处 这里人家的字符串通过处理  (用了字符异或解密)然后我们其实这里我们没有必要用关注字符的加密解密 这个creakme我想重点是找到它内部算法 在没有字符提示的情况下  这里我又又又用到了IDA 然后找到main发现了 

int __cdecl main(int argc, const char **argv, const char **envp)
{
  void *v3; // ebx@1
  char *v4; // ebp@3
  char *v5; // edi@5
  char *v6; // esi@7
  int v7; // eax@9
  char v8; // al@9
  int v9; // ebp@9
  signed int v10; // ecx@12
  int v12; // [sp+10h] [bp-10h]@10
  char *v13; // [sp+14h] [bp-Ch]@3
  int v14; // [sp+1Ch] [bp-4h]@11

  v3 = malloc(0x100u);
  if ( !v3 )
    exit(-1);
  v4 = (char *)malloc(0x100u);
  v13 = v4;
  if ( !v4 )
    exit(-1);
  v5 = (char *)malloc(0x100u);
  if ( !v5 )
    exit(-1);
  v6 = (char *)malloc(0x100u);
  if ( !v6 )
    exit(-1);
  sub_401200((const char *)&unk_407030, v3, 64);
  fprintf(&stru_4070C8, aS_0, v3);
  sub_401200((const char *)&unk_40705C, v3, 74);
  fprintf(&stru_4070C8, aS, v3);
  fgets(v5, 256, &stru_4070A8);
  sub_401200((const char *)&unk_407064, v3, 84);
  fprintf(&stru_4070C8, aS, v3);
  fgets(v4, 256, &stru_4070A8);
  v7 = sub_401240(v5);
  sprintf((char *)v3, a010ld, 238 * (v7 ^ 0x5E));
  *v6 = 0;
  v8 = *(_BYTE *)v3;
  v9 = 0;
  if ( *(_BYTE *)v3 )
  {
    v12 = 0;
    do
    {
      sprintf((char *)&v14, a02x, v9 ^ v12 ^ v8);
      strcat(v6, (const char *)&v14);
      v3 = (char *)v3 + 1;
      v8 = *(_BYTE *)v3;
      ++v9;
      v12 += 64;
    }
    while ( *(_BYTE *)v3 );
  }
  v10 = strlen(v6);
  *((_BYTE *)v3 + 64) = 0;
  if ( v10 > 0 )
  {
    do
    {
      if ( *v6 != *v13 )
        *((_BYTE *)v3 + 64) = 1;
      ++v6;
      --v10;
      ++v13;
    }
    while ( v10 );
  }
  if ( *((_BYTE *)v3 + 64) )
    sub_401200((const char *)&unk_40707C, v3, 104);
  else
    sub_401200((const char *)&unk_40706C, v3, 94);
  fprintf(&stru_4070C8, aS_1, v3);
  return 0;
}

其中的 函数401200 就是字符解密并打印的实现 有兴趣的可以跟进去看看它的内部算法的实现 这个实现其实还是很好分析的 然后面的两个gets函数我们就可以知道是name code 可以到OD里 可以去验证 然后我们重点来观察 后面的循环  可以知道后面的循环就是我们比较的函数  那么 我们上个函数就是求出我们真正的code  那么我们就分析这部分 

我们知道v5 就是我们输入的name 那么看看401240 是干嘛的

这里用python来表示就是

name=input()
code=0
str(name)
for i in (name):
    code+=ord(i)

print(code)

然后我们再往下看  往下就是 v3=238*(v7^0x5e) 

然后就是生成code 的那个循环 根据这个循环就可以写出注册机 那么其实我们可以看ida写出来(如果这个exe加壳了 那么脱壳是很必要的 )

那么我就用c++ 来写出这个循环的大概意思

但是不知道是我编译器的问题还是怎么 别人的都是大写字母 但是我的是小写 我进入ida看的时候是这个样子的 可能是哪里出问题了 我进入ida看到了几个转化字母 但是不敢确定 有什么问题 还是欢迎大佬们指教的

#include <iostream>
#include <stdio.h>
#include <math.h>
#include <algorithm>
#include <string.h>
using namespace std;
int main()
{
     char name[256],code_sz[256],ans[256],code_l[256],code[256];
    unsigned int code_int=0,len,code_len,j,i;
     scanf("%s",name);
     len=strlen(name);
     name[len]='\n';
     for(i=0;i<=len;i++)
     {
          code_int+=name[i];
     }
     code_int=238*(code_int^0x5e);
     sprintf(code_sz,"%010ld",code_int);
     printf("%x\n",code_int);
     printf("%s\n",code_sz);
     code_len=strlen(code_sz);
     j=0;
     memset(code,0,sizeof(code));
     for(i=0;i<code_len;i++)
     {
              printf("%x %x\n",i,j);
             memset(code_l,0,sizeof(code_l));
             sprintf(code_l,"%02x",code_sz[i]^i^j);
             strcat(code,code_l);
             printf("%s\n",code_l);
             j+=64;
     }
     printf("%s",(char *)code);
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值