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

逆向入门(41)程序逆向篇-crackme

0x01 crackme

无壳
在这里插入图片描述
打开以后,发现挺特别
在这里插入图片描述
需要新建一个key.dat
在这里插入图片描述
有了以后就提示不对,上od看看
在这里插入图片描述
这里应该是有一个爆破点,接着往上找
在这里插入图片描述
这里是读完以后的,下个断一步步看吧
在这里插入图片描述
注释挺长的,但是实际上只用了key.dat的前三位一直运算,最后相乘运算的结果和0x2A8BF4相等就行,但是试了下程序居然崩了,接着再往下看
在这里插入图片描述
这里有个call esi,而刚刚好esi的地址就是刚刚转换后key的首地址,看来得让这个地方能够正常call,还得继续往上再看一段代码了

但是上面的代码好像不影响esi,这里把他改成常规的函数头试试

push ebp   ; 0x55
mov ebp,esp ; 0x8b 0xec

经验证确实为0x2a8bf4
在这里插入图片描述
写出注册机

int main() {char str1[256] = { 0 };str1[0] = 0x55 ^ 3 ^ 0x54 ^ 0x1e ^ 0;str1[1] = 0x8b ^ 3 ^ 0x4d ^ 0xbf ^ 0;str1[2] = 0xec ^ 3 ^ 0x47 ^ 0xa2 ^ 0;printf("%x,%x,%x,%x", str1[0], str1[1], str1[2]);return 0;
}

在这里插入图片描述
将结果写入到16进制的key.dat中,发现程序闪退
在这里插入图片描述
原因发现这里进入了死循环,这里是将算好的前三位放入到新的内存地址中,一直碰到0x20才会停止,所以在刚刚的代码基础之上还得再加一个字符作为终止符,这位就是第4位,处理经过以下流程
在这里插入图片描述
用这一部分 计算好的key1去和key4异或最后的结果是0x20

int main() {char str1[256] = { 0 };str1[0] = 0x55 ^ 0x1e ^ 0x54^ 4 ;str1[1] = 0x8b ^ 0xbf ^ 0x4d^ 4 ;str1[2] = 0xec ^ 0xa2 ^ 0x47^ 4 ;char tmp_str0 = str1[0] ^ 0x54 ^ 4;str1[3] = 0x20  ^ tmp_str0 ^ 4;printf("%x,%x,%x,%x", str1[0], str1[1], str1[2], str1[3]);return 0;
}

在这里插入图片描述
可以了
在这里插入图片描述
但是这里用户名还没有显示名出来,用户应该应该是移动到了这一部分放着了
在这里插入图片描述
所以,最后的注册机可以写成带有用户名的

#include <iostream>
#include <string>int main() {std::string username;printf("用户名: ");std::getline(std::cin, username);int nameLen = username.length();int totalLen = nameLen + 4;char str1[256] = { 0 };str1[0] = 0x55 ^ 0x1e ^ 0x54^ totalLen;str1[1] = 0x8b ^ 0xbf ^ 0x4d^ totalLen;str1[2] = 0xec ^ 0xa2 ^ 0x47^ totalLen;char tmp_str0 = str1[0] ^ 0x54 ^ totalLen;str1[3] = 0x20  ^ tmp_str0 ^ totalLen;printf("%02x %02x %02x %02x", str1[0], str1[1], str1[2], str1[3]);for (int i = 0; i < nameLen; i+=3){username[i] ^= str1[i + 1] ^ 0x4d;   //因为第4位是个空白的,所以整体后移了一位username[i+1] ^= str1[i + 2] ^ 0x47;username[i+2] ^= str1[i] ^ 0x5d;}for (int i = 0; i < nameLen; i++){printf(" %02x", username[i]);}return 0;
}

在这里插入图片描述
但是结果仍然有点问题
在这里插入图片描述
排查原因发现是因为在下列代码异或的时候,即使长度不够也会继续异或得到值,总是要取被3字节整的数才可以
在这里插入图片描述
同时调整了了一下字符输出的方式,并直接生成key.dat文件

#include <iostream>
#include <fstream>  int main() {char username[255] = {0};printf("用户名: ");std::cin.getline(username, 255);int nameLen = strlen(username);int totalLen = nameLen + 4 ;int realLen = totalLen % 3 == 0 ? totalLen : (totalLen + 3 - (totalLen % 3));char str1[256] = { 0 };str1[0] = 0x55 ^ 0x1e ^ 0x54^ realLen;str1[1] = 0x8b ^ 0xbf ^ 0x4d^ realLen;str1[2] = 0xec ^ 0xa2 ^ 0x47^ realLen;char tmp_str0 = str1[0] ^ 0x54 ^ realLen;str1[3] = 0x20  ^ tmp_str0 ^ realLen;for (int i = 0; i < realLen - 4; i+=3){str1[i + 4] = username[i] ^ str1[1]  ^ realLen ^ 0x4d ^ realLen;   //因为第4位是个空白的,所以整体后移了一位str1[i + 5] = username[i+1] ^ str1[2] ^ realLen ^ 0x47 ^ realLen;str1[i + 6] = username[i+2] ^ str1[0] ^ realLen ^ 0x54 ^ realLen;}for (int i = 0; i < realLen; i++){printf("%02x ", str1[i]);}// 写入到 key.dat 文件std::ofstream keyFile("key.dat", std::ios::binary);if (keyFile.is_open()) {keyFile.write(str1, realLen);keyFile.close();std::cout << "已写入 key.dat 文件" << std::endl;}else {std::cerr << "无法创建 key.dat 文件" << std::endl;}return 0;
}

在这里插入图片描述
最后运行结果完美,终于搞定了,断断续续看了5天才写完
在这里插入图片描述

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

相关文章:

  • OceanBase数据库
  • 设备虚拟化技术
  • 从零开始学习Dify-Excel数据可视化(四)
  • Rocky9部署Zabbix7(小白的“升级打怪”成长之路)
  • 【bug】websocket协议不兼容导致的一个奇怪问题
  • (46)elasticsearch-华为云CCE无状态负载部署
  • #Linux内存管理# 在一个播放系统中同时打开几十个不同的高清视频文件,发现播放有些卡顿,打开视频文件是用mmap函数,请简单分析原因。
  • MCU芯片AS32S601在卫星光纤放大器(EDFA)中的应用探索
  • VPS海外部署Linux分布式计算任务调度-跨国资源整合方案
  • k8s:docker compose离线部署haborV2.13.1及采用外部的postgresql及redis数据库
  • uni-app动态获取屏幕边界到安全区域距离的完整教程
  • 在离线 Ubuntu 22.04机器上运行 ddkj_portainer-cn 镜像 其他相关操作也可以复刻 docker
  • Elasticsearch 学习笔记
  • 使用react编写一个简单的井字棋游戏
  • nodejs模块化
  • JS WebAPIs DOM节点概述
  • 前端_Javascript复习
  • C语言:第11天笔记
  • Python通关秘籍(四)数据结构——列表
  • 力扣 hot100 Day52
  • 网络基础DAY16-MSTP-VRRP
  • 2025 年最新 AI 技术:全景洞察与深度解析​
  • 02-netty基础-java四种IO模型
  • 深入解析 Spark:关键问题与答案汇总
  • 【Spring拦截器实战】路径拦截与访问控制系统设计
  • 期货配资软件开发注意事项?
  • Linux文件——文件系统Ext2(1)_理解硬件
  • Java (Spring AI) 实现MCP server实现数据库的智能问答
  • 2️⃣tuple(元组)速查表
  • 从“点状用例”到“质量生态”:现代软件测试的演进、困局与破局