添加两个地址

Adding two addreses

我有可执行文件,出于教育目的我正在对其进行调查。我正在使用 IDA pro 来了解可执行文件的用途,但有几个问题。这是我的代码:

1.text:00401525                 call    ebp ; MapViewOfFile
2.text:00401527                 mov     ebp, eax
3.text:00401529                 test    ebp, ebp
4.text:0040152B                 mov     [esp+54h+argv], ebp ; argv-shi ari chemi dll gadmotanili
5.text:0040152F                 jnz     short loc_401538
6.text:00401531                 push    eax             ; Code
7.text:00401532                 call    ds:exit
8.text:00401538 ; ---------------------------------------------------------------------------
9.text:00401538
10.text:00401538 loc_401538:                             ; CODE XREF: _main+EFj
11.text:0040154C                 mov     esi, [ebp+3Ch]
12.text:0040154F                 push    ebp
13.text:00401550                 add     esi, ebp
14.text:00401552                 mov     ebx, eax
15.text:00401554                 push    esi
16.text:00401555                 mov     [esp+68h+var_30], ebx
17.text:00401559                 mov     ecx, [esi+78h]
18.text:0040155C                 push    ecx
19.text:0040155D                 call    sub_401040

我进行枚举只是为了简化我的问题。

正如您在第 1 行看到的 MapViewofFile 函数被调用,返回的地址存储在 ebp 中,然后存储在 argv 中(只是为了清楚kernel32.dll 是正在映射的文件)。

在第 11 行之后(据我所知)一些函数指针被移到了 esi3ch十进制是60,每个函数都是4字节,我把kernel32.dll导出的所有函数都列出来,发现第15个函数是AddSecureMemoryCacheCallback。然后 ebp 被压入堆栈,在第 13 行我完全糊涂了。据我了解,它会将 kernel32.dlls 的指针添加到指向 AddSecureMemoryCacheCallback 的指针,这是无稽之谈,但我想不出它能做什么,这样做的目的是什么?抱歉,如果我的问题听起来很愚蠢,我是汇编新手,我无法粘贴整个代码,因为它太大了。谢谢。

函数调用MapViewOfFile

Return value
If the function succeeds, the return value is the starting address of the mapped view.
If the function fails, the return value is NULL. To get extended error information, call GetLastError.

这是优化代码,因此 ebp 用作通用寄存器,而不是基指针。

1   call    ebp ; MapViewOfFile
2   mov     ebp, eax            //EBP = start address of mapped view.
3   test    ebp, ebp            //Success or failure?
4   mov     [esp+54h+argv], ebp //save mapped address in a variable
5   jnz     short loc_401538    //Success -> jump to loc_401538
6   push    eax                 //failure -> clean up and exit.  
7   call    ds:exit
8 ---------------------------------------------------------------------------
9
10 loc_401538:                             ; CODE XREF: _main+EFj
11  mov     esi, [ebp+3Ch]       //esi = MappedFile.SomeOffset at addr 60 in the mapped file
12  push    ebp                  //Param3 =  Addr(MappedFile)               
13  add     esi, ebp             //esi = pointer(MappedFile.SomeOffset)
14  mov     ebx, eax             //ebx = start of mapped file
15  push    esi                  //Param2 = pointer(MappedFile.SomeOffset)
16  mov     [esp+68h+var_30], ebx //store start of mapped file in some var
17  mov     ecx, [esi+78h]       //ecx = MappedFile.SomeOffset-> = 120 
18  push    ecx                  //Param1 = MappedFile.SomeOffset[120]
19  call    sub_401040           //call subroutine(Param1, Param2, Param3)

该子例程是使用 cdecl calling convention 的具有 3 个参数的函数。 Param2 和 Param3 是指向映射文件的指针,param1 是一些未知数据。
如果您知道被映射文件的文件名,那么您可以使用十六进制编辑器查看数据并(可能)查看哪个偏移量存储在偏移量 60 处,然后计算偏移量处存储的数据:[0+offset[60]][120] .

请注意,调用 return 的子例程很可能是一个值,因为 eax 可用。

关于您的评论
您认为此代码段调用 Kernel32.dll 中的函数的假设是不正确的。所有指针都指向由 MapViewOfFile 编辑的 return 缓冲区,您必须研究该特定文件的内容才能理解代码的作用。

寄存器的推送只是工作中的cdecl调用约定。因为这是 c 代码,它在内部使用 cdecl 调用约定,要求所有参数都使用堆栈传输。
在外部它使用 stdcall 将前 3 个参数传输到寄存器中。

stdcallcdecl return 的结果都是 EAX