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

[crackme]018-crackme_0006

在 0x004011D0 下个断(程序能运行起来,输入信息后check后断下)

请添加图片描述

这段程序在获取磁盘的序列号,然后进行了逻辑左移,循环左移的操作。但是可以发现左移的结果并没有被使用,通过静态分析可以更明显的观察出来:

  • IDA静态分析结果:

在这里插入图片描述

直接使用的是磁盘序列号。

  • 在求斜边长使用的浮点寄存器

在这里插入图片描述

push ebp	保存旧栈帧
mov ebp, esp	建立新栈帧
add esp, -0x4	分配 4 字节局部变量([local.1])
push ebx/esi/edi	保存寄存器
wait	等待 FPU 就绪
finit	初始化 FPU
fild [arg.1]	将第一个整数参数(a)加载到 FPU 栈顶
fld st	复制栈顶(a)
fmulp st(1), st	计算 a²,结果存入 st(1),弹出 st
fild [arg.2]	将第二个整数参数(b)加载到 FPU 栈顶
fld st	复制栈顶(b)
fmulp st(1), st	计算 b²,结果存入 st(1),弹出 st
faddp st(1), st	计算 a² + b²,结果存入 st(0)
fsqrt	计算 √(a² + b²)
fistp [local.1]	将浮点结果四舍五入为整数,存入局部变量

注意:最后求的结果是四舍五入的

随后使用系统 API GetDlgItemTextA 获取输入的用户名,

  • 将用户名累乘,再和斜边,再进行循环左移或的操作,再进行与的操作,赋值给 v11
  • 对上面的结果对16取余,0到15的数字作为模板字符串的下标,取出字符,赋值给 v10,这个v10就保存计算出的序列号
  • 每次整除4,更新 v11,并将 v13 更新
  • 最后做是否相等的判断

在这里插入图片描述

值得注意的是这个将用户名累乘的操作也不是完全这样的,看汇编代码:

在这里插入图片描述

mul ecx 在累乘之后,高位存放在 edx,低位在eax,如果高位 edx 有值,会将edx 加到eax的低位上,所以输入的用户名累乘相加只要在4字节以内就没问题,如果溢出 4 字节就是另外的情况。

破解算法:

