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

逆向练习(六)Andrénalin.3/4

最近沉迷挖洞,然后七月份干活去了。回来接着学学底层的东西,赶紧把Andrénalin这个东西的后面两个给弄掉,然后玩新程序去。

Andrénalin.3

老样子,看程序,看pe

爆破

还是和之前的一样,搜关键词,找跳转,爆破

算法

从爆破断点向上找起始点,下断,运行后输入123开始调试

一直到出现函数,然后来看这些函数

上面这一长条和2简直一模一样,就是在做字符判断和字符提取,然后下面有一个循环从00402026回到00401F68,由此可以知道,这和2一样是一个循环加码的过程。

接下来就是在这个范围内逐步调试查找关键变化的点,下断,然后记录下变化值。

上面整个过程可以概述为:

  • 00401F70-00401FAA:I4、ordinal、varval,提取字符

  • add A:1-> 31+A=3B-> ;

  • 00401FB4-00402026 free、fornext,循环

我们输入的是123,所以输出结果就应该是31+A 32+A 33+A=3B3C3D -> ;<=

OK,验证一下,最终我们输出的结果是在00402050进行序列码比较,相同就成功,不同就失败,所以上面的00402036就是序列码本身,因为这个是从程序中获得的字符串,push的两个中必有一个是我们的上面计算的结果。

所以,我们最终的目的是要求这个:kXy^rO|*yXo*m\\kMuOn*+进行逆向计算的结果。这里有一个问题,这串符号多了一个\,因为\本质上是一种转义字符,当单独使用时会导致编译器跳过它将其和k一起识别为k,所以需要在前方再添加一个\使得编译器可以将\认识为\而不是直接跳过。因此要去内存部分看它实际的ASCII编码是多少。这个从我们反向计算的结果也能看出来:aNoThEr oNe cRRaCkEd !如果懂英语的话就会发现这里多了个R。这些特殊英语的写法可能有形状相似数字字母变化、元音重写延长读音,但很少出现辅音重写造成断读的情况,除非是个日本人写的拗音。

无论什么语言中遇到了斜杠和0这些极有可能带有特殊意义的字符都要多一个心眼,防止转义或跳过。

最后,解码程序:

def final_key(serial):key = []for i in serial:k = ord(i) - 10k1 = chr(k)key.append(k1)return keyuser_input = input('serial: ')
output = final_key(user_input)
print('key: ', ''.join(output))

Andrénalin.4

先说结论,这个程序用OD分析比较麻烦,它的判断是和按键一起进行的,需要不断的取消断点、输入、下断,关键点只要一断就会导致程序完全点不动,遇到这种操作麻烦的程序时,最好使用某些特殊反编译工具让我们能直接查看源码,就和前面的delphi一样。不要头铁硬分析。

爆破

爆破方法非常简单,拉进OD,看字符,随便点一个进去,修改跳转就搞定。

算法

由于它没有壳子,这里直接使用VB decompiler

由上面图示分析可知,程序总共有13个按钮和4个计时器,其中数字1234...分别对应command1234...,*->10、0->11、#->12、删除->13

查看一下这几个按钮,基本是一样的,区别只在于输入的字符。结合OD分析时内存窗口不断运行可以猜测,所有的程序运行、判断、算法全都在计时器里。

经过查看下面的计时器,可以发现不同计时器的结构也是一样的。第一部分代码调用的是command13,所以这个是删除字符后的计时判断,我们不需要这个。因此着重分析第二部分。

这里涉及几个VB函数

  • Ctsr 字符串
  • Clng 长整型
  • Mid(string, start[, length]) 从某字符串的起始位置start返回长度length的字符串
  • $ 以ASCII码处理
  • Asc 转换为ASCII格式
  • Hex 转换为16进制字符
  • Left 从字符串左侧返回指定长度的字符
  • Val 返回数字直到非数字字符停止

然后我们来分析一下这个循环计算:

var_44 = Form.Text1.Text //输入字符
For var_24 = 1 To Len(var_44) Step 1 //循环读取字符If var_F8 Then //如果当前不为0var_34 = var_34 & Hex$((Asc(Mid$(CStr(var_44), CLng(var_24), 1)) + Val(CStr(Left(var_44, 1))))) //计算Next var_24 //1++GoTo loc_0040492F //返回循环
End If //结束

计算部分:从输入的字符中当前位置取1位(也就是本位),转换为ASCII值,将这个值和输入字符左边第一位数字相加,最后转换成16进制格式并循环拼接。

然后这个循环拼接出来的字符串要规定的字符串相等:

If (var_34 = "0817E747D7AFF7C7F82836D74RR7A7F7E7B7C7D826D81KE7B7C") ThenSet var_54 = Form1.Label3var_D0 = var_54var_54.Caption = "REGISTRIERT"
End If

