我来我网
https://5come5.cn
 
您尚未 登录  注册 | 菠菜 | 软件站 | 音乐站 | 邮箱1 | 邮箱2 | 风格选择 | 更多 » 
 

本页主题: [玩玩]Crackme & Reverseme & Overflowme 显示签名 | 打印 | 加为IE收藏 | 收藏主题 | 上一主题 | 下一主题

yinx



性别: 帅哥 状态: 该用户目前不在线
等级: 人见人爱
家族: 丢丢
发贴: 2333
威望: 0
浮云: 1260
在线等级:
注册时间: 2006-09-15
最后登陆: 2009-05-11

5come5帮你背单词 [ playground /'pleigraund/ n. 运动场,游戏场 ]


[玩玩]Crackme & Reverseme & Overflowme

【文章标题】: bxm的第6个CrackMe[屏蔽]分析
【文章作者】: netwind
【作者QQ号】: 群:8601428
【下载地址】: http://bbs.pediy.com/attachment.php?s=&attachmentid=4612
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
od载入,查找-》所有参考文本串-》双击“good job!"
可以看到如下代码:
004016F0   . 83EC 60     sub   esp, 60
004016F3   . 53         push   ebx
004016F4   . 55         push   ebp
004016F5   . BB 01000000   mov   ebx, 1
004016FA   . 57         push   edi
004016FB   . 8BE9       mov   ebp, ecx
004016FD   . 53         push   ebx
004016FE   . E8 B5780100   call   00418FB8
00401703   . 8D4424 0C   lea   eax, [esp+C]
00401707   . 6A 14       push   14             ; /Arg3 = 00000014
00401709   . 50         push   eax             ; |Arg2
0040170A   . 68 E9030000   push   3E9             ; |Arg1 = 000003E9
0040170F   . 8BCD       mov   ecx, ebp         ; |
00401711   . E8 1F820100   call   00419935         ; \crackme_.00419935
00401716   . 83F8 03     cmp   eax, 3           ; 用户名长度需大于3
00401719   . 0F8C A7000000 jl     004017C6
0040171F   . 8D4C24 48   lea   ecx, [esp+48]
00401723   . 6A 21       push   21             ; /Arg3 = 00000021
00401725   . 51         push   ecx             ; |Arg2
00401726   . 68 EA030000   push   3EA             ; |Arg1 = 000003EA
0040172B   . 8BCD       mov   ecx, ebp         ; |
0040172D   . E8 03820100   call   00419935         ; \crackme_.00419935
00401732   . 8D7C24 0C   lea   edi, [esp+C]       ; 将用户名字符串地址给edi
00401736   . 83C9 FF     or     ecx, FFFFFFFF
00401739   . 33C0       xor   eax, eax
0040173B   . 33D2       xor   edx, edx
0040173D   . F2:AE       repne   scas byte ptr es:[edi>
0040173F   . F7D1       not   ecx
00401741   . 49         dec   ecx
00401742     74 25       je     short 00401769     ; 用户名串长度为0则跳(感觉多余代码,前面已经判断要大于3了)
00401744   . 56         push   esi             ; 保存esi
00401745   . BE 14000000   mov   esi, 14
0040174A   > 0FBE4414 10   movsx   eax, byte ptr [esp+edx+10>; 从头开始取用户名字符asc码
0040174F   . 0FAFC6     imul   eax, esi         ; 将取得的asc码乘以esi
00401752   . 03D8       add   ebx, eax
00401754   . 42         inc   edx
00401755   . 8D7C24 10   lea   edi, [esp+10]
00401759   . 83C9 FF     or     ecx, FFFFFFFF
0040175C   . 33C0       xor   eax, eax
0040175E   . 4E         dec   esi             ; esi-1
0040175F   . F2:AE       repne   scas byte ptr es:[edi>; 从头开始扫描edi指的字符串,同时ecx-1。
00401761   . F7D1       not   ecx
00401763   . 49         dec   ecx
00401764   . 3BD1       cmp   edx, ecx         ; ecx 实际上是edi指的字符串的长度。
00401766   .^ 72 E2       jb     short 0040174A     ; 因此这里循环次数为用户名的长度
00401768   . 5E         pop   esi
00401769     8B15 C0D04200 mov   edx, [42D0C0]       ; 这里获取通过GetStartupInfo(&si)运算得到的随机数
0040176F   . 8D4C24 24   lea   ecx, [esp+24]
00401773   . 6A 0A       push   0A
00401775   . 03D3       add   edx, ebx         ; ebx为上面的那个循环计算得到的数
00401777   . 51         push   ecx
00401778   . 52         push   edx
00401779   . E8 687F0000   call   004096E6         ; 将edx对应的十进制数转为字符串
0040177E   . 8D7C24 30   lea   edi, [esp+30]       ; 取得字符串地址
00401782   . 83C9 FF     or     ecx, FFFFFFFF
00401785   . 33C0       xor   eax, eax
00401787   . 83C4 0C     add   esp, 0C
0040178A   . 33D2       xor   edx, edx
0040178C   . F2:AE       repne   scas byte ptr es:[edi>
0040178E   . F7D1       not   ecx
00401790   . 49         dec   ecx             ; 执行后ecx 实际上是edi指的字符串的长度。
00401791     74 23       je     short 004017B6     ; 若串长度为0提示正确信息(感觉这里的代码是多余的,它不可能为0)
00401793   > 0FBE4414 24   movsx   eax, byte ptr [esp+ed>; 取所得串第一个字符
00401798   . 0FBE4C14 48   movsx   ecx, byte ptr [esp+ed>; 取输入的注册码第一个字符
0040179D   . 03C2       add   eax, edx         ; 将串第一个字符asc码加其序号(从0开始)
0040179F   . 3BC1       cmp   eax, ecx         ; 再与注册码第一个字符比较
004017A1     75 23       jnz   short 004017C6     ; 不相等,则错
004017A3   . 8D7C24 24   lea   edi, [esp+24]
004017A7   . 83C9 FF     or     ecx, FFFFFFFF
004017AA   . 33C0       xor   eax, eax
004017AC   . 42         inc   edx
004017AD   . F2:AE       repne   scas byte ptr es:[edi>
004017AF   . F7D1       not   ecx
004017B1   . 49         dec   ecx
004017B2   . 3BD1       cmp   edx, ecx
004017B4   .^ 72 DD       jb     short 00401793     ; 再对第二个字符比较,循环次数为所得串的长度
004017B6   > 6A 00       push   0               ; 两串匹配则提示正确消息
004017B8   . 6A 00       push   0
004017BA   . 68 34B14200   push   0042B134         ; ASCII "Good job!"
004017BF   . 8BCD       mov   ecx, ebp
004017C1   . E8 96700100   call   0041885C
004017C6   > 5F         pop   edi
004017C7   . 5D         pop   ebp
004017C8   . 5B         pop   ebx
004017C9   . 83C4 60     add   esp, 60
004017CC   . C3         retn

下面看看42D0C0里的随机数是怎么得到的:
重新用od载入,载od左下角内存窗口右键-转到-表达式 填42D0C0 然后转到这个地址;现在这个地址是四个0
将这四个0选中,右键-断点-内存写入。
然后运行程序断在:0040141E   . 8915 C0D04200 mov   [42D0C0], edx       ; |
其附近有如下代码:
00401405   . 51         push   ecx             ; /pStartupinfo
00401406   . FF15 78224200 call   [<&KERNEL32.GetStartu>; \GetStartupInfoA
0040140C   . 8B5424 30   mov   edx, [esp+30]       ; startupinfo结构第9个参数
00401410   . 8B4424 24   mov   eax, [esp+24]       ; 第6个参数
00401414   . 8B5C24 20   mov   ebx, [esp+20]       ; 第5个参数
00401418   . 03D0       add   edx, eax
0040141A   . 03D3       add   edx, ebx         ; 将三个参数相加就得到随机数
0040141C   . 6A 00       push   0               ; /Revert = FALSE
0040141E   . 8915 C0D04200 mov   [42D0C0], edx       ; |


大致算法如下:
1、将用户名每一位乘以esi(esi=esi-1初始值esi=0x14)所得的和相加,再加1,得到一个数。
2、将此数加上随机数,得到另一个数。
3、将得到数的十进制每一位加上它对应的序号(比如123加序号后为135)得到的数的十进制,作为一个字符串就是注册码。
根据bxm提示,随机数是在用od载入时才产生,那么第二步则可省略,就剩下第一步和第三步。
算法c程序表示如下:
#include <stdio.h>
#include <string.h>
void main()
{
  char name[]="netwind";
  char temp[20];
  long c=1,esi=0x14;
  int i,l;
  for(i=0;i<strlen(name);i++,esi--)
    c=c+name*esi;
  i=0;
    while(c)               //将数字十进制转字符串。
  { temp[i++]=c%10+'0';     //这里得的是逆序的。
    c/=10;
  }
  temp=0;
  l=strlen(temp);
    for(i=0;i<strlen(temp);i++,l--) //每一位加上其正序时的序号。
  printf("%c",temp[l-1]+=i);     //将逆序串从最后一为开始输出,就是注册码。
  printf("\n");
  }
过程与汇编代码一样,只是汇编代码中间有一步把逆序串转正序,这里节省了这一步。
感想:
这个crackme很特别,很容易让人感觉写不出注册机.
程序应该加了异常处理吧,
od载入时,则会读取本进程STARTUPINFO 结构.
lpStartupInfo,参数结构
typedef struct _STARTUPINFO { // si
  DWORD   cb; //结构长度
  LPTSTR lpReserved; //保留
  LPTSTR lpDesktop; //保留
  LPTSTR lpTitle; //如果为控制台进程则为显示的标题
  DWORD   dwX; //窗口位置...........
  DWORD   dwY; //窗口位置...........
  DWORD   dwXSize; //窗口大小
  DWORD   dwYSize; //窗口大小
  DWORD   dwXCountChars; //控制台窗口字符号宽度 .........
  DWORD   dwYCountChars; //控制台窗口字符号高度
  DWORD   dwFillAttribute; //控制台窗口填充模式
  DWORD   dwFlags; //创建标记
  WORD   wShowWindow; //窗口显示标记如同ShowWindow中的标记
  WORD   cbReserved2; //
  LPBYTE lpReserved2; //
  HANDLE hStdInput; //标准输入句柄
  HANDLE hStdOutput; //标准输出句柄
  HANDLE hStdError; //标准错误句柄
} STARTUPINFO, *LPSTARTUPINFO;
将读出的结构的第9,6,5个参数的值相加得到随机数,然后加上前面运算得到的数字,得到一个数,把该数十进制每一位加该位的序号(从0开始)得到一个数,把该数十进制表示的数转为字符串形式便是注册码.
如果单用od跟踪,而没考虑到异常的话,很难想象可以做出一个注册机.
因为:
netwind (2007-03-02 22:42:07)
问下:
GetStartupInfo(&si);获得当前进程的STARTUPINFO 结构
如何获得指定某个进程的STARTUPINFO 结构
大牛(2007-03-02 22:43:16)
那些信息都存放在那个进程的 PEB 里。
大牛 (2007-03-02 22:43:30)
PEB 不公开的。去找些资料来看
netwind (2007-03-02 22:44:06)
恩,谢谢了
没有其他的简单方法了吗?
大牛 (2007-03-02 22:44:17)

大牛 (2007-03-02 22:44:27)
或者说,我不知道

crackme的算法分析较容易,爆破点也很容易找到,对异常处理那块较感兴趣.
希望有人能贴出更好的破文,谢谢!
这个crackme应该公布 源代码 希望如此,bxm大牛辛苦了,多谢!
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!

                                    2007年03月03日 12:51:45
本帖最近评分记录:
  • 浮云:10 (by 独飞の孤心) | 理由: 貌似现在熟悉汇编的越来越少了
  • 顶端 Posted: 2007-03-05 11:20 | [楼 主]
    zgb91



    性别: 帅哥 状态: 该用户目前不在线
    头衔: 曱甴
    等级: 人见人爱
    家族: 东北一家人
    发贴: 4789
    威望: 0
    浮云: 1117
    在线等级:
    注册时间: 2006-03-06
    最后登陆: 2012-05-18

    5come5帮你背单词 [ rosy /'rəuzi/ a. 玫瑰色的,美好的,光明的 ]


    有些深奥
    顶端 Posted: 2007-03-05 11:28 | [1 楼]
    我来我网·5come5 Forum » 程序员之家

    Total 0.009960(s) query 6, Time now is:11-23 19:04, Gzip enabled
    Powered by PHPWind v5.3, Localized by 5come5 Tech Team, 黔ICP备16009856号