开新坑开新坑~~~

说明

  后面的一些样本都在这,来源是 B 站的“艮艮为山”,在此感谢 UP 的分享!
   链接:https://pan.baidu.com/s/1BaROP5e9UbJMSN1sgOOKbA
   提取码:z2i6

Crackme

查壳

查壳
查壳

  无壳,编程语言是 Delphi。

  拖入 x32dbg 打开,并按 shift + D,查看字符串。

查看字符串
查看字符串

  点击“Error!”跳转

关键跳转
关键跳转

  显然,选中位置按空格将 je 修改为 jne 即可。

Crackme
Crackme

Keygenme

分析

  Crackme 的位置往上找到函数入口。

关键部分
关键部分

  最前面应该是某个校验的部分,猜测是判断调用函数是否成功?

  第一个函数 GetDlgItemTextW 函数 (winuser.h),对话框中的控件关联的标题或文本。存入了第三个参数,也就是 abexcm5.402324 中。这里获取的是输入的 key。
  第二个函数 GetVolumeInformationA 函数 (fileapi.h),获取指定卷名称,也就是文件存放的位置,例子中地址 40225C 保存内容为 “新加卷”。
如果卷名是中文,记住在内存查看的时候将编码修改为 GBK。

修改编码
修改编码

  第三个函数 lstrcatA 函数 (winbase.h),将一个字符串追加到另一个字符串后面。这里将字符串 1 追加到卷名后。
  然后循环 2 次,将从卷名保存地址开始的前四个字节每次加 1。
  后续将字符串 2 写入新位置,再将前面循环结果追加到字符串 2 的后面。
  第四个函数 lstrcmpA 函数 (winbase.h),将输入 key 与追加完成后的字符串进行对比,相等则比较成功。也在这里可知在我这台电脑上计算出来的正确 Key 值为 “L2C-5781夷菊卷4562-ABEX”。简单代码注释如下:
注释代码
注释代码

代码

// 环境:VS2022
#include<stdio.h>
#include<string.h>

#define MAX 100

int main(int argc, char* argv[])
{
    char Str1[MAX] = "4562-ABEX";
    char* pStr1 = Str1;
    char Str2[MAX] = "L2C-5781";
    char* pStr2 = Str2;
    int equal = 1;
    char Str3[MAX];
    printf("请输入 key\n");
    scanf("%s",Str3);


    char szVolumeNameBuf[MAX_PATH];
    char szFileSystemBuf[MAX_PATH];
    DWORD dwVolumeSerialNum, dwMaxComponentLength, dwSysFlags;

    BOOL bGet = GetVolumeInformationA(
        NULL,
        szVolumeNameBuf,
        MAX_PATH,
        &dwVolumeSerialNum,
        &dwMaxComponentLength,
        &dwSysFlags,
        szFileSystemBuf,
        MAX_PATH);

    //if (bGet) {
    //    printf("Default Volume Name: %s\n", szVolumeNameBuf);
    //    printf("Default File System: %s\n", szFileSystemBuf);
    //}
    //else {
    //    DWORD dwError = GetLastError();
    //    printf("Failed to get volume information. Error code: %d\n", dwError);
    //}

    pStr1 = lstrcatA(szVolumeNameBuf, Str1);
    for (int i = 0; i < 2; i++)
    {
        pStr1[0] = pStr1[0] + 1;
        pStr1[1] = pStr1[1] + 1;
        pStr1[2] = pStr1[2] + 1;
        pStr1[3] = pStr1[3] + 1;
    }
    pStr2 = lstrcatA(pStr2, pStr1);
    printf("正确 Key 为:%s\n", pStr2);
    equal = lstrcmpiA(pStr2, Str3);
    if (!equal)
    {
        printf("Well Done!\n");
        printf("Yep, you entered a correct serial!\n");
    }
    else
    {
        printf("Error!\n");
        printf("The serial you entered is not correct!\n");
    }
    return 0;
}