import ctypes
from ctypes import wintypesdef arithmetic_left_shift(x: int, n: int, width: int = 32) -> int:"""固定位宽算术左移(低位补 0,高位超出 width 的部分丢弃)width 可设为 8/16/32/64 …"""mask = (1 << width) - 1          # 例如 32 位: 0xFFFF_FFFFreturn (x << n) & maskdef rotate_left(x: int, n: int, width: int = 32) -> int:"""固定位宽循环左移"""n %= width                       # 允许 n >= widthmask = (1 << width) - 1x &= mask                        # 先截断到固定位宽return ((x << n) | (x >> (width - n))) & mask
# 定义常量
MAX_PATH = 260# 加载 kernel32.dll
kernel32 = ctypes.windll.kernel32# 定义函数原型
GetVolumeInformationA = kernel32.GetVolumeInformationA
GetVolumeInformationA.argtypes = [wintypes.LPCSTR,       # lpRootPathNamewintypes.LPSTR,        # lpVolumeNameBufferwintypes.DWORD,        # nVolumeNameSizewintypes.LPDWORD,      # lpVolumeSerialNumberwintypes.LPDWORD,      # lpMaximumComponentLengthwintypes.LPDWORD,      # lpFileSystemFlagswintypes.LPSTR,        # lpFileSystemNameBufferwintypes.DWORD         # nFileSystemNameSize
]
GetVolumeInformationA.restype = wintypes.BOOL# 准备缓冲区
volume_name = ctypes.create_string_buffer(MAX_PATH)
serial_number = wintypes.DWORD()
max_component_length = wintypes.DWORD()
file_system_flags = wintypes.DWORD()
file_system_name = ctypes.create_string_buffer(MAX_PATH)# 调用函数(例如获取 C: 盘信息)
root_path = b"C:\\"
success = GetVolumeInformationA(root_path,volume_name,MAX_PATH,ctypes.byref(serial_number),ctypes.byref(max_component_length),ctypes.byref(file_system_flags),file_system_name,MAX_PATH
)c_serial = serial_number.valueroot_path = b"D:\\"
success = GetVolumeInformationA(root_path,volume_name,MAX_PATH,ctypes.byref(serial_number),ctypes.byref(max_component_length),ctypes.byref(file_system_flags),file_system_name,MAX_PATH
)d_serial = serial_number.value
# 原始序列号 使用勾股定理
c = round((c_serial ** 2 + d_serial ** 2) ** 0.5)
# c = int((c_serial ** 2 + d_serial ** 2) ** 0.5 + 1)
#print(c)def hash_username(name: str) -> int:"""将用户名字符串按 ASCII 码做“累乘+高位回加”,结果始终保持在 32 位无符号整数范围内。"""value = 0for ch in name:byte = ord(ch)          # 当前字符 ASCIIvalue = value * 0x100 + byte      # 累乘:左移 8 位 + 追加新字节# 处理超 32 位部分while value > 0xFFFFFFFF:high = value >> 32          # 超出 32 位的高位low  = value & 0xFFFFFFFF   # 低 32 位value = high + low          # 高位加回低 32 位return value & 0xFFFFFFFF           # 确保返回 32 位无符号username = "easyaaaaaa"
# user_unmber = hash_username(username)
user_unmber = 1
for i in username:user_unmber_gw = 0user_unmber *= ord(i)user_unmber_gw = user_unmber >> 32user_unmber = user_unmber & 0xFFFFFFFFprint(hex(user_unmber),user_unmber_gw)user_unmber = user_unmber + user_unmber_gwbase = (c | rotate_left(user_unmber, 1)) & 0xFFFFFFFmb = '071362de9f8ab45c'
flag = ''
while  True:base2 = baseflag += mb[base % 16]base = base2 // 4base2 = baseif(base == 0):breakprint(flag)

62de9f8ab45c’
flag = ‘’
while True:
base2 = base
flag += mb[base % 16]
base = base2 // 4
base2 = base
if(base == 0):
break

print(flag)


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

相关文章:

  • 滨海专业做网站wordpress博客分页
  • 如何做衣服销售网站淄博网站制作制作
  • 东台建设局网站公司信息查询网
  • 建站套餐和定制网站的区别2013电子商务网站建设考试试卷
  • 中山币做网站公司网站的建设不包括什么
  • CSP 复赛入门组高频算法:典型例题、代码模板与实战题号
  • 做网站需要哪些准备工作心得体会简短的
  • 基础建设文本网站阿里云1M做网站
  • 江苏建设工程信息网站网站的设计页面
  • 网站建设工作基本流程做二手网站赚钱不
  • 嵌入式学习笔记5.定时器TIM
  • 博达高校网站群建设教程家在临深业主论坛家在深圳
  • 两学一做网站网站网站开发前端库
  • 模型轻量化三大核心技术之:蒸馏
  • 备案关闭网站建设影响淮南最新通告今天
  • 购物网站怎么建立门户类网站模板
  • 昭通微网站建设wordpress 只显示标题
  • 数据结构从入门到实战————队列
  • 微信二维码网站制作固原网络推广
  • 丢弃法-Dropout
  • 1.多线程基础概念
  • 队列queue
  • 网站平台规划最便宜的网站叫什么名字
  • 【Java】从入门到放弃-05:高级语法
  • 全国十大网站建设公司wordpress mp6
  • 责任链与规则树设计实战解析(自用)
  • 网站建设太金手指六六二九代理产品网
  • 栾城做网站云南信息发布平台
  • DrissionPage爬取汽车之家:(车名 + 颜色 + 车辆型号/续航里程)
  • 360做企业网站多少钱淘宝客网站怎么做的