首页
社区
课程
招聘
穿山甲小牛试刀之一+秒杀N层马甲之Nnewell的某KeyGenMe
发表于: 2004-5-18 03:17 10678

穿山甲小牛试刀之一+秒杀N层马甲之Nnewell的某KeyGenMe

2004-5-18 03:17
10678

穿山甲小牛试刀之一+秒杀N层马甲之Nnewell的某KeyGenMe
【目    标】: Nnewell的某KeyGenMe
【工    具】:Olydbg1.1B(diy版)、LORDPE、ImportREC1.6F
【任    务】:.透视N层马甲(暴破),简单脱N层壳.
【操作平台】:winxp sp1
【作    者】:loveboom[DFCG][FCG]
【相关链接】: 见附件
【简要说明】:很久没有写什么文章,都快老了,我自己也终于结束了几年的网吧调试生活,就此献给所有的朋友,也算是献给男羽终于一次爬上TOP1的小礼吧,失误之处还请各位老大多多指教。我用Nnewell老大的东西出来骗一下MM,不知道老大有什么意见..如老大说不要这样的就我就删除本贴.
【详细过程】:
如果暴破来说,这个东西还是比较易的,牛老大说要写注册机,我水平没够所以就难一下,再说也没有空去分析算法。好了,搞定任务一.,透视N层马甲,再来强暴.
用od加载目标,去除调试标志.忽略全部异常。
加载并运行目标,这样第一次在这里异常:
042E137F    6285 0E0B0000   BOUND EAX,QWORD PTR SS:[EBP+B0E]    ;这里异常
042E1385    EB 02           JMP SHORT 042E1389
异常后,shift+f9继续,这样程序就运行了,现在看看od里怎么什么也没有了,不用紧张,“上有政策,下有对策”嘛,程序运行后,我们按一下F12怎么样,OD里有东西了吧,按f12断下后,按F9让程序继续,这样会有一个异常的提示,注意了,点那个消息框后按shift+f9而不要按f9,因为这样的话,等一下就死的好看的。好了,操作完毕后,ALT+M打开内存页,看看code段的baseimg是多少,原来是401000,,现在回到od的cpu窗口中,按ctrl+G跳到401000那里(当然这一步不是必需的),到主程序的段里后下断bp GetWindowTextA
在目标里输入你的大名和注册码,然后点register,这样会断在这里:
77D17FEC >  6A 0C           PUSH 0C        ;断在这里
77D17FEE    68 309DD677     PUSH USER32.77D69D30
断下后,alt+f9执行到返回:
0040D917    FF15 AA374100   CALL DWORD PTR DS:[4137AA]                ; 这里就是GetDlgItemTextA
0040D91D    A3 4C364100     MOV DWORD PTR DS:[41364C],EAX             ; 用户长度入地址,eax=用户名长度
0040D922    0BC0            OR EAX,EAX
0040D924    75 1F           JNZ SHORT KeygenMe.0040D945               ; 如果用户不为空就跳
0040D926    6A 00           PUSH 0                                    ; 注册名为空就跳到这里,也就是over的路
0040D928    FF75 0C         PUSH DWORD PTR SS:[EBP+C]
0040D92B    FF75 10         PUSH DWORD PTR SS:[EBP+10]
0040D92E    FF75 08         PUSH DWORD PTR SS:[EBP+8]
0040D931    FF15 B0374100   CALL DWORD PTR DS:[4137B0]                ; 这里就是MessageBoxA了
0040D937    5B              POP EBX
0040D938    891D 5C364100   MOV DWORD PTR DS:[41365C],EBX
0040D93E    5F              POP EDI
0040D93F    5E              POP ESI
0040D940    5B              POP EBX
0040D941    C9              LEAVE
0040D942    C2 1800         RETN 18
0040D945    68 00010000     PUSH 100                                  ; 这里准备获取注册码
0040D94A    8D85 D0FAFFFF   LEA EAX,DWORD PTR SS:[EBP-530]
0040D950    50              PUSH EAX
0040D951    68 E9030000     PUSH 3E9                                  ; push id
0040D956    FF75 08         PUSH DWORD PTR SS:[EBP+8]
0040D959    FF15 AA374100   CALL DWORD PTR DS:[4137AA]                ; GetDlgItemTextA
0040D95F    A3 50364100     MOV DWORD PTR DS:[413650],EAX             ; 这里eax=注册码长度
0040D964    0BC0            OR EAX,EAX
0040D966    75 1F           JNZ SHORT KeygenMe.0040D987               ; 如果注册码不为空就跳
0040D968    6A 00           PUSH 0                                    ; 为空就不好玩了,为空走这里
0040D96A    FF75 0C         PUSH DWORD PTR SS:[EBP+C]
0040D96D    FF75 14         PUSH DWORD PTR SS:[EBP+14]
0040D970    FF75 08         PUSH DWORD PTR SS:[EBP+8]
0040D973    FF15 B0374100   CALL DWORD PTR DS:[4137B0]                ; KeygenMe.0040E79E
0040D979    5B              POP EBX
0040D97A    891D 5C364100   MOV DWORD PTR DS:[41365C],EBX
0040D980    5F              POP EDI
0040D981    5E              POP ESI
0040D982    5B              POP EBX
0040D983    C9              LEAVE
0040D984    C2 1800         RETN 18
0040D987    8D85 D0FAFFFF   LEA EAX,DWORD PTR SS:[EBP-530]
0040D98D    50              PUSH EAX                                  ; 注册码入栈
0040D98E    E8 9D0D0000     CALL KeygenMe.0040E730                    ; 这个call把注册码转换为大写
0040D993    E8 2E0C0000     CALL KeygenMe.0040E5C6        ;这里要小心,在下一行下断,因为这个call里什么东西都不做,N多次异常在里面
0040D998    8D85 D0FAFFFF   LEA EAX,DWORD PTR SS:[EBP-530]
0040D99E    50               PUSH EAX
0040D99F    E8 9A0C0000      CALL KeygenMe.0040E63E                       ; 这个call判断注册码的合法性
0040D9A4    83F8 01          CMP EAX,1
0040D9A7    75 1F            JNZ SHORT KeygenMe.0040D9C8                  ; 如果合法就跳
0040D9A9    6A 00            PUSH 0
0040D9AB    FF75 0C          PUSH DWORD PTR SS:[EBP+C]                    ; 不合法就出错信息
0040D9AE    FF75 18          PUSH DWORD PTR SS:[EBP+18]
0040D9B1    FF75 08          PUSH DWORD PTR SS:[EBP+8]
0040D9B4    FF15 B0374100    CALL DWORD PTR DS:[4137B0]                   ; KeygenMe.0040E79E
0040D9BA    5B               POP EBX
0040D9BB    891D 5C364100    MOV DWORD PTR DS:[41365C],EBX
0040D9C1    5F               POP EDI
0040D9C2    5E               POP ESI
0040D9C3    5B               POP EBX
0040D9C4    C9               LEAVE
0040D9C5    C2 1800          RETN 18
0040D9C8    33DB             XOR EBX,EBX
0040D9CA    8B35 4C364100    MOV ESI,DWORD PTR DS:[41364C]                ; 注册名长度入esi
0040D9D0    8D95 D0FBFFFF    LEA EDX,DWORD PTR SS:[EBP-430]               ; 注册名入edx,我自己取的注册名是loveboom
0040D9D6    B8 01000000      MOV EAX,1                                    ; 初始赋值eax为1
0040D9DB    0FB64C10 FF      MOVZX ECX,BYTE PTR DS:[EAX+EDX-1]            ; 依次读取注册名的每一位,用于后面的运算
0040D9E0    8BF8             MOV EDI,EAX                                  ; a=1;for i=1 to 8
0040D9E2    83C7 03          ADD EDI,3                                    ; a=a+3 sasc=asc(mid(name,i,1))
0040D9E5    0FAFCF           IMUL ECX,EDI                                 ; b=sasc;b=b*a
0040D9E8    03D9             ADD EBX,ECX                                  ; c=c+b
0040D9EA    40               INC EAX
0040D9EB    3BC6             CMP EAX,ESI
0040D9ED    77 02            JA SHORT KeygenMe.0040D9F1                   ; 这里跳到下一步
0040D9EF  ^ EB EA            JMP SHORT KeygenMe.0040D9DB                  ; next
0040D9F1    8BC3             MOV EAX,EBX                                  ; 运算后的结果195e入eax
0040D9F3    99               CDQ
0040D9F4    69C0 C9430000    IMUL EAX,EAX,43C9                            ; 运算结果195e*43c9=6b784ce
0040D9FA    05 BBEF9505      ADD EAX,595EFBB                              ; eax=6b784ce+595efbb
0040D9FF    8BF0             MOV ESI,EAX                                  ; 计算后的结果放入esi中(0c4d7489)
0040DA01    56               PUSH ESI
0040DA02    68 00304100      PUSH KeygenMe.00413000                       ; ASCII "%1d"
0040DA07    8D45 D0          LEA EAX,DWORD PTR SS:[EBP-30]
0040DA0A    50               PUSH EAX
0040DA0B    E8 580D0000      CALL KeygenMe.0040E768                       ; JMP to USER32.wsprintfA
0040DA10    83C4 0C          ADD ESP,0C
0040DA13    8B0D 50364100    MOV ECX,DWORD PTR DS:[413650]
0040DA19    8D75 D0          LEA ESI,DWORD PTR SS:[EBP-30]
0040DA1C    8DBD D0FAFFFF    LEA EDI,DWORD PTR SS:[EBP-530]
0040DA22    FC               CLD
0040DA23    A6               CMPS BYTE PTR DS:[ESI],BYTE PTR ES:[EDI]
0040DA24    75 25            JNZ SHORT KeygenMe.0040DA4B                  ; 这里注册码和第一次的运算结果比较如果相算就完了
0040DA26    49               DEC ECX
0040DA27  ^ 75 FA            JNZ SHORT KeygenMe.0040DA23
0040DA29    C785 CCFAFFFF 01>MOV DWORD PTR SS:[EBP-534],1
0040DA33    6A 10            PUSH 10                                      ; 如果到了这里就不好玩了,下面就提示出错了
0040DA35    FF75 0C          PUSH DWORD PTR SS:[EBP+C]
0040DA38    FF75 1C          PUSH DWORD PTR SS:[EBP+1C]
0040DA3B    FF75 08          PUSH DWORD PTR SS:[EBP+8]
0040DA3E    FF15 B0374100    CALL DWORD PTR DS:[4137B0]                   ; KeygenMe.0040E79E
0040DA44    5B               POP EBX
0040DA45    891D 5C364100    MOV DWORD PTR DS:[41365C],EBX
0040DA4B    C785 CCFAFFFF 00>MOV DWORD PTR SS:[EBP-534],0                 ; 不相等就跳到这里
0040DA55    5F               POP EDI
0040DA56    5E               POP ESI
0040DA57    5B               POP EBX
0040DA58    C9               LEAVE
0040DA59    C2 1800          RETN 18
返回到这里:
0040DFD1    E8 F0050000      CALL KeygenMe.0040E5C6    ;这里大概看一下,因为好晚了,也因为我想睡所以没有跟下去找算法
0040DFD6    8D85 9CE3FFFF    LEA EAX,DWORD PTR SS:[EBP-1C64]
0040DFDC    50               PUSH EAX
0040DFDD    8D85 9CE7FFFF    LEA EAX,DWORD PTR SS:[EBP-1864]

