本篇内容介绍了“怎么编写一个Linux64位软件注册机”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
准备工作
我们将会使用到以下工具
1:Linux机器(64bitmintbox)2:EDBdebugger3:IDA反汇编工具4:编译器5:本文相关的文件(链接:http://pan.baidu.com/s/1hqti6LA密码:djnt)
运行file命令检测该文件类型
filer5
下面为返回数据
r5:ELF64-bitLSBexecutable,x86-64,version1(SYSV),dynamicallylinked(usessharedlibs),forGNU/Linux2.6.24,BuildID[sha1]=86bf854ce620288567d153883d4609163485d34d,notstripped
从返回数据中我们得知了构建版本,以及得知它是一个动态链接文件
~/Desktop$nmr50000000000601109B__bss_start00000000006010e0Dbuf000000000040069dTcheck_password0000000000601109bcompleted.69720000000000601060D__data_start0000000000601060Wdata_start00000000006010a0Ddelta00000000004005e0tderegister_tm_clones0000000000400650t__do_global_dtors_aux0000000000600e18t__do_global_dtors_aux_fini_array_entry0000000000601068D__dso_handle0000000000600e28d_DYNAMIC0000000000601109D_edata0000000000601110B_end0000000000400894T_fini0000000000400670tframe_dummy0000000000600e10t__frame_dummy_init_array_entry0000000000400a80r__FRAME_END__0000000000601000d_GLOBAL_OFFSET_TABLE_w__gmon_start__0000000000400500T_init0000000000600e18t__init_array_end0000000000600e10t__init_array_start00000000004008a0R_IO_stdin_usedw_ITM_deregisterTMCloneTablew_ITM_registerTMCloneTable0000000000600e20d__JCR_END__0000000000600e20d__JCR_LIST__w_Jv_RegisterClasses0000000000400890T__libc_csu_fini0000000000400820T__libc_csu_initU__libc_start_main@@GLIBC_2.2.500000000004007b6Tmain0000000000601080DmasterUprintf@@GLIBC_2.2.5Uputs@@GLIBC_2.2.5Urandom@@GLIBC_2.2.50000000000400610tregister_tm_clones00000000004005b0T_startUstrcmp@@GLIBC_2.2.5Ustrcpy@@GLIBC_2.2.5Ustrlen@@GLIBC_2.2.50000000000601110D__TMC_END__
64位程序集基础
相对于X86架构,X64架构增加了扩展寄存器设置和一些额外的指令。
以下为X64增加的寄存器列表
r8,r9,r10,r11,r12,r13,r14,r15
可以通过r8d访问r8寄存器中的低32位,通过r8w访问r8寄存器中的低16位,通过rb8访问r8寄存器中的低8位。
这样更多的RIP(指令指针)就可以直接进行访问了。
X64架构中所有的寄存器都是64位的,RIP同样也是64位,但是目前的实现方法仅是支持48位线性地址(线性地址:逻辑活动:慈云数据爆款香港服务器,CTG+CN2高速带宽、快速稳定、平均延迟10+ms 速度快,免备案,每月仅需19元!! 点击查看地址到物理地址变换之间的中间层)
除了普通的寄存器它还增加了SSE寄存器,命名为xmm8~xmm15。
如果在EAX寄存器上进行数据移动操作,他将从0一直连续到RAX寄存器的高32位。
为了达到调试程序的目的,我们将使用EDB debugger,这个调试程序类似于Windows平台下的ollydbg,上手十分容易,下面就是默认的EDB窗口。
在X64架构下参数传递与X86架构完全不同。
RDI, RSI, RDX, RCX, r8以及r9等都是通过堆栈进行参数传递。
菜单栏和ollydbg一样简洁
破解开始
运行我们的r5文件,返回输出如下
~/Desktop$./r5Usage:./r5password
明文信息毕竟不太好,但是他给了我们一个需要密码的提示。我们必须弄清楚在反汇编程序中打开它会发生什么?显然它在寻找并传送一个参数到函数中。
你可以清楚看到argv[1]作为参数传递给check_password()函数。
首先是有关于输入字符串的长度,字符串长度要与“this_is_not_even_interesting_its_garbage”这个字符串的长度相等。
.data:00000000006010E0;charbuf[].data:00000000006010E0bufdb\'this_is_not_even_interesting_its_garbage\',0.data:00000000006010E0;DATAXREF:check_password+1C#o.data:00000000006010E0;check_password+3C#o....data:00000000006010E0_dataends.data:00000000006010E0.bss:0000000000601109;===========================================================================
检测这里
call_strlen;CallProceduremovrbx,raxmovedi,offsetbuf;“this_is_not_even_interesting_its_garbag”…call_strlen;CallProcedurecmprbx,rax;CompareTwoOperandsjzshortGo;JumpifZero(ZF=1)
在这之后,字符串中的数据就会被我们输入的字符串数据替换
movrax,[rbp+passcode]movrsi,rax;srcmovedi,offsetbuf;\"this_is_not_even_interesting_its_garbag\"...call_strcpy;CallProceduremov[rbp+VarCheck],1jmploc_400791;Jump
经过这个操作之后,程序会进入一个循环。如果指标指数delta值为0那么就会跳过这个循环体。
movzxeax,delta[rax];
如果不是,将利用delta的值和其他参数在输入字符串中执行一些数学运算。
用C语言来表示
x=(random()%delta[index])+1;delta[index]=delta[index]-x;var_check=var_check^(unsignedint)delta[index];
random() 并没有调用srand()进行初始化,所以我们可以轻松的进行猜测。
***,经过40轮的循环,变化的字符串如果与“this_aint_that_simple_but_good_luck_haha”相等,那么将显示“password OK”
我们可以使用以下C语言代码进行计算字符串
#includeunsignedchardelta[]={3,253,3,249,0,3,6,0,241,0,250,7,22,235,8,252,246,2,254,243,4,19,1,234,237,15,253,240,242,15,12,243,241,12,7,0,5,14,10,4,};unsignedcharbuff[48];intmain(intargc,char**argv){intindex=0;intvar_check=1;unsignedcharx=\'\x00\';strcpy(buff,\"this_aint_that_simple_but_good_luck_haha\");while(var_check){index=0;var_check=0;while(index
还没有评论,来说两句吧...