分析一个delphi程序

系统 : Windows xp

程序 : k4n6

程序下载地址 :https://pan.baidu.com/s/1pLANxyj

要求 : 注册机编写

使用工具 : OD & DeDe

可在看雪论坛中查找关于此程序的破文,传送门

首先在DeDe找到激发按钮点击事件的 代码:

0044435C   55                     push    ebp
0044435D   8BEC                   mov     ebp, esp
0044435F   33C9                   xor     ecx, ecx
00444361   51                     push    ecx
00444362   51                     push    ecx
00444363   51                     push    ecx
00444364   51                     push    ecx
00444365   51                     push    ecx
00444366   51                     push    ecx
00444367   51                     push    ecx
00444368   51                     push    ecx
00444369   53                     push    ebx
0044436A   56                     push    esi
0044436B   57                     push    edi
0044436C   8BD8                   mov     ebx, eax
0044436E   33C0                   xor     eax, eax
00444370   55                     push    ebp

* Possible String Reference to: ‘閒铥朕_^[嬪]?
|
00444371   680D454400             push    $0044450D

***** TRY
|
00444376   64FF30                 push    dword ptr fs:[eax]
00444379   648920                 mov     fs:[eax], esp
0044437C   8D55E4                 lea     edx, [ebp-$1C]

* Reference to control Edit3 : TEdit
|
0044437F   8B83D8020000           mov     eax, [ebx+$02D8]

* Reference to: controls.TControl.GetText(TControl):TCaption;
|
00444385   E892F9FDFF             call    00423D1C
0044438A   8B45E4                 mov     eax, [ebp-$1C]

* Reference to: [email protected]:Integer;
|           or: [email protected];
|           or: system.DynArraySize(Pointer):Integer;
|
0044438D   E8CEF7FBFF             call    00403B60
00444392   48                     dec     eax
00444393   0F8C4C010000           jl      004444E5
00444399   8D55E8                 lea     edx, [ebp-$18]

* Reference to control Edit3 : TEdit
|
0044439C   8B83D8020000           mov     eax, [ebx+$02D8]....略

看到提供的很多Call  dede都提供了参考,再用od载入程序查看该段代码:

0044435C   .  55            push    ebp                              ;  Button1Click
0044435D   .  8BEC          mov     ebp, esp
0044435F   .  33C9          xor     ecx, ecx
00444361   .  51            push    ecx
00444362   .  51            push    ecx
00444363   .  51            push    ecx
00444364   .  51            push    ecx
00444365   .  51            push    ecx
00444366   .  51            push    ecx
00444367   .  51            push    ecx
00444368   .  51            push    ecx
00444369   .  53            push    ebx
0044436A   .  56            push    esi
0044436B   .  57            push    edi
0044436C   .  8BD8          mov     ebx, eax
0044436E   .  33C0          xor     eax, eax
00444370   .  55            push    ebp
00444371   .  68 0D454400   push    0044450D
00444376   .  64:FF30       push    dword ptr fs:[eax]
00444379   .  64:8920       mov     dword ptr fs:[eax], esp
0044437C   .  8D55 E4       lea     edx, dword ptr [ebp-1C]
0044437F   .  8B83 D8020000 mov     eax, dword ptr [ebx+2D8]
00444385   .  E8 92F9FDFF   call    00423D1C
0044438A   .  8B45 E4       mov     eax, dword ptr [ebp-1C]          ;  获取密钥
0044438D   .  E8 CEF7FBFF   call    00403B60                         ;  取长度
00444392   .  48            dec     eax
00444393   .  0F8C 4C010000 jl      004444E5                         ;  字符串为空则跳出判断
00444399   .  8D55 E8       lea     edx, dword ptr [ebp-18]
0044439C   .  8B83 D8020000 mov     eax, dword ptr [ebx+2D8]
004443A2   .  E8 75F9FDFF   call    00423D1C
004443A7   .  8D55 F0       lea     edx, dword ptr [ebp-10]
004443AA   .  8B83 D0020000 mov     eax, dword ptr [ebx+2D0]
004443B0   .  E8 67F9FDFF   call    00423D1C
004443B5   .  8D55 EC       lea     edx, dword ptr [ebp-14]
004443B8   .  8B83 D4020000 mov     eax, dword ptr [ebx+2D4]
004443BE   .  E8 59F9FDFF   call    00423D1C
004443C3   .  8B45 F0       mov     eax, dword ptr [ebp-10]          ;  获取用户名
004443C6   .  E8 95F7FBFF   call    00403B60                         ;  取长度
004443CB   .  83F8 04       cmp     eax, 4                           ;  小于4则跳出判断
004443CE   .  0F8C 11010000 jl      004444E5
004443D4   .  8B45 EC       mov     eax, dword ptr [ebp-14]          ;  获取公司名
004443D7   .  E8 84F7FBFF   call    00403B60                         ;  取长度
004443DC   .  83F8 03       cmp     eax, 3                           ;  小于3则跳出判断
004443DF   .  0F8C 00010000 jl      004444E5
004443E5   .  8B45 F0       mov     eax, dword ptr [ebp-10]          ;  取用户名
004443E8   .  0FB600        movzx   eax, byte ptr [eax]              ;  取第一个字符
004443EB   .  0FB680 DF5944>movzx   eax, byte ptr [eax+4459DF]       ;  按照字符的值取出 表里的值,这里用插件取出表
004443F2   .  8945 F4       mov     dword ptr [ebp-C], eax
004443F5   .  8B45 F0       mov     eax, dword ptr [ebp-10]
004443F8   .  0FB640 02     movzx   eax, byte ptr [eax+2]            ;  取第三个字符
004443FC   .  0FB6B0 DF5944>movzx   esi, byte ptr [eax+4459DF]       ;  按照字符的值取出 表里的值
00444403   .  8B45 EC       mov     eax, dword ptr [ebp-14]          ;  再取公司名
00444406   .  E8 55F7FBFF   call    00403B60                         ;  获取公司名长度
0044440B   .  8B55 EC       mov     edx, dword ptr [ebp-14]          ;  保存公司名
0044440E   .  0FB64402 FE   movzx   eax, byte ptr [edx+eax-2]        ;  取倒数第二个字符
00444413   .  0FB6B8 DF5944>movzx   edi, byte ptr [eax+4459DF]       ;  按照字符的值取出 表里的值
0044441A   .  8B45 EC       mov     eax, dword ptr [ebp-14]
0044441D   .  E8 3EF7FBFF   call    00403B60
00444422   .  8B55 EC       mov     edx, dword ptr [ebp-14]
00444425   .  0FB64402 FF   movzx   eax, byte ptr [edx+eax-1]        ;  取倒数第一个字符
0044442A   .  0FB680 DF5944>movzx   eax, byte ptr [eax+4459DF]       ;  按照字符的值取出 表里的值
00444431   .  8B55 F0       mov     edx, dword ptr [ebp-10]
00444434   .  0FB652 03     movzx   edx, byte ptr [edx+3]            ;  取用户名第四个字符
00444438   .  0FB692 DF5944>movzx   edx, byte ptr [edx+4459DF]       ;  按照字符的值取出 表里的值
0044443F   .  8B4D EC       mov     ecx, dword ptr [ebp-14]
00444442   .  0FB649 02     movzx   ecx, byte ptr [ecx+2]            ;  取公司名第三个字符
00444446   .  0FB689 DF5944>movzx   ecx, byte ptr [ecx+4459DF]       ;  按照字符的值取出 表里的值
0044444D   .  0FAFD1        imul    edx, ecx
00444450   .  8955 F8       mov     dword ptr [ebp-8], edx           ;  保存相乘结果
00444453   .  8B55 F4       mov     edx, dword ptr [ebp-C]           ;  用户名第一个字符在表中对应的值
00444456   .  0FAFD6        imul    edx, esi
00444459   .  0FAFD7        imul    edx, edi
0044445C   .  0FAFD0        imul    edx, eax
0044445F   .  0355 F8       add     edx, dword ptr [ebp-8]
00444462   .  8955 FC       mov     dword ptr [ebp-4], edx
00444465   .  8B45 FC       mov     eax, dword ptr [ebp-4]
00444468   .  35 D8280000   xor     eax, 28D8
0044446D   .  05 7D4A8D28   add     eax, 288D4A7D
00444472   .  8945 FC       mov     dword ptr [ebp-4], eax           ;  结果保存
00444475   .  8B45 FC       mov     eax, dword ptr [ebp-4]
00444478   .  B9 39300000   mov     ecx, 3039
0044447D   .  C1C1 06       rol     ecx, 6                           ;  循环左移
00444480   .  35 14970000   xor     eax, 9714
00444485   .  C1C8 02       ror     eax, 2
00444488   .  C1F8 03       sar     eax, 3                           ;  算数右移
0044448B   .  01C8          add     eax, ecx
0044448D   .  0345 F8       add     eax, dword ptr [ebp-8]
00444490   .  40            inc     eax
00444491   .  66:F7D0       not     ax
00444494   .  09C1          or      ecx, eax
00444496   .  05 9A020000   add     eax, 29A
0044449B   .  8945 FC       mov     dword ptr [ebp-4], eax           ;  结果保存
0044449E   .  33C0          xor     eax, eax
004444A0   .  55            push    ebp
004444A1   .  68 DB444400   push    004444DB
004444A6   .  64:FF30       push    dword ptr fs:[eax]
004444A9   .  64:8920       mov     dword ptr fs:[eax], esp
004444AC   .  8D55 E0       lea     edx, dword ptr [ebp-20]
004444AF   .  8B83 D8020000 mov     eax, dword ptr [ebx+2D8]
004444B5   .  E8 62F8FDFF   call    00423D1C                         ;  获取密钥
004444BA   .  8B45 E0       mov     eax, dword ptr [ebp-20]
004444BD   .  E8 4E36FCFF   call    00407B10                         ;  StrToInt
004444C2   .  3B45 FC       cmp     eax, dword ptr [ebp-4]           ;  和结果是否相同?
004444C5   .  75 0A         jnz     short 004444D1
004444C7   .  B8 24454400   mov     eax, 00444524                    ;  good , this number come from your keygen ?
004444CC   .  E8 A3FAFFFF   call    00443F74                         ;  ShowMessage
004444D1   >  33C0          xor     eax, eax
004444D3   .  5A            pop     edx
004444D4   .  59            pop     ecx
004444D5   .  59            pop     ecx