上面的call进来看到一个异常,我就没跟了:
0040E5C6    C705 94314100 F5>MOV DWORD PTR DS:[413194],KeygenMe.0040E5F5
0040E5D0    892D 90314100    MOV DWORD PTR DS:[413190],EBP
0040E5D6    68 31104000      PUSH KeygenMe.00401031                               ; 异常回到的地方
0040E5DB    64:FF35 00000000 PUSH DWORD PTR FS:[0]                                ; 这里准备异常了
0040E5E2    8925 8C314100    MOV DWORD PTR DS:[41318C],ESP
0040E5E8    64:8925 00000000 MOV DWORD PTR FS:[0],ESP
0040E5EF    33F6             XOR ESI,ESI
0040E5F1    33C0             XOR EAX,EAX                                          ; 这里开始异常了
0040E5F3    8900             MOV DWORD PTR DS:[EAX],EAX
0040E5F5    64:8F05 00000000 POP DWORD PTR FS:[0]
懒了,没跟下去,直接在下面找到那个跳转.
0040E054    E8 5EFBFFFF      CALL KeygenMe.0040DBB7
0040E059    23C0             AND EAX,EAX        ;这里置eax为1就暴破了
0040E05B    74 1F            JE SHORT KeygenMe.0040E07C
0040E05D    8D85 9CEFFFFF    LEA EAX,DWORD PTR SS:[EBP-1064]
0040E063    50               PUSH EAX
0040E064    8D85 3AFAFFFF    LEA EAX,DWORD PTR SS:[EBP-5C6]
0040E06A    50               PUSH EAX
0040E06B    8D85 D6FAFFFF    LEA EAX,DWORD PTR SS:[EBP-52A]
0040E071    50               PUSH EAX
0040E072    FF75 08          PUSH DWORD PTR SS:[EBP+8]
0040E075    E8 C9F7FFFF      CALL KeygenMe.0040D843            ;这里进去就是MessageBoxA
0040E07A    EB 1D            JMP SHORT KeygenMe.0040E099
到此暴破完毕,在上面要注意一下的就是程序有了不少异常来干扰我们的视线,特别注意的是,遇到int3的时候一定要记得按shift+f9.下面进入第二个环节,脱掉它全部的马甲,让它“全?”.
如果只是脱的话,一下就脱掉了,我想讲讲大概的方法,最后快速脱壳
再次载入目标.设置不变:入口处看到不少90,但有一句明显的jmp eax,所以直接到jmp eax处
00438029    90               NOP
0043802A    90               NOP
0043802B    B8 01604300      MOV EAX,KeygenMe.00436001
00438030    FFE0             JMP EAX        ;载入后f4到这里
现在看到第一层壳了:
00436001    60               PUSHAD
00436002    E8 03000000      CALL KeygenMe.0043600A
00436007  - E9 EB045D45      JMP 45A064F7
peid说是PENinja -> +DZA Kracker/TNT!的壳,不过我看到之后倒觉得是aspack来的.
到第一层壳处按f7到这里
0043601C    81EB 00600300    SUB EBX,36000
00436022    83BD 22040000 00 CMP DWORD PTR SS:[EBP+422],0
00436029    899D 22040000    MOV DWORD PTR SS:[EBP+422],EBX                       ; KeygenMe.00400000
0043602F    0F85 65030000    JNZ KeygenMe.0043639A
现在直接在43639a处按f4运行到那里,到达后(这个过程可能慢一点)按几次f8到一个新地方了:
00435000    55               PUSH EBP
00435001    8BEC             MOV EBP,ESP
00435003    6A FF            PUSH -1
00435005    68 14135200      PUSH 521314
这里不是OEP来的,原因:你看看相关代码就明白了,再按一会f8到第二层壳了
这里第二层
00427000    60               PUSHAD
00427001    E8 00000000      CALL KeygenMe.00427006
00427006    5D               POP EBP
这里就不要一步一步跟了,因为跟过一两次之后就知道,这个壳有点像svkp来的,所以到这里后,我们按f9运行,这样就会出现svkp典型异常
042E137F    6285 0E0B0000    BOUND EAX,QWORD PTR SS:[EBP+B0E]    ;这里异常
042E1385    EB 02            JMP SHORT 042E1389
异常后,我们在code段按f2,下断后,shift+f9运行,这样就到这里:
0430B6B1    8A06             MOV AL,BYTE PTR DS:[ESI]        ;断在这里
0430B6B3    46               INC ESI
0430B6B4    47               INC EDI
0430B6B5    8843 0F          MOV BYTE PTR DS:[EBX+F],AL
0430B6B8    8A46 FF          MOV AL,BYTE PTR DS:[ESI-1]
0430B6BB    55               PUSH EBP
0430B6BC    E8 00000000      CALL 0430B6C1
0430B6C1    5D               POP EBP
0430B6C2    81ED 0D470000    SUB EBP,470D
0430B6C8    8A8D 50030000    MOV CL,BYTE PTR SS:[EBP+350]
0430B6CE    5D               POP EBP
0430B6CF    32C1             XOR AL,CL
0430B6D1    8847 FF          MOV BYTE PTR DS:[EDI-1],AL
0430B6D4    8BC5             MOV EAX,EBP
0430B6D6    4D               DEC EBP
0430B6D7    85C0             TEST EAX,EAX
0430B6D9  ^ 75 A4            JNZ SHORT 0430B67F
0430B6DB    33C0             XOR EAX,EAX
0430B6DD    5D               POP EBP
0430B6DE    5F               POP EDI
0430B6DF    5E               POP ESI
0430B6E0    5B               POP EBX
0430B6E1    C2 1400          RETN 14            ;直接F4到这里
现在再在code段F2下断并运行,这样很快就到了第三个壳的地方:
第三层(好像是早期的aspr来的):
00401000    68 01504100      PUSH KeygenMe.00415001        ;呵呵,直接停在这里
00401005    E8 01000000      CALL KeygenMe.0040100B
0040100A    C3               RETN
看到早期的aspr的就好办了,取消内存异常,第十六次异常后停在这里:
0040E5F3    8900             MOV DWORD PTR DS:[EAX],EAX
0040E5F5    64:8F05 00000000 POP DWORD PTR FS:[0]
0040E5FC    83C4 04          ADD ESP,4
0040E5FF    C705 94314100 33>MOV DWORD PTR DS:[413194],KeygenMe.0040E633
0040E609    892D 90314100    MOV DWORD PTR DS:[413190],EBP
0040E60F    68 31104000      PUSH KeygenMe.00401031
0040E614    64:FF35 00000000 PUSH DWORD PTR FS:[0]
0040E61B    8925 8C314100    MOV DWORD PTR DS:[41318C],ESP
0040E621    64:8925 00000000 MOV DWORD PTR FS:[0],ESP
0040E628    33DB             XOR EBX,EBX
0040E62A    33D2             XOR EDX,EDX
0040E62C    B8 02000000      MOV EAX,2
0040E631    F7F3             DIV EBX
0040E633    64:8F05 00000000 POP DWORD PTR FS:[0]
0040E63A    83C4 04          ADD ESP,4
0040E63D    C3               RETN            ;直接在这里下f2,然后shift+f9就会运行到这里的.
停在retn处后,再按一次f8就到了程序的OEP:
0040E707    6A 00             PUSH 0            ;OEP
0040E709    68 EBDB4000       PUSH KeygenMe.0040DBEB
0040E70E    6A 00             PUSH 0
到此oep就找到了,用impr用level1找一下就剩2个无效的api,用aspr1.22的插件或手工都轻松搞定。
知道怎么回事之后,我现在要快速脱它,
载入目标,按f9运行程序,异常后再在code段下f2??>shift+f9然后,f4到retn 14处à在code段下f2àf9运行这样到了aspr层,后面的按aspr的方法就可以一下搞定,我自己是写一下脚本:
var cbase
var csize
var count

