我正在努力解决大学的这一练习。我们必须“破解”一个程序,该程序缺少启动该程序所需的许可证文件。我们仅使用Linux Shell。
所以我已经做的是创建此丢失的许可证文件。它是一个.ini,其中包括许可证持有人和许可证密钥。我现在唯一要寻找的是正确的许可证密钥。任务说我们应该使用“ strace”和“ ltrace”来解决这个问题。 这是我得到的输出:
fopen("license.ini", "r") =0x55c088307380
fgets("LicenseHolder=annabell.krause@ex"..., 4096, 0x55c088307380) = 0x7ffe72450860
strncmp("LicenseKey=", "LicenseHolder=annabell.krause@ex"..., 11) = 3
strncmp("LicenseHolder=", "LicenseHolder=annabell.krause@ex"..., 14) = 0
sscanf(0x7ffe72450860, 0x55c08753c16b, 0x7ffe72450800, 0xffffc000) = 1
fgets("LicenseKey=aoeklycf", 4096, 0x55c088307380) = 0x7ffe72450860
strncmp("LicenseKey=", "LicenseKey=aoeklycf", 11) = 0
sscanf(0x7ffe72450860, 0x55c08753c121, 0x7ffe72450840, 0xfffff800) = 1
fgets("LicenseKey=aoeklycf", 4096, 0x55c088307380) = 0
memfrob(0x7ffe72450840, 8, 0, 0xfbad2498) = 0x7ffe72450840
strncmp("KEOAFSIL", "aoeklycf", 8) = -22
fwrite("ERROR: License key is invalid.\n", 1, 31, 0x7faeabe60680
ERROR: License key is invalid.
) = 31
+++ exited (status 1) +++
所以我想答案就在最后的memfrob和strncmp函数中。但是我不知道下一步是什么。
答案 0 :(得分:4)
让我们逐个查看库跟踪调用。重要的部分在步骤5中。
打开文件
fopen("license.ini", "r") =0x55c088307380
打开许可证文件。
解析许可证持有人
fgets("LicenseHolder=annabell.krause@ex"..., 4096, 0x55c088307380) = 0x7ffe72450860
从文件LicenseHolder=annabell.krause@ex…
中读取一行。
strncmp("LicenseKey=", "LicenseHolder=annabell.krause@ex"..., 11) = 3
该行是否以LicenseKey=
开头? 3
的返回值表示否,不是。
strncmp("LicenseHolder=", "LicenseHolder=annabell.krause@ex"..., 14) = 0
该行是否以LicenseHolder=
开头?是的,确实如此。
sscanf(0x7ffe72450860, 0x55c08753c16b, 0x7ffe72450800, 0xffffc000) = 1
不幸的是,ltrace没有取消引用任何地址来显示内容。我们知道0x7ffe72450860是当前行,因此大概是从当前行中提取电子邮件地址。
解析许可证密钥
fgets("LicenseKey=aoeklycf", 4096, 0x55c088307380) = 0x7ffe72450860
它读取另一行:LicenseKey=aoeklycf
。
strncmp("LicenseKey=", "LicenseKey=aoeklycf", 11) = 0
该行是否以LicenseKey=
开头?是的,确实如此。
sscanf(0x7ffe72450860, 0x55c08753c121, 0x7ffe72450840, 0xfffff800) = 1
它正在解析当前行。大概是提取您输入的许可证密钥aoeklycf
,并将其保存在变量中,以便以后与预期的许可证密钥进行比较。类似于sscanf(line, "LicenseKey=%s", licenseKey);
。
文件结束
fgets("LicenseKey=aoeklycf", 4096, 0x55c088307380) = 0
它尝试读取另一行并点击EOF。忽略第一个参数,它只是显示上次调用后缓冲区中剩余的内容。
许可证密钥比较
memfrob(0x7ffe72450840, 8, 0, 0xfbad2498) = 0x7ffe72450840
通过将每个字节与42异或来“加密”某个存储区的8个字节。这可以通过再次运行memfrob()
来反转。我将“加密”放在空中引号中,因为这几乎不能称为加密。只是有点困惑。
请注意,0x7ffe72450840是来自上方sscanf()
的地址。这正在扰乱我在上面称为licenseKey
的变量,即从输入文件中提取的LicenseKey=
字符串。
strncmp("KEOAFSIL", "aoeklycf", 8) = -22
这是钱线。它会比较实际值和预期值,但会失败。
错误消息
fwrite("ERROR: License key is invalid.\n", 1, 31, 0x7faeabe60680) = 31
打印错误。
但是作者不希望您能够运行简单的字符串搜索(如strings ./program
)将许可证密钥从可执行文件中拉出。为避免必须在license.ini
中输入许可证密钥的 frobbed 版本,而不是原始字符串strings
会找到。
代码可能类似于:
char *expected = "aoeklycf";
char actual[BUFSIZE];
sscanf(line, "LicenseKey=%s", actual);
memfrob(actual);
if (strncmp(actual, expected, strlen(expected)) != 0) {
error("ERROR: License key is invalid.\n");
}
您是否从程序中提取了aoeklycf
?如果是这样,则您错过了memfrob()
步骤。 license.ini
需要列出许可证密钥的“加密”版本:KEOAFSIL
。