逆向的第一个小代码

第一次逆向来个简单的加强信心,http://www.crackmes.de/users/lucifer/first_c_crackme/。(这个图片里有crackme,右键保存下图标,把后缀改为zip,即可。)

1. 用OllyDbg加载停在程序开始处:00401000,接着在00401013处调用了call 00401080,跟进去,看到这个过程中各种SetXXX,再往下发现一个ExitProcess,而这之上有调用00401165处的call 004014E2,所有的处理应该都在这里面了,进入004014E2过程。序列号的运算都在这里面了。

2. 看了别人的解决方案是,直接在"Searce for -> All referenced text strings"中查找"Your Name:",直接定位到004014E2过程中,更加快捷有效。

3. 核心代码如下:

00401668  |.  8D85 F8FEFFFF lea     eax, dword ptr [ebp-108]         ; |
0040166E  |.  890424        mov     dword ptr [esp], eax             ; |
00401671  |.  E8 5AF60000   call    <jmp.&msvcrt.strlen>             ; strlen
00401676  |.  89C2          mov     edx, eax                         ;  得到了name的长度存放在eax中,然后赋给edx
00401678  |.  69D2 CD750800 imul    edx, edx, 875CD                  ;  将长度乘以0x875CD
0040167E  |.  B8 1F85EB51   mov     eax, 51EB851F
00401683  |.  F7E2          mul     edx
00401685  |.  89D0          mov     eax, edx
00401687  |.  C1E8 05       shr     eax, 5                           ;  这一段4行代码为用edx/0x64,结果放在eax中
0040168A  |.  69C0 90FCFFFF imul    eax, eax, -370                   ;  在将eax乘以-0x370
00401690  |.  BA 00000000   mov     edx, 0
00401695  |.  52            push    edx                              ; ||format => NULL
00401696  |.  50            push    eax                              ; ||s
00401697  |.  DF2C24        fild    qword ptr [esp]                  ; ||将上面计算得到的eax值转为双精度浮点数8字节
0040169A  |.  8D6424 08     lea     esp, dword ptr [esp+8]           ; ||
0040169E  |.  DD9D F0FBFFFF fstp    qword ptr [ebp-410]              ; ||浮点数保存下来
004016A4  |.  DD85 F0FBFFFF fld     qword ptr [ebp-410]              ; ||再进入浮点寄存器中
004016AA  |.  DD5C24 08     fstp    qword ptr [esp+8]                ; ||浮点数放入堆栈待用,下面%i只用到了前面4字节
004016AE  |.  C74424 04 691>mov     dword ptr [esp+4], 00401469      ; ||ASCII "%i-x019871"
004016B6  |.  8D85 F8FCFFFF lea     eax, dword ptr [ebp-308]         ; ||
004016BC  |.  890424        mov     dword ptr [esp], eax             ; ||
004016BF  |.  E8 FCF50000   call    <jmp.&msvcrt.sprintf>            ; |sprintf

4. 根据算法,用C++写了如下算号器:

// 在Microsoft Visual C++ 2008中编译
#include <iostream>
#include <string>
using namespace std;

int main()
{
    cout << "Input your name: ";
    string strName;
    cin >> strName;
    int iTemp = strName.length();
    iTemp *= 0x875CD;
    iTemp /= 0x64;
    iTemp *= -0x370;
    unsigned unTemp = iTemp;
    double dTemp = unTemp;
    int *piTemp = (int*) &dTemp;
    cout << "Serial Number: " << *piTemp << "-x019871" << endl;;
    system("pause");
    return 0;
}
原文地址:https://www.cnblogs.com/wnarutou/p/3426220.html