gmi eip,CODEBASE
mov cbase,$RESULT
gmi eip,CODESIZE
mov csize,$RESULT
mov count,10

start:
   run

lbl1:
  bprm cbase,csize
  esto

lbl2:
  bpmc
  findop eip,#C21400#
  go $RESULT

lbl3:
  bprm cbase,csize
  run

lbl4:
  bpmc
  cmt eip,"取消内存异常项,然后按resume继续!"
  pause

lbl5:
  eoe lbl6
  run

lbl6:
  cmp count,0
  je lbl7
  sub count,1
  esto
  jmp lbl6

lbl7:
  findop eip,#C3#
  bp $RESULT
  eob lbl8
  eoe lbl8
  esto

lbl8:
  bc $RESULT
  sto
  cmt eip,"Hehe!"
  ret
到此就算基本解决问题了。

 
【总    结】: 
好想睡了,各位看官自己看看有什么问题,明天再说吧. 

Thanks: 

Fly 辉仔yock、jingulong、tDasm、David、ahao、ufo(brother)、alan(sister)、所有曾经关心支持或帮助过我的朋友!谢谢您们! 

                    by  loveboom[DFCG][FCG]                            
                     Email:bmd2chen@tom.com


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 10
支持
分享
最新回复 (17)
雪    币: 556
活跃值: (2303)
能力值: ( LV9,RANK:2130 )
在线值:
发帖
回帖
粉丝
2
2004-5-18 03:21
0
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
观赏一下

