使用Ghidra破解注册程序,编写python注册码生成程序。

Crackme(目标程序):https://crackmes.one/static/crackme/5c268e8333c5d41e58e00654.zip

Ghidra(NSA反编译工具):https://github.com/NationalSecurityAgency/ghidra

BlackArch(操作系统):https://blackarch.org/

Pycharm(python编译器):https://www.jetbrains.com/pycharm/

一、使用Ghidra加载目标程序,跟踪反编译代码。

1、运行程序参数提示如下:

[ BlackArch ~ ]# ./keyGme 
Usage: ./keyGme [serial-key]

2、在函数列表中搜索程序主函数“main”,找到该函数的代码如下:

undefined4 main(int param_1,undefined4 *param_2)

{
  undefined4 uVar1;
  size_t sVar2;
  uint uVar3;
  
  if (param_1 == 2) {
    sVar2 = strlen((char *)param_2[1]);         
    if (sVar2 == 0x10) {               //serial-key的长度为十六进制的0x10,即十进制的16,注册码的长度为16个字符。
uVar3
= FUN_08048323((char *)param_2[1]); //函数FUN_08048323的返回值赋值给变量uVar3 if (uVar3 == 0) { puts(s_Sorry,_the_code_was_invalid._08049749); } else { puts(s_Congratulation,_You_are_register_08049721); //如果uVar3的值为1则提示注册成功 } uVar1 = 0; } else { puts(s_Your_key_must_be_16_characters._08049701); uVar1 = 2; } } else { printf(s_Usage:_%s_[serial-key]_080496e9,*param_2); uVar1 = 1; } return uVar1; }

3、双击函数名称“FUN_08048323”得到该函数的代码如下:


uint FUN_08048323(char *param_1)

{
  size_t sVar1; //定义序列号中字符位置
  int iVar2;
  int local_10; //定义循环使用的计数器
  int local_c; //定义序列号字符对应的ASCii码
 
  sVar1 = strlen(param_1); //sVar1的初始值为1,结束值为16
  local_c = 0;
  local_10 = 0;
  do {
    if ((int)(sVar1 - 1) <= local_10) {
      return (uint)(local_c == (int)param_1[sVar1 - 1]);
    }
    iVar2 = FUN_080482c1(param_1[local_10]);
    if (iVar2 == 0) {
      iVar2 = FUN_080482f2(param_1[local_10]);
      if (iVar2 == 0) {
        puts(s_Found_invalid_character!_080496d0); //如果FUN_080482c1和FUN_080482f2的返回值为0,则提示无效字符。
                    /* WARNING: Subroutine does not return */
        exit(3); //跳出循环
      }
    }
    local_c = (local_c + (int)param_1[local_10] >> 1) % 0xf00 + 10; //序列号中,最后一个字符的ascii值等于\
                                           通过公式(character_sumasc+ord(previous_character))>>1%3840+10循环累加

   local_10 = local_10 + 1; //计数器加1
  } while( true );
}

4、双击函数名称“FUN_080482c1”和“FUN_080482f2”得到如下代码:可以判断出序列号中只包含大写字母A-Z和数字0-9中的随机字符

undefined4 FUN_080482c1(char param_1)

{
  undefined4 uVar1;   //定义函数返回值为uVar1
  
  if ((param_1 < 'A') || ('Z' < param_1)) {  //如果函数变量param_1不在A-Z这些字母中的话,返回值为0,即无效字符。
    uVar1 = 0;                               //所以序列号中包含的字母范围为A-Z
  }
  else {
    uVar1 = 1;
  }
  return uVar1;
}



undefined4 FUN_080482f2(char param_1)

{
  undefined4 uVar1;   //定义函数返回值为uVar1
  
  if ((param_1 < '0') || ('9' < param_1)) {    //如果函数变量param_1不在0-9这些数字中的话,返回值为0,即无效字符。
    uVar1 = 0;                                 //所以序列号中包含的数字范围为0-9
  }
  else {
    uVar1 = 1;
  }
  return uVar1;
}

二、编写python脚本,生成序列号。

该脚本满足以下几个条件:

1、序列号长度为16位

2、序列号中包含的字母范围为A-Z

3、序列号中包含的数字范围为0-9

4、最后一个字符的ascii值是前15个的值通过公式character_sumasc=(character_sumasc+ord(previous_character))>>1%3840+10累加得来

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import random
import string

choices = string.ascii_uppercase + string.digits

def key_check(key):
    character_sumasc = 0
    for k in key:
        character_sumasc += ord(k)
        character_sumasc = character_sumasc >> 1
        character_sumasc %= int('0xf00',16)
        character_sumasc += 10
    final_letter = chr(character_sumasc)
    if final_letter in choices:
        key += final_letter
        print("Key: {0}".format(key))
    else:
        key_gen()

def key_gen():
    key  = ""
    while len(key) < 15:
        key += random.choice(choices)
    key_check(key)

if __name__ == '__main__':
    key_gen()

附:http://www.runoob.com/python/python-operators.html

 

转载于:https://www.cnblogs.com/heycomputer/articles/10740904.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值