题目地址题目包含两个部分,首先解决右边的Serial进入后随便输入(这里我在正确结果后面加了一个空格,懒得重新截图了hhhhhh),然后查看报错信息为这样用x32dbg打开程序,通过字符串定位到Tri Again!!字符串,定位到这里的代码可以看到正确信息的前面调用了一个函数,在函数前面分别是输入的内容和另一个字符串,应一个字符串应该就是正确的注册码,下面紧接着调用判断函数决定结果跳转到正确还是错误。在程序中输入,得到正确弹窗。接着分析另一个部分。首先看其代码结构,在弹窗提示对错附近的结构是这样的可见其会经过两步判断,都通过才会提示正确。先观察第一步判断,执行了一个函数之后和4进行比较。一般来说,注册码的第一步比较很可能是长度比较。但是这里也只是猜测,先进入406930函数查看代码,发现代码比较简单,其中有这样一句repne scasb基本可以确定这个函数的作用是获取字符串长度。所以这里的判断应该是输入的用户名长度应大于4。但是第二部判断之前的得不到什么有用的信息,但是可以在跳转之前找到输入的注册码和正确的注册码。这里可以看到正确的注册码是CW-4108-CRACKED,我输入的注册码是987654.在上面,有两个固定字符串分别就是注册码的前半部分和后半部分,所以这里基本可以确定注册码的格式了,可变部分就只有中间的数字,前后都是固定的。且这里出现注册码固定字符串,注册码肯定是在其前后运算的。这段程序调用了大量的函数,但是根据函数的参数和执行结果可以大体看出其函数的作用。首先看到41AA58函数调用了两次,都有两个参数,且执行过只有其中一个空参数都变成了输入的数据,所以可以确定41AA58函数的作用是获取输入的字符串,类似于qt的lineedit.text()函数。这里调用了两次403708函数,且都有两个参数,一个是字符串,一个是空参数,执行过后空参数的值就变成了字符串,所以这里可以确定403708函数的作用是字符串复制然后在下面看到了406718函数,这个函数有var_18和431750两个参数,其中执行过后,var_18的值就变成了注册码中间部分。所以猜测这个函数可能是核心算法部分,但也不确定,因为其引入了应一个参数431750,这个参数在上面又参与了运算。所以这里返回上面分析431750.可以看到这里的ax是输入字符串的第一个字符,431750的初始值是一个固定的29h,然后先把输入字符串的第一个字符的16进制和29h相乘,再加上自身,就得到了下面用到的那个431750.这里我以为下面的那个函数才是核心算法,但是那个函数调用关系很复杂,也没分析出整个过程是什么。最后发现下面那个函数只是把上面算出的结果变成十进制字符串输出了,相当于用python表示为str(int(431750,16)),所以其实核心算法只是上面的几行代码。这样就可以编写注册机。注册机核心代码'CW-'+str(ord(name[0])*0x29*2)+'-CRACKED'注册机运行结果点击下载本题目注册机
repne scasb
'CW-'+str(ord(name[0])*0x29*2)+'-CRACKED'
题目地址首先查壳,这个程序没有壳。直接放进x64dbg中分析(因为在idapro中静态分析会有问题)。首先输入两个测试数据,查看弹窗字符串在x64dbg中查询字符串程序函数结构比较简单,字符串大对数为有用信息。直接定位到报错字符串的位置,发现在关键跳转上方有一个字符串比较函数则真正的注册码肯定在字符串比较函数之前就已经计算出来,所以在其下断点。可以看到到这里已经得到了真正的注册码,所以注册码计算过程肯定在上方代码中。然后在不断的下断点判断输出之后,大体上判断出了几个主要函数的作用。其中call dword ptr ds:[eax+A0]和call dword ptr ds:[eax+A0]这两个函数分别把输入的名字部分给了ebp-18、ebp-1C(实际上就是放入了堆栈)。下面就是核心算法部分,首先获取了输入字符串的长度,然后和17CFB相乘,结果存进edi中,再通过call dword ptr ds:[<&rtcAnsiValueBstr>]函数把输入字符串的第一个字符给ax,并将其复制给dx后与上面运算的结果相加,最终得到一个16进制数。然后通过调用call dword ptr ds:[<&__vbaStrI4>]函数把16进制数字变成十进制字符串,作为最后注册码的可变部分。最后把计算的字符串和'AKA-'拼接即可得到最后的注册码。注册机核心代码为
call dword ptr ds:[eax+A0]
call dword ptr ds:[<&rtcAnsiValueBstr>]
call dword ptr ds:[<&__vbaStrI4>]
注册机运行结果:
(都是pyqt5写的,只不过照上面那个美化了一下,我闲的hhhhhhhh)点击下载本题目注册机
题目地址这个程序前半部分的过程和上一个类似,算法也类似,先获取了输入的名称字符串后,将其长度乘以15B38后与第一个字符的16进制值相加,得到一个初步的字符串后面则有所不同。后面执行了三次把上面得到的字符串变为浮点数字的函数,所以后面主要主要分为三个过程,都是对浮点数的操作。第一次变为浮点数后,首先压栈,然后再把10(浮点数)压入栈中再除以2(浮点数),并和上面变为浮点数的字符串相加然后再变回字符串,存放在ax中其实整个过程就相当于对上面的初步字符串变为整数后+2然后再一次把字符串变成浮点数,乘以3再减2,变回字符串最后一次变成浮点数,然后把数值减去-15(实际上就是+15),然后变回字符串,就是最终需要输入的注册码。(下面截图里注释打错了hhhhh)实际上整个最然是浮点操作,但是运算都是与整数进行运算。注册机核心代码为
注册机运行结果点击下载本题目注册机
题目地址这个题目是一个Delphi程序,程序中没有确定按钮,只有两个输入框,根据程序提示,注册成功后,下面会出现一张图片。因为是Delphi程序,所以可以使用其他的程序辅助分析。(我把这个程序放进idapro和x64dbg中都识别不到,不知道为啥。)可以看到有几个重要的字符串然后使用DeDe进行分析,分析程序事件,可以看到程序整体的主要事件有单击、双击、chkcoode等等。刚开始猜测双击可能是主要操作,因为双击可能存在判断是否是正确的字符串。所以把这里的rva复制到x64dbg中下断点在输入完数据的时候程序停在断点,然后我对这里的代码进行了分析,如下图但是我发现这里的过程和最终生成的注册码好像并没有关系。我在跟踪程序的时候发现这时候在内存中已经存在了可能是注册码的字符串,不过不知道为什么不相同。所以这就说明这部分的过程和最终的注册码没有什么关系。接着往上面分析。把chkcode事件的rva复制到x64dbg中下断点。这里在输入数据的时候发现当输入注册码时只输入了一个字符就触发了断点,目前不知道原因。然后发现在403c3函数运行过之后生成了注册码,猜想这个函数可能是生成注册码的主要函数。进入函数分析,可以看到在这段代码中出现了所有的注册码组成部分,其中就包括之前找到的字符串。用bx控制循环次数和字符串的偏移地址,然后执行函数对字符串进行拼接,最后组成注册码。注册码一共由四个部分组成,其中包括发现的两个固定字符串和用户输入的名称,还有一个两位数字字符串。在上面分析,发现407b04函数执行过后出现了那个两位数字字符串,不过在上面分析的程序下面的代码可以知道这个函数的作用是把十六进制数字变成十进制字符串,这个函数本身应该不参与程序的注册码算法。所以在上面应该可以找到相关的数字。在这个函数上面,找到了一个存储着输入字符串长度的内存(但是我也不知道这个长度是咋来的,也没找到啥函数,可能在之前代码有获取字符串长度的函数hhhhhh),然后对这个长度+5,把计算后的结果作为参数输入到函数中,最终输出组成注册码的二位字符串。所以注册码的算法就已经明显了。下面是注册机核心算法
但是把注册机生成的注册码直接复制进程序还是不能注册成功。结合上面只输入了一个字符就触发了断点,应该是程序会获取键盘输入操作,只有在键盘输入注册码的时候才会出触发,并判断受否注册成功,把注册码直接复制进程序中是不能成功注册的。于是把注册码改成输入,注册成功。点击下载本题注册机
'AKA-'
+
str
(
int
len
(name)
*
0x17cfb
ord
(name[
0
])))
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)