看着象是幻影呢,据说是Delphi写的
2004-5-18 08:38
0
雪    币: 898
活跃值: (4039)
能力值: ( LV9,RANK:3410 )
在线值:
发帖
回帖
粉丝
4
试试脱壳后的程序能否跨平台运行
2004-5-18 12:12
0
雪    币: 392
活跃值: (909)
能力值: ( LV9,RANK:690 )
在线值:
发帖
回帖
粉丝
5
强!学习!
2004-5-18 13:16
0
雪    币: 556
活跃值: (2303)
能力值: ( LV9,RANK:2130 )
在线值:
发帖
回帖
粉丝
6
呵呵,在win98下是不能用的,在2K/xp下没有问题,条件所限,没有办法修复这个问题
2004-5-18 13:50
0
雪    币: 124
活跃值: (107)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
7
不脱直接跟也能跟出点头脑;)
小心避开kgme里的N多异常也能跟个七八不离九,异常CALL是N某老大使的小坏而已:D
2004-5-18 15:03
0
雪    币: 270
活跃值: (176)
能力值: ( LV12,RANK:370 )
在线值:
发帖
回帖
粉丝
8
rsa的,还有很多的常规变换,keygen不好做啊,太费时间了
2004-5-18 16:23
0
雪    币: 898
活跃值: (4039)
能力值: ( LV9,RANK:3410 )
在线值:
发帖
回帖
粉丝
9
最初由 loveboom 发布
呵呵,在win98下是不能用的,在2K/xp下没有问题,条件所限,没有办法修复这个问题


