linux的破解(i386)相对于其它unix下的破解自然要容易一些,因为
大家对于8086系列的结构以及汇编多少都有些了解。不过对于第一次做
linux下的破解,还是让人感到富有挑战而又令人兴奋的.
要动手破解,除了破解本身的乐趣外,动力多半还是来自被破解对象
--应用程序的诱惑,
我就是被mtv
player的功能给吸引了,又不满它每次
只放一小会就静音了,
于是乎我抄起了家伙---gdb
老实说,原来没怎么用过gdb,
经常是通过xwpe间接的用,于是当时
就抱了抱佛脚。
gdb主要是针对源程序的调试除错的,对汇编级的支持的并不好(最
不好的就是没有类似debug中的a命令,没法汇编),对于破解,gdb常用的命令
有:
info
target
显示当前目标的一些信息,包括一些分段的信息
info
functions
可以列出所有定义的函数名和数据类型,相当有用,
有的程序检查系列号和License会在一个名称明确的函数里
info
functions
REGEXP
可以列出匹配正规表达表的函数
info
registers
列出所有寄存器(除浮点)的值,
这个跟踪时自然常用到
info
all-registers
列出所有寄存器(包括浮点)的值
info
registers
REGNAME...
列出所指出的所有寄存器的值
info
break
列出所有的断点和观察点
break
*ADDR
在地址ADDR处设置断点
break
FUNCTION
在函数FUNCTION处设置断点
clear
FUNCTION
删除在函数FUNCTION入口处的断点
delete
BNUMS
删除BNUMS指定序点的断点或观察点
backtrace(bt)
显示堆栈中的信息,也很有用,可以在调试中搞清楚当前的调用关系
x/NFU
ADDR
这个也是常用,N:重复数,
F:显示格式,s字串,i机器码,
缺省是x十六进制数,
U:单元大小,b字节,h半字(两字节),w字(四字节,缺省)
ADDR为地址,如
x/3uh
0x54320
set
$REGNAME=VALUE
设定寄存器REGNAME的值为VALUE,还可以是
set
$sp
+=
4这样的让sp加4
set
{TYPE}ADDR=VALUE
将地址ADDR的TYPE类型的值设为VALUE,例
如:set
{int}0x83040=4
nexti(ni)
执行一行机器码,如果是函数调用,则执行到函数返回
stepi(si)
执行一行机器码,如果是函数调用,则进入函数
disassemble
FUNCTION
反汇编FUNCTION函数
disassemble
ADDR1
ADDR2
反汇编ADDR1和ADDR2间的机器码
disassemble
ADDR
反汇编ADDR所在的函数
run(r)
开始执行程序到第一个断点或程序结束
continue(c)
继续程序的执行到下一断点或程序结束
continue(c)
IGNORE-COUNT
继续程序的执行并忽略掉IGNORE-COUNT个断
点,在第IGNORE-COUNT+1个断点停下或程序结束
正式开工了:
运行mtv,首先出现的是对话框,要求"Enter
Key"或是"Try
it!",选"Enter
Key",
填写了资料后,提示注册信息不正确,
显然这其中做了Key的合法性检查,于时选中这
里做突破口:
$
gdb
mtv
GNU
gdb
4.17
Copyright
1998
Free
Software
Foundation,
Inc.
GDB
is
free
software,
covered
by
the
GNU
General
Public
License,
and
you
are
welcome
to
change
it
and/or
distribute
copies
of
it
under
certain
conditions.
Type
"show
copying"
to
see
the
conditions.
There
is
absolutely
no
warranty
for
GDB.
Type
"show
warranty"
for
details.
This
GDB
was
configured
as
"i386-redhat-linux"...
(no
debugging
symbols
found)...
(gdb)
通常第一个断点可以设在_start函数处,也可以先运行,中途送中断信号让它停下来
(一般可以
kill
-18
pid,
18是SIGCONT)做这些之前还可以先看看程序中的函数
(包括使用到的共享库的函数),特别对于Xwindows应用程序,这点十分重要:
(gdb)info
functions
All
defined
functions:
Non-debugging
symbols:
08049cf0
_init
08049d34
fl_set_object_lstyle
08049d44
fl_set_object_gravity
08049d54
fl_add_browser
08049d64
waitpid
08049d74
printf
08049d84
__strtod_internal
08049d94
fl_set_slider_bounds
08049da4
fl_set_form_atclose
08049db4
ungetc
08049dc4
sigemptyset
08049dd4
strerror
08049de4
fl_end_group
08049df4
hsearch
08049e04
fl_show_question
08049e14
fl_add_roundbutton
08049e24
XCloseDisplay
08049e34
getenv
08049e44
fl_add_text
08049e54
fl_set_input_filter
08049fd4
fl_hide_object
08049fe4
lseek
08049ff4
abort
0804a004
fl_end_form
0804a014
fl_remove_io_callback
0804a024
pipe
0804a034
fl_set_object_color
0804a044
fl_set_object_posthandler
0804a054
calloc
0804a064
fl_bgn_form
0804a074
rindex
0804a084
write
0804a094
fprintf
0804a0a4
kill
0804a0b4
ctime
0804a0c4
fl_get_menu
0804a0d4
strcat
0804a0e4
fl_bgn_group
0804a0f4
fl_set_atclose
0804a104
chdir
0804a114
fl_invalidate_fselector_cache
0804a124
XCreateBitmapFromData
0804a134
fseek
0804a144
mktime
0804a154
fl_show_fselector
0804a164
__libc_init_first
0804a174
fl_do_forms
0804a184
signal
0804a194
read
0804a1a4
fl_get_fselector_form
0804a1b4
fl_set_form_icon
0804a1c4
fl_set_slider_value
0804a1d4
fl_set_timer
0804a1e4
XParseGeometry
0804a1f4
fl_show_object
0804a204
strncpy
0804a214
unlink
0804a224
strcasecmp
0804a234
fl_set_form_geometry
0804a244
fl_get_menu_item_mode
0804a254
fl_add_input
0804a264
fl_get_input
<------------------好显眼啊..icon_razz.gif
0804a274
_IO_getc
0804a284
fork
0804a294
sscanf
0804a2a4
fl_hide_oneliner
0804a2b4
sigaction
0804a2c4
fl_set_focus_object
0804a2d4
strdup
0804a2e4
gettimeofday
0804a2f4
fl_add_slider
0804a304
fopen
0804a314
memset
0804a324
ftell
0804a334
fl_set_menu
0804a344
fl_get_pattern
0804a354
fl_set_oneliner_color
0804a364
fclose
0804a374
time
0804a384
fl_add_valslider
0804a394
fl_set_object_lcol
0804a3a4
fl_set_object_label
0804a3b4
fl_set_counter_step
0804a3c4
fl_library_version
0804a3d4
fl_show_oneliner
0804a3e4
sprintf
0804a3f4
fl_set_border_width
0804a404
atexit
0804a414
fl_mapcolor
0804a424
fl_initialize
0804a434
fl_set_menu_item_mode
0804a444
fl_set_input_maxchars
0804a454
fl_set_browser_fontstyle
0804a464
fl_get_button
0804a474
fl_hide_form
0804a484
fl_set_counter_bounds
0804a494
fl_set_object_lsize
0804a4a4
fl_add_checkbutton
0804a4b4
fl_set_object_callback
0804a4c4
fl_add_menu
0804a4d4
fl_use_fselector
0804a4e4
__errno_location
0804a4f4
exit
0804a504
fl_get_filename
0804a514
__fxstat
0804a524
fl_add_timer
0804a534
fl_set_object_resize
0804a544
open
0804a554
fl_set_object_lalign
0804a564
fl_get_directory
0804a574
fl_show_choice
0804a584
fl_set_slider_size
0804a594
fputs
0804a5a4
execvp
0804a5b4
fl_get_counter_value
0804a5c4
close
0804a5d4
XOpenDisplay
0804a5e4
free
0804a604
fl_set_button
0804a614
_start
08052e7c
whereError
080583c0
_fini
mtv用到了xforms库,fl_xxxx都是这个库里的函数,
其中的哪个fl_get_input是
这么的显眼,
虽然没有做过xforms的编程,但是可以大胆设想这个东东会不会类似
windows中的GetDlgItemText(GetDlgItemTextA),
所以不妨试试
(gdb)break
fl_get_input
Breakpoint
1
at
0x804a264
(gdb)r
Starting
program:
/usr/X11R6/bin/mtv
(no
debugging
symbols
found)...Breakpoint
1
at
0x400429e3
出现填写注册信息对话框,
我做如下输入
Name:
I007
Order
number:
B123456789
(有editmask,只能一字母后跟字数)
Key:
87654321
(也有editmask)
按OK键后,
mtv果然在断点处停住,
猜得不错.
如果没猜中,
只好慢慢跟踪罗
(no
debugging
symbols
found)...(no
debugging
symbols
found)...
Breakpoint
1,
0x400429e3
in
fl_get_input
()
(gdb)
继续让它运行...
(gdb)
c
Continuing.
Breakpoint
1,
0x400429e3
in
fl_get_input
()
(gdb)
c
Continuing.
Breakpoint
1,
0x400429e3
in
fl_get_input
()
(gdb)
c
Continuing.
它连续调用了fl_get_input三次,
正好对应三个输入项,
然后注册信息错误的
对话框就出现了,
看来是没错了,
现在关键是要看最后一次调用fl_get_input
后的代码,当然看它每次调用fl_get_input后到取回的字串放到了什么地地方
也很重要.我重新输入一次注册信息,然后让它在三次调用fl_get_input后的
情况:
(gdb)
c
Continuing.
Breakpoint
1,
0x400429e3
in
fl_get_input
()
(gdb)
bt
#0
0x400429e3
in
fl_get_input
()
#1
0x804ea96
in
_start
()
#2
0x4003b5f5
in
fl_do_forms
()
#3
0x8050a59
in
_start
()
这是堆栈中的情况,
看来调用完fl_get_input后应返回到_start中的
地址0x804ea96处,
我们来看看这段代码
(gdb)
disass
0x804ea96
0x804ffff
Dump
of
assembler
code
from
0x804ea96
to
0x804ffff:
0x804ea96
<_start+17538>:
movl
%eax,0x806e584
0x804ea9b
<_start+17543>:
pushl
%eax
0x804ea9c
<_start+17544>:
movl
0x806e9d4,%eax
0x804eaa1
<_start+17549>:
movl
0x18(%eax),%ecx
0x804eaa4
<_start+17552>:
pushl
%ecx
0x804eaa5
<_start+17553>:
call
0x804a264
<fl_get_input>
<-第二次
0x804eaaa
<_start+17558>:
movl
%eax,%ebp
0x804eaac
<_start+17560>:
movl
0x806e9d4,%eax
0x804eab1
<_start+17565>:
pushl
%eax
0x804eab2
<_start+17566>:
movl
0x10(%eax),%edx
0x804eab5
<_start+17569>:
pushl
%edx
0x804eab6
<_start+17570>:
call
0x804a264
<fl_get_input>
<-第三次
0x804eabb
<_start+17575>:
movl
%eax,%ebx
0x804eabd
<_start+17577>:
movl
%ebp,%edx
0x804eabf
<_start+17579>:
movl
%ebp,%eax
0x804eac1
<_start+17581>:
addl
$0x18,%esp
0x804eac4
<_start+17584>:
andl
$0x3,%edx
0x804eac7
<_start+17587>:
je
0x804eadf
<_start+17611>
0x804eac9
<_start+17589>:
jp
0x804eada
<_start+17606>
0x804eacb
<_start+17591>:
cmpl
$0x2,%edx
0x804eace
<_start+17594>:
je
0x804ead5
<_start+17601>
0x804ead0
<_start+17596>:
cmpb
%dh,(%eax)
....
(gdb)
break
*0x804ea96
Breakpoint
2
at
0x804ea96
(gdb)
c
Continuing.
Breakpoint
2,
0x804ea96
in
_start
()
(gdb)
info
reg
eax
eax
0x8083dd0
134757840
(gdb)
x/s
0x8083dd0
0x8083dd0:
"I007"
看来
"I007"
放在
0x8083dd0,
这个地址还存放到了
0x806e584
(gdb)
ni
....
到第三次调用fl_get_input完回到0x804eabb时,我们知道了输入的信息存在在哪
名称
值
地址
Name
"I007"
0x8083dd0
Order
number
"B123456789"
0x809e850
Key
"87654321"
0x809e880
以下的一些反汇编代码中会有一些注释,
主要说明是执行到这样地方时一些情况,
也不一步步的ni了..
(gdb)
disass
0x804eabb
0x804ffff
Dump
of
assembler
code
from
0x804eabb
to
0x804ffff:
0x804eabb
<_start+17575>:
movl
%eax,%ebx
(eax:
0x809e880->""87654321")
0x804eabd
<_start+17577>:
movl
%ebp,%edx
(ebp:
0x809e850->"B123456789"
)
0x804eabf
<_start+17579>:
movl
%ebp,%eax
0x804eac1
<_start+17581>:
addl
$0x18,%esp
0x804eac4
<_start+17584>:
andl
$0x3,%edx
0x804eac7
<_start+17587>:
je
0x804eadf
<_start+17611>
--
0x804eac9
<_start+17589>:
jp
0x804eada
<_start+17606>
|
0x804eacb
<_start+17591>:
cmpl
$0x2,%edx
|
0x804eace
<_start+17594>:
je
0x804ead5
<_start+17601>
|
0x804ead0
<_start+17596>:
cmpb
%dh,(%eax)
|
0x804ead2
<_start+17598>:
je
0x804eb05
<_start+17649>
|
0x804ead4
<_start+17600>:
incl
%eax
|
0x804ead5
<_start+17601>:
cmpb
%dh,(%eax)
|
0x804ead7
<_start+17603>:
je
0x804eb05
<_start+17649>
|
0x804ead9
<_start+17605>:
incl
%eax
|
0x804eada
<_start+17606>:
cmpb
%dh,(%eax)
|
0x804eadc
<_start+17608>:
je
0x804eb05
<_start+17649>
|
0x804eade
<_start+17610>:
incl
%eax
|
|
以下检查Order
number长度是否为10:
|
0x804eadf
<_start+17611>:
movl
(%eax),%edx
<-
0x804eae1
<_start+17613>:
testb
%dh,%dl
0x804eae3
<_start+17615>:
jne
0x804eaed
<_start+17625>
0x804eae5
<_start+17617>:
testb
%dl,%dl
0x804eae7
<_start+17619>:
je
0x804eb05
<_start+17649>
0x804eae9
<_start+17621>:
testb
%dh,%dh
0x804eaeb
<_start+17623>:
je
0x804eb04
<_start+17648>
0x804eaed
<_start+17625>:
testl
$0xff0000,%edx
0x804eaf3
<_start+17631>:
je
0x804eb03
<_start+17647>
0x804eaf5
<_start+17633>:
addl
$0x4,%eax
0x804eaf8
<_start+17636>:
testl
$0xff000000,%edx
0x804eafe
<_start+17642>:
jne
0x804eadf
<_start+17611>
0x804eb00
<_start+17644>:
subl
$0x3,%eax
0x804eb03
<_start+17647>:
incl
%eax
0x804eb04
<_start+17648>:
incl
%eax
0x804eb05
<_start+17649>:
subl
%ebp,%eax
0x804eb07
<_start+17651>:
cmpl
$0xa,%eax
0x804eb0a
<_start+17654>:
jne
0x804ebe6
<_start+17874>
以下检查Key的长度是否为8:
0x804eb10
<_start+17660>:
movl
%ebx,%edx
0x804eb12
<_start+17662>:
movl
%ebx,%eax
0x804eb14
<_start+17664>:
andl
$0x3,%edx
0x804eb17
<_start+17667>:
je
0x804eb2f
<_start+17691>
-
0x804eb19
<_start+17669>:
jp
0x804eb2a
<_start+17686>
|
0x804eb1b
<_start+17671>:
cmpl
$0x2,%edx
|
0x804eb1e
<_start+17674>:
je
0x804eb25
<_start+17681>
|
0x804eb20
<_start+17676>:
cmpb
%dh,(%eax)
|
0x804eb22
<_start+17678>:
je
0x804eb55
<_start+17729>
|
0x804eb24
<_start+17680>:
incl
%eax
|
0x804eb25
<_start+17681>:
cmpb
%dh,(%eax)
|
0x804eb27
<_start+17683>:
je
0x804eb55
<_start+17729>
|
0x804eb29
<_start+17685>:
incl
%eax
|
0x804eb2a
<_start+17686>:
cmpb
%dh,(%eax)
|
0x804eb2c
<_start+17688>:
je
0x804eb55
<_start+17729>
|
0x804eb2e
<_start+17690>:
incl
%eax
|
0x804eb2f
<_start+17691>:
movl
(%eax),%edx
<-
0x804eb31
<_start+17693>:
testb
%dh,%dl
0x804eb33
<_start+17695>:
jne
0x804eb3d
<_start+17705>
0x804eb35
<_start+17697>:
testb
%dl,%dl
0x804eb37
<_start+17699>:
je
0x804eb55
<_start+17729>
0x804eb39
<_start+17701>:
testb
%dh,%dh
0x804eb3b
<_start+17703>:
je
0x804eb54
<_start+17728>
0x804eb3d
<_start+17705>:
testl
$0xff0000,%edx
0x804eb43
<_start+17711>:
je
0x804eb53
<_start+17727>
0x804eb45
<_start+17713>:
addl
$0x4,%eax
0x804eb48
<_start+17716>:
testl
$0xff000000,%edx
0x804eb4e
<_start+17722>:
jne
0x804eb2f
<_start+17691>
0x804eb50
<_start+17724>:
subl
$0x3,%eax
0x804eb53
<_start+17727>:
incl
%eax
0x804eb53
<_start+17727>:
incl
%eax
0x804eb54
<_start+17728>:
incl
%eax
0x804eb55
<_start+17729>:
subl
%ebx,%eax
0x804eb57
<_start+17731>:
cmpl
$0x8,%eax
0x804eb5a
<_start+17734>:
jne
0x804ebe6
<_start+17874>
检查Order
nuber是否为"I000000000":
0x804eb60
<_start+17740>:
movl
%ebp,%esi
(ebp:0x809e850->"B123456789
")
0x804eb62
<_start+17742>:
movl
$0x805b9a6,%edi
(0x805b9a6->"I000000000
")0x804eb67
<_start+17747>:
movl
$0xb,%ecx
0x804eb6c
<_start+17752>:
cld
0x804eb6d
<_start+17753>:
xorl
%eax,%eax
0x804eb6f
<_start+17755>:
repz
cmpsb
%ds:(%esi),%es:(%edi)
0x804eb71
<_start+17757>:
je
0x804eb77
<_start+17763>
0x804eb73
<_start+17759>:
sbbl
%eax,%eax
0x804eb75
<_start+17761>:
orb
$0x1,%al
0x804eb77
<_start+17763>:
testl
%eax,%eax
0x804eb79
<_start+17765>:
jne
0x804ebd1
<_start+17853>
-
...
|
...
|
0x804ebd1
<_start+17853>:
pushl
%eax
(eax:0xffffffff)
<-
0x804ebd2
<_start+17854>:
pushl
$0x806e9ac
(0x806e9ac:0x00000000)
0x804ebd7
<_start+17859>:
pushl
%ebx
(ebx:0x809e880->"87654321")
0x804ebd8
<_start+17860>:
pushl
%ebp
(ebp:0x809e850->"B123456789")
0x804ebd9
<_start+17861>:
call
0x8055978
<whereError+11004>
^____这里很可疑
0x804ebde
<_start+17866>:
movl
%eax,0x806e574
0x804ebe3
<_start+17871>:
addl
$0x10,%esp
0x804ebe6
<_start+17874>:
movl
0x806e574,%edx
0x804ebec
<_start+17880>:
testl
%edx,%edx
0x804ebee
<_start+17882>:
je
0x804ec62
<_start+17998>
...
0x804ec62
<_start+17998>:
movl
0x806e9d4,%eax
0x804ec67
<_start+18003>:
pushl
%eax
0x804ec68
<_start+18004>:
movl
(%eax),%edx
0x804ec6a
<_start+18006>:
pushl
%edx
0x804ec6b
<_start+18007>:
call
0x804a474
<fl_hide_form>
0x804ec70
<_start+18012>:
pushl
$0x1
0x804ec72
<_start+18014>:
pushl
$0x8059017
0x804ec77
<_start+18019>:
pushl
$0x805ba6c
(0x805ba6c->"Check
registration
information
and
try
again")
0x804ec7c
<_start+18024>:
pushl
$0x805ba99
(0x805ba99->"Incorrect
registration
information!")
0x804ec81
<_start+18029>:
call
0x804a790
<_start+380>
(警告框出现)
.......
到注册信息不对的警告框出现,只有一个函数调用比较可疑:
0x804ebd9
call
0x8055978
<whereError+11004>
而且调用结束后还有一个比较跳转的动作,
那么我们就跟踪进去看看
(gdb)
break
*0x8055978
Breakpoint
3
at
0x8055978
(gdb)
c
Continuing.
Breakpoint
3,
0x8055978
in
whereError
()
(gdb)
disass
0x8055978
0x805ffff
Dump
of
assembler
code
from
0x8055978
to
0x805ffff:
0x8055978
<whereError+11004>:
subl
$0x8,%esp
0x805597b
<whereError+11007>:
pushl
%ebp
0x805597c
<whereError+11008>:
pushl
%edi
0x805597d
<whereError+11009>:
pushl
%esi
0x805597e
<whereError+11010>:
pushl
%ebx
0x805597f
<whereError+11011>:
movl
0x1c(%esp,1),%ebp
(0x809e850)
0x8055983
<whereError+11015>:
movl
0x20(%esp,1),%esi
(0x809e880)
0x8055987
<whereError+11019>:
movl
0x24(%esp,1),%ebx
(0x806e9ac)
0x805598b
<whereError+11023>:
testb
$0x1,(%ebx)
0x805598e
<whereError+11026>:
je
0x80559c0
<whereError+11076>
-
.....
|
0x80559c0
<whereError+11076>:
pushl
%eax
<
0x80559c1
<whereError+11077>:
leal
0x18(%esp,1),%eax
0x80559c5
<whereError+11081>:
pushl
%eax
(eax:0xbffff70c)
0x80559c6
<whereError+11082>:
pushl
$0x8060cbb
(0x8060cbb->"
%x")
0x80559cb
<whereError+11087>:
pushl
%esi
(esi:0x809e880->"87654321")
0x80559cc
<whereError+11088>:
call
0x804a294
<sscanf>
0x80559d1
<whereError+11093>:
movl
%eax,%edi(此时0xbffff70c->0x87654321)
0x80559d3
<whereError+11095>:
addl
$0x10,%esp
0x80559d6
<whereError+11098>:
cmpl
$0x1,%edi
0x80559d9
<whereError+11101>:
je
0x8055a01
<whereError+11141>
-
.....
|
0x8055a01
<whereError+11141>:
testb
$0x1,(%ebx)
<-
0x8055a04
<whereError+11144>:
je
0x8055a3a
<whereError+11198>
-
.....
|
0x8055a3a
<whereError+11198>:
pushl
%ebp(ebp:0x809e850->"B123456789")
<-
0x8055a3b
<whereError+11199>:
pushl
$0x0
0x8055a3d
<whereError+11201>:
call
0x80561d9
<whereError+13149>
^______会不会去算正确的Key?
0x8055a42
<whereError+11206>:
movl
%eax,%esi
(eax:0x8eee5816)
0x8055a44
<whereError+11208>:
addl
$0x8,%esp
0x8055a47
<whereError+11211>:
testb
$0x1,(%ebx)
0x8055a4a
<whereError+11214>:
je
0x8055a7a
<whereError+11262>
-
.....
|
0x8055a7a
<whereError+11262>:
movl
0x14(%esp,1),%edx
<-
0x8055a7e
<whereError+11266>:
cmpl
%esi,%edx
(edx:0x87654321,这是我输入的Key
它在与0x8eee5816比较???)
0x8055a80
<whereError+11268>:
jne
0x8055ab9
<whereError+11325>
-
....
|
0x8055ab9
<whereError+11325>:
testb
$0x1,(%ebx)
<-
0x8055abc
<whereError+11328>:
je
0x8055aec
<whereError+11376>
-
....
|
0x8055aec
<whereError+11376>:
xorl
%eax,%eax
<-
0x8055aee
<whereError+11378>:
popl
%ebx
0x8055aef
<whereError+11379>:
popl
%esi
0x8055af0
<whereError+11380>:
popl
%edi
0x8055af1
<whereError+11381>:
popl
%ebp
0x8055af2
<whereError+11382>:
addl
$0x8,%esp
0x8055af5
<whereError+11385>:
ret
0x8055a7e处的比较说明,
很有可能函数0x80561d9就是在依照我输入的Order
number算正确的Key,而后比较结果,所以不妨先用
8EEE5816
做Key试一试.
结果,8EEE5816果然就是正确的Key,
mtv检查正确后在$HOME目录中产生一个
.mtvrc文件,
以后每次使用都会自动读出.mtvrc中的注册信息并检查..
还可以据0x80561d9函数写出注册机:
(gdb)
disass
0x80561d9
0x805624e
Dump
of
assembler
code
from
0x80561d9
to
0x805624e:
0x80561d9
<whereError+13149>:
pushl
%edi
0x80561da
<whereError+13150>:
pushl
%esi
0x80561db
<whereError+13151>:
pushl
%ebx
0x80561dc
<whereError+13152>:
movl
0x14(%esp,1),%edi
0x80561e0
<whereError+13156>:
movl
0x10(%esp,1),%edx
0x80561e4
<whereError+13160>:
xorl
%ebx,%ebx
0x80561e6
<whereError+13162>:
movl
%edi,%eax
0x80561e8
<whereError+13164>:
movl
%edi,%esi
0x80561ea
<whereError+13166>:
andl
$0x3,%eax
0x80561ed
<whereError+13169>:
je
0x8056205
<whereError+13193>
0x80561ef
<whereError+13171>:
jp
0x8056200
<whereError+13188>
0x80561f1
<whereError+13173>:
cmpl
$0x2,%eax
0x80561f4
<whereError+13176>:
je
0x80561fb
<whereError+13183>
0x80561f6
<whereError+13178>:
cmpb
%ah,(%esi)
0x80561f8
<whereError+13180>:
je
0x8056229
<whereError+13229>
0x80561fa
<whereError+13182>:
incl
%esi
0x80561fb
<whereError+13183>:
cmpb
%ah,(%esi)
0x80561fd
<whereError+13185>:
je
0x8056229
<whereError+13229>
0x80561ff
<whereError+13187>:
incl
%esi
0x8056200
<whereError+13188>:
cmpb
%ah,(%esi)
0x8056202
<whereError+13190>:
je
0x8056229
<whereError+13229>
0x8056204
<whereError+13192>:
incl
%esi
0x8056205
<whereError+13193>:
movl
(%esi),%eax
0x8056207
<whereError+13195>:
testb
%ah,%al
0x8056209
<whereError+13197>:
jne
0x8056213
<whereError+13207>
0x805620b
<whereError+13199>:
testb
%al,%al
0x805620d
<whereError+13201>:
je
0x8056229
<whereError+13229>
0x805620f
<whereError+13203>:
testb
%ah,%ah
0x8056211
<whereError+13205>:
je
0x8056228
<whereError+13228>
0x8056213
<whereError+13207>:
testl
$0xff0000,%eax
0x8056218
<whereError+13212>:
je
0x8056227
<whereError+13227>
0x805621a
<whereError+13214>:
addl
$0x4,%esi
0x805621d
<whereError+13217>:
testl
$0xff000000,%eax
0x8056222
<whereError+13222>:
jne
0x8056205
<whereError+13193>
0x8056224
<whereError+13224>:
subl
$0x3,%esi
0x8056227
<whereError+13227>:
incl
%esi
0x8056228
<whereError+13228>:
incl
%esi
0x8056229
<whereError+13229>:
subl
%edi,%esi
0x805622b
<whereError+13231>:
cmpl
%esi,%ebx
0x805622d
<whereError+13233>:
jnl
0x8056248
<whereError+13260>
0x805622f
<whereError+13235>:
movb
(%ebx,%edi,1),%al
0x8056232
<whereError+13238>:
incl
%ebx
0x8056233
<whereError+13239>:
andl
$0xff,%eax
0x8056238
<whereError+13244>:
pushl
%eax
0x8056239
<whereError+13245>:
pushl
%edx
0x805623a
<whereError+13246>:
call
0x8055b58
<whereError+11484>
0x805623f
<whereError+13251>:
movl
%eax,%edx
0x8056241
<whereError+13253>:
addl
$0x8,%esp
0x8056244
<whereError+13256>:
cmpl
%esi,%ebx
0x8056246
<whereError+13258>:
jl
0x805622f
<whereError+13235>
0x8056248
<whereError+13260>:
popl
%ebx
0x8056249
<whereError+13261>:
movl
%edx,%eax
0x805624b
<whereError+13263>:
popl
%esi
0x805624c
<whereError+13264>:
popl
%edi
0x805624d
<whereError+13265>:
ret
0x8055b58处的函数太长了,
bbs不让我发..icon_sad.gif
砍掉了
由这个程序的破解可以看出,
linux下的破解并不困难,
只是gdb有点不太方便
有时会有点小毛病(比如ni有时也会跟到函数中),
不过用多了就习惯了.