所以从算法我们可知,这个var_34的字符串一定是个16进制字符串,所以只要它里面存在其它特殊符号和F以后的字母全都不符合。从OD里面把所有的字符串给复制出来,然后写个脚本来判断一下:结果就一个。

def is_hex(s):try:int(s, 16)  return Trueexcept ValueError:return Falsewith open('D:/Andrnalin.4/str.txt', 'r') as file:for line_num, line in enumerate(file, 1):line = line.strip()  if not line: continueif is_hex(line):print(f"Line {line_num}: '{line}'  是")else:print(f"不是")

然后我们就需要使用这个字符来进行逆向计算,注意一下,现在这个字符有51位,是单数,数量不对,所以应该去掉一个被填充的字符0,然后看第一位数字81=129,这就是Val(CStr(Left(var_44, 1))),然后循环用后面的数字减去这个值并转换为ascii字符,最后拼接起来:

hexlist = "0123456789ABCDEF"
enc = "0817E747D7A7D7C7F82836D74747A7F7E7B7C7D826D817E7B7C"# 用10进制计算
def hexstr_to_dec(s):a = hexlist.index(s[0])b = hexlist.index(s[1])return a * 16 + b# 提取密钥的第二、三位并转换
key_str = enc[1:3]
key_value = hexstr_to_dec(key_str)# 计算左边的数字
kb = "0123456789*#"
base_value = None
for x in range(1, 10):for y in range(0, 10):if y + x * 10 + ord(kb[x]) == key_value:base_value = x * 10 + ybreakif base_value is not None:breakprint(f"开头数字: {base_value}")# 逆向计算
dec = ""
for i in range(1, len(enc), 2):  # 从8开始,每2字符处理key_str = enc[i:i+2]key_value = hexstr_to_dec(key_str)p = chr(key_value - base_value)  # ASCII转换dec += pprint(f"serial: {dec}")

总结

看OD不能只盯着CPU窗口,内存和寄存器同样重要,有时候关键的变化就在这些地方,因为不是所有的工具都会在CPU窗口显示出字符。脑子里要随时记住各种编码转换的形式和结果,要对长度敏感。另外,OD、dbg、ida这些工具只是通用但并不是万能的,有时候针对性的反汇编工具可以帮大忙,毕竟好看方便的界面可以大大提升效率。不要迷信个人技术(真有技术干嘛不自己手搓电脑),善用工具本身就是技术能力的一部分。

http://www.dtcms.com/a/332398.html

相关文章:

  • Linux应用软件编程---多任务(进程2)(资源回收函数(wait、waitpid)、exec函数族、linux下的命令、const四种位置表示的含义)
  • 一周学会Matplotlib3 Python 数据可视化-绘制树形图
  • Laravel 中解决分表问题
  • ESP32-C3_SMARTCAR
  • 高并发场景下限流算法对比与实践指南
  • 【unity实战】Unity游戏开发:如何用ScriptableObject与序列化多态实现可复用的模块化效果系统?
  • ABP vNext+ WebRTC DataChannel 低延迟传感推送
  • 物联网(IoT)系统中,通信协议如何选择
  • C++——分布式
  • Al大模型-本地私有化部署大模型-大模型微调
  • 图像识别控制技术(Sikuli)深度解析:原理、应用与商业化前景
  • Zabbix【部署 01】Zabbix企业级分布式监控系统部署配置使用实例(在线安装及问题处理)程序安装+数据库初始+前端配置+服务启动+Web登录
  • 後端開發Python篇
  • StarRocks集群部署
  • 从 0 到 1 玩转Claude code(蓝耘UI界面版本):AI 编程助手的服务器部署与实战指南
  • Xget:为您的开发工作流解锁极致速度
  • 清除 pnpm 缓存,解决不同源安装依赖包失败的问题
  • “大模型”技术专栏 | 浅谈基于 Kubernetes 的 LLM 分布式推理框架架构:概览
  • 力扣 hot100 Day74
  • Floyd 判圈算法(龟兔赛跑算法)
  • LeetCode热题100--146.LRU缓存--中等
  • SSL和TLS协议的消息认证码(MAC)
  • Grafana 与 InfluxDB 可视化深度集成(一)
  • Grafana 与 InfluxDB 可视化深度集成(二)
  • LeetCode 刷题【42. 接雨水】
  • RecyclerView 性能优化:从原理到实践的深度优化方案
  • 新手向:Python函数定义与参数传递(位置参数、关键字参数、默认参数)
  • electron之win/mac通知免打扰
  • 什么是接口?PHP如何使用 SessionHandlerInterface 接口实现Session自定义会话数据存储
  • cloudflare缓存配置