看见论坛研究破解的不少,但是研究破解linux的很少。
在中秋佳节之季,发一个自己写的linux内存注册机,希望高手能将它改成通用的linux内存注册机吧. 
此内存注册机的原理是,调用ptrace,在指定的地址处修改被调用进程的指令为int3,使其中断,然后查看各寄存器的值,得到自己需要的注册码.

作者:软件路由论坛 www.routerclub.com 想得太美 



一个linux程序,下面为在ida中反编译出来的代码,我们需要在08049658处设置断点,注册码保存在[ebp+arg_4](即[ebp+12]) 中.

代码:
.text:0804962D                 push    [ebp+var_C]     ; FILE * .text:08049630                 call    _fclose .text:08049635                 add     esp, 10h .text:08049638                 mov     [ebp+var_18], 0 .text:0804963C                 sub     esp, 4 .text:0804963F                 sub     esp, 8 .text:08049642                 push    [ebp+arg_4]     ; char * .text:08049645                 call    _strlen .text:0804964A                 add     esp, 0Ch .text:0804964D                 push    eax             ; size_t .text:0804964E                 push    [ebp+arg_4]     ; char *  // 注册码的存放地址 .text:08049651                 lea     eax, [ebp+var_98] .text:08049657                 push    eax             ; char * .text:08049658                 call    _strncmp .text:0804965D                 add     esp, 10h .text:08049660                 test    eax, eax .text:08049662                 jnz     short loc_8049670 .text:08049664                 mov     [ebp+var_9C], 1 .text:0804966E                 jmp     short loc_804967A




以下为内存注册机的源码,本注册机调用原程序,在原程序的08049658处设置断点,同时读取[epb+12]地址处的的值,从而得到注册码:

代码:
#include <sys/ptrace.h> #include <sys/types.h> #include <sys/wait.h> #include <unistd.h> #include <linux/user.h> #include <sys/syscall.h> unsigned char backup[4],backup1[4],bin[64]; const int long_size = sizeof(long); void getdata(pid_t child, long addr, char *str, int len) {   char *laddr;     int i, j;     union u {             long val;             char chars[long_size];     }data;          i = 0;     j = len / long_size;     laddr = str;     while(i < j) {         data.val = ptrace(PTRACE_PEEKTEXT, child, addr + i * 4, NULL);         memcpy(laddr, data.chars, long_size);         ++i;         laddr += long_size;     }          j = len % long_size;     if(j != 0) {         data.val = ptrace(PTRACE_PEEKTEXT, child, addr + i * 4, NULL);         memcpy(laddr, data.chars, j);     }     str[len] = '\0';        } void putdata(pid_t child, long addr, char *str, int len) {   char *laddr;     int i, j;     union u {             long val;             char chars[long_size];     }data;          i = 0;     j = len / long_size;     laddr = str;     while(i < j) {         memcpy(data.chars, laddr, long_size);         ptrace(PTRACE_POKETEXT, child, addr + i * 4, data.val);         ++i;         laddr += long_size;     }          j = len % long_size;     if(j != 0) {         memcpy(data.chars, laddr, j);         ptrace(PTRACE_POKETEXT, child, addr + i * 4, data.val);     } } int main() {   pid_t child;     const int long_size = sizeof(long);     child = fork();     if(child == 0) {         ptrace(PTRACE_TRACEME, 0, NULL, NULL);         execl("/home/gtr/crackme", "crackme", NULL);     }     else {         int status;         union u {             long val;             char chars[long_size];         }data;         struct user_regs_struct regs,regi;         int start = 0;         long ins,zz;         char **a_eax;         int i,jj=0;         char code[] = {0xcd,0x80,0xcc,0};  //int3机器码         unsigned char check[4];         char str[6]={1,2,3,4,5,6};         char str1[128]={0,0,0,0,0,0};                                             while(1) {             wait(&status);             if(WIFEXITED(status))                 break;                                ptrace(PTRACE_GETREGS, child, NULL, &regs);             ins = ptrace(PTRACE_PEEKTEXT, child, regs.eip, NULL);                                       if (jj==0){             getdata(child, 0x08049658, backup1, 3);             putdata(child, 0x08049658, code, 3);   //修改程序的数据,设置断点              jj=1;           }                            if (regs.eip!=0x40000790) {              getdata(child, regs.ebp+12, str,40);  //读取指定地址处的值              getdata(child, *(long*)str, str1,128);  //读取指定地址处的值              printf("EIP地址是: %lx 注册码是:%s\n", regs.eip,str1);                            }                                                     }     return 0; }