应该可以吧,据sinker说  ;)
2004-5-18 17:48
0
雪    币: 270
活跃值: (176)
能力值: ( LV12,RANK:370 )
在线值:
发帖
回帖
粉丝
10
在xp下dump,在98下修复输入表,98/xp都可以运行
2004-5-18 21:48
0
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
最初由 ikki 发布
在xp下dump,在98下修复输入表,98/xp都可以运行



值得借鉴
2004-5-18 22:31
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
再说一遍:p
这个keygenme的壳是我加的。(-___-|||丢人了)
当初N给我源程序的时候,
考虑到不想做成unpackme所以加了几层纸老虎。(还请fly先玩了一下体验版-___-bbb)
记得很快就被cjsman(好像是这个ID)脱了。
脱壳爆破都很容易,
有兴趣的话就试试去除程序中的反跟踪。也很简单。
算法我是白痴,见笑了:p
2004-5-19 21:09
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
突然发现yesky写了分析,呵呵,牛阿
~:p
2004-5-19 21:09
0
雪    币:
能力值: (RANK: )
在线值:
发帖
回帖
粉丝
14
hihi, 不错,能否提供那个keygenme 呢 ? :)
2004-5-21 05:27
0
雪    币: 214
活跃值: (70)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
2004-5-22 10:29
0
雪    币: 221
活跃值: (100)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
强``顶
2004-5-22 11:46
0
雪    币: 0
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
17
厉害啊

先顶再学习 一下
2005-1-7 16:54
0
雪    币: 898
活跃值: (4039)
能力值: ( LV9,RANK:3410 )
在线值:
发帖
回帖
粉丝
18
如果没有什么问题的话,不要用“顶”字把老帖子再翻出来
2005-1-7 17:12
0
游客
登录 | 注册 方可回帖
返回
//