您好,登錄后才能下訂單哦!
本篇內容介紹了“怎么編寫一個Linux64位軟件注冊機”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
準備工作
我們將會使用到以下工具
1: Linux 機器 ( 64bit mint box) 2: EDB debugger 3: IDA 反匯編工具 4: 編譯器 5: 本文相關的文件(鏈接:http://pan.baidu.com/s/1hqti6LA 密碼:djnt)
運行file命令檢測該文件類型
file r5
下面為返回數據
r5: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=86bf854ce620288567d153883d4609163485d34d, not stripped
從返回數據中我們得知了構建版本,以及得知它是一個動態鏈接文件
~/Desktop $ nm r5 0000000000601109 B __bss_start 00000000006010e0 D buf 000000000040069d T check_password 0000000000601109 b completed.6972 0000000000601060 D __data_start 0000000000601060 W data_start 00000000006010a0 D delta 00000000004005e0 t deregister_tm_clones 0000000000400650 t __do_global_dtors_aux 0000000000600e18 t __do_global_dtors_aux_fini_array_entry 0000000000601068 D __dso_handle 0000000000600e28 d _DYNAMIC 0000000000601109 D _edata 0000000000601110 B _end 0000000000400894 T _fini 0000000000400670 t frame_dummy 0000000000600e10 t __frame_dummy_init_array_entry 0000000000400a80 r __FRAME_END__ 0000000000601000 d _GLOBAL_OFFSET_TABLE_ w __gmon_start__ 0000000000400500 T _init 0000000000600e18 t __init_array_end 0000000000600e10 t __init_array_start 00000000004008a0 R _IO_stdin_used w _ITM_deregisterTMCloneTable w _ITM_registerTMCloneTable 0000000000600e20 d __JCR_END__ 0000000000600e20 d __JCR_LIST__ w _Jv_RegisterClasses 0000000000400890 T __libc_csu_fini 0000000000400820 T __libc_csu_init U __libc_start_main@@GLIBC_2.2.5 00000000004007b6 T main 0000000000601080 D master U printf@@GLIBC_2.2.5 U puts@@GLIBC_2.2.5 U random@@GLIBC_2.2.5 0000000000400610 t register_tm_clones 00000000004005b0 T _start U strcmp@@GLIBC_2.2.5 U strcpy@@GLIBC_2.2.5 U strlen@@GLIBC_2.2.5 0000000000601110 D __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位線性地址(線性地址:邏輯地址到物理地址變換之間的中間層)
除了普通的寄存器它還增加了SSE寄存器,命名為xmm8~xmm15。
如果在EAX寄存器上進行數據移動操作,他將從0一直連續到RAX寄存器的高32位。
為了達到調試程序的目的,我們將使用EDB debugger,這個調試程序類似于Windows平臺下的ollydbg,上手十分容易,下面就是默認的EDB窗口。
在X64架構下參數傳遞與X86架構完全不同。
RDI, RSI, RDX, RCX, r8以及r9等都是通過堆棧進行參數傳遞。
菜單欄和ollydbg一樣簡潔
破解開始
運行我們的r5文件,返回輸出如下
~/Desktop $ ./r5 Usage: ./r5 password
明文信息畢竟不太好,但是他給了我們一個需要密碼的提示。我們必須弄清楚在反匯編程序中打開它會發生什么?顯然它在尋找并傳送一個參數到函數中。
你可以清楚看到argv[1]作為參數傳遞給check_password()函數。
首先是有關于輸入字符串的長度,字符串長度要與“this_is_not_even_interesting_its_garbage”這個字符串的長度相等。
.data:00000000006010E0 ; char buf[] .data:00000000006010E0 buf db 'this_is_not_even_interesting_its_garbage',0 .data:00000000006010E0 ; DATA XREF: check_password+1C#o .data:00000000006010E0 ; check_password+3C#o ... .data:00000000006010E0 _data ends .data:00000000006010E0 .bss:0000000000601109 ; ===========================================================================
檢測這里
call _strlen ; Call Procedure mov rbx, rax mov edi, offset buf ; “this_is_not_even_interesting_its_garbag”… call _strlen ; Call Procedure cmp rbx, rax ; Compare Two Operands jz short Go ; Jump if Zero (ZF=1)
在這之后,字符串中的數據就會被我們輸入的字符串數據替換
mov rax, [rbp+passcode] mov rsi, rax ; src mov edi, offset buf ; "this_is_not_even_interesting_its_garbag"... call _strcpy ; Call Procedure mov [rbp+VarCheck], 1 jmp loc_400791 ; Jump
經過這個操作之后,程序會進入一個循環。如果指標指數delta值為0那么就會跳過這個循環體。
movzx eax, delta[rax] ;
如果不是,將利用delta的值和其他參數在輸入字符串中執行一些數學運算。
用C語言來表示
x = (random() % delta[index] ) + 1; delta[index] = delta[index] - x; var_check = var_check ^ (unsigned int )delta[index] ;
random() 并沒有調用srand()進行初始化,所以我們可以輕松的進行猜測。
***,經過40輪的循環,變化的字符串如果與“this_aint_that_simple_but_good_luck_haha”相等,那么將顯示“password OK”
我們可以使用以下C語言代碼進行計算字符串
#include <stdio.h> unsigned char delta[] = { 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, }; unsigned char buff [48] ; int main(int argc, char **argv) { int index = 0; int var_check = 1; unsigned char x = '\x00'; strcpy(buff, "this_aint_that_simple_but_good_luck_haha"); while ( var_check ) { index = 0; var_check = 0; while ( index < 40) { if (delta[index]) { x = (random() % delta[index] ) + 1; delta[index] = delta[index] - x; var_check = var_check ^ (unsigned int )delta[index] ; buff[index] = buff[index] + x; } // if zero index++; } } printf("%s\n", buff); }
編譯并運行這個程序,我們獲得以下輸出
“well_done_now_go_on_irc_and_ask_for_more” ~/Desktop $ ./r5 “well_done_now_go_on_irc_and_ask_for_more”
密碼成功破解。
“怎么編寫一個Linux64位軟件注冊機”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。