代码分析完毕,虽然变量操作很多很复杂,但耐下心来做的话还是觉得比较简单的。

打开http://www.cnblogs.com/ZRBYYXDM/p/5115596.html中搭建的框架,向着界面上多加一个编辑框和标签用来输入公司名。

ID: IDC_EDIT_COMPANY | TYPE:BUTTON
ID: IDC_STATIC | TYPE:Label | Caption:公司名

修改OnBtnDecrypt函数如下:

void CKengen_TemplateDlg::OnBtnDecrypt()
{
    // TODO: Add your control notification handler code here
    CString name;
    GetDlgItemText( IDC_EDIT_NAME,name );                    //获取用户名字串基本信息。

    CString company;
    GetDlgItemText( IDC_EDIT_COMPANY,company );                    //获取用户名字串基本信息。

    if ( name.GetLength() >= 4 && company.GetLength() >= 3 ){      //格式控制。
        int table[] = {
            0x00, 0x10, 0x39, 0x44, 0x00, 0x24, 0x39, 0x44, 0x00, 0x0C,
            0xAF, 0x40, 0x00, 0x14, 0xAF, 0x40, 0x00, 0x1C, 0xAF, 0x40,
            0x00, 0x24, 0xAF, 0x40, 0x00, 0x34, 0xAF, 0x40, 0x00, 0x3C,
            0xAF, 0x40, 0x00, 0x44, 0xAF, 0x40, 0x00, 0x4C, 0xAF, 0x40,
            0x00, 0x54, 0xAF, 0x40, 0x00, 0x5C, 0xAF, 0x40, 0x00, 0x2C,
            0xAF, 0x40, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
            0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03,
            0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00,
            0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0A,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2C, 0x61, 0x23,
            0x47, 0x0E, 0x26, 0x61, 0x20, 0x31, 0x49, 0x36, 0x24, 0x2B,
            0x42, 0x31, 0x63, 0x0E, 0x29, 0x5E, 0x30, 0x4B, 0x38, 0x2A,
            0x33, 0x44, 0x3D
        };

        unsigned int ch = table[name[0]];
        unsigned int ch2 = table[name[2]];
        unsigned int ch3 = table[ company[company.GetLength() - 2] ];
        unsigned int ch4 = table[ company[company.GetLength() - 1] ];
        unsigned int ch5 = table[ name[3] ];
        unsigned int ch6 = table[ company[2] ];

        unsigned int res = ch5 * ch6;
        unsigned int res2 = ch * ch2 * ch3 * ch4 + res;
        unsigned int res3;

        //左移异或这些操作直接拷贝源汇编代码改改
        __asm{
            push eax
            push ecx

            mov eax, res2
            xor eax, 0x28D8
            add eax, 0x288D4A7D

            mov ecx, 0x3039
            rol ecx, 6
            xor eax, 0x9714
            ror eax, 2
            sar eax, 3
            add eax, ecx

            add eax, res
            inc eax
            not ax
            or ecx, eax
            add eax, 0x29A
            mov res3, eax

            pop ecx
            pop eax
        }

        CString PassWord;
        PassWord.Format( "%lu",res3 );
        SetDlgItemText( IDC_EDIT_PASSWORD2,PassWord );
    }
    else
        MessageBox( "用户名格式错误!" );
}

再将OnBtnCopy函数改成:

void CKengen_TemplateDlg::OnBtnCopy()
{
    // TODO: Add your control notification handler code here
    CString cmd;
    GetDlgItemText( IDC_BTN_COPY,cmd );

    if ( OpenClipboard() ){                                        //打开剪贴板
        CString str;
        HANDLE hClip;
        char *pBuf;

        EmptyClipboard();

        if ( cmd == "拷贝用户名" )                                //如果命令是拷贝用户名
            GetDlgItemText( IDC_EDIT_NAME,str );
        else{
            if ( cmd == "拷贝公司名" )
                GetDlgItemText( IDC_EDIT_COMPANY,str );
            else
                GetDlgItemText( IDC_EDIT_PASSWORD2,str );
        }

        hClip = GlobalAlloc( GMEM_MOVEABLE,str.GetLength() + 1 );
        pBuf = (char*)GlobalLock( hClip );
        strcpy( pBuf,str );
        GlobalUnlock( hClip );
        SetClipboardData( CF_TEXT,hClip );
        CloseClipboard();

        if ( cmd == "拷贝用户名" ){                                //变换命令
            SetDlgItemText( IDC_BTN_COPY,"拷贝公司名" );
            SetDlgItemText( IDC_STC_MSG,"拷贝用户名成功!" );    //提示成功
        }
        else{
            if ( cmd == "拷贝公司名" ){
                SetDlgItemText( IDC_BTN_COPY,"拷贝序列号" );
                SetDlgItemText( IDC_STC_MSG,"拷贝公司名成功!" );
            }
            else{
                SetDlgItemText( IDC_BTN_COPY,"拷贝用户名" );
                SetDlgItemText( IDC_STC_MSG,"拷贝序列号成功!" );
            }
        }
    }
    else
        SetDlgItemText( IDC_STC_MSG,"拷贝失败!" );
}

再在OnInitDialog中添加此代码修改标题:SetWindowText(_T("Keygen"));

运行效果:

时间: 2024-10-14 04:56:10

分析一个delphi程序的相关文章

OD 实验(十二) - 对一个 Delphi 程序的逆向

程序: 运行程序 界面显示的是未注册 点击 Help -> About 点击 Use Reg Key 这里输入注册码 用 PEiD 看一下 该程序是用 Delphi 6.0 - 7.0 写的 逆向: 用 OD 打开程序 右键 -> 查找 -> 所有参考文本字串 然后右键 -> 查找文本 搜索 这里有个是 accepted 为接受,failed 为失败 双击 accepted 处 在 Delphi 中,push 后的 retn 指令相当于 jmp 指令 原文地址:https://ww

OD学习笔记10:一个VB程序的加密和解密思路

前边,我们的例子中既有VC++开发的程序,也有Delphi开发的程序,今天我们给大家分析一个VB程序的加密和解密思路. Virtual BASIC是由早期DOS时代的BASIC语言发展而来的可视化编程语言. VB是由事件驱动的编程语言:就是在可视化编程环境下我们可以绘制一些窗体,按钮,编辑框等控件,然后为这些控件所可能引发的事件如按钮被单击或者被双击编写对应的处理代码. 所有的VB程序几乎都是依赖于一个外部的动态链接库.这个动态链接库的名字是:MSVBVM60.dll(可能有多个版本,但名字都差

学习笔记之03-第一个C程序代码分析

一.代码分析 打开项目中的main.c文件(C程序的源文件拓展名为.c),可以发现它是第一个C程序中的唯一一个源文件,代码如下: 1 #include <stdio.h> 2 3 int main(int argc, const char * argv[]) { 4 // insert code here... 5 printf("Hello, World!\n"); 6 return 0; 7 } 1.#include <stdio.h> #include 是

第一个C程序代码分析

一.代码分析 1.打开项目中的main.c文件(C程序的源文件拓展名为.c),可以发现它是第一个C程序中的唯一一个源文件,代码如下: #include <stdio.h> int main(int argc, const char * argv[]) { // insert code here... printf("Hello, World!\n"); return 0; } 2.#include <stdio.h> (1)#include 是C语言的预处理指令

【转】delphi程序只允许运行一个实例的三种方法:

一.        创建互斥对象 在工程project1.dpr中创建互斥对象 Program project1 Uses Windows,Form, FrmMain in 'FrmMain.pas' {MainForm}; {$R *.res} var hAppMutex: THandle; //声明互斥变量 begin hAppMutex := CreateMutex(nil, false,’projectname’); //创建互斥对象projectname工程名称 if ( (hAppM

【C语言】03-第一个C程序代码分析

前面我们已经创建了一个C程序,接下来分析一下里面的代码. 项目结构如下: 一.代码分析 打开项目中的main.c文件(C程序的源文件拓展名为.c),可以发现它是第一个C程序中的唯一一个源文件,代码如下: 1 #include <stdio.h> 2 3 int main(int argc, const char * argv[]) 4 { 5 6 // insert code here... 7 printf("Hello, World!\n"); 8 return 0;

C语言 03-第一个C程序代码分析

本文目录 一.代码分析 二.开发和运行C程序的步骤 三.总结 说明:这个C语言专题,是学习iOS开发的前奏.也为了让有面向对象语言开发经验的程序员,能够快速上手C语言.如果你还没有编程经验,或者对C语言.iOS开发不感兴趣,请忽略. 在上一篇中我们已经创建了一个C程序,接下来分析一下里面的代码. 项目结构如下: 一.代码分析 打开项目中的main.c文件(C程序的源文件拓展名为.c),可以发现它是第一个C程序中的唯一一个源文件,代码如下: 1 #include <stdio.h> 2 3 in

软件测试第二次作业 - 写一个Java程序,用于分析一个字符串中各个单词出现的频率,并将单词和它出现的频率输出显示。

题目一: 1. 写一个Java程序,用于分析一个字符串中各个单词出现的频率,并将单词和它出现的频率输出显示.(单词之间用空格隔开,如“Hello World My First Unit Test”): 2. 编写单元测试进行测试: 3. 用ElcEmma查看代码覆盖率,要求覆盖率达到100%. Demo类: 1 import java.util.HashMap; 2 import java.util.Iterator; 3 import java.util.Map; 4 import java.

基于Linux C的socketEthereal程序和Package分析 (一个)

 执行测试平台:CentOS 6.5发行版,内核版本号3.11 1. Linux抓包源程序 在OSI七层模型中.网卡工作在物理层和数据链路层的MAC子层. 进行网络通信时.源主机通过socket(或其他)应用程序产生IP报文,经过各个OSI层层封装,数据包以Ethernet帧的形式进入物理层.Ethernet帧包括源主机地址.IP报文.目标地址(IP地址.port号或映射的6字节MAC地址)和须要传送到目标主机的其他信息. 目标的MAC地址是哪里来的呢?这牵扯到一个ARP协议(介乎于网络层和