当前位置: 首页 > news >正文

逆向入门(43)程序逆向篇-tsrh-crackme

没壳
在这里插入图片描述
不过需要先去个NAG
在这里插入图片描述
想着先进调试器吧,结果一进调试器就退出了,F8追了下
在这里插入图片描述
这里改一下jne,就变成了和直接运行一样的效果,先有NAG然后再正常启动
在这里插入图片描述
查了一个getlasterror,看来是不允许多开了
在这里插入图片描述
接下来找nag,直接f9运行到弹窗的时候,这个时候搜索字符串
在这里插入图片描述
有大量地方调用了403000这个内存地址,并且字符串显示的就是nag,接下来给这个内存地址下硬段,重新加载一下,再运行就断下来了
在这里插入图片描述
一直运行到ret以后跟下去
在这里插入图片描述
就定位到这里了,这里有个je判断跳一个MeseageBoxA,直接改了下eax的值,尝试一下
在这里插入图片描述
最终是正常绕过了,先patch一个
在这里插入图片描述
这样就搞定了去NAG,再接着找
在这里插入图片描述
看一手字符串
在这里插入图片描述
找到了对应位置
在这里插入图片描述
下个断,追一下,发现序列号前四个字节必须为tsrh
在这里插入图片描述
再往后追就看到了这么一段,在这里插入图片描述
这个函数其实做了一堆操作,看着不是很复杂,现在就是不想看了。往IDA里面丢吧
在这里插入图片描述
定位了这样一段,发现在前面还少分析了一个sub_4011f3函数
在这里插入图片描述
做了一个格式化,a1eax,从OD看了下,就是用户名的长度
在这里插入图片描述所以这一串最后得到了一个Stringtsrh-2008-字符串,前四个字符已经分析过了,接下来分析第二个条件
在这里插入图片描述
这一段也有点奇怪,伪代码显示没有参数,但是上一段又传了相加以后值进去,突然又多了个奇怪的v5出来
在这里插入图片描述
不过函数作用还是好理解的,也可以写出这一段的代码出来

    int len = strlen(username);// 1. 初始化序列号sprintf(serial, "tsrh-%d-", len + 2003);int current_length = strlen(serial);// 2. 处理用户名中的每个字符for (int i = 0; i < len; i++) {unsigned char c = username[i];unsigned char v4 = c + 12;int value = (2 * (int)v4 - 17 - current_length) ^ (int)v4;// 将值格式化为大写十六进制并追加char hex[9];sprintf(hex, "%X", value);strcat(serial, hex);current_length += strlen(hex);}int total_length = current_length;

运算结果相同
在这里插入图片描述
再接着往下看
在这里插入图片描述
这里的伪代码有点坑,对应的汇编在这
在这里插入图片描述
其实在第一次赋值以后,后面的内容都被截断了,所以40129C处的edx只有第一次是正常读到了值,后面读到的数值都是0,注意这里的0不是数字0,如果是数字0则会显示为48的,最后注册机显示如下:

#define _CRT_SECURE_NO_WARNINGS#include <stdio.h>
#include <string.h>
#include <ctype.h>void generate_serial(const char* username, char* serial) {int len = strlen(username);// 1. 初始化序列号sprintf(serial, "tsrh-%d-", len + 2003);int current_length = strlen(serial);// 2. 处理用户名中的每个字符for (int i = 0; i < len; i++) {unsigned char c = username[i];unsigned char v4 = c + 12;int value = (2 * (int)v4 - 17 - current_length) ^ (int)v4;// 将值格式化为大写十六进制并追加char hex[9];sprintf(hex, "%X", value);strcat(serial, hex);current_length += strlen(hex);}int esi = 1;bool first = true;int edx = 0;// 3. 调整序列号的特定位置(关键修正)while(true){printf("esi: %d\t", esi);if (!username[esi -1]) break;int eax = username[esi - 1] + 1;if (first) {edx = serial[esi + 0xB];first = false;}else {edx = NULL;}printf("edx:%d\t", edx);eax = eax ^ edx;while (eax < 0x41) eax += 0x8;while (eax > 90) eax -= 0x3;esi += 0x9;serial[esi] = eax;serial[esi + 1] = NULL;printf("%s,%d\n", serial, serial[esi + 1]);esi -= 0x8;if (esi == 0x10) break;}}int main() {char username[256];char serial[256];printf("用户名注册机 (长度>=5)\n");while (1) {printf("\n请输入用户名 (输入quit退出): ");fgets(username, sizeof(username), stdin);// 移除换行符username[strcspn(username, "\n")] = 0;if (strcmp(username, "quit") == 0) {break;}int len = strlen(username);if (len < 5) {printf("错误: 用户名长度必须至少5个字符\n");continue;}// 生成序列号generate_serial(username, serial);printf("生成的序列号: %s\n", serial);}return 0;
}

写是写得粗糙一点啦,其实还可以再优化,不过这样就够了
在这里插入图片描述
搞定,现在做一个题时间花得真久啊,利用好ida加快速度
在这里插入图片描述

http://www.xdnf.cn/news/1197415.html

相关文章:

  • 【笔记】系统
  • 20250727让飞凌OK3576-C开发板在Rockchip的原厂Android14下通过耳机播音
  • 【设计】设计一个web版的数据库管理平台后端(之二)
  • 29.【.NET8 实战--孢子记账--从单体到微服务--转向微服务】--单体转微服务--用户配置服务
  • Java中排序规则详解
  • solidity从入门到精通 第六章:安全第一
  • vmware虚拟机中 ubuntu 20.04通过nat设置静态ip(固定ip)
  • Java学习-------桥接模式
  • 文件权限标记机制在知识安全共享中的应用实践
  • 通信名词解释:I2C、USART、SPI、RS232、RS485、CAN、TCP/IP、SOCKET、modbus
  • 基于开源AI智能名片链动2+1模式S2B2C商城小程序的人格品牌化实现路径研究
  • Linux-文件与文本管理
  • 嵌入式软件面试八股文
  • Photo Studio PRO 安卓版:专业级照片编辑的移动解决方案
  • STM32-USART串口实现接收数据三种方法(1.根据\r\n标志符、2.空闲帧中断、3.根据定时器辅助接收)
  • 将远程 main 分支同步到 develop 分支的完整指南
  • 深入理解指针(三)
  • 用 Flask 打造宠物店线上平台:从 0 到 1 的全栈开发实践
  • 2024-2025华为ICT大赛中国区 实践赛网络赛道(高教组)全国总决赛 理论部分真题+解析
  • KNN算法实现图片的识别
  • 实战演练1:实战演练之命名实体识别
  • JavaScript数组去重性能优化:Set与Object哈希表为何效率最高
  • 俄罗斯方块游戏开发(面向对象编程)
  • 通过v4l2,采集视频,FFmpeg编码压缩封装视频(三)
  • Python-初学openCV——图像预处理(三)
  • 01人工智能中优雅草商业实战项目视频字幕翻译以及声音转译之底层处理逻辑阐述-卓伊凡|莉莉
  • Python 数据分析(四):Pandas 进阶
  • macOS配置 GO语言环境
  • 【NLP舆情分析】基于python微博舆情分析可视化系统(flask+pandas+echarts) 视频教程 - 微博舆情分析实现
  • Linux 系统网络配置及 IP 地址相关知识汇总