无法理解此汇编 x86 代码

Unable to understand this assembly x86 code

我很困惑为什么“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++代码。

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

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

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

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

这是 CRYPTO_malloc

的论据

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

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

当然是在crypto\rsa\rsa_ossl.c.

中定义了inside rsa_ossl_private_encrypt

这是一个亮点,因为有三个调用“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 的值)。我手动分析发现call在下面几行,可能是版本不同造成的。

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