“金山杯2007逆向分析挑战赛”第一阶段第一题分析

  • 时间:
  • 浏览:0
  • 来源:uu快3大小_uu快3网站_开奖历史

  从里面的代码逻辑中其他人还能看后很糙要的其他,要修改 nUserBits 的某一位(假设为 nWhichBit),没办法 须要满足以下条件,nUserBits 须要居于如下状况:

  0031219490849267008495623294423911312678

  3299167863423793371021417500742237107415

  

  http://www.pediy.com/kssd/

  User:   hoodlum19500  Serial:

  注册机截图,用 VC 写的另一一个多多对话框应用线程(写成 Console 应用线程更容易,但 Windows 应用线程对用户来说更熟悉):

  113125008166832091668636237633720213174500

  7405425284528981213658365842894658733257

  最后,随便给出另一一个多多注册机计算出的注册码作为开始(将会注册码太长,就说 插入了换行和缩进):

  CrackMe.exe 是另一一个多多简单的注册应用线程,见附件,请写另一一个多多注册机,要求:

  3247535700312114908492570084957232944209

  这里,附上原题目应用线程,我写的注册机的源码以及可执行文件的压缩包下载:

  【2】关于对话框的窗口过程,是非常简单的。但它在栈上为临时变量分配空间使用的都有常规的( sub esp, ....) 一句话,就说 调用了函数(loc_500540)来完成分配临时光英文英文间,你这俩函数都须要总结为等效于( sub esp, eax ),只须要把你这俩函数理解成分配栈上空间即可。(2014年5月4日 补充 --hoodlum19500)

  2. 注册机都须要使用 ASM,VC,BC,VB,Delphi等语言书写,其他谢绝使用;

  4242840289212146582658628926588332475377

  【1】关于 DecryptText 函数,用于加/解密字符串(对称),其等效 C 语言代码如下:

  2668167832991688634237733710216175007412

  5347006121849094924700049552320442991171

  有另一一个多多数组x,都须要把它理解为另一一个多多二进制数,每个数组元素表示另一一个多多bit。x = f (UserName) 。无需 切换 x[i] (i = 1, 2, 3, ..., n )的准许条件是:

  void CheckSerialNo(int nUserVal, char* pSerialNo);

  昨天我偶然浏览到这里,看后你这俩题目,于是看后下,题目早就将会是过去时了,但今天依然都须要看看,要花费 用了半天时间求解此题目(那我以为挺简单,但实际上还是少很糙难度的)。把附件下载下来都须要看后,CrackMe.exe 是另一一个多多仅有 1.85 KB 的 Windows 对话框应用线程。界面也非常简单,只有另一一个多多文本框用于获取用户名,注册码,和另一一个多多注册按钮,当点击注册按钮时,将会注册码正确,会弹出 MessageBox 显示 "OK!!",因此会显示 "Fail!" 。

  16683219166863523763374021317410740237500

  在代码段(.text) 的第另一一个多多函数就说 解密函数,其原型形如:void DecrptText(const BYTE* pSecret, char* pPlainTextBuffer);  你这俩加解密非常简单,就说 把另一一个多多数组用那我事先拟定好的 key 数组线性的异或了一下而已,就说 这都有本题重点,在此暂时省略不提(其 C 语言代码版本见本文结尾 [1] )。

  

  通过你这俩函数,其他人都须要很容易看后它是要怎样弹老出示着 “Fail!!" 的消息框的,该函数首先在栈放到 置成功和失败的文本密文,因此通过检测结果,把相应的密文地址传送到解密函数(这里称之为 DecryptText),解密函数把解密后的明文放到 栈上的缓冲区,因此以此调用 MessageBox,非常明显,这是模拟软件的常规保护法律法律依据,在实际软件中总要将关键和敏感信息进行隐藏,当然这也都有这道题目的重点,将会很容易就找到密文的位置,为紧靠 EBP 付近的另一一个多多字节数组。

  这里给出另一一个多多例子来说明,以校验的索引范围为从 1 到 4 ,假设 nUserBits 的初始状况为 { 0, 0, 0, 1 } (索引从 1 开始),则要怎样经过一系列上述规则允许的元素切换,把它变为 { 0, 0, 0, 0 },参考下表(整个过程我你会应该 起了汉诺塔,都须要很容易看出,整体解蕴藏 晒 了形式相同的规模更小的子大问题的解):

  740237207405426284528931213658

  现将此题目概述粘贴如下:

 

  为此其他人给出注册机的如下多个函数,即为题目要求的注册机,显然,注册码将会不限长度,都须要与非 数多个,但其他人当然选择生成简短的。

  就说 那因此你提示注册机算法,都须要用递归函数 ( 下面代码中的 SetBit 函数 ) 来求解。注册码是由一系列的 nWhichBit (要切换状况的位索引)组成,你这俩索引是根据注册码的当前位得到的。换句话说,求注册码要花费 找出那我另一一个多多有序序列,{ b1, b2, b3, ...,  } ,每一步都有合法切换,外理后 nUserBits 所有位都为 0。

  (2)将会 i > 1, 有 x [ i - 1 ] = 1;

  1. 注册机是KeyGen,都有内存注册机或文件Patch;

  ......

  很显然,将会其他人直接修改你这俩 exe,跳过其注册码检测将会修改里面的跳转逻辑,修改调用 DecryptText 的参数,修改栈上的密文数据等等,有 无数种法律法律依据都须要直接令你这俩应用线程显示 “OK!!” 消息框。因此,这显然都有你这俩题目的目的(将会这太简单了,也无需理解哪几种验证用的汇编代码)。根据题目要求,都须要看出出题者的要求是,因为 用线程是只有修改的,解题的人通过阅读和分析验证注册码的汇编代码,得出其验证思路,因此根据此写出注册机(KeyGen),实现给出任意的 UserName,得出 SerialNo = f (UserName) ,也就说 要求找出 f 关系,并用编程语言实现注册机。

  在汇编代码右侧,我将会大致写了一定的注释,下面把你这俩校验注册码的函数翻译到 C 语言如下(为了使代码的文本紧凑,帕累托图使用了起始大括号不换行的代码风格),因此根据代码推断注册机算法。

  3. 注册机须要都须要运行在 Windows 系统上;

  首先是,当点击“注册"按钮,应用线程将会检测注册码与非 正确。在对话框的窗口过程[参考补充说明2]中,都须要找到一段重要代码,现在把它提取出来作为另一一个多多注册机要用到的重要函数,即根据用户名字符串得到另一一个多多整数形态值,汇编代码省略,这里把你这俩函数翻译为 C 语言如下:

  下面给出的是你这俩应用线程的关键汇编代码,也就说 CheckSerialNo 的删剪代码,此题目的本意正是要求玩转信用卡 你这俩函数的逻辑,并找出注册机算法。你这俩函数较长,但分开割裂不太好,就说 删剪粘贴如下(注:主体来自于 IDA 反汇编结果,为了更好的显示和更好的可读性,我分派和调整了反汇编结果的帕累托图细节,以及对帕累托图地址标号进行了重命名)(前面有一大段花里胡哨的稀奇古怪的指令,其他变量赋值操作也通过隔开小量的 PUSH / POP 来完成,最恶劣的是 DWORD 指针竟然地址不对齐,仿佛是人为故意设置的障碍):

  接下来,应用线程将会调用另一一个多多校验注册码的函数,在你这俩函数中同总要弹出 MessageBox,你这俩函数由十几个 功能组成,也是此题目须要要分析的重点,你这俩函数的原型都须要推测出为形如:

  3710742542428462892121865826585289265893

  http://files.cnblogs.com/hoodlum19500/CrackMe_1_1.zip

  那我注册机算法就算呼之欲出了,还有另一一个多多简单大问题是,其他人的目标是把  nUserBits 中的每一位都变为 0,没办法 应该先从哪一位入手呢,应该按照从左(低位)向右(高位)的顺序依次清零,还是从右(高位)向左(低位)?很难得出答案应该采用后者,将会在设置某一位为 0 时,其所有低位总要动态变化,而高位则不受影响都须要保持静态不动。就说 其他人应该先把高位清零,因此在逐一向低位方向推进。应用线程中显式的把最高位(索引为9)设置为 1,也暗示了你这俩求解顺序。

  (1)对任何 1 <= j <= i - 2,有 x [ j ] = 0; 因此

  第13篇 论坛活动 \ 金山杯5007逆向分析挑战赛 \ 第一阶段 \ 第一题 \ 题目 \ [第一阶段 第一题];

  用 IDA 反汇编你这俩极小的应用线程,都须要看后它的组成非常简单,下面给出其他主要的汇编代码,并帕累托图的翻译成 C 语言。

  题目来自于如下网址:

  把最右侧一列的索引值连在同去,就说 另一一个多多其他人须要设计的位置序列 { 121312141213121 },依次对哪几种位置进行开关切换(把 nUserBits 每另一一个多多元素想象成另一一个多多开关)后,就都须要让 nUserBits 数组变为全为 0 的状况(注册码正确的条件)。将会不须要和用户形态值关联到同去一句话,那这你这俩序列就说 注册码。但因为 用线程中是通过注册码和用户形态值(nUserVal)混编后得到你这俩调整序列,就说 其他人只须要对你这俩调整序列做个逆运算,“剔除”其中的用户形态值成分,即可得到实际注册码。

  在高级语言版本中,我使用了其他语言法律法律依据,来外理在高级语言代码把汇编中的哪几种相对跳转直译为 goto,大体上将是等效的。从里面的代码中都须要看出检查注册码的重要标准,将会其他人把注册码看做输入,实际上在扫描注册码的过程中,就说 nUserBits 你这俩元素为二元的数组变化的过程,nUserBits 是根据用户填写的用户名计算得到的数组,就说 它的元素和用户名相关,是不选择的,注册码扫描开始后,你这俩数组须要所有元素都为 0。因此,要花费 以注册码为驱动。

  也就说 说,当其他人要切换某一位的状况时,从你这俩位向低位方向(左侧)看去,应该是 【0】* N + 【1】 的组合(紧邻的低位为 1, 其余均为 0)。最低位(索引 1 )都须要随时修改,将会左边将会没办法 位了,当然就没必要向左看后。这里把上述逻辑用数学语言表述如下:

  这时都须要执行对 x [ i ] 的切换动作(对该位取反)。注册码正确的标准是,根据注册码执行一系列动作(注册码的每一位对应于切换 x 的哪一位)后,x 的所有元素为0。在 x 初始化时,将会将 x 的最高位固定设置为1,以外理 x 的初始值恰好都有 0 的特殊状况。