装配:添加两个地址

时间:2017-05-21 17:06:35

标签: assembly reverse-engineering cpu-registers ida

我是程序员的新手,目前有可执行文件,我正在调查用于教育目的。我正在使用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中(只是为了清楚{{1}已被映射)。之后在第11行(据我所知),一些函数指针在kernel32.dll中移动了。十进制的esi3ch,每个函数是4个字节,我列出了从60导出的所有函数,发现第15个函数是kernel32.dll。然后AddSecureMemoryCacheCallback被推到堆栈上,第13行我完全糊涂了。据我所知,它会将ebp s的指针添加到指向kernel32.dll的指针,这是无意义的,但我想不出它可以做什么,这是什么目的?对不起,如果我的问题听起来很傻,我是装配新手,我无法粘贴整个代码,因为它太大了。感谢。

1 个答案:

答案 0 :(得分:2)

该函数调用MapViewOfFile

  

返回值
  如果函数成功,则返回值是映射视图的起始地址   如果函数失败,则返回值为NULL。要获取扩展错误信息,请调用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是一些未知数据 如果您知道要映射的文件的文件名,那么您可以使用hexeditor查看数据并(可能)查看偏移量60中存储的偏移量,然后计算偏移量中存储的数据:[0+offset[60]][120]

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

关于您的评论
您假设此代码段调用Kernel32.dll中的函数不正确。所有指针都指向MapViewOfFile返回的缓冲区,您必须研究该特定文件的内容以了解代码的作用。

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

stdcallcdecl都会在EAX中返回结果。