【问题标题】:Unable to understand this assembly x86 code无法理解此程序集 x86 代码
【发布时间】:2020-12-06 04:37:51
【问题描述】:

我很困惑为什么“sub_18054DFD0”函数使用“crypto\rsa\rsa_ossl.c”的地址作为参数而不使用它。( “crypto\rsa\rsa_ossl.c”是 openssl api 库中的一个文件。)
我想知道它是否调用了 rsa_ossl 库中的函数?

.text:00000001805BF4E7 loc_1805BF4E7:                          ; DATA XREF: .rdata:0000000180902990o
.text:00000001805BF4E7                                         ; .rdata:00000001809029A0o ...
.text:00000001805BF4E7                 mov     [rsp+28h+arg_50], r15
.text:00000001805BF4EF                 call    sub_1805AF500   ; STR: "crypto\bn\bn_ctx.c"
.text:00000001805BF4F4                 mov     rcx, rsi
.text:00000001805BF4F7                 call    sub_1805AF3D0   ; STR: "crypto\bn\bn_ctx.c"
.text:00000001805BF4FC                 mov     rcx, rsi
.text:00000001805BF4FF                 mov     r15, rax
.text:00000001805BF502                 call    sub_1805AF3D0   ; STR: "crypto\bn\bn_ctx.c"
.text:00000001805BF507                 mov     rcx, [rbx+18h]
.text:00000001805BF50B                 mov     rdi, rax
.text:00000001805BF50E                 call    sub_1805614B0
.text:00000001805BF513                 add     eax, 7
.text:00000001805BF516                 mov     r8d, 100h
.text:00000001805BF51C                 cdq
.text:00000001805BF51D                 and     edx, 7
.text:00000001805BF520                 add     eax, edx
.text:00000001805BF522                 lea     rdx, aCryptoRsaRsa_o ; "crypto\\rsa\\rsa_ossl.c"
.text:00000001805BF529                 sar     eax, 3
.text:00000001805BF52C                 movsxd  rbp, eax
.text:00000001805BF52F                 mov     rcx, rbp
.text:00000001805BF532                 call    sub_18054DFD0

进入函数“sub_18054DFD0”:

.text:000000018054DFD0 sub_18054DFD0   proc near               ; CODE XREF: sub_1804FE630+42Ap
.text:000000018054DFD0                                         ; sub_1804FFAE0+AAp ...
.text:000000018054DFD0                 mov     eax, 28h
.text:000000018054DFD5                 call    sub_180670B80
.text:000000018054DFDA                 sub     rsp, rax
.text:000000018054DFDD                 mov     rax, cs:off_18091E640
.text:000000018054DFE4                 test    rax, rax
.text:000000018054DFE7                 jz      short loc_18054DFFC
.text:000000018054DFE9                 lea     r9, sub_18054DFD0
.text:000000018054DFF0                 cmp     rax, r9
.text:000000018054DFF3                 jz      short loc_18054DFFC
.text:000000018054DFF5                 add     rsp, 28h
.text:000000018054DFF9                 jmp     rax
.text:000000018054DFFC ; ---------------------------------------------------------------------------
.text:000000018054DFFC
.text:000000018054DFFC loc_18054DFFC:                          ; CODE XREF: sub_18054DFD0+17j
.text:000000018054DFFC                                         ; sub_18054DFD0+23j
.text:000000018054DFFC                 test    rcx, rcx
.text:000000018054DFFF                 jnz     short loc_18054E008
.text:000000018054E001                 xor     eax, eax
.text:000000018054E003                 add     rsp, 28h
.text:000000018054E007                 retn
.text:000000018054E008 ; ---------------------------------------------------------------------------
.text:000000018054E008
.text:000000018054E008 loc_18054E008:                          ; CODE XREF: sub_18054DFD0+2Fj
.text:000000018054E008                 mov     cs:dword_18091E638, 0
.text:000000018054E012                 add     rsp, 28h
.text:000000018054E016                 jmp     j_malloc_0
.text:000000018054E016 sub_18054DFD0   endp ; sp-analysis failed

编译器:MSVC
架构:x86-64bit
该文件是一个混合DLL,这部分是C++代码。

【问题讨论】:

  • ????????请在此处以纯文本形式发布代码、错误、示例数据或文本输出,而不是难以阅读、无法复制粘贴以帮助测试代码或在答案中使用的图像,并且对依赖的人构成障碍在屏幕阅读器上。您可以编辑问题以在问题正文中添加代码。为了便于格式化,请使用{} 按钮标记代码块,或使用四个空格缩进以获得相同的效果。 屏幕截图的内容无法搜索、作为代码运行或复制和编辑以创建解决方案。

标签: assembly visual-c++ openssl x86-64 reverse-engineering


【解决方案1】:

这是CRYPTO_malloc的论据

很容易看出,这个函数将把它的参数传递给malloc_impl,如果不是它自己,否则,回退到malloc
OpenSSL(及其分支,如 BoringSSL)使用这种间接方式来增强 malloc,请参阅 this

字符串 crypto\rsa\rsa_ossl.cwhere 您的 first 代码块中的函数的来源。
由于 OpenSSL 是开源的并且有源文件名信息,因此很容易查明您正在查看的代码:

inside rsa_ossl_private_encrypt 当然是在 crypto\rsa\rsa_ossl.c 中定义的。

因为有 3 个调用“BN 函数”(我猜是一个大数字工具),其中两个相同,以及一个调用“内存分配函数”。
一个人可能会被分配内存的计算所抛弃,特别是一个人可能会搜索常量,但正如源代码所示,它们是由内联宏 BN_num_bytes 完成的,因此,搜索那些常量(即 256、7 , 8 和所有其他数字)不会给出任何信息。

如您所见,sub_18054DFD0 处的函数是OPENSSL_malloc,它只需要一个参数。

OPENSSL_malloc 将传递OPENSSL_FILE(其中as this doc pod says, it's just an alias for __FILE__)作为CRYPTO_malloc 的第二个参数。
它还将行号作为第三个参数传递,在您的情况下为 256(r8d 的值)。我手动分析发现调用了下面几行,可能是版本不同。

这些内存分配例程跟踪分配调用者的文件和行号,以减轻内存泄漏和损坏的调试。
如果没有像 Valgrind 或 DrMemory(适用于 Windows)这样的工具,由于内存损坏,真的很难查明错误,所以这是有道理的。

【讨论】:

  • 很抱歉我没有认真看OpenSSL...所以你的意思是这个代码段“loc_1805BF4E7”实际上是crypto\rsa\rsa_ossl.c中的“rsa_ossl_private_encrypt”函数.我弄错了吗?那我不明白为什么汇编代码会以这种方式显示对 API 库函数的调用,而不是显示“调用 rsa_ossl_private_encrypt”并将函数指向导入函数。 (我是逆向工程的新手,如果这个问题很愚蠢,请原谅我)。谢谢!
  • @Jenny 这些是 OpenSSL 内部函数,即使库被编译为 DLL,除非程序标记它们,否则它们不会被导出。编译后,库会丢失其所有源代码,包括变量和函数名称。只有导出的函数会保留一个名称(并不总是,也不总是源中的那个),但这些是内部函数。顺便说一句,如果您希望 IDA 识别所有函数名称,您可以尝试为您的 OpenSSL 版本查找(或生成)FLIRT 签名或调试符号。
【解决方案2】:

sub_18054DFD0 似乎是内存分配调用。如果在 cs:off_18091E640 内存位置中没有指定覆盖函数,它将使用默认函数 (j_malloc_0)。

上面的代码块会加载这个值,检查它是否不是NULL,检查它是否指向这个函数(cs:off_18091E640,这将创建一个永无止境的递归调用),然后调用覆盖。

如果任一覆盖检查失败(无覆盖或循环引用),则检查内存分配大小是否为 0。如果是,则立即返回 nullptr,否则流传递到 j_malloc_0

覆盖函数或j_malloc_0 都可以使用edx 寄存器值(可能作为分配诊断的一部分)。

【讨论】:

  • 它表明 cs:off_18091E640 指向函数 sub_18054DFD0 ,所以它会调用一个神经结束的递归调用,然后像你说的那样调用 j_malloc_0 。但我仍然很困惑 j_malloc_0 是 malloc 的封装函数,这个 sub_18054DFD0 函数究竟做了什么?它会调用 c 文件中的 encrypt 函数吗?
猜你喜欢
  • 2017-11-13
  • 1970-01-01
  • 2011-12-18
  • 2011-08-28
  • 2021-07-10
  • 2014-03-19
  • 2020-05-14
  • 1970-01-01
相关资源
最